js实现canvas三色线条三维空间旋转动画效果代码

代码语言:html

所属分类:动画

代码描述:js实现canvas三色线条三维空间旋转动画效果代码

代码标签: 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