【canvas】网易云音乐鲸云动效『水晶音波』的简单实现
生活随笔
收集整理的這篇文章主要介紹了
【canvas】网易云音乐鲸云动效『水晶音波』的简单实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近閑來無事,打開網易云音樂,發現還有鯨云音效這種東西,嗯?『水晶音波』,挺炫。嗯?黑膠VIP專享?(其實我已經是黑膠VIP)好像實現起來也不很復雜呀,所以花了一下午,實現了一個簡單版本。
這是網易云音樂的截圖,結尾放我自己實現的效果
先明確一點,簡單實現,所以沒搞懂的,不想做的,都省略不做了。
HTML
簡單嘛~
不需要太多元素,簡簡單單才是真
CSS
開局找個地,然后畫個圈
.debut {position: absolute;width: 100%;height: 100%;display: inline-flex;align-items: center;justify-content: center; }.music-cover {width: 23.75rem; /* 380px */height: 23.75rem; /* 380px */box-sizing: border-box;border: .125rem solid #B3B3B3; /* 2px solid #B3B3B3 */border-radius: 50%;display: inline-flex;align-items: center;justify-content: center; }使用flex布局實現居中
圈中貼個圖,讓它轉起來
.music-cover-image {width: 21.25rem; /* 340px */height: 21.25rem; /* 340px */border: none;border-radius: 50%;animation: rotate infinite linear 25s; }@keyframes rotate {from { transform: rotate(0deg); }to { transform: rotate(360deg); } }動畫時間25s是我用秒表測的
圖后畫陰影,顏色簡單選
.music-cover::before {content: "";position: absolute;width: 21.25rem; /* 340px */height: 21.25rem; /* 340px */border-radius: 50%;filter: blur(1.875rem); /* 30px */background-image: radial-gradient(white, silver); }使用偽元素就夠了
一通操作之后,“唱片”就實現了,下面是效果圖:
嗯,還行,接下來才是canvas畫背景部分,也就是三角形往外飄嘛~
不難。
canvas
畫布定個位
.music-cover-background {position: absolute; }position: absolute后,會因為父元素.debut采用flex布局而居中
緊接定大小
const canvas = document.getElementById('background'); canvas.width = canvas.height = Math.ceil(canvas.parentNode.lastElementChild.offsetWidth * 1.68421);堆個三角形
const PI2 = 2 * Math.PI; class Triangle {constructor(context, speed, pole, range) {this.ctx = context;this.pole = pole;this.range = range;this.speed = speed;this.points = [[0, 0], [0, 0], [0, 0]];this.__restart();}__restart() {this.angle = Math.random() * PI2; // 隨機生成一個移動方向this.speedX = Math.cos(this.angle) * this.speed;this.speedY = Math.sin(this.angle) * this.speed;this.opacity = 1;const dist = Math.random() * 150; // 為了讓三角形生成錯落有致,所以讓三角形從距離pole點的一個隨機距離dist出發const distX = Math.cos(this.angle) * dist;const distY = Math.sin(this.angle) * dist;const θ = Math.random() * PI2; // 將三角形隨機旋轉一個θ°const x2 = Math.random() * 10;const y2 = 20 + Math.random() * 20;const x3 = 10 + Math.random() * 15;const y3 = 12 + Math.random() * 6;this.points[0][0] = Math.floor(this.pole[0] + distX);this.points[0][1] = Math.floor(this.pole[1] + distY);this.points[1][0] = Math.floor(this.pole[0] + distX + (x2 * Math.cos(θ) - y2 * Math.sin(θ)));this.points[1][1] = Math.floor(this.pole[1] + distY + (y2 * Math.cos(θ) + x2 * Math.sin(θ)));this.points[2][0] = Math.floor(this.pole[0] + distX + (x3 * Math.cos(θ) - y3 * Math.sin(θ)));this.points[2][1] = Math.floor(this.pole[1] + distY + (y3 * Math.cos(θ) + x3 * Math.sin(θ)));}__distance() {const dx = this.points[0][0] - this.pole[0];const dy = this.points[0][1] - this.pole[1];return Math.floor(Math.sqrt(dx * dx + dy * dy));}__lerp(src, dst, coeff) {return src + (dst - src) * coeff;}__update() {const dist = this.__distance();if (dist - this.range > 0.0001)this.__restart();else {this.points.forEach((point, index) => {this.points[index][0] = point[0] + this.speedX;this.points[index][1] = point[1] + this.speedY;});this.opacity = this.__lerp(1, 0, dist / this.range);}}render() {this.__update();this.ctx.lineWidth = 2;this.ctx.lineJoin = "miter";this.ctx.strokeStyle = `rgba(179, 179, 179, ${this.opacity})`;this.ctx.beginPath();this.ctx.moveTo(this.points[0][0], this.points[0][1]);this.ctx.lineTo(this.points[1][0], this.points[1][1]);this.ctx.lineTo(this.points[2][0], this.points[2][1]);this.ctx.closePath();this.ctx.stroke();this.ctx.fillStyle = 'rgba(67, 67, 67, .2)';this.ctx.fill();} }定義個“場景”
class Scene {constructor(canvas) {this.cvs = canvas;this.ctx = canvas.getContext('2d');this.triangleSet = [];this.triangleNum = 25; // 三角形個數const realm = this.cvs.width / 2; // 畫布中心for (let i = 0; i < this.triangleNum; ++i)this.triangleSet[i] = new Triangle(this.ctx, 1.5, [realm, realm], realm);}render() {this.ctx.clearRect(0, 0, this.cvs.width, this.cvs.height); // 及時清除畫布this.triangleSet.forEach(triangle => triangle.render());}run() {if (!this.timer) {this.timer = setInterval(this.render.bind(this), 25);}}stop() {if (this.timer) {clearInterval(this.timer);this.timer = 0;}} }最后“跑場景”
const canvas = document.getElementById('background'); canvas.width = canvas.height = Math.ceil(canvas.parentNode.lastElementChild.offsetWidth * 1.68421); const scene = new Scene(canvas); scene.run();完成,下面是最終效果
源碼鏈接在這:github
在線演示:codepen
codepen上的代碼會有些不同,因為不想引用圖片,所以用css簡單畫了一個唱片,效果如下
下篇:【canvas】網易云音樂鯨云動效『孤獨星球』的簡單實現
總結
以上是生活随笔為你收集整理的【canvas】网易云音乐鲸云动效『水晶音波』的简单实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 绘制BA图, 绘制Blan
- 下一篇: 反向代理和正向代理以及Nginx工具的简