This is an AI-generated translation of the original Polish article and may contain minor errors.
Building an Interactive 3D Rubik's Cube in Vue 3 and WebGL

3D graphics in the browser have long ceased to be just a technological curiosity, becoming a powerful tool for building highly interactive experiences. When we think of 3D on the web, the first association is often the Three.js library. In this post, however, I would like to present an architectural approach consisting of building an Interactive 3D Rubik's Cube fully within the Vue 3 framework, relying heavily on the native WebGL interface API and precise state management of rotation fractions.
You can explore my latest open-source project – rubic-cube – in its entirety on my public Gitea instance. Enjoy reading!
Architecture and Challenges
The main problem when implementing logic games like a Rubik's Cube is not just "drawing" cubes in space, but collision-free management of their rotations across individual axes.
Why Vue 3?
Using Vue 3's reactive state (thanks to the Composition API – ref, computed, watch) allows us to elegantly decouple the logic and mathematics of the cube itself (the state of the individual 27 smaller cubes, so-called Cubies) from the rendering layer casting frames onto the <canvas>. Vue's reactive engine works brilliantly in tracking the "intent" of the user to rotate a given face (e.g., swiping a finger across the screen).
Rendering Loop vs Reactivity Board
In a typical web 3D flow, we have a requestAnimationFrame loop that calculates and redraws the world 60 (or 120) times per second. Throwing the entire reactive Vue state into it would drastically kill performance on weaker devices (mobile).
My solution for maintaining 60 FPS was to limit reactivity. The cube's arrangement representation (data model) is updated only on demand during specific algorithm moves, while WebGL simply projects polygons into cosmic space in a raw loop querying transformation matrices, almost completely bypassing the Vue proxy during pure painting (rendering).
TIP
The best optimization tactic in Vue for heavy rendering projection operations is to separate the transformation matrices as raw JS objects without the overhead of Reactivity.
Mathematical Model – Quaternions and Euler Angles
To prevent the famous Gimbal Lock problem, we implement the rotations of the entire 3x3x3 matrix of individual planes using Quaternions rather than Euler Angles. When we make a "quick turn" of the right face, a CSS animation is too unreliable to depend on.
Rotation occurs by mapping positions relative to the central iteration:
// Conceptual fragment of the column rotation algorithm in Vue
function rotateSlice(axis, index, direction) {
state.isAnimating = true;
const targetAngle = direction * (Math.PI / 2); // 90 degrees
animateValue(0, targetAngle, 300, (currentAngle) => {
// Updating the rotation matrix for active cubies
updateActiveCubiesMatrix(axis, currentAngle);
}).then(() => {
snapToGrid();
state.isAnimating = false;
});
}Thanks to this, we obtain the effect of the cube "snapping" into its hard places exactly every 90 degrees while maintaining a perfectly smooth, isometrically projected rotation.
Responsiveness and Mobile Touch
A Rubik's Cube requires three-dimensional dragging – we do not have flat scrolling here. This was solved by registering native touchstart, touchmove events on the <canvas> object, which allows analyzing drag delta vectors:
<template>
<div class="cube-container">
<canvas
ref="webglCanvas"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
></canvas>
</div>
</template>The whole thing is fully playable on a touch screen and works with noticeably low latency – almost as good as a native application, which is a phenomenal success of modern web standards.
Try it yourself!
Building graphics based on spatial mathematics develops an engineer's mind much more than standard assembling of REST forms and queries. It opens the eyes to hardware optimizations.
Take a look at the public repository on my domain to download the code yourself and run it locally: 👉 Rubic Cube Repository on Gitea 7u.pl
Solve it all and show off your scramble algorithm PR time! 🚀