2012-05-29 160 views
23

我試圖完全捏縮放手勢完全符合谷歌地圖。我觀看了斯蒂芬伍茲的演講 - "Creating Responsive HTML5 Touch Interfaces」 - 關於這個問題,並使用了上述技巧。我們的想法是將目標元素的變換原點設置爲(0,0)並在變換點進行縮放。然後翻譯圖像以保持它在變換點處居中。捏與CSS3縮放

在我的測試代碼縮放工作正常。圖像在後續翻譯之間放大和縮小。問題是我沒有正確計算翻譯值。我正在使用jQuery和Hammer.js進行觸摸事件。如何在變換回調中調整我的計算,以便圖像保持居中在變換點上?

的CoffeeScript中(#test-resizediv與背景圖像)

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

第二個鏈接已損壞。 –

+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)您將需要修改插件,因爲*您必須啓用錘子內的捏才能工作*。 EL [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'); 

,其中包裝是你的ID在ID =「包裝」

<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 = X縮放原點位置縮放原點

A的

  • y = y位置小例子:

    <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佈局