Подтвердить что ты не робот

Матричная шкала/перевод из точки

Я пытаюсь масштабировать изображение и правильно его переводить из точки начала (в основном, для увеличения). Я пытаюсь найти решение, которое не связано с изменением 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)",
  });
}

Событие Mousewheel

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

Ответ 1

Один простой подход заключается в создании объекта вне экрана и центра его трансформации-источника. Примените масштабирование к этому объекту.

Затем скопируйте преобразование матрицы из элемента вне экрана в элемент на экране, и вы должны иметь правильный масштаб.

Вот некоторые прототипы изображений для копирования матрицы:

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 - это внеэкранное изображение.

Ответ 2

Попробуйте следующее: 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();
  });
});

Ответ 3

Я получил частичное решение. Я думаю, что он делает то, что вам нужно, увеличивать и уменьшать масштаб в точке, заданной вашей мышью. К сожалению, если вы увеличиваете масштаб, переместите мышь в другую точку, а затем снова увеличите масштаб, она скачет.

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();
  });
});