<div class="wrapper">
<canvas id="canvas"></canvas>
<h1 class="title">Particle</h1>
</div>
/* #7EC2C2 #9DDCDC #FFF4E1 #E67A7A */
* {
margin: 0;
padding: 0;
}
body {
background-color: #a0d8ef;
}
.wrapper {
width: 100vw;
height: 100vh;
position: relative;
}
.title {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 100px;
font-weight: bold;
color: #fff4e14d;
}
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
window.requestAnimationFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.weblitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (cb) { setTimeout(cb, 17); };
const NUM = 400; // 表示数
const particles = [];
const mouse = {
x: null,
y: null,
radius: 50,
}
window.addEventListener('mousemove', (event) => {
mouse.x = event.x;
mouse.y = event.y;
});
class Particle {
constructor(x, y, radius, directionX, directionY, index) {
this.x = x;
this.y = y;
this.radius = radius;
this.directionX = directionX;
this.directionY = directionY;
this.index = index;
}
render() {
// 色の設定
this.setColor();
// パーティクルの描画
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
}
setColor() {
if(this.index % 3 === 0) {
ctx.fillStyle = "#fff";
ctx.fill();
} else if (this.index % 3 === 1) {
ctx.strokeStyle = "#fff";
ctx.lineWidth = 1;
ctx.stroke()
} else {
ctx.globalAlpha = 0.8;
ctx.fillStyle = "#0f0091";
ctx.fill();
}
}
update () {
// もし衝突していたらカーソルから離れるようにする
if (this.detectCollision()) {
if (this.x > mouse.x) {
this.x += this.radius;
if (this.directionX < 0) this.directionX = -this.directionX;
}
if (this.x < mouse.x) {
this.x -= this.radius;
if (this.directionX > 0) this.directionX = -this.directionX;
}
if (this.y > mouse.y) {
this.y += this.radius;
if (this.y < 0) this.directionY = -this.directionY;
}
if (this.y < mouse.y) {
this.y -= this.radius;
if (this.y > 0) this.directionY = -this.directionY;
}
}
this.x += this.directionX;
this.y += this.directionY;
if (this.x > canvas.width + this.radius || this.x < this.radius) {
this.directionX = -this.directionX
}
if (this.y > canvas.height + this.radius || this.y < this.radius) {
this.directionY = -this.directionY
}
this.render();
}
detectCollision () {
// 衝突しているかどうか
const dx = mouse.x - this.x;
const dy = mouse.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
return distance < mouse.radius + this.radius;
}
}
init();
render();
function init() {
for(let i = 0; i < NUM; i++) {
// particles
const x = Math.random() * canvas.width;
const y = Math.floor(Math.random() * canvas.height);
const radius = Math.floor(Math.random() * 10);
const directionX = Math.random() * 2;
const directionY = Math.random() * 2 - 1;
const particle = new Particle(x, y, radius, directionX, directionY, i);
particles.push(particle);
}
}
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(let i = 0; i < particles.length; i++) {
particles[i].update();
}
requestAnimationFrame(render);
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.