'use strict'; const fs=require('fs'),path=require('path'),os=require('os'); const root=path.resolve(__dirname,'..'),fixtures=path.join(__dirname,'.fixtures'); const script=text=>''; const versions=['3.4','3.5','3.6','3.7','3.8','4.0','4.1','4.2','4.3']; const frames=versions.map(version=>{ const dir=path.join(fixtures,version,'spineboy'); const source=path.join(dir,['3.4','3.5'].includes(version)?'spineboy-mesh.skel':'spineboy-pro.skel'); let html=script(`var module={exports:{}};const modules={};function require(n){return modules[n]}const version=${JSON.stringify(version)};`); for(const name of ['spine-webgl-rasterizer','spine-canvas-clipping','spine-background','spine-legacy-binary']) html+=script('module={exports:{}};\n'+fs.readFileSync(path.join(root,'js',name+'.js'),'utf8')+`\nmodules['./${name}.js']=module.exports;`); html+=script(fs.readFileSync(path.join(root,'lib',version,'spine-canvas.js'),'utf8')); html+=script(`(async()=>{try{ const image=new Image();image.src='data:image/png;base64,${fs.readFileSync(path.join(dir,'spineboy.png')).toString('base64')}';await image.decode(); const text=${JSON.stringify(fs.readFileSync(path.join(dir,'spineboy.atlas'),'utf8'))}; const texture=new (spine.CanvasTexture||spine.canvas.CanvasTexture)(image);let atlas; if(spine.TextureAtlas.length<=1){atlas=new spine.TextureAtlas(text);for(const page of atlas.pages){if(page.setTexture)page.setTexture(texture);else page.texture=texture}} else atlas=new spine.TextureAtlas(text,()=>texture); modules['./spine-legacy-binary.js'].install(spine,version); const bytes=Uint8Array.from(atob('${fs.readFileSync(source).toString('base64')}'),c=>c.charCodeAt(0)); const data=new spine.SkeletonBinary(new spine.AtlasAttachmentLoader(atlas)).readSkeletonData(bytes),skeleton=new spine.Skeleton(data); if(spine.Physics)skeleton.updateWorldTransform(spine.Physics.update);else skeleton.updateWorldTransform(); const offset=new spine.Vector2(),size=new spine.Vector2();skeleton.getBounds(offset,size,[]); const canvas=document.createElement('canvas');canvas.width=canvas.height=400;document.body.appendChild(canvas); const ctx=canvas.getContext('2d'),renderer=modules['./spine-canvas-clipping.js'].createRenderer(spine,ctx,version); if(renderer.rasterization!=='webgl')throw Error('WebGL not active'); let normal; for(const mode of [0,2]){ ctx.setTransform(1,0,0,1,0,0);ctx.fillStyle='#1e1e1e';ctx.fillRect(0,0,400,400); const scale=320/Math.max(size.x,size.y);ctx.translate(200,200);ctx.scale(scale,-scale);ctx.translate(-offset.x-size.x/2,-offset.y-size.y/2); modules['./spine-background.js'].drawCheckerboard(ctx,400,400); for(const slot of skeleton.slots)slot.data.blendMode=mode; renderer.draw(skeleton);const pixels=ctx.getImageData(0,0,400,400).data; if(mode===0)normal=pixels;else{let changed=0;for(let i=0;i3)changed++;if(changed<100)throw Error('Slot multiply did not change image');} } renderer.premultipliedAlpha=true;renderer.draw(skeleton);renderer.dispose(); parent.postMessage({version,result:'PASS'},'*'); }catch(error){parent.postMessage({version,error:error.stack},'*')}})();`); return html; }); const html='
RUNNING
'+script(`let results=[];window.addEventListener('message',e=>{if(e.data.version){results.push(e.data);document.getElementById('result').textContent=JSON.stringify(results)}});for(const html of ${JSON.stringify(frames)}){const frame=document.createElement('iframe');frame.srcdoc=html;document.body.appendChild(frame)}`); const output=path.resolve(process.argv[2]||path.join(os.tmpdir(),'spineviewer-browser-preview-test.html')); fs.writeFileSync(output,html);console.log(output);