矩阵缩放/平移的点是什么意思?

15

我想尝试对一张图片进行缩放,并确保其从一个起始点正确移动(基本上是捏合缩放)。我正在尝试找到一个解决方案,不涉及更改transform-origin属性,因为这将使查找图像的左/上边缘变得复杂,而我正在为此问题使用它们。

这更像是一个数学问题。 我遇到了麻烦,无法想出一个方程来确定根据原点需要平移多少图像。 我目前想出的等式不能正确地从一个点缩放。 关于演示,当用鼠标滚动时,图像应该从鼠标指针处放大。

我不想寻找变通方法或替代设计。如前所述,我不能修改transform-origin属性。

演示:https://jsfiddle.net/dook/ort0efjd/

矩阵变换函数

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)",
  });
}

鼠标滚轮事件

// 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

你想做什么?JSFiddle 在某些方面似乎是有效的。 - Brett DeWoody
1
我不明白到底哪里出了问题? - fnune
我更新了问题,希望更清楚地表达我的问题。 - dook
3个回答

2

一个简单的方法是创建一个离屏对象并将其变换原点居中。将缩放应用于此对象。

然后从离屏元素复制矩阵变换到屏幕元素,这样您就可以获得正确的比例。

以下是一些图像原型可用于复制矩阵:

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 返回一个矩阵字符串。 setMatrix 接受一个矩阵字符串。

targetImage.setMatrix(sourceImage.getMatrix())

其中,targetImage是显示的图像,sourceImage是屏幕外的图像。


1

我得到了一个部分解决方案。我认为它可以做到你想要的,即以鼠标指定的点为中心进行缩放。不幸的是,如果你先缩放,然后将鼠标移动到另一个点,再次缩放,它会跳来跳去。

var image_center = $("#image");
var base_image = $(".outer");
var dim = {};
var original_offset = image_center.offset();

function resetDim() {
  // Initialize image.dim with values
  dim.cont_width = base_image.width(); // Container width
  dim.cont_height = base_image.height(); // Container height
  dim.width = image_center.width(); // Element width
  dim.height = image_center.height(); // Element height

  dim.new_x = 0; // Initial/new x position
  dim.new_y = 0; // Initial/new y position
  dim.new_scale = 1; // Initial/new scale
  dim.max_scale = 3; // Max image scale
};

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)",
  });
}

$(document).ready(function() {
  resetDim();

  $('.outer').bind('mousewheel', function(ev) {
    // onScroll start
    // Determine pointer origin in relation to picture
    var originX = ev.originalEvent.pageX - original_offset.left;
    var originY = ev.originalEvent.pageY - original_offset.top;

    // onScroll ev
    dim.new_scale += (ev.originalEvent.deltaY > 0) ? -0.1 : 0.1;
    if (dim.new_scale > dim.max_scale) dim.new_scale = dim.max_scale;
    else if (dim.new_scale < 1) dim.new_scale = 1;

    // Translate based on origin
    dim.new_x = -(originX * (dim.new_scale-1) );
    dim.new_y = -(originY * (dim.new_scale-1) );

    transform();
  });
});

1

试试这个:https://jsfiddle.net/6c585qom/2/

当然,如果你滚动得太快,过渡效果就会跟不上,但如果你慢慢滚动,图像就会锁定在鼠标上。

var image_center = $("#image");
var base_image = $(".outer");
var dim = {};

function resetDim() {
  // Initialize image.dim with values
  dim.cont_width = base_image.width(); // Container width
  dim.cont_height = base_image.height(); // Container height
  dim.width = image_center.width(); // Element width
  dim.height = image_center.height(); // Element height

  dim.left_edge = 0;
  dim.top_edge = 0; // Edge translation
  dim.init_x = 0;
  dim.new_x = 0; // Initial/new x position
  dim.init_y = 0;
  dim.new_y = 0; // Initial/new y position
  dim.init_scale = 1;
  dim.new_scale = 1; // Initial/new scale
  dim.max_scale = 3; // Max image scale
};

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)",
  });
}

$(document).ready(function() {
  resetDim();
  transform();

  $('.outer').bind('mousewheel', function(ev) {
    // onScroll start
    // Determine pointer origin in relation to picture
    var offset = image_center.offset();
    var originX = ev.originalEvent.pageX - offset.left;
    var originY = ev.originalEvent.pageY - offset.top;
    // Calculate current size of the image.
    var width = dim.width * dim.new_scale;
    var height = dim.height * dim.new_scale;
        // Calculate the relative position of the mouse independent of current scale.
    var mx = originX / width;
    var my = originY / height;

    // onScroll ev
    dim.new_scale += (ev.originalEvent.deltaY > 0) ? -0.1 : 0.1;
    if (dim.new_scale > dim.max_scale) dim.new_scale = dim.max_scale;
    else if (dim.new_scale < 1) dim.new_scale = 1;

    // Update new image position based upon new scale.
    var new_width = dim.width * dim.new_scale;
    var new_height = dim.height * dim.new_scale;
    var new_mouse_x = new_width * mx;
    var new_mouse_y = new_height * my;
    dim.new_x += originX - new_mouse_x;
    dim.new_y += originY - new_mouse_y;
    transform();
  });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接