日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【canvas】网易云音乐鲸云动效『水晶音波』的简单实现

發布時間:2024/1/1 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【canvas】网易云音乐鲸云动效『水晶音波』的简单实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近閑來無事,打開網易云音樂,發現還有鯨云音效這種東西,嗯?『水晶音波』,挺炫。嗯?黑膠VIP專享?(其實我已經是黑膠VIP)好像實現起來也不很復雜呀,所以花了一下午,實現了一個簡單版本。

這是網易云音樂的截圖,結尾放我自己實現的效果

先明確一點,簡單實現,所以沒搞懂的,不想做的,都省略不做了。




HTML

簡單嘛~
不需要太多元素,簡簡單單才是真

<div class="debut"><!-- 背景部分 --><canvas class="music-cover-background" id="background">your brower does not support canvas</canvas><!-- 前景部分 --><div class="music-cover"><img src="images/1753378458.jpg" class="music-cover-image"></img></div> </div>

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】网易云音乐鲸云动效『水晶音波』的简单实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。