회전하는 3D 와이어프레임 큐브
Wikiprompt, 무료 프롬프트 백과사전에서
회전하는 3D 와이어프레임 큐브 Canvas 2D만 사용하여 WebGL 없이 원근감 있게 회전하는 3D 와이어프레임 큐브를 생성하는 프롬프트.
관련 미디어
프롬프트 내용저장
🌐
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D wireframe cube · canvas 2d</title>
<style>
body {
background: #0b0e14;
margin: 0;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
background: #1a1f2a;
padding: 1.5rem;
border-radius: 1.5rem;
box-shadow: 0 20px 40px rgba(0,0,0,0.6);
}
canvas {
display: block;
width: 480px;
height: 480px;
border-radius: 0.8rem;
background: #10141c;
box-shadow: inset 0 0 30px rgba(0,0,0,0.5);
}
.info {
text-align: center;
margin-top: 0.8rem;
font-family: 'Segoe UI', Roboto, system-ui, sans-serif;
color: #a8b3c0;
font-size: 0.9rem;
letter-spacing: 0.5px;
}
.info span {
color: #6fc3df;
font-weight: 500;
}
</style>
</head>
<body>
<div class="container">
<canvas id="cubeCanvas" width="480" height="480"></canvas>
<div class="info">wireframe cube · <span>canvas 2d</span> · slow rotation</div>
</div>
<script>
(function() {
const canvas = document.getElementById('cubeCanvas');
const ctx = canvas.getContext('2d');
// ---------- fixed perspective parameters ----------
const W = canvas.width;
const H = canvas.height;
const CX = W / 2;
const CY = H / 2;
// camera distance (perspective strength)
const VIEW_DIST = 4.2; // larger = flatter, smaller = more perspective
const SCALE = 1.9; // base scale factor (fits cube nicely)
// ---------- cube vertices (unit cube centered at origin) ----------
// 8 vertices: x,y,z in [-1, 1]
const VERTICES = [
[-1, -1, -1], // 0
[ 1, -1, -1], // 1
[ 1, 1, -1], // 2
[-1, 1, -1], // 3
[-1, -1, 1], // 4
[ 1, -1, 1], // 5
[ 1, 1, 1], // 6
[-1, 1, 1] // 7
];
// ---------- edges (12 lines) ----------
const EDGES = [
[0, 1], [1, 2], [2, 3], [3, 0], // back face
[4, 5], [5, 6], [6, 7], [7, 4], // front face
[0, 4], [1, 5], [2, 6], [3, 7] // connecting edges
];
// ---------- rotation state (slow) ----------
let angleX = 0.0;
let angleY = 0.0;
const ROT_SPEED_X = 0.0022; // radians per frame (slow)
const ROT_SPEED_Y = 0.0017;
// ---------- projection: rotate -> perspective -> screen ----------
function project(vertex, rotX, rotY) {
// 1. rotate around Y axis
const x0 = vertex[0];
const y0 = vertex[1];
const z0 = vertex[2];
const cosY = Math.cos(rotY);
const sinY = Math.sin(rotY);
const x1 = x0 * cosY + z0 * sinY;
const z1 = -x0 * sinY + z0 * cosY;
const y1 = y0; // unchanged by Y rotation
// 2. rotate around X axis
const cosX = Math.cos(rotX);
const sinX = Math.sin(rotX);
const y2 = y1 * cosX - z1 * sinX;
const z2 = y1 * sinX + z1 * cosX;
const x2 = x1; // unchanged by X rotation
// 3. perspective projection (z is depth)
// camera looks along +Z? we want classic: z goes into screen.
// we use perspective factor = VIEW_DIST / (VIEW_DIST + z2)
// but we want cube to be visible: use z2 in range [-sqrt(3), sqrt(3)]
// we shift to make it comfortable: add 3.0 to depth so it's always positive.
const depth = VIEW_DIST + z2 * 0.9; // z2 in [-1.73, 1.73] -> depth in [2.5, 5.8]
const perspective = VIEW_DIST / depth;
// 4. scale and center
const screenX = CX + x2 * SCALE * perspective * 100; // 100 = pixel factor
const screenY = CY - y2 * SCALE * perspective * 100; // minus because y goes down
return { x: screenX, y: screenY };
}
// ---------- render frame ----------
function draw() {
ctx.clearRect(0, 0, W, H);
// subtle grid (optional, for depth perception)
ctx.strokeStyle = '#2a3342';
ctx.lineWidth = 0.6;
for (let i = -4; i <= 4; i++) {
const offset = i * 30;
ctx.beginPath();
ctx.moveTo(CX + offset, 0);
ctx.lineTo(CX + offset, H);
ctx.strokeStyle = '#202a38';
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, CY + offset);
ctx.lineTo(W, CY + offset);
ctx.strokeStyle = '#202a38';
ctx.stroke();
}
// project all vertices
const projected = VERTICES.map(v => project(v, angleX, angleY));
// draw edges (lines) with subtle glow effect
ctx.lineWidth = 2.0;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
// first pass: darker underlay for glow
ctx.strokeStyle = '#3d4f66';
ctx.lineWidth = 3.5;
for (const [i, j] of EDGES) {
const p1 = projected[i];
const p2 = projected[j];
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
ctx.stroke();
}
// second pass: bright core lines
ctx.strokeStyle = '#b8d8f0';
ctx.lineWidth = 1.6;
for (const [i, j] of EDGES) {
const p1 = projected[i];
const p2 = projected[j];
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
ctx.stroke();
}
// draw vertices as small dots (helps spatial orientation)
ctx.fillStyle = '#e0f0ff';
ctx.shadowColor = '#7fc4ff';
ctx.shadowBlur = 6;
for (const p of projected) {
ctx.beginPath();
ctx.arc(p.x, p.y, 3.2, 0, 2 * Math.PI);
ctx.fill();
}
ctx.shadowBlur = 0; // reset for next frame
// update rotation (slow)
angleX += ROT_SPEED_X;
angleY += ROT_SPEED_Y;
requestAnimationFrame(draw);
}
// start animation
draw();
})();
</script>
</body>
</html>
전체 프롬프트를 보려면 로그인하세요
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
사용법
이 프롬프트는 coding와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.
최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.
토론
댓글 0개