最近何もない、オープン網易クラウド音楽、サウンドクラウドクジラがああのようなものを発見しましたか?「クリスタル・ソニック」は非常に鉉。ああ?ビニール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
ストップウォッチで測定されたI
図の斜線、単に色を選択
.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);
}
擬似要素を使用することで十分です
パス動作の後、「記録」が実現され、ここでのレンダリングは、以下のとおりです。
ああ、大丈夫、次の部分は、三角形のものである背景のキャンバスの絵画、ある-アウトゴーンの風では
難しいことではありません。
キャンバス
キャンバスは、ビットを設定しました
.music-cover-background {
position: absolute;
}
position: absolute
その後、親要素のために.debut
使用してflex
レイアウトを中心に
すぐにリサイズ
const canvas = document.getElementById('background');
canvas.width = canvas.height = Math.ceil(canvas.parentNode.firstElementChild.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
次のような効果があり、簡単なレコードを描きました