js实现canvas鼠标撩动垂柳自然摆动动画效果代码
代码语言:html
所属分类:动画
代码描述:js实现canvas鼠标撩动垂柳自然摆动动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<html> <head> <style> html, body { margin: 0; padding: 0; height: 100%; } body { user-select: none; background-color: #000; display: flex; align-items: center; justify-content: center; overflow: hidden; } canvas { flex-shrink: 0; background-color: #222; image-rendering: -moz-crisp-edges; image-rendering: -webkit-crisp-edges; image-rendering: pixelated; object-fit: contain; } #message { color: white; font-family: sans-serif; position: absolute; left: 50%; top: 40%; transform: translate(-50%,-50%); text-align: center; } h1,h4 { margin: 0; } h1 { font-size: 10vmin; } h4 { font-size: 4vmin; } </style> </head> <body> <div></div> <script> function lerpColor(a, b, amount) { var ah = parseInt(a.replace(/#/g, ""), 16), ar = ah >> 16, ag = (ah >> 8) & 0xff, ab = ah & 0xff, bh = parseInt(b.replace(/#/g, ""), 16), br = bh >> 16, bg = (bh >> 8) & 0xff, bb = bh & 0xff, rr = ar + amount * (br - ar), rg = ag + amount * (bg - ag), rb = ab + amount * (bb - ab); return ( "#" + (((1 << 24) + (rr << 16) + (rg << 8) + rb) | 0).toString(16).slice(1) ); } const PI = Math.PI, TWO_PI = Math.PI * 2; const Util = {}; Util.timeStamp = function() { return window.performance.now(); }; Util.random = function(min, max) { return min + Math.random() * (max - min); }; Util.map = function(a, b, c, d, e) { return (a - b) / (c - b) * (e - d) + d; }; Util.lerp = function(value1, value2, amount) { return value1 + (value2 - value1) * amount; }; Util.clamp = function(value, min, max) { return Math.max(min, Math.min(max, value)); }; const Tween = {}; Tween.linear = function(currentTime, start, degreeOfChange, duration) { return degreeOfChange * currentTime / duration + start; }; Tween.easeInOutQuad = function(t, b, c, d) { t /= d / 2; if (t < 1) return c / 2 * t * t + b; t--; return -c / 2 * (t * (t - 2) - 1) + b; }; Tween.easeInOutExpo = function(t, b, c, d) { t /= d / 2; if (t < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b; t--; return c / 2 * (-Math.pow(2, -10 * t) + 2) + b; }; class v3 { constructor(x, y, z) { this.x = x; this.y = y; this.z = z; } } class Vector { constructor(x, y) { this.x = x || 0; this.y = y || 0; } set(x, y) { this.x = x; this.y = y; } reset() { this.x = 0; this.y = 0; } fromAngle(angle) { let x = Math.cos(angle), y = Math.sin(angle); return new Vector(x, y); } add(vector) { this.x += vector.x; this.y += vector.y; } sub(vector) { this.x -= vector.x; this.y -= vector.y; } mult(scalar) { this.x *= scalar; this.y *= scalar; } div(scalar) { this.x /= scalar; this.y /= scalar; } dot(vector) { return vector.x * this.x + vector.y * this.y; } limit(limit_value) { if (this.mag() > limit_value) this.setMag(limit_value); } mag() { return Math.hypot(this.x, this.y); } setMag(new_mag) { if (this.mag() > 0) { this.normalize(); } else { this.x = 1; this.y = 0; } this.mult(new_mag); } normalize() { let mag = this.mag(); if (mag > 0) { this.x /= mag; this.y /= mag; } } heading() { return Math.atan2(this.y, this.x); } setHeading(angle) { let mag = this.mag(); this.x = Math.cos(angle) * mag; this.y = Math.sin(angle) * mag; } dist(vector) { return new Vector(this.x - vector.x, this.y - vector.y).mag(); } angle(vector) { return Math.atan2(vector.y - this.y, vector.x - this.x); } copy() { return new Vector(this.x, this.y); } } // init canvas let canvas = document.createElement("canvas"), ctx = canvas.getContext("2d"), W, H; document.body.appendChild(canvas); setSize(); document.body.onresize = function() { let old_width = W; setSize(); populate(); }; function setSize() { W = canvas.width = window.innerWidth; H = canvas.height = window.innerHeight; ctx.lineCap = "round"; ctx.lineJoin = "round"; } let mouse = new Vector(W/2, H/2); canvas.onmousemove = function(event) { mouse.x = event.clientX - canvas.offsetLeft; mouse.y = event.clientY - canvas.offsetTop; }; // class Point { constructor(x, y) { this.position = new Vector(x, y); this.old_position = this.position.copy(); this.pinned = false; this.angle = undefined; } render() { ctx.beginPath(); ctx.arc(this.position.x, this.position.y, 4, 0, 2 * Math.PI); ctx.stroke(); } } class Leaf { constructor(parent, length) { this.parent = parent; this.end = new Point(parent.position.x, parent.position.y + (length * Util.random(0.9, 1.1))); this.end.angle = 0; this.z_value = 0; this.colors = ["#2c4c28", "#48792c", "#69982d"]; this.true_color = this.colors[ Math.floor(Math.random() * this.colors.length) ]; this.size = (length * 2) * Util.random(0.8, 1.2); this.thickness = this.size * 0.5 * Util.random(0.6, 1.2); } setZ(z_value) { this.z_value = z_value; this.color = lerpColor(this.true_color, backgroundColor, this.z_value); } render() { ctx.strokeStyle = this.color; //ctx.lineWidth = this.thickness; ctx.beginPath(); ctx.moveTo(this.parent.position.x, this.parent.position.y); ctx.lineTo(this.end.position.x, this.end.position.y); ctx.closePath(); ctx.stroke(); /* ctx.save(); ctx.translate(this.parent.position.x, this.parent.position.y); ctx.rotate(angle + Math.PI / 2); ctx.beginPath(); ctx.ellipse(0, -this.size, this.thickness, this.size, 0, 0, 2 * Math.PI); ctx.fill(); ctx.restore(); */ } } class Link { constructor(p0, p1) { this.p0 = p0; this.p1 = p1; this.length = .........完整代码请登录后点击上方下载按钮下载查看
网友评论0