JSFiddle - React, Tailwind, and code Playground
HTML
<div id="test1">
<div id="rect-1">
Rect 1 (easy one)
</div>
<div id="goal-x1">
It works if box lands here!
</div>
</div>
<div id="test2">
<div id="rect-2">
Rect 2 (crazy transform!)
</div>
<div id="goal-x2">
It works if box lands here!
</div>
</div>
<div id="test3">
<div id="rect-3">
Rect 3 (crazier transform!)
</div>
<div id="goal-x3">
It works if box lands here!
</div>
</div>
CSS
#rect-1 {
width: 200px;
height: 200px;
border: 1px solid;
}
#rect-2 {
width: 200px;
height: 200px;
border: 1px solid;
transform: rotate(20deg);
}
#rect-3 {
width: 200px;
height: 200px;
border: 1px solid;
transform: matrix(2, 1, 0, 1, 1, 0);
transform-origin: bottom left;
}
#goal-x1,
#goal-x2,
#goal-x3 {
width: 200px;
height: 200px;
border: 1px solid;
transform: translateX(200px);
position: relative;
top: -202px;
}
JavaScript
function animate(elm, milliseconds, distance) {
console.warn('Running an "animate" method that should be named "moveRightOnly"')
if (distance < 0 || milliseconds < 0) {
throw new Error(
"Feeling negative? Really? This method only moves things to the right. Sorry!"
);
}
const MatrixAPI = window.DomMatrix || window.WebKitCSSMatrix; // Just for compatibility issue
const currentMatrix = new MatrixAPI(
getComputedStyle(elm).getPropertyValue("transform")
);
const params =
"matrix(" +
"abcdef"
.split("")
.map(c => {
if (c !== "e") {
return currentMatrix[c];
} else {
return currentMatrix[c] + distance;
}
})
.join(", ") +
")";
const newMatrix = new MatrixAPI(currentMatrix).setMatrixValue(params);
const transitionRules = (elm.style.transition || "")
.split(",")
.filter(Boolean);
elm.style.transition = transitionRules
.filter(rule => !/transform/i.test(rule))
.concat(`transform ${milliseconds}ms`)
.join(",");
elm.style.transform = newMatrix;
}
const elms = ["rect-1", "rect-2", "rect-3"];
elms.forEach(elmId => {
const elm = document.getElementById(elmId);
elm.addEventListener("click", () => {
animate(elm, 1000, 200);
});
});