45 lines
3.4 KiB
JavaScript
45 lines
3.4 KiB
JavaScript
'use strict';
|
|
// Rasterize the existing H5 vector geometry for the native image component.
|
|
// No remote assets or generated face shapes are used.
|
|
const fs = require('node:fs'), path = require('node:path'), vm = require('node:vm');
|
|
const { chromium } = require('playwright');
|
|
const root = path.resolve(__dirname, '..'), h5 = path.join(root, '../h5');
|
|
const out = path.join(root, 'assets/camera');
|
|
async function main() {
|
|
fs.mkdirSync(out, { recursive: true });
|
|
const sandbox = { window: {} };
|
|
vm.runInNewContext(fs.readFileSync(path.join(h5, 'js/camera-geometry.js'), 'utf8'), sandbox);
|
|
const app = fs.readFileSync(path.join(h5, 'js/app.js'), 'utf8');
|
|
vm.runInNewContext(app.split('/* camera-outline-pure-begin */')[1].split('/* camera-outline-pure-end */')[0], sandbox);
|
|
const browser = await chromium.launch();
|
|
try {
|
|
const page = await browser.newPage({ viewport: { width: 375, height: 726 }, deviceScaleFactor: 2 });
|
|
for (const [index, name] of ['front', 'left', 'right'].entries()) {
|
|
const geometry = sandbox.window.CameraGeometry[index];
|
|
for (const live of [false, true]) {
|
|
const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="375" height="726" viewBox="0 86 375 726">' +
|
|
'<defs><mask id="cut"><rect x="0" y="86" width="375" height="726" fill="white"/><path d="' + sandbox.smoothCameraOutline(geometry.outline) + '" fill="black"/></mask></defs>' +
|
|
'<rect x="0" y="86" width="375" height="726" fill="black" fill-opacity=".85" mask="url(#cut)"/>' +
|
|
'<g fill="none" stroke="' + (live ? '#fff' : '#111') + '" stroke-width="2.5" stroke-dasharray="5 5">' + geometry.guides.map(d => '<path d="' + d + '"/>').join('') + '</g></svg>';
|
|
await page.setContent('<style>html,body{margin:0;background:transparent}svg{display:block}</style>' + svg);
|
|
await page.screenshot({ path: path.join(out, 'mask-' + name + (live ? '-live' : '') + '.png'), omitBackground: true });
|
|
}
|
|
await page.setContent('<style>html,body{margin:0;background:transparent}svg{display:block}</style><svg xmlns="http://www.w3.org/2000/svg" width="375" height="726" viewBox="0 86 375 726"><path fill="white" d="' + sandbox.smoothCameraOutline(geometry.outline) + '"/></svg>');
|
|
await page.screenshot({ path: path.join(out, 'hole-' + name + '.png'), omitBackground: true });
|
|
}
|
|
for (const name of ['icon-album.png', 'icon-shutter.png', 'icon-switch-camera.png']) {
|
|
fs.copyFileSync(path.join(h5, 'assets/img/ui-20261009', name), path.join(out, name));
|
|
}
|
|
fs.copyFileSync(path.join(h5, 'assets/img/ui-20261012/scan-face-mask.png'), path.join(out, 'scan-face-mask.png'));
|
|
const data = fs.readFileSync(path.join(h5, 'assets/img/ui-20261012/scan-base.webp')).toString('base64');
|
|
const png = await page.evaluate(async data => {
|
|
const image = new Image(); image.src = 'data:image/webp;base64,' + data; await image.decode();
|
|
const canvas = document.createElement('canvas'); canvas.width = image.width; canvas.height = image.height;
|
|
canvas.getContext('2d').drawImage(image, 0, 0); return canvas.toDataURL('image/png').split(',')[1];
|
|
}, data);
|
|
fs.writeFileSync(path.join(out, 'scan-base.png'), Buffer.from(png, 'base64'));
|
|
} finally { await browser.close(); }
|
|
console.log('Built H5 camera geometry, icons and scan artwork in taobao/assets/camera');
|
|
}
|
|
main().catch(error => { console.error(error.message); process.exitCode = 1; });
|