先看下演示:
或者看看liuyuanlin.com的顶部背景,可以借鉴一下。
怎么样?很好看把?可以用他在做背景等特效。
首先看下html结构代码:
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>HTML5 Canvas流动线条动画特效</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div id="holder"></div> <script src="js/index.js"></script> </body> </html>
其次是css样式css/style.css,仅供参考:
* { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #000; overflow: hidden; } #holder { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; }
最后是重点,是js代码js/index.js:
(function () { var pi = Math.PI; var pi2 = 2 * Math.PI; this.Waves = function (holder, options) { var Waves = this; Waves.options = extend(options || {}, { resize: false, rotation: 45, waves: 5, width: 100, hue: [11, 14], amplitude: 0.5, background: true, preload: true, speed: [0.004, 0.008], debug: false, fps: false, }); Waves.waves = []; Waves.holder = document.querySelector(holder); Waves.canvas = document.createElement('canvas'); Waves.ctx = Waves.canvas.getContext('2d'); Waves.holder.appendChild(Waves.canvas); Waves.hue = Waves.options.hue[0]; Waves.hueFw = true; Waves.stats = new Stats(); Waves.resize(); Waves.init(Waves.options.preload); if (Waves.options.resize) window.addEventListener('resize', function () { Waves.resize(); }, false); }; Waves.prototype.init = function (preload) { var Waves = this; var options = Waves.options; for (var i = 0; i < options.waves; i++) Waves.waves[i] = new Wave(Waves); if (preload) Waves.preload(); }; Waves.prototype.preload = function () { var Waves = this; var options = Waves.options; for (var i = 0; i < options.waves; i++) { Waves.updateColor(); for (var j = 0; j < options.width; j++) { Waves.waves[i].update(); } } }; Waves.prototype.render = function () { var Waves = this; var ctx = Waves.ctx; var options = Waves.options; Waves.updateColor(); Waves.clear(); if (Waves.options.debug) { ctx.beginPath(); ctx.strokeStyle = '#f00'; ctx.arc(Waves.centerX, Waves.centerY, Waves.radius, 0, pi2); ctx.stroke(); } if (Waves.options.background) { Waves.background(); } each(Waves.waves, function (wave, i) { wave.update(); wave.draw(); }); }; Waves.prototype.animate = function () { var Waves = this; Waves.render(); if (Waves.options.fps) { Waves.stats.log(); Waves.ctx.font = '12px Arial'; Waves.ctx.fillStyle = '#fff'; //Waves.ctx.fillText(Waves.stats.fps() + ' FPS', 10, 22); } window.requestAnimationFrame(Waves.animate.bind(Waves)); }; Waves.prototype.clear = function () { var Waves = this; Waves.ctx.clearRect(0, 0, Waves.width, Waves.height); }; Waves.prototype.background = function () { var Waves = this; var ctx = Waves.ctx; var gradient = Waves.ctx.createLinearGradient(0, 0, 0, Waves.height); gradient.addColorStop(0, '#000'); gradient.addColorStop(1, Waves.color); ctx.fillStyle = gradient; ctx.fillRect(0, 0, Waves.width, Waves.height); }; Waves.prototype.resize = function () { var Waves = this; var width = Waves.holder.offsetWidth; var height = Waves.holder.offsetHeight; Waves.scale = window.devicePixelRatio || 1; Waves.width = width * Waves.scale; Waves.height = height * Waves.scale; Waves.canvas.width = Waves.width; Waves.canvas.height = Waves.height; Waves.canvas.style.width = width + 'px'; Waves.canvas.style.height = height + 'px'; Waves.radius = Math.sqrt(Math.pow(Waves.width, 2) + Math.pow(Waves.height, 2)) / 2; Waves.centerX = Waves.width / 2; Waves.centerY = Waves.height / 2; //Waves.radius /= 2; // REMOVE FOR FULLSREEN }; Waves.prototype.updateColor = function () { var Waves = this; Waves.hue += (Waves.hueFw) ? 0.01 : -0.01; if (Waves.hue > Waves.options.hue[1] && Waves.hueFw) { Waves.hue = Waves.options.hue[1]; Waves.Waves = false; } else if (Waves.hue < Waves.options.hue[0] && !Waves.hueFw) { Waves.hue = Waves.options.hue[0]; Waves.Waves = true; } var a = Math.floor(127 * Math.sin(0.3 * Waves.hue + 0) + 128); var b = Math.floor(127 * Math.sin(0.3 * Waves.hue + 2) + 128); var c = Math.floor(127 * Math.sin(0.3 * Waves.hue + 4) + 128); Waves.color = 'rgba(' + a + ',' + b + ',' + c + ', 0.1)'; }; function Wave(Waves) { var Wave = this; var speed = Waves.options.speed; Wave.Waves = Waves; Wave.Lines = []; Wave.angle = [ rnd(pi2), rnd(pi2), rnd(pi2), rnd(pi2) ]; Wave.speed = [ rnd(speed[0], speed[1]) * rnd_sign(), rnd(speed[0], speed[1]) * rnd_sign(), rnd(speed[0], speed[1]) * rnd_sign(), rnd(speed[0], speed[1]) * rnd_sign(), ]; return Wave; } Wave.prototype.update = function () { var Wave = this; var Lines = Wave.Lines; var color = Wave.Waves.color; Lines.push(new Line(Wave, color)); if (Lines.length > Wave.Waves.options.width) { Lines.shift(); } }; Wave.prototype.draw = function () { var Wave = this; var Waves = Wave.Waves; var ctx = Waves.ctx; var radius = Waves.radius; var radius3 = radius / 3; var x = Waves.centerX; var y = Waves.centerY; var rotation = dtr(Waves.options.rotation); var amplitude = Waves.options.amplitude; var debug = Waves.options.debug; var Lines = Wave.Lines; each(Lines, function (line, i) { if (debug && i > 0) return; var angle = line.angle; var x1 = x - radius * Math.cos(angle[0] * amplitude + rotation); var y1 = y - radius * Math.sin(angle[0] * amplitude + rotation); var x2 = x + radius * Math.cos(angle[3] * amplitude + rotation); var y2 = y + radius * Math.sin(angle[3] * amplitude + rotation); var cpx1 = x - radius3 * Math.cos(angle[1] * amplitude * 2); var cpy1 = y - radius3 * Math.sin(angle[1] * amplitude * 2); var cpx2 = x + radius3 * Math.cos(angle[2] * amplitude * 2); var cpy2 = y + radius3 * Math.sin(angle[2] * amplitude * 2); ctx.strokeStyle = (debug) ? '#fff' : line.color; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x2, y2); ctx.stroke(); if (debug) { ctx.strokeStyle = '#fff'; ctx.globalAlpha = 0.3; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(cpx1, cpy1); ctx.stroke(); ctx.beginPath(); ctx.moveTo(x2, y2); ctx.lineTo(cpx2, cpy2); ctx.stroke(); ctx.globalAlpha = 1; } }); }; function Line(Wave, color) { var Line = this; var angle = Wave.angle; var speed = Wave.speed; Line.angle = [ Math.sin(angle[0] += speed[0]), Math.sin(angle[1] += speed[1]), Math.sin(angle[2] += speed[2]), Math.sin(angle[3] += speed[3]) ]; Line.color = color; } function Stats() { this.data = []; } Stats.prototype.time = function () { return (performance || Date) .now(); }; Stats.prototype.log = function () { if (!this.last) { this.last = this.time(); return 0; } this.new = this.time(); this.delta = this.new - this.last; this.last = this.new; this.data.push(this.delta); if (this.data.length > 10) this.data.shift(); }; Stats.prototype.fps = function () { var fps = 0; each(this.data, function (data, i) { fps += data; }); return Math.round(1000 / (fps / this.data.length)); }; function each(items, callback) { for (var i = 0; i < items.length; i++) { callback(items[i], i); } } function extend(options, defaults) { for (var key in options) if (defaults.hasOwnProperty(key)) defaults[key] = options[key]; return defaults; } function dtr(deg) { return deg * pi / 180; } function rtd(rad) { return rad * 180 / pi; } function diagonal_angle(w, h) { var a = Math.atan2(h, w) * 1.27325; return a; } function rnd(a, b) { if (arguments.length == 1) return Math.random() * a; return a + Math.random() * (b - a); } function rnd_sign() { return (Math.random() > 0.5) ? 1 : -1; } })(); var waves = new Waves('#holder', { fps: true, waves: 3, width: 200, }); waves.animate();
声明:本文采用 BY-NC-SA 协议进行授权,如无注明均为原创,转载请注明转自 你好!刘
本文地址:HTML5 Canvas流动线条动画特效
本文地址:HTML5 Canvas流动线条动画特效
小满
1 年前 Google Chrome 118 Windows 10博主您好,可以请问一下这个动画在vue中要导入什么依赖
皇家元林
1 年前 Firefox 119 Windows 10@小满 不需要,这就是一段js代码。