Как я создал браузерный кубик Рубика на чистом Canvas

<script>
    const canvas = document.getElementById('rubikCanvas');
    const ctx = canvas.getContext('2d');

    function resizeCanvas() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }
    window.addEventListener('resize', resizeCanvas);
    resizeCanvas();

    let angleX = 0.4;
    let angleY = 0.2;
    let angleZ = 0.2;

    const vertices = [
        {x: -1, y: -1, z: -1},
        {x:  1, y: -1, z: -1},
        {x:  1, y: -1, z:  1},
        {x: -1, y: -1, z:  1},
        {x: -1, y:  1, z: -1},
        {x:  1, y:  1, z: -1},
        {x:  1, y:  1, z:  1},
        {x: -1, y:  1, z:  1}
    ];

    const edges = [
        [0,1], [1,2], [2,3], [3,0], 
        [4,5], [5,6], [6,7], [7,4], 
        [0,4], [1,5], [2,6], [3,7] 
    ];

    function rotatePoint(point, angleX, angleY, angleZ) {
        let {x, y, z} = point;


        let cosX = Math.cos(angleX), sinX = Math.sin(angleX);
        let y1 = y * cosX - z * sinX;
        let z1 = y * sinX + z * cosX;
        y = y1; z = z1;


        let cosY = Math.cos(angleY), sinY = Math.sin(angleY);
        let x1 = x * cosY + z * sinY;
        let z2 = -x * sinY + z * cosY;
        x = x1; z = z2;


        let cosZ = Math.cos(angleZ), sinZ = Math.sin(angleZ);
        let x2 = x * cosZ - y * sinZ;
        let y2 = x * sinZ + y * cosZ;

        return {x: x2, y: y2, z: z2};
    }

    function projectTo2D(x, y, z) {
        const scale = Math.min(canvas.width, canvas.height) * 0.35;
        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;
        const distance = 5;
        const perspective = distance / (distance + z);
        return {
            x: centerX + x * scale * perspective,
            y: centerY - y * scale * perspective
        };
    }

    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.strokeStyle="#0f0";
        ctx.lineWidth = 2;

        edges.forEach(edge => {
            const v1 = vertices[edge[0]];
            const v2 = vertices[edge[1]];

            const rotated1 = rotatePoint(v1, angleX, angleY, angleZ);
            const rotated2 = rotatePoint(v2, angleX, angleY, angleZ);

            const proj1 = projectTo2D(rotated1.x, rotated1.y, rotated1.z);
            const proj2 = projectTo2D(rotated2.x, rotated2.y, rotated2.z);

            ctx.beginPath();
            ctx.moveTo(proj1.x, proj1.y);
            ctx.lineTo(proj2.x, proj2.y);
            ctx.stroke();
        });

        angleX += 0.005;
        angleY += 0.007;
        angleZ += 0.003;
        requestAnimationFrame(draw);
    }

    draw();
</script>
 

Источник

Читайте также