const ANGLE = 45 * (Math.PI / 180)
const box = document.getElementById("box")
const rotate = document.getElementById("rotate")
const resizerBr = document.getElementById("resizer-br")
function getMatrix() {
return box.style.transform
.replace("matrix3d(", "")
.replace(")", "")
.split(", ")
.map((x) => Number(x))
}
box.style.transform = `matrix3d(
${Math.cos(ANGLE)}, ${Math.sin(ANGLE)}, 0, 0,
-${Math.sin(ANGLE)}, ${Math.cos(ANGLE)}, 0, 0,
0, 0, 1, 0,
150, 150, 0, 1
)`
box.addEventListener("mousedown", (e) => {
if (e.target !== box) return
const boxRect = box.getBoundingClientRect()
const initX = e.clientX
const initY = e.clientY
const mt = getMatrix()
function drag(event) {
const dx = event.clientX - initX
const dy = event.clientY - initY
// prettier-ignore
const matrix = [
mt[0], mt[1], 0, 0,
mt[4], mt[5], 0, 0,
0, 0, 1, 0,
mt[12] + dx, mt[13] + dy, 0, 1
]
box.style.transform = `matrix3d(${matrix})`
}
function clearListeners() {
window.removeEventListener("mousemove", drag)
window.removeEventListener("mouseup", clearListeners)
}
window.addEventListener("mousemove", drag)
window.addEventListener("mouseup", clearListeners)
})
rotate.addEventListener("mousedown", (e) => {
const boxRect = box.getBoundingClientRect()
const initX = boxRect.left + boxRect.width / 2
const initY = boxRect.top + boxRect.height / 2
const mt = getMatrix()
function rotate(event) {
const dx = event.clientX - initX
const dy = event.clientY - initY
const angle = Math.atan2(dy, dx) + Math.PI / 2
// prettier-ignore
const rotationMatrix = [
Math.cos(angle), Math.sin(angle), 0, 0,
-Math.sin(angle), Math.cos(angle), 0, 0,
0, 0, 1, 0,
mt[12], mt[13], 0, 1
]
box.style.transform = `matrix3d(${rotationMatrix})`
}
function clearListeners() {
window.removeEventListener("mousemove", rotate)
window.removeEventListener("mouseup", clearListeners)
}
window.addEventListener("mousemove", rotate)
window.addEventListener("mouseup", clearListeners)
})
resizerBr.addEventListener("mousedown", (e) => {
const boxRect = box.getBoundingClientRect()
const initX = e.clientX
const initY = e.clientY
const width = boxRect.width
const height = boxRect.height
const mt = getMatrix()
function resize(event) {
const dx = event.clientX - initX
const dy = event.clientY - initY
const newWidth = width + dx
const newHeight = height + dy
box.style.width = `${newWidth}px`
box.style.height = `${newHeight}px`
}
function clearListeners() {
window.removeEventListener("mousemove", resize)
window.removeEventListener("mouseup", clearListeners)
}
window.addEventListener("mousemove", resize)
window.addEventListener("mouseup", clearListeners)
})
.box-wrapper {
position: relative;
}
.box {
height: 200px;
width: 300px;
background-color: red;
position: relative;
}
.rotate {
position: absolute;
height: 50px;
width: 10px;
top: -50px;
left: 146px;
background-color: blue;
}
.resizer.br {
width: 50px;
height: 50px;
background-color: aqua;
position: absolute;
top: calc(100% - 50px);
left: calc(100% - 50px);
}
<div id="box" class="box">
<div id="rotate" class="rotate"></div>
<div id="resizer-br" class="resizer br"></div>
</div>