Ad

Matrix Scale/translate From Point

- 1 answer

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
Ad

Answer

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

Ad
source: stackoverflow.com
Ad