2012-05-29 5 views
23

Я пытаюсь реализовать жесты сжимать до зума точно так же, как в Картах Google. Я смотрел разговор Стивена Вудса - "Creating Responsive HTML5 Touch Interfaces” - о проблеме и использовал упомянутую технику. Идея состоит в том, чтобы установить начало преобразования целевого элемента в (0, 0) и масштабировать в точке преобразования. Затем переведите изображение, чтобы оно было сосредоточено в точке преобразования.Пинч для увеличения с помощью CSS3

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

The 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 

ответ

19

мне удалось получить его работу.

jsFiddle demo

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

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

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

Затем вычисляет новый размер изображения и найти путь, чтобы перевести на. Уравнение перевода взято из Stephen Woods' talk.

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)" 

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

+10

тот мой кот! !! ?? –

+0

2-я ссылка не работает. –

+0

Существует действительно хороший момент от Стивена Вудса: не делайте абсолютного ничего в коде при преобразовании с помощью css (не загружая материал и т. Д.). Помогли в моем собственном проекте. – Hardy

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

} 
+0

Можете ли вы прочитать? «** Я успешно использовал этот фрагмент для изменения размеров изображений **« Я никогда не упоминал _dragging_. '$ (imgID) .hammer(). on (" pinch ", function (event) [...] function attachPinch (wrapperID, imgID) [...]" ' –

+0

Это отличный скрипт, но для тех, кто хочет повторите его: обратите внимание, что (a) он использует плагин JQuery для молотка и (b) вам нужно будет изменить плагин, потому что * вы должны включить зажим в молот для его работы *. \t \t \t \t {hamObj = new Hammer ($ эль [0], опционы); \t \t \t \t hamObj.get ('пинч') множество ({включить: истинно}.); \t \t \t \t $ el.data ("молот", hamObj);} – Ukuser32

2

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

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

где обертка ваш идентификатор, как и в ид = «обертку»

<div id="wrapper"> 
    <img src="smth.jpg" /> 
</div> 
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 = увеличения или уменьшения
  • x = х позиции масштабирования происхождения
  • y = у позиции масштабирования происхождения

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

<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 макета