Вопрос по jquery, javascript, css3 – Щепотка, чтобы увеличить с CSS3

24

Я пытаюсь реализовать жесты «пинч-масштаб» точно так же, как в Картах Google. Я смотрел разговор Стивена Вудса -& quot; Создание адаптивных сенсорных интерфейсов HTML5 & # x201D; - о проблеме и использованной технике. Идея состоит в том, чтобы установить начало преобразования целевого элемента в (0, 0) и масштабировать в точке преобразования. Затем переведите изображение, чтобы оно было отцентрировано в точке преобразования.

В моем тесте масштабирование кода работает нормально. Изображение увеличивается и уменьшается между последующими переводами. Проблема в том, что я неправильно рассчитываю перевод. Я использую jQuery и Hammer.js для сенсорных событий. Как я могу скорректировать мои вычисления в обратном вызове преобразования, чтобы изображение оставалось центрированным в точке преобразования?

CoffeeScript (#test-resize этоdiv с фоновым изображением)

image = $('#test-resize')

hammer = image.hammer ->
  prevent_default: true
  scale_treshold: 0

width = image.width()
height = image.height()
toX = 0
toY = 0
translateX = 0
translateY = 0
prevScale = 1
scale = 1

hammer.bind 'transformstart', (event) ->

  toX = (event.touches[0].x + event.touches[0].x) / 2
  toY = (event.touches[1].y + event.touches[1].y) / 2

hammer.bind 'transform', (event) ->

  scale = prevScale * event.scale
  shiftX = toX * ((image.width() * scale) - width) / (image.width() * scale)
  shiftY = toY * ((image.height() * scale) - height) / (image.height() * scale)
  width = image.width() * scale
  height = image.height() * scale

  translateX -= shiftX
  translateY -= shiftY

  css = 'translateX(' + @translateX + 'px) translateY(' + @translateY + 'px) scale(' + scale + ')'
  image.css '-webkit-transform', css
  image.css '-webkit-transform-origin', '0 0'

hammer.bind 'transformend', () ->
  prevScale = scale

Ваш Ответ

5   ответов
0

Не реальный ответ, но ссылка на плагин, который сделает все за вас. Отличная работа!

https://github.com/timmywil/jquery.panzoom

(Спасибо "Тиммивиль", кто бы вы ни были)

19

Мне удалось заставить его работать.

jsFiddle demo

В демонстрационной версии jsFiddle нажатие на изображение представляет жест жесткости с центром в точке щелчка. Последующие щелчки увеличивают масштабный коэффициент на постоянную величину. Чтобы сделать это полезным, вы бы хотели выполнять масштабирование и перевод вычислений гораздо чаще для события преобразования (в файле hammer.js это предусмотрено).

Ключом к тому, чтобы заставить его работать, было правильное вычисление координат точки шкалы относительно изображения. я использовалevent.clientX/Y чтобы получить координаты экрана. Следующие строки преобразуют из экрана в координаты изображения:

x -= offset.left + newX
y -= offset.top + newY

Затем мы вычисляем новый размер изображения и находим расстояния для перевода. Уравнение перевода взято изСтивен Вудс говорить.

newWidth = image.width() * scale
newHeight = image.height() * scale

newX += -x * (newWidth - image.width) / newWidth
newY += -y * (newHeight - image.height) / newHeight

Наконец, мы масштабируем и переводим

image.css '-webkit-transform', "scale3d(#{scale}, #{scale}, 1)"         
wrap.css '-webkit-transform', "translate3d(#{newX}px, #{newY}px, 0)"

Мы выполняем все наши переводы на элементе-обертке, чтобы гарантировать, что источник перевода остается в верхнем левом углу нашего изображения.

У Стивена Вудса есть одна хорошая мысль: ничего не делать в коде при преобразовании с помощью css (не загружая вещи и т. Д.). Очень помог в моем собственном проекте.
это мой кот! !! ??
2-я ссылка не работает.
6

Я успешно использовал этот фрагмент, чтобы изменить размеры изображений на телефоне, используя молоток и jquery.

Если это кого-то интересует, я перевел это на JS.

function attachPinch(wrapperID,imgID)
{
    var image = $(imgID);
    var wrap = $(wrapperID);

    var  width = image.width();
    var  height = image.height();
    var  newX = 0;
    var  newY = 0;
    var  offset = wrap.offset();

    $(imgID).hammer().on("pinch", function(event) {
        var photo = $(this);

        newWidth = photo.width() * event.gesture.scale;
        newHeight = photo.height() * event.gesture.scale;

        // Convert from screen to image coordinates
        var x;
        var y;
        x -= offset.left + newX;
        y -= offset.top + newY;

        newX += -x * (newWidth - width) / newWidth;
        newY += -y * (newHeight - height) / newHeight;

        photo.css('-webkit-transform', "scale3d("+event.gesture.scale+", "+event.gesture.scale+", 1)");      
        wrap.css('-webkit-transform', "translate3d("+newX+"px, "+newY+"px, 0)");

        width = newWidth;
        height = newHeight;
    });

}
Можешь прочитать ? & Quot;I successfully used that snippet to resize images& Quot; Я никогда не упоминалdragging. $(imgID).hammer().on("pinch", function(event)[...] function attachPinch(wrapperID,imgID)[...]"
Это отличный сценарий, но для тех, кто хочет его воспроизвести - обратите внимание, что (а) он использует плагин Jquery для молотка и (б) вам нужно будет изменить плагин, потому чтоyou must enable pinch within hammer for it work, {hamObj = новый молот ($ el [0], параметры); hamObj.get ("ущипнуть"). set ({enable: true}); $ el.data (& quot; hammer & quot ;, hamObj);}
0

Это то, что я написал несколько лет назад на Java и недавно преобразовал в JavaScript

function View()
{
 this.pos = {x:0,y:0};
 this.Z = 0;
 this.zoom = 1;
 this.scale = 1.1;
 this.Zoom = function(delta,x,y)
 {
  var X = x-this.pos.x;
  var Y = y-this.pos.y;
  var scale = this.scale;
  if(delta>0) this.Z++;
  else
  {
   this.Z--;
   scale = 1/scale;
  }
  this.zoom = Math.pow(this.scale, this.Z);
  this.pos.x+=X-scale*X;
  this.pos.y+=Y-scale*Y;
 }
}

this.Zoom = function(delta,x,y) принимает:

  • delta = zoom in or out
  • x = x position of the zoom origin
  • y = y position of the zoom origin

Небольшой пример:

<script>
var view = new View();
var DivStyle = {x:-123,y:-423,w:300,h:200};
function OnMouseWheel(event)
{
 event.preventDefault();
 view.Zoom(event.wheelDelta,event.clientX,event.clientY);
 div.style.left = (DivStyle.x*view.zoom+view.pos.x)+"px";
 div.style.top = (DivStyle.y*view.zoom+view.pos.y)+"px";
 div.style.width = (DivStyle.w*view.zoom)+"px";
 div.style.height = (DivStyle.h*view.zoom)+"px";
}
function OnMouseMove(event)
{
 view.pos = {x:event.clientX,y:event.clientY};
 div.style.left = (DivStyle.x*view.zoom+view.pos.x)+"px";
 div.style.top = (DivStyle.y*view.zoom+view.pos.y)+"px";
 div.style.width = (DivStyle.w*view.zoom)+"px";
 div.style.height = (DivStyle.h*view.zoom)+"px";
}
</script>
<body onmousewheel="OnMouseWheel(event)" onmousemove="OnMouseMove(event)">
<div id="div" style="position:absolute;left:-123px;top:-423px;width:300px;height:200px;border:1px solid;"></div>
</body>

Это было сделано с целью использования с холстом и графикой, но оно должно прекрасно работать для обычного HTML-макета

2

Я просмотрел весь интернет и все что угодно, пока не наткнулся на единственный работающий плагин / библиотеку -http://cubiq.org/iscroll-4

var myScroll;
myScroll = new iScroll('wrapper');

где обертка - это ваш идентификатор, как в id = "обертка"

<div id="wrapper">
    <img src="smth.jpg" />
</div>

Похожие вопросы