I’m developing a game using basic JS that involves moving game pieces around a board. I’m running into an issue when trying to perform multiple transformations, specifically rotations.
The game requires that the pieces “pivot” around their top corners, then move in the direction they are facing after the rotation (see the example), and perform additional rotations as needed.
My issue is that, as soon as I add the transform-origin property to choose a pivot corner, the previous rotation gets messed up.
I’m searching for a way to retain the previous transformation, and then start clean with a new one on the next move.
CodePen
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rectangle Transformation</title>
<style>
body {
display: flex;
margin: 0;
height: 100vh;
}
.inputs {
margin: 20px;
}
.rectangle {
width: 200px;
height: 100px;
background-color: coral;
position: absolute;
top: 50%;
left: 50%;
transform-origin: center;
}
</style>
</head>
<body>
<div class="inputs">
<div>
<span>Rotate:</span>
<input type="range" id="rotate-slider" min="0" max="360" value="0" step="1">
</div>
<div>
<span>Move:</span>
<input type="range" id="move-slider" min="0" max="360" value="0" step="1">
</div>
<div>
<span>Transform Origin: </span>
<select onchange="selected(this)">
<option>center</option>
<option>top right</option>
<option>top left</option>
</select>
</div>
</div>
<div class="rectangle" id="rectangle"></div>
<script>
const rectangle = document.getElementById('rectangle');
const rotateSlider = document.getElementById('rotate-slider');
const moveSlider = document.getElementById('move-slider');
const select = document.querySelector('select');
function updateRotation(angle) {
rectangle.style.transform = `rotate(${angle}deg)`;
}
rotateSlider.addEventListener('input', (e) => {
let angle = e.target.value;
if (select.value == 'top left') {
angle = 360 - angle;
}
updateRotation(angle);
});
function selected(selectObject) {
var value = selectObject.value;
rectangle.style.transformOrigin = value;
}
function moveRectangle() {
const distance = parseFloat(moveSlider.value);
const angle = parseFloat(rotateSlider.value);
const radians = angle * (Math.PI / 180);
const moveY = distance * Math.cos(radians);
const moveX = distance * Math.sin(radians);
rectangle.style.left = `calc(50% + ${moveX}px)`;
rectangle.style.top = `calc(50% + ${moveY * -1}px)`;
}
moveSlider.addEventListener('input', moveRectangle);
</script>
</body>
</html>
Is my approach to this all wrong?
pmock is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.