'use strict'; // Local visual diagnostic. The private project/export remain outside version control. const fs = require('fs'), path = require('path'); const root = path.resolve(__dirname, '..'); const source = process.argv[2]; if (!source) throw Error('Usage: node tests/build-x10-comparison.js x10.skel [x10.atlas] [x10.png] [output.html]'); const assets = require('../js/spine-utils').discoverAssets(source); const atlasPath = process.argv[3] || assets.atlasPath; const texturePath = process.argv[4] || assets.texturePaths['x10.png']; const output = process.argv[5] || '/tmp/spine-x10-comparison.html'; const baseline = process.env.SPINE_COMPARE_BASELINE === '1'; const script = s => ''; let html = '
RUNNING
'; html += script('var module={exports:{}};const modules={};function require(n){return modules[n]}'); for (const name of ['spine-webgl-rasterizer', 'spine-canvas-clipping']) html += script('module={exports:{}};\n' + (baseline ? require('child_process').execFileSync('git',['show','HEAD:js/'+name+'.js'],{cwd:root,encoding:'utf8'}) : fs.readFileSync(path.join(root, 'js', name+'.js'), 'utf8')) + `\nmodules['./${name}.js']=module.exports;`); html += script(fs.readFileSync(path.join(root, 'lib/4.2/spine-canvas.js'), 'utf8')); html += script(`(async()=>{try{ const raw=Uint8Array.from(atob('${fs.readFileSync(texturePath).toString('base64')}'),c=>c.charCodeAt(0)); const image=new Image();image.src='data:image/png;base64,${fs.readFileSync(texturePath).toString('base64')}';await image.decode(); if(modules['./spine-webgl-rasterizer.js'].prepareTexture) await modules['./spine-webgl-rasterizer.js'].prepareTexture(image,new Blob([raw],{type:'image/png'})); const atlas=new spine.TextureAtlas(${JSON.stringify(fs.readFileSync(atlasPath,'utf8'))});for(const page of atlas.pages)page.setTexture(new spine.CanvasTexture(image)); const data=new spine.SkeletonBinary(new spine.AtlasAttachmentLoader(atlas)).readSkeletonData(Uint8Array.from(atob('${fs.readFileSync(source).toString('base64')}'),c=>c.charCodeAt(0))); const reference=new Image();reference.src='data:image/png;base64,${fs.readFileSync(path.join(__dirname,'对比测试.png')).toString('base64')}';await reference.decode(); const reports=[]; function panel(name){const e=document.createElement('section');e.innerHTML='
'+name+'
';const c=document.createElement('canvas');c.width=973;c.height=557;e.appendChild(c);document.body.appendChild(e);return c;} const rc=panel('Spine editor export'),rx=rc.getContext('2d');rx.fillStyle='#555';rx.fillRect(0,0,973,557);rx.drawImage(reference,0,0);const expected=rx.getImageData(0,0,973,557).data; function redBounds(pixels){let x0=973,y0=557,x1=0,y1=0;for(let y=0;y<557;y++){const xs=[];for(let x=0;x<973;x++){const i=(y*973+x)*4;if(pixels[i]>100&&pixels[i]>pixels[i+1]*2&&pixels[i]>pixels[i+2]*2)xs.push(x)}if(xs.length>24){x0=Math.min(x0,...xs);y0=Math.min(y0,y);x1=Math.max(x1,...xs);y1=Math.max(y1,y)}}return [x0,y0,x1,y1];} const rb=redBounds(expected); for(const frame of [7,8]){ const sk=new spine.Skeleton(data),state=new spine.AnimationState(new spine.AnimationStateData(data));state.setAnimation(0,'word_fly',false);state.update(frame/30);state.apply(sk);sk.updateWorldTransform(spine.Physics.update); const off=new spine.Vector2(),size=new spine.Vector2();sk.getBounds(off,size,[]); const c=panel('Plugin frame '+frame),ctx=c.getContext('2d');ctx.fillStyle='#555';ctx.fillRect(0,0,973,557); // Editor exports tight bounds plus its export padding. Record bounds for registration. const scale=Math.min(973/size.x,557/size.y);ctx.translate(973/2,557/2);ctx.scale(scale,-scale);ctx.translate(-off.x-size.x/2,-off.y-size.y/2); const renderer=modules['./spine-canvas-clipping.js'].createRenderer(spine,ctx,'4.2');renderer.premultipliedAlpha=true;renderer.draw(sk); const ab=redBounds(ctx.getImageData(0,0,973,557).data),ratio=(rb[2]-rb[0])/(ab[2]-ab[0]); const transform=ctx.getTransform();ctx.setTransform(1,0,0,1,0,0);ctx.fillStyle='#555';ctx.fillRect(0,0,973,557); ctx.translate((rb[0]+rb[2])/2-ratio*(ab[0]+ab[2])/2,(rb[1]+rb[3])/2-ratio*(ab[1]+ab[3])/2);ctx.scale(ratio,ratio);ctx.transform(transform.a,transform.b,transform.c,transform.d,transform.e,transform.f);renderer.draw(sk);renderer.dispose(); const actual=ctx.getImageData(0,0,973,557).data;let sum=0;for(let i=0;i