728x90
반응형
Mouse Bubble Effect Code 기록
import React, {useEffect, useRef} from 'react';
interface BubbleMouseType {
x?: number,
y?: number,
radius: number
}
export default function Bubble(){
const canvasRef = useRef<HTMLCanvasElement>(null);
const mouse: BubbleMouseType = { x: undefined, y: undefined, radius: 150 }
let particlesArray: any = [];
let adjustX = 0;
let adjustY = 0;
useEffect(() => {
const canvas = canvasRef?.current;
if (canvas) {
let ctx = canvas.getContext('2d');
class Particle {
private x: any;
private y: any;
private size: number;
private baseX: any;
private baseY: any;
private density: number;
private distance: number | undefined;
constructor(x: any, y: any) {
this.x = x;
this.y = y;
this.size = 3;
this.baseX = this.x;
this.baseY = this.y;
this.density = (Math.random() * 30) + 1;
}
draw() {
if (ctx) {
ctx.fillStyle = 'rgba(255,255,255,0.8)';
ctx.strokeStyle = 'rgba(34,147,214,1)';
ctx.beginPath();
if (this.distance) {
if (this.distance < mouse.radius -5) {
this.size = 13;
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.arc(this.x - 3, this.y - 3, this.size / 2.5, 0, Math.PI * 2);
ctx.arc(this.x + 7, this.y + 1, this.size / 3.5, 0, Math.PI * 2);
} else if (this.distance <= mouse.radius) {
this.size = 10;
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.arc(this.x - 2, this.y - 2, this.size / 3, 0, Math.PI * 2);
} else {
this.size = 8;
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.arc(this.x - 1, this.y - 1, this.size / 3, 0, Math.PI * 2);
}
}
ctx.closePath();
ctx.fill();
}
}
update() {
if (mouse.x && mouse.y) {
let dx = mouse.x - this.x
let dy = mouse.y - this.y;
let distance = Math.sqrt(dx * dx + dy * dy);
this.distance = distance;
let forceDirectionX = dx / distance;
let forceDirectionY = dy / distance;
let maxDistance = mouse.radius;
let force = (maxDistance - distance) / maxDistance;
let directionX = forceDirectionX * force * this.density;
let directionY = forceDirectionY * force * this.density;
if (distance < mouse.radius) {
this.x -= directionX;
this.y -= directionY;
} else {
if (this.x !== this.baseX) {
let dx = this.x - this.baseX;
this.x -= dx / 10;
}
if (this.x !== this.baseX) {
let dy = this.y - this.baseY;
this.y -= dy / 10;
}
}
}
}
}
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
window.addEventListener('mousemove', (event) => {
mouse.x = event.x;
mouse.y = event.y;
});
if (ctx) {
ctx.lineWidth = 3;
ctx.fillStyle = 'white';
ctx.font = '15px Verdana';
ctx.fillText('요요', 25, 25);
const textCoordinates = ctx.getImageData(0,0,100,100);
const init = () => {
particlesArray = [];
for (let y=0, y2 = textCoordinates.height;y<y2;y++) {
for (let x = 0, x2 = textCoordinates.width;x<x2;x++) {
if (textCoordinates.data[(y * 4 * textCoordinates.width) + (x * 4) + 3] > 128) {
let positionX = x + adjustX;
let positionY = y + adjustY;
particlesArray.push(new Particle(positionX * 25, positionY * 25));
}
}
}
}
init();
const connect = () => {
let opacityValue = 1;
for (let a = 0;a<particlesArray.length;a++) {
for (let b = a;b<particlesArray.length;b++) {
let dx = particlesArray[a].x - particlesArray[b].x;
let dy = particlesArray[a].y - particlesArray[b].y;
let distance = Math.sqrt(dx * dx + dy* dy);
opacityValue = 1 - (distance/50);
if (ctx) ctx.strokeStyle = 'rgba(255,255,255,' + opacityValue + ')';
if (distance < 50 && ctx) {
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(particlesArray[a].x, particlesArray[a].y);
ctx.lineTo(particlesArray[b].x, particlesArray[b].y);
ctx.stroke();
}
}
}
}
const animate = () => {
if (ctx) {
ctx.clearRect(0,0, canvas.width, canvas.height);
for (let i=0;i<particlesArray.length;i++) {
particlesArray[i].draw();
particlesArray[i].update();
}
// connect();
requestAnimationFrame(animate);
}
};
animate();
}
}
}, []);
return (
<canvas className="canvas" ref={canvasRef}></canvas>
);
};
.canvas{ position: absolute; z-index: 1; background: black; width: 100%; height: 100%; top: 0; left: 0; }
728x90
반응형
'Javascript' 카테고리의 다른 글
Canvas Crash Effect 기록(react + typescript) (0) | 2022.12.07 |
---|---|
React Native WebView postMessage로 네이티브, 웹 데이터 전달 (0) | 2022.03.29 |
[JS] URL 접속 QR code 만들기 (0) | 2021.11.30 |
[Vue js] dom drag move 돔 드래그로 이동시키기 (0) | 2021.11.11 |
[Vue js] 카카오 맵 api 로 현재위치 마커찍는 코드 (0) | 2021.11.10 |
댓글