43 lines
3.0 KiB
HTML
43 lines
3.0 KiB
HTML
<!doctype html><meta charset="utf-8"><title>Spine preview compositing tests</title>
|
|
<pre id="result">RUNNING</pre>
|
|
<script>var module={exports:{}},__dirname='';function require(n){return n==='path'?{join:()=>''}:{}}</script>
|
|
<script src="../js/spine-webgl-rasterizer.js"></script>
|
|
<script>const rasterizer=module.exports;module={exports:{}};</script>
|
|
<script src="../js/spine-background.js"></script>
|
|
<script>const background=module.exports;module={exports:{}};</script>
|
|
<script src="../js/spine-badge.js"></script>
|
|
<script>
|
|
try {
|
|
const badge=module.exports;
|
|
function check(ok,message){if(!ok)throw Error(message)}
|
|
function canvas(w,h){const c=document.createElement('canvas');c.width=w;c.height=h;return c.getContext('2d')}
|
|
function pixel(c,x,y){return c.getImageData(x,y,1,1).data}
|
|
const grid=canvas(220,220);grid.translate(10,20);grid.scale(2,2);background.drawCheckerboard(grid,220,220);
|
|
check(pixel(grid,109,70)[0]===90 && pixel(grid,110,70)[0]===80,'50-unit cells must scale to 100px and follow translation');
|
|
const source=canvas(8,8);source.fillStyle='rgb(128,64,192)';source.fillRect(0,0,8,8);
|
|
const destination=[80,120,160],color=[128,64,192];
|
|
for(const mode of ['source-over','lighter','multiply','screen']) for(const alpha of [1,0.5]){
|
|
const target=canvas(64,64);target.fillStyle='rgb(80,120,160)';target.fillRect(0,0,64,64);
|
|
const raster=rasterizer.createRasterizer(target);check(raster&&raster.begin(),'WebGL unavailable');
|
|
target.globalAlpha=alpha;target.globalCompositeOperation=mode;
|
|
raster.triangle(source.canvas,8,8,0,0,56,8,1,0,56,56,1,1);
|
|
raster.triangle(source.canvas,8,8,0,0,56,56,1,1,8,56,0,1);raster.end();
|
|
const actual=pixel(target,32,32);
|
|
for(let channel=0;channel<3;channel++){
|
|
const s=color[channel]*alpha,d=destination[channel];
|
|
const expected=mode==='lighter'?Math.min(255,s+d):mode==='multiply'?d*(s/255+1-alpha):mode==='screen'?s+d*(1-s/255):s+d*(1-alpha);
|
|
check(Math.abs(actual[channel]-expected)<2,mode+' '+alpha+' channel '+channel+': '+actual[channel]+' vs '+expected);
|
|
}
|
|
check(actual[3]===255,'background alpha must remain opaque');
|
|
target.globalAlpha=1;target.globalCompositeOperation='source-over';target.fillStyle='#ff0000';target.fillRect(0,0,64,64);
|
|
raster.begin();raster.end();check(pixel(target,32,32)[0]===255&&pixel(target,32,32)[1]===0,'background texture must refresh each frame');
|
|
raster.dispose();
|
|
}
|
|
const stamp=canvas(400,400);let text='';const fillText=stamp.fillText.bind(stamp);stamp.fillText=(s,...args)=>{text=s;fillText(s,...args)};
|
|
badge.drawVersion(stamp,400,400,'4.3.75-beta');check(text==='4.3.75-beta','beta version watermark');
|
|
let white=0;for(const value of stamp.getImageData(12,354,170,34).data)if(value>200)white++;
|
|
check(white>100,'watermark pixels');
|
|
document.getElementById('result').textContent='PASS: moving/scaling 50-unit checkerboard, four blend modes at two opacities, background refresh, 4.3 beta watermark';
|
|
}catch(error){document.getElementById('result').textContent='FAIL: '+error.stack}
|
|
</script>
|