The problem of the approach taken from the accepted answer is that assigning the transform
value to the css property translate
"breaks" other element transformations (for example, rotation).
There is a more flexible way. Modern browsers support the DOMMatrix
interface, which is designed specifically for working with transformations.
You can read more about it, for example, on MDN (en) .
Or, you can use the following simple helpers that change the value of the transformation through matrix()
:
class CssTransform2d { constructor(element) { this.el = element; } get matrix() { let tm = getComputedStyle(this.el).getPropertyValue('transform').match(/\((.*)\)/); return (tm ? tm[1] : '1,0,0,1,0,0').split(/,\s*/).map(v => +v); } set matrix(v) { this.el.style.transform = `matrix(${v.join(', ')})`; } get translate() { return this.matrix.slice(-2); } set translate(xy) { this.matrix = [...this.matrix.slice(0, 4), ...xy]; } get translateX() { return this.matrix[4]; } set translateX(v) { this.matrix = [...this.matrix.slice(0, 4), v, this.matrix[5]]; } get translateY() { return this.matrix[5]; } set translateY(v) { this.matrix = [...this.matrix.slice(0, 4), this.matrix[4], v]; } } /*--------------------- использование ---------------------*/ const ct = new CssTransform2d($('#box')[0]); console.log(ct.matrix.join(', ')); $('.btn-move').click(function () { const $this = $(this); let [x, y] = ct.translate; switch ($this.data('direction')) { case '<': x -= 30; break; case '>': x += 30; break; case '∧': y -= 30; break; case '∨': y += 30; } ct.translate = [x, y]; console.clear() || console.log(ct.matrix.join(', ')); });
.btn-move { width: 2rem; height: 1.7rem; } .btn-move::after { content: attr(data-direction); display: inline; } #btns { position: relative; z-index: 99; } #box { width: 3rem; height: 3rem; background: #4d4; transition: transform 0.15s linear; transform: translate(10rem, 20vh) rotate(45deg); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="btns"> <button class="btn-move" data-direction="<"></button> <button class="btn-move" data-direction="∧"></button> <button class="btn-move" data-direction="∨"></button> <button class="btn-move" data-direction=">"></button> </div> <div id="box"></div>
(The code in the example works only with a 2D transform, while DOMMatrix
supports three-dimensional ones. Plus, the standard interface offers much more features, and it is not written on the knee :)
)