canvas实现拨开云雾见太阳光芒四射晚霞逼真动画效果代码
代码语言:html
所属分类:动画
代码描述:canvas实现拨开云雾见太阳光芒四射晚霞逼真动画效果代码
代码标签: canvas 拨开 云雾 太阳 光芒 四射 晚霞 逼真 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!doctype html> <html> <head> <meta charset="utf-8"> <title></title> <style> html, body { height: 100%; width: 100%; margin: 0; padding: 0; border: 0; overflow: hidden; } </style> </head> <body> <canvas></canvas> <script> // Currently in Chrome you need to click the "Get Adobe Flash" button so it'll ask you if you want to // allow flash to run. // The rest of this is formatted as: // // Explanation of the compressed code // // ... // // // Commented out, compressed code // // Readable (more or less) version of the code // ... document.addEventListener("DOMContentLoaded", go); function go() { "use strict"; // JS1K's HTML shim gives us a canvas (a) and its 2D context (c) for free. We'll set them up here. let canvas = document.querySelector('canvas'); let ctx = canvas.getContext('2d'); // First off - we define an abbreviation function. This takes an object, iterates over its properties // and stores their names as strings in a 2 or 3 letter variable ("this" is the window object). // // p[0]+p[6] will evaluate to the 1st and 7th letter (or the 1st+"undefined" if there's no 7th), // [p[20]] will be an empty string if the property's name is too short ([undefined] gets coerced to // an empty string). // // This is a variation on Marijn Haverbeke's technique - see https://marijnhaverbeke.nl/js1k/ // // We won't be using it in the readable version of the demo. // A=o=>{for(p in o)this[p[0]+p[6]+[p[20]]]=p} // Next we abbreviate all the properties in our window object because requestAnimationFrame() is // kind of long. We can't call A(window) because it will try to abbreviate all our abbreviations (since // it stores them in the window object) so we'll use it on "top" which has the same properties. // We really just need a shorter requestAnimationFrame(). // // Sidenote: this is a clear violation of JS1K rules, which is why it's very important not to read them // before the competition is over. // A(top) // Now, since our demo is fairly heavy we use a small canvas, but we want it to be fullscreen on a // black background, so we waste ~90 bytes on some CSS to stretch it (currently "object-fit:contain" // doesn't work for canvas on MS browsers). // // To avoid wasting 90 bytes just on this, we take this opportunity to define P and Q as 'width' and // 'height' for later. This is probably a mistake since I ended up packing it with regpack anyway. // // The weird bit at the end is an ES6 template literal being abused to call the array's join method // with something that will be coerced into the string ':100%;'. // a.style=[P='width',Q='height','object-fit:contain;background:#000'].join`:100%;` canvas.style = 'width: 100%; height: 100%; object-fit:contain; background:#000;'; // Now we need a frame counter. // t=0 let frame = 0; // B() is the requestAnimationFrame callback. // B=_=>{ function onFrame() { // Set width and height on our canvases, we'll be using a smaller canvas for the godrays. This // also clears and resets their states. While we're at it, we'll store their dimensions in one // letter vars for later. // w=a[P]=512 // h=a[Q]=256 // W=E[P]=128 // H=E[Q]=64 canvas.width = 512; canvas.height = 256; godraysCanvas.width = 128; godraysCanvas.height = 64; // Set the sun's vertical position. // T=C(t++/w)*24 let sunY = Math.cos(frame++ / 512) * 24; // This is actually the offset from the middle of the canvas. // Get the 2D context for our godrays canvas, and create abbreviations for all the context properties. // A(F=E.getContext`2d`) let godraysCtx = godraysCanvas.getContext('2d'); // Now we set the godrays' context fillstyle (window.fy is 'fillStyle') to a newly created gradient // (cr is 'createRadialGradient') which we also run through our abbreviator. // A(F[fy]=g=F[cR](H,32+T,0,H,32+T,44)) // Could have shaved one more char here... let emissionGradient = godraysCtx.createRadialGradient( godraysCanvas.width / 2, godraysCanvas.height / 2 + sunY, // The sun's center. 0, // Start radius. godraysCanvas.width / 2, godraysCanvas.height / 2 + sunY, // Sun's center again. 44 // End radius. ); godraysCtx.fillStyle = emissionGradient; // Now we addColorStops. This needs to be a dark gradient because our godrays effect will basically // overlay it on top of itself many many times, so anything lighter will result in lots of white. // // If you're not space-bound you can add another stop or two, maybe fade out to black, but this // actually looks good enough. // g[ao](.1,'#0C0804') // g[ao](.2,'#060201') emissionGradient.addColorStop(.1, '#0C0804'); // Color for pixels in radius 0 to 4.4 (44 * .1). emissionGradient.addColorStop(.2, '#060201'); // Color for everything past radius 8.8. // Now paint the gradient all over our godrays canvas. // F[fc](0,0,W,H) godraysCtx.fillRect(0, 0, godraysCanvas.width, godraysCanvas.height); // And set the fillstyle to black, we'll use it to paint our occlusion (mountains). // F[fy]='#000' godraysCtx.fillStyle = '#000'; // For our 1K demo, we paint our sky a solid #644 reddish-brown. But here - let's do it right. // c[fy]=g='#644' // c[fc](0,0,w,h) let skyGradient = ctx.createLinearGradient(0, 0, 0, canvas.height); skyGradient.addColorStop(0, '#2a3e55'); // Blueish at .........完整代码请登录后点击上方下载按钮下载查看
网友评论0