Код: Выделить всё
const DEFAULT_ROTATION = [-27, -36];
let position = [0, 0];
let rotation = DEFAULT_ROTATION;
let isMoved = false;
const container = document.querySelector(".container");
const rotate = () => {
container.style.setProperty("--rotate-x", rotation[0] + "deg");
container.style.setProperty("--rotate-y", rotation[1] + "deg");
};
const reset = () => {
position = [0, 0];
rotation = DEFAULT_ROTATION;
rotate();
};
const cube = document.querySelector(".cube");
cube.addEventListener("pointerdown", e => {
position = [e.clientX, e.clientY];
cube.setPointerCapture(e.pointerId);
});
cube.addEventListener("pointermove", e => {
if (!cube.hasPointerCapture(e.pointerId)) return;
const rx = floorMod(rotation[0], 360),
ryDir = rx > 90 && rx < 270 ? 1 : -1;
rotation = [
rotation[0] - (Math.round(e.clientY) - position[1]),
rotation[1] - ryDir * (Math.round(e.clientX) - position[0]) % 360,
];
rotate();
const newPosition = [Math.round(e.clientX), Math.round(e.clientY)];
if (!isMoved && Math.hypot(position[0] - newPosition[0], position[1] - newPosition[1]) >= 1) isMoved = true;
position = newPosition;
});
cube.addEventListener("pointerup", e => {
position = [0, 0];
cube.releasePointerCapture(e.pointerId);
const target = document.elementFromPoint(e.pageX, e.pageY);
const face = target?.closest(".face");
if (e.button === 1 || e.button === 2) { if (!isMoved) reset(); }
else if (!isMoved && face instanceof HTMLElement) face.click();
isMoved = false;
});
const faces = document.querySelectorAll(".face");
faces.forEach(face => face.addEventListener("click", e => {
faces.forEach(face => face.classList.remove("selected"));
face.classList.add("selected");
}));
function floorMod(x, y) {
let result = x % y;
if (result !== 0 && x < 0 !== y < 0)
result += y;
return result;
}< /code>
.container {
--side-length: 200px;
width: var(--side-length);
height: var(--side-length);
position: relative;
transform: rotateX(var(--rotate-x, -27deg)) rotateY(var(--rotate-y, -36deg));
transform-style: preserve-3d;
user-select: none;
transition: all cubic-bezier(0, 0, 0, 1) 250ms;
}
.face {
width: var(--side-length);
height: var(--side-length);
position: absolute;
align-content: center;
overflow: clip;
text-align: center;
color: black;
background-color: #ffffffb3;
border: 2px solid #0000000f;
border-radius: calc(8 / 200 * var(--side-length));
pointer-events: auto;
transition: none;
&.front {
transform: translateZ(calc(var(--side-length) / 2));
}
&.back {
transform: translateZ(calc(var(--side-length) / -2)) rotateY(180deg);
}
&.left {
transform: translateX(calc(var(--side-length) / -2)) rotateY(-90deg);
}
&.right {
transform: translateX(calc(var(--side-length) / 2)) rotateY(90deg);
}
&.top {
transform: translateY(calc(var(--side-length) / -2)) rotateX(90deg);
}
&.bottom {
transform: translateY(calc(var(--side-length) / 2)) rotateX(-90deg);
}
&.selected {
color: white;
background-color: #005fb8;
&:hover {
background-color: #005fb8e0;
}
&:active {
background-color: #005fb8c0;
}
}
&:not(.selected) {
&:hover {
color: #005fb8;
}
&:active {
color: #005fb880;
}
}
}
.cube {
display: grid;
place-items: center;
width: 350px;
height: 350px;
perspective: 750px;
cursor: grab;
&:active {
cursor: grabbing;
}
}
body {
display: grid;
place-items: center;
height: 100vh;
margin: 0;
}
* {
box-sizing: border-box;
}< /code>
Front
Back
Left
Right
Top
Bottom
< /p>
В целом, он работает нормально. Однако, если лицо (включая верхнюю, внизу, слева, справа, но исключая спереди и сзади), обращенное к экрану, его нельзя щелкнуть. Например:
Это лицо не может быть нажат, и можно щелкнуть только одну из случайных боковых лиц. Элемент ( ctrl + shift + c ), он все еще не будет выбран.
Я попробовал метод здесь, он уменьшает угол, где его нельзя щелкнуть. Тем не менее, он по -прежнему не работает при вращении ровно до 90 градусов.>
Подробнее здесь: https://stackoverflow.com/questions/794 ... -to-certai