js实现canvas三色线条三维空间旋转动画效果代码
代码语言:html
所属分类:动画
代码描述:js实现canvas三色线条三维空间旋转动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<html> <head> <style> body { background: #262626; } #c { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style> </head> <body><canvas id="c" ></canvas> <script> // These have to be ordered by size (ascending) for them to be correctly drawn var circles = [ { color: '#21a5ad', size: 84, angle: Math.PI / 3 }, { color: '#ffad10', size: 92, angle: - Math.PI / 3 }, { color: '#ef4239', size: 100, angle: 0 } ]; // To be able to "twist a circle", it has to be defined as a set of linked points // This is the number of these points (you can see it if you set it to 3 or 4) var segmentsPerCircle = 200; // Time scaling factor : slower when closer to 0, faster when bigger than 1 var speed = .8; // Easing function on the twist (indicates how fast the rotation goes at a given time) // This is equivalent to an ease-in-out-quad // A list of basic easings is available here https://gist.github.com/gre/1650294 function twistEasing(t) { return (t < .5) ? 2 * t * t : 1 - 2 * (t = 1 - t) * t; } var c = document.getElementById('c'), ctx = c.getContext('2d'); Math.PI2 = 2 * Math.PI; // ˉ\_(ツ)_/ˉ // "3d" rotation functions, around base axes // I didn't feel like using matrices so it uses basic 2d geometry and rotation algorithms (trigonometry, pythagore) // rotateZ is a standard 2d rotation around [0,0] (measures the distance, the current angle and increases it, then goes back to X,Y coordinates) // rotateX and rotateY are the same but as if we were viewing the scene from above (for rotateY, so y becomes z) or from the right function rotateX(p, a) { var d = Math.sqrt(p[2] * p[2] + p[1] * p[1]), na = Math.atan2(p[1], p[2]) + a; return [p[0], d * Math.sin(na), d * Math.cos(na)]; } function rotateY(p, a) { var d = Math.sqrt(p[2] * p[2] + p[0] * p[0]), na = Math.atan2(p[2], p[0]) + a; return [d * Math.cos(na), p[1], d * Math.sin(na)]; } function rotateZ(p, a) { var d = Math.sqrt(p[1] * p[1] + p[0] * p[0]), na = Math.atan2(p[1], p[0]) + a; return [d * Math.cos(na), d * Math.sin(na), p[2]]; } // Change the canvas size and restore other properties (lost when we resize) function resize() { c.width = c.offsetWidth; c.height = c.offsetHeight; ctx.translate(c.width *.5, c.height * .5); ctx.lineWidth = 5; ctx.lineCap = 'round'; ctx.lineJoin = 'round'; } window.addEventListener('resize', resize); resize(); // Variables enabling mouse control (just adds an extra rotation around Y based on the mouse positions) // To get a nicer result we smoothly transition to the new mouse position, so we have to use 2 variables // (one for the actual angle and one for the final one, where the mouse points) var angleOffset = 0, angleOffsetGoal = 0; c.addEventListener('mousemove', function(e) { angleOffsetGoal = Math.PI2 * (e.clientX / c.width - .5); }); c.addEventListener('mouseout', function(e) { angleOffsetGoal = 0; }); // This is one of the main elements I guess, it creates a regular polygon (so something close to a circle with enough points) // but also rotates the points around the X axis progressively from 0 at the left up to `angle` at the right // this creates the "twist". Here is what it would look like with twelve points and different `angle` values https://imgur.com/a/5FmOn function loxo(radius, angle, segments) { var r = []; for(var i = 0; i < segments; i++) { // We place the points regularly on a full circle so the angle increment is 2*PI (radians so 1 turn) divided by the number of segments // (and we multiply that by i to get the current one) var a = Math.PI2 * i / segments, c = Math.cos(a), s = Math.sin(a); var ax = Math.PI * .5; // c is the cosine, which is also the x position of the point on the circle with this angle // in [-1, 1], so (c + 1) * .5 gives the horizontal position from 0 (left) to 1 (right) // And the quantity of rotation around the X axis is basically `angle` multiplied by this 0 to 1 factor .........完整代码请登录后点击上方下载按钮下载查看
网友评论0