0xa0154806…bb3asent to0xaf40b660…0f2f·#18,609,611·view on Etherscan
// and assign uniforms
gl.useProgram(simp);
gl.uniform1fv(loc_km,km);
gl.uniform1fv(loc_kl,kl);
// gl.uniform1fv(loc_kv,kv);
// gl.uniform1fv(loc_kw,kw);
gl.uniform1fv(loc_rand,rand);
gl.useProgram(colp);
gl.uniform1fv(loc_randc,rand);
let prevt=performance.now(); //0;
let dt = 1000/30;
let tmult=1,init=1;
let running=true;
let periodic=0;
let flip=0;
let count=0;
let dxycount=0;
let TT = 60+Math.floor(1000*Math.exp(kl[0]-1));//240;
let om0 = 10*0.01;
let time0 = prevt;
let time;
function render() {
if (running) {
let wgt = count/TT;
time=performance.now(); // ms
if (time-prevt>dt) {
count++;
gl.viewport(0,0,Nx,Ny);
gl.useProgram(simp);
gl.uniform1f(loc_mult,tmult);
if (count%TT==0) {
for (let i=0; i<Nrand; i++) { randp[i]=randn[i]; randn[i]=.5*rnd()+.5*rand[i]; }
setrand();
count=0;
}
let wgtfac = wgt*wgt*(1-Math.exp(-4*kl[1]*wgt));
if (count%TT==0) {
for (let i=0; i<Nrand; i++) { rand[i]=randp[i]+(randn[i]-randp[i])*wgtfac; }
setrand();
gl.uniform1fv(loc_rand,rand);
}
let dx1=0,dy1=0,dz1=0;
if (dxycount==0) {
dx=dxc-dxp;
dy=dyc-dyp;
dz=dzc-dzp;
zc *= Math.exp(2*dz); //zc += dz;
xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc;
yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc;
// imposing max(uc.x)<=1, i.e. -xc+zc <= 1, i.e. xc >= zc-1, i.e. dxc >= zc-1-xc
// imposing min(uc.x)>=0, i.e. -xc >= 0, i.e. xc <= 0, i.e. dxc <= -xc
// we need to impose this again because inequalities may fail because zc changed
xc=Math.max(zc-1,Math.min(0,xc));
yc=Math.max(zc-1,Math.min(0,yc));
// // if truncated, fix dx,dxc,dy,dyc
dx = (-.5/(1+dz)+.5)/2; dxc = dxp+dx;
dy = (-.5/(1+dz)+.5)/2; dyc = dyp+dy;
(zc==1)&&(dxc=dyc=0);
kp[6]*=Math.sin(count/TT*2*PI);
kp[7]*=Math.sin(count/TT*2*PI);
}
gl.uniform1fv(loc_kp,kp);
// for (let i=0; i<Nrand; i++) { rand[i]*=0.99; }
if (dx!=0 || dy!=0 || dz!=0) {
dxycount++;
}
gl.uniform3fv(loc_dxy,[dx, dy, dz]);
gl.uniform3fv(loc_rc,[xc, yc, zc]);
gl.uniform1f(loc_t,time/1000.);
gl.uniform1f(loc_tr,count/TT);
for (let j=0; j<2; j++) {
flip = !flip;
gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA));
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB));
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, tex00);
gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, (flip ? texA2 : texB2));
gl.activeTexture(gl.TEXTURE3);
gl.bindTexture(gl.TEXTURE_2D, tex02);
gl.drawBuffers([ gl.COLOR_ATTACHMENT0,gl.COLOR_ATTACHMENT1 ]);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
// flip = !flip;
gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly);
gl.useProgram(colp);
gl.uniform1f(loc_tc,time/1000);
gl.uniform2f(loc_Lc,Lx,Ly);
gl.uniform2f(loc_mousec,mousex,mousey);
gl.uniform1fv(loc_klc,kl);
gl.uniform3fv(loc_dxyc,[dx-dx1, dy-dy1, dz-dz1]);
gl.uniform3fv(loc_rcc,[xc, yc, zc]);
dxycount=0;dx=0;dy=0;dz=0;dxp=dxc;dyp=dyc;dzp=dzc;
if (count>12) { init=0; }
if (!init) {
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA));
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texC); //color map
gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, tex00); //(flip ? texA : texB)); // previous
gl.activeTexture(gl.TEXTURE3);
gl.bindTexture(gl.TEXTURE_2D, (flip ? texB2 : texA2));
gl.activeTexture(gl.TEXTURE4);
gl.bindTexture(gl.TEXTURE_2D, tex02); //(flip ? texA2 : texB2)); // previous
//if (dz==0)
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
}
prevt=time-(time-prevt)%dt;
}
if (savescr==1) {
savescr=2;
resize_render();
}
if (savescr==2) {
savescr=0;
var tC = document.createElement("canvas");
tC.width = Lx; tC.height = Ly;
var ctx = tC.getContext("2d", { preserveDrawingBuffer: true });
const pixels = new Uint8Array(4);
gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, pixels);
ctx.setTransform(1,0,0,-1,0,gl.height);
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);gl.flush();gl.clientWaitSync(sync, 0, gl.TIMEOUT_IGNORED);gl.deleteSync(sync);
C.toBlob((blob) => { saveBlob(blob, `Atlas-${tokenData.tokenId}.png`); });
}
requestAnimationFrame(render);
}
const saveBlob = (function() {
const a = document.createElement('a');
document.body.appendChild(a);
a.style.display = 'none';
return function saveData(blob, fileName) {
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
};
}());
// resize event
let tid=0;
onresize => {
clearTimeout(tid);
tid=setTimeout(resize_render,150)
};
let f1=0,savescr=0;
// keyboard event
onkeyup=e=>{
if (e.key==' ') { // spacebar
running = !running;
}
if ( window !== window.parent ) {
// iframe
if (e.keyCode==65) dxc-=0.01; //a = left
if (e.keyCode==68) dxc+=0.01; //d = right
if (e.keyCode==87) dyc+=0.01; //w = up
if (e.keyCode==83) dyc-=0.01; //s = down
} else {
// not iframe
if (e.keyCode==37) dxc-=0.01; //left
if (e.keyCode==39) dxc+=0.01; //right
if (e.keyCode==38) dyc+=0.01; //up
if (e.keyCode==40) dyc-=0.01; //down
}
if (e.keyCode>=49&&e.keyCode<=56) tmult=1+e.keyCode-49; //1-8
if (e.keyCode==77) anim=!anim; //m = anim/!anim
if (e.keyCode==88) dzc-=0.03; //x = zoom in
if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = zoom out
if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f
if (e.keyCode==80) { savescr=1; Lx = C.width; Ly = C.height; } //p = print screen
return false;
}
document.body.style.cursor = "none";
function handler(e) {
if (running) {
var scroll = (e.deltaY || -1*e.wheelDelta || 10*e.detail);
var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0;
dzc=Math.min(0,dzc+.5*Math.max(-0.1,Math.min(0.1,scroll/Ly*2*(1+3*isTouchPad))));
}
e.stopPropagation();
e.preventDefault();
return false;
}
gl.canvas.addEventListener("mousewheel", handler, false);
gl.canvas.addEventListener("DOMMouseScroll", handler, false);
const delta = 6;
let startx;
let starty;
let startdist=0;
let mousedown=0;
let mousex=.5;
let mousey=.5;
function handler_down(e) {
if (running) {
mousedown=1;
startx = (e.clientX || (e.touches && e.touches[0].clientX));
starty = (e.clientY || (e.touches && e.touches[0].clientY));
if (e.touches && e.touches.length === 2) {
e.preventDefault();
startx = startx/2 + e.touches[1].clientX / 2;
starty = starty/2 + e.touches[1].clientY / 2;
startdist = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2);
}
}
}
gl.canvas.addEventListener("mousedown", handler_down, false);
gl.canvas.addEventListener("touchstart", handler_down, false);
function handler_move(e) {
mousex = e.clientX/Lx*2;
mousey = 1-e.clientY/Ly*2;
if (running && mousedown) {
const sx = (e.clientX || (e.touches && e.touches[0].clientX));
const sy = (e.clientY || (e.touches && e.touches[0].clientY));
e.preventDefault();
if (e.touches && e.touches.length === 2) {
e.preventDefault(); // Prevent page scroll
let scale = 100;
const deltaDistance = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2);
if (startdist!=0) {
scale = 100*(1-deltaDistance/startdist);
}
dzc=Math.min(0,dzc+.5*Math.max(-0.25,Math.min(0.25,1.3*scale/Ly)));
} else {
dxc-=(sx-startx)/Lx*Math.exp(0.2-0.1*dzc);
dyc+=(sy-starty)/Ly*Math.exp(0.2-0.1*dzc);
// imposing max(uc.x)<=1, i.e. -xc+zc <= 1, i.e. xc >= zc-1, i.e. dxc >= zc-1-xc
// imposing min(uc.x)>=0, i.e. -xc >= 0, i.e. xc <= 0, i.e. dxc <= -xc
dxc=Math.max(-1-xc+zc,Math.min(-xc,dxc));
dyc=Math.max(-1-yc+zc,Math.min(-yc,dyc));
startx = sx;starty = sy;
}
}
}
gl.canvas.addEventListener("mousemove", handler_move, false);
gl.canvas.addEventListener("touchmove", handler_move, false);
gl.canvas.addEventListener('ondragstart', function (e) { e.preventDefault(); return false; });
gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; });
gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; });
gl.canvas.addEventListener('touchend', function (e) { mousedown=0; });
gl.canvas.addEventListener('dblclick', function (e) { running = !running; });
resize_render();