it-swarm.com.de

Prise zum Zoomen mit CSS3

Ich versuche, Pinch-to-Zoom-Gesten genau wie in Google Maps zu implementieren. Ich habe mir einen Vortrag von Stephen Woods - "Responsive HTML5 Touch Interfaces erstellen" - über das Problem angesehen und die erwähnte Technik verwendet. Die Idee ist, den Transformationsursprung des Zielelements auf (0, 0) und die Skalierung auf festzulegen den Punkt der Transformation: Übersetzen Sie dann das Bild, um es am Punkt der Transformation zentriert zu halten. 

In meinem Testcode funktioniert die Skalierung gut. Das Bild wird zwischen nachfolgenden Übersetzungen vergrößert und verkleinert. Das Problem ist, dass ich die Übersetzungswerte nicht richtig berechne. Ich benutze jQuery und Hammer.js für Touch-Events. Wie kann ich meine Berechnung im Transformations-Callback so anpassen, dass das Bild am Transformationspunkt zentriert bleibt?

Das CoffeeScript (#test-resize ist eine div mit einem Hintergrundbild)

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
23
Maros Hluska

Ich habe es geschafft, es zum Laufen zu bringen. 

jsFiddle Demo

In der jsFiddle-Demo wird durch Klicken auf das Bild eine am Klickpunkt zentrierte Pinch-Geste dargestellt. Nachfolgende Klicks erhöhen den Skalierungsfaktor um einen konstanten Betrag. Um dies nützlich zu machen, möchten Sie die Skalierungs- und Konvertierungsberechnungen bei einem Transformationsereignis viel häufiger durchführen (Hammer.js stellt eines bereit).

Der Schlüssel dazu war, den Skalierungspunkt relativ zum Bild korrekt zu berechnen. Ich habe event.clientX/Y verwendet, um die Bildschirmkoordinaten zu erhalten. Die folgenden Zeilen werden von Bildschirm- in Bildkoordinaten konvertiert:

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

Dann berechnen wir eine neue Größe für das Bild und ermitteln die zu übersetzenden Entfernungen. Die Übersetzungsgleichung stammt aus Stephen Woods 'Vortrag .

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

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

Zum Schluss skalieren und übersetzen wir

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

Wir machen alle unsere Übersetzungen auf einem Wrapper-Element, um sicherzustellen, dass der translate-Origin oben links in unserem Bild bleibt.

19
Maros Hluska

Ich habe dieses Snippet erfolgreich verwendet, um die Größe von Bildern in Phonegap mithilfe von Hammer und Jquery zu ändern.

Wenn es jemanden interessiert, habe ich das an JS übersetzt.

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

}
6
Raphael Toselli

Ich schaute überall im Internet und außerhalb des Internets, bis ich auf das einzige funktionierende Plugin/die Bibliothek stieß - http://cubiq.org/iscroll-4

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

wo Wrapper ist Ihre ID wie in ID = "Wrapper"

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

Keine echte Antwort, aber ein Link zu einem Plug = in, der alles für Sie erledigt. Gute Arbeit! 

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

(Danke 'Timmywil', wer auch immer du bist)

0
Ideogram

Das habe ich vor ein paar Jahren in Java geschrieben und kürzlich in JavaScript konvertiert

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

Die this.Zoom = function(delta,x,y) dauert:

  • delta = vergrößern oder verkleinern
  • x = x Position des Zoom-Ursprungs
  • y = y Position des Zoom-Ursprungs

Ein kleines Beispiel:

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

Dies wurde mit der Absicht gemacht, mit einer Leinwand und Grafiken verwendet zu werden, sollte jedoch für normales HTML-Layout perfekt funktionieren

0
Isaac