rotatable-tiltable element

dragging on the element makes the image rotating and tilting

by cs09g

HTML

<div id="map">MAP</div>
<div id="compass"></div>

CSS

#compass {
  width: 100px;
  height: 100px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E %3Cpolygon fill='%23333333' points='6,9 10,1 14,9'/%3E %3Cpolygon fill='%23CCCCCC' points='6,11 10,19 14,11 '/%3E %3C/svg%3E");
  font-size: 100px;
  user-select: none;
}
#map {
  width: 200px;
  height: 200px;
  border: 1px solid black;
  user-select: none;
  font-size: 100px;
}

JavaScript

let map = document.querySelector("#map")
let compass = document.querySelector("#compass");
let dragging = false;
let tilt = 0;
let rotate = 0;

map.addEventListener("mousedown", (e) => {
  dragging = true;
  compass.style.transition = "none";
});

map.addEventListener("mousemove", (e) => {
	if (dragging) {
		tilt += -e.movementY;
    rotate += -e.movementX;
    if (tilt < 0) {
    	tilt = 0;
    } else if (tilt > 60) {
	    tilt = 60;
    }
    compass.style.transform = `rotateX(${tilt}deg) rotateZ(${rotate}deg)`;
  }
});

compass.addEventListener("click", (e) => {
	if (rotate === 0) {
  	tilt = 0;
  } else {
  	rotate = 0;
  }
  compass.style.transition = "1s";
  //compass.style.transform = `rotateX(${tilt}deg) rotateZ(${rotate}deg)`;
  compass.style.transform = `rotateX(0deg) rotateZ(0deg)`;
});

map.addEventListener("mouseup", (e) => {
  dragging = false;
});

map.addEventListener("mouseout", (e) => {
	dragging = false;
});