I'm attempting to scale an image and have it translate correctly from an origin point (basically a pinch to zoom). I'm trying to find a solution that doesn't involve changing transform-origin
, because it will complicate finding the left/top edges of the picture, which I'm using for more than just this problem.
This is more of a math problem. I'm having trouble coming up with an equation to determine how much to translate the image, based on an origin. The current equation I have worked out does not scale from a point correctly. In regards to the demo, the image should blow up from the mouse pointer when scrolling with the mouse.
I'm not looking for a workaround, or an alternative design. As stated before, I can't modify the transform-origin property.
Demo: https://jsfiddle.net/dook/ort0efjd/
Matrix transform function
function transform() {
var matrix = [dim.new_scale, 0, 0, dim.new_scale, dim.new_x, dim.new_y].join(",");
image_center.css({
"transform": "matrix(" + matrix + ") translate3d(0, 0, 0)",
"-webkit-transform": "matrix(" + matrix + ") translate3d(0, 0, 0)",
"-moz-transform": "matrix(" + matrix + ") translate3d(0, 0, 0)",
});
}
Mousewheel event
// Determine mousewheel pointer in relation to picture origin
var offset = image_center.offset();
var originX = ev.originalEvent.pageX - offset.left;
var originY = ev.originalEvent.pageY - offset.top;
// truncated --- new_scale is modified
// Translate based on pointer origin -- This is where I need help
dim.new_x = originX + dim.height * (dim.new_scale - 1);
dim.new_y = originY + dim.height * (dim.new_scale - 1);
// truncated -- Keep image within constraints
transform(); // Applies everything in dim to CSS transform matrix
A translation cannot be represented by a 2x2 matrix. To see why this is so we must realise that a 2x2 matrix is actually generating a linear combination of its inputs, i.e.: In such a combination, there is no way to represent a term which is independent of both x and y.
You can translate a point in 2D by adding translation coordinate (tx, ty) to the original coordinate X,Y to get the new coordinate X′,Y′. The pair (tx, ty) is called the translation vector or shift vector. The above equations can also be represented using the column vectors.
One simple approach is to create an off-screen object and center it's transform-origin. Apply the scaling to this object.
Then copy the Matrix transformation from the off-screen element to the on screen element and you should have the correct scale.
Here are some image prototypes to copy the matrix:
HTMLImageElement.prototype.getMatrix = function() {
var st = window.getComputedStyle(this, null);
return st.getPropertyValue("-webkit-transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform") ||
'none';
};
HTMLImageElement.prototype.setMatrix = function(matrix) {
this.style.webkitTransform =
this.style.msTransform =
this.style.MozTransform =
this.style.OTransform =
this.style.transform =
matrix;
return this;
};
getMatrix
returns a matrix string.
setMatrix
takes a matrix string.
targetImage.setMatrix(sourceImage.getMatrix())
were targetImage is the displayed image and sourceImage is the off-screen image
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With