0xa0154806…bb3asent to0x99a9b7c1…b069·#16,513,895·view on Etherscan
let M=1;
var isMobile = window.matchMedia("(hover: none)").matches; // no hovering
function resize_render() {
let w=innerWidth, h=innerHeight, dpr=devicePixelRatio;
C.width = M*w*dpr|0;
C.height = M*h*dpr|0;
if (head || f1==1) {
Lx = Math.min(C.width,C.height); Ly=Lx;
} else if (f1==2 || isMobile) {
Lx = C.width; Ly=C.height;
if (Lx>Ly) { Lx=Math.min(Lx,2.5*Ly); }
if (Ly>Lx) { Ly=Math.min(Ly,2.5*Lx); }
} else {
Lx = Math.min(3*Nx,C.width);
Ly = Math.min(3*Ny,C.height);
}
C.style.width = w+'px';
C.style.height = h+'px';
gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly);
render();
}
function texset(wrap) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
}
let tex00,texA,texB,texC,fbA,fbB;
let wrap = gl.REPEAT;
tex00 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex00);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4));
texset(wrap);
texA = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texA);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4));
fbA = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbA);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texA, 0);
texset(wrap);
texB = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texB);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
fbB = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbB);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texB, 0);
texset(wrap);
texC = gl.createTexture(); //colormap
gl.bindTexture(gl.TEXTURE_2D, texC);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 10, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, pal);
texset(wrap);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0);
gl.useProgram(colp);
gl.uniform1i(loc_palc, 1); //texture 1
// and assign uniforms
gl.useProgram(simp);
gl.uniform1fv(loc_km,km);
gl.uniform1fv(loc_kl,kl);
gl.uniform1fv(loc_rand,rand);
gl.useProgram(colp);
gl.uniform1fv(loc_randc,rand);
let prevt=performance.now();
let dt = 1000/60;
let running=true;
let periodic=0;
let anim=0;
let flip=0;
let count=0;
let dxycount=0;
let TT = 120;
let om0 = 0.01, A=0.002;
function render() {
if (running) {
count++;
let time=performance.now();
if (time-prevt>dt) {
gl.viewport(0,0,Nx,Ny);
gl.useProgram(simp);
if (count%TT==0) {
for (let i=0; i<Nrand; i++) { rand[i]=.7*rnd()+.3*rand[i]; }
gl.uniform1fv(loc_rand,rand);
}
if (dxycount==0) {
dx=dxc-dxp;
dy=dyc-dyp;
dz=dzc-dzp;
zc *= 1+2*dz;
xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc;
yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc;
kp[0]+= dx/3;
kp[1]+= dy/3;
kp[15]*=Math.exp(dx/3);
kp[16]*=Math.exp(dy/3);
}
gl.uniform1fv(loc_kp,kp);
if (dx!=0 || dy!=0 || dz!=0) {
dxycount++;
}
gl.uniform3fv(loc_dxy,[dx, dy, dz]);
gl.uniform3fv(loc_rc,[xc, yc, zc]);
gl.uniform1i(loc_t,time);
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.drawArrays(gl.TRIANGLES, 0, 6);
}
gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly);
gl.useProgram(colp);
gl.uniform1i(loc_tc,time);
gl.uniform2f(loc_Lc,Lx,Ly);
gl.uniform3fv(loc_dxyc,[dx, dy, dz]);
gl.uniform3fv(loc_rcc,[xc, yc, zc]);
if (dxycount>=1) {
dxycount=0;
dx=0;dy=0;dz=0;
dxp=dxc;dyp=dyc;dzp=dzc;
}
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, (flip ? texA : texB));
if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6);
}
prevt=time-(time-prevt)%dt;
}
// requestAnimationFrame(render.bind());
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");
ctx.setTransform(1,0,0,-1,0,gl.height);
ctx.drawImage(C,-(C.width-Lx)/2,-(C.height-Ly)/2);
tC.toBlob((blob) => { saveBlob(blob, `Calian-${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==88) dzc-=0.03; //x = in
if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = out
if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f
if (e.keyCode==80) { savescr=1; Lx = Ly = min(C.width,C.height); } //p = print screen
// dzc+=e.deltaY/Ly;
return false;
//e.stopPropagation(); e.preventDefault();
}
function handler(e) {
var scroll = (e.deltaY || -1*e.wheelDelta || 10*e.detail);
var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0;
//if ( window == window.parent ) dzc=Math.min(0,dzc+Math.max(-0.03,Math.min(0.03,e.deltaY/Ly*(1+3*isTouchPad))));
dzc=Math.min(0,dzc+.5*Math.max(-0.03,Math.min(0.03,scroll/Ly*(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 mousedown=0;
gl.canvas.addEventListener('mousedown', function (e) {
mousedown=1;
startx = e.clientX;
starty = e.clientY;
});
gl.canvas.addEventListener('mousemove', function (e) {
if (mousedown) {
dxc-=.5*(e.clientX-startx)/Lx*Math.exp(-0.1*dzc);
dyc+=.5*(e.clientY-starty)/Ly*Math.exp(-0.1*dzc);
startx = e.clientX;
starty = e.clientY;
}
});
gl.canvas.addEventListener('mouseleave', function (e) {
mousedown=0;
});
gl.canvas.addEventListener('mouseup', function (e) {
mousedown=0;
});
gl.canvas.addEventListener('dblclick', function (e) {
running = !running;
});
resize_render();