바뀌었낭
html canvas로 그렸는데. 챗지피티한테 해달라 하니까 와 뚝딱이네.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>☆ 퍼플이 아이콘 ☆</title>
<link href="https://fonts.googleapis.com/css2?family=Nanum+Gothic&display=swap" rel="stylesheet">
<style>
@font-face {
font-family: 'SeoulHangangM';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_two@1.0/SeoulHangangM.woff') format('woff');
font-weight: normal;
font-style: normal;
}
body {
margin: 0;
background: white;
overflow: hidden;
}
canvas {
display: block;
margin: auto;
/* width: 25px;
height: 25px;*/
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const ANI_SPEED_RATE = 1;
const CANVAS_SIZE = 100;
const TRIANGLE_NUM = 50;
const TRIANGLE_INTERVAL = 30;
const TRIANGLE_MAX_SIZE = 120;
const TRIANGLE_DURATION = 800;
const TEXT_START_TIME = 700;
const TEXT = "퍼플히아신스";
const TEXT_SPEED = 4;
const TEXT_SIZE = 0.7;
const TEXT_FONT = "SeoulHangangM";
const TEXT_COLOR_1 = "white";
const TEXT_COLOR_2 = "#56f";
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
canvas.width = CANVAS_SIZE;
canvas.height = CANVAS_SIZE;
const COLORS = [
[96, 16, 255, 1],
[32, 0, 255, 1],
[80, 0, 0, 1],
[96, 0, 0, 0.5],
[255, 0, 0, 0.01]
];
const totalPhases = COLORS.length - 1;
function lerp(a, b, t) {
return a + (b - a) * t;
}
function lerpColor(c1, c2, t) {
return [
Math.floor(lerp(c1[0], c2[0], t)),
Math.floor(lerp(c1[1], c2[1], t)),
Math.floor(lerp(c1[2], c2[2], t)),
lerp(c1[3], c2[3], t)
];
}
function rgbaToString(rgba) {
return `rgba(${rgba[0]}, ${rgba[1]}, ${rgba[2]}, ${rgba[3]})`;
}
function generateRandomTriangle(x, y, range = TRIANGLE_MAX_SIZE) {
return Array.from({ length: 3 }, () => ({
x: x + Math.random() * range,
y: y + Math.random() * range
}));
}
function drawTriangle(points, color) {
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
ctx.lineTo(points[1].x, points[1].y);
ctx.lineTo(points[2].x, points[2].y);
ctx.closePath();
ctx.fillStyle = color;
ctx.fill();
}
const triangles = [];
class AnimatedTriangle {
c o n s - t r u c t o r(points) {
this.points = points;
this.startTime = performance.now();
}
updateAndDraw(now) {
const elapsed = ( now - this.startTime ) * ANI_SPEED_RATE;
const currentPhase = Math.floor(elapsed / TRIANGLE_DURATION);
if (currentPhase >= totalPhases) return false;
const phaseProgress = (elapsed % TRIANGLE_DURATION) / TRIANGLE_DURATION;
const from = COLORS[currentPhase];
const to = COLORS[currentPhase + 1];
const currentColor = lerpColor(from, to, phaseProgress);
drawTriangle(this.points, rgbaToString(currentColor));
return true;
}
}
let allTrianglesSpawned = false;
let textStartTime = null;
setTimeout(() => {
textStartTime = performance.now();
}, TEXT_START_TIME / ANI_SPEED_RATE);
function animateAll() {
const now = performance.now();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "lighter";
for (let i = triangles.length - 1; i >= 0; i--) {
const stillVisible = triangles[i].updateAndDraw(now);
if (!stillVisible) {
triangles.splice(i, 1);
}
}
if (textStartTime !== null) {
const timeSinceStart = now - textStartTime;
const t = timeSinceStart * ANI_SPEED_RATE;
const x = canvas.width + 50 - TEXT_SPEED / 16 * t;
ctx.font = `${canvas.height * TEXT_SIZE}px "${TEXT_FONT}"`;
ctx.textBaseline = "middle";
ctx.textAlign = "left";
ctx.fillStyle = TEXT_COLOR_2;
ctx.fillText(TEXT, x+6, canvas.height / 2);
ctx.fillStyle = TEXT_COLOR_1;
ctx.fillText(TEXT, x, canvas.height / 2);
}
requestAnimationFrame(animateAll);
}
function spawnTriangles() {
let count = 0;
const interval = setInterval(() => {
if (count >= TRIANGLE_NUM) {
clearInterval(interval);
allTrianglesSpawned = true;
return;
}
const x = Math.random() * (canvas.width + TRIANGLE_MAX_SIZE) - TRIANGLE_MAX_SIZE/2;
const y = Math.random() * (canvas.height + TRIANGLE_MAX_SIZE) - TRIANGLE_MAX_SIZE/2;
const points = generateRandomTriangle(x, y);
triangles.push( new AnimatedTriangle(points) );
count++;
}, TRIANGLE_INTERVAL / ANI_SPEED_RATE);
}
animateAll();
spawnTriangles();
</script>
</body>
</html>