2015-05-26 2 views
15

Wie kann ich mit fabricjs schwenken und zoomen? Ich habe versucht, die Methoden zoomToPoint und setZoom zu verwenden, aber sie funktionieren nicht zum Schwenken. Sobald ich verschiedene Zoom-Punkte verwende, habe ich Probleme.Fabricjs schwenken und zoomen

$('#zoomIn').click(function(){ 
    canvas.setZoom(canvas.getZoom() * 1.1) ; 
}) ; 

$('#zoomOut').click(function(){ 
    canvas.setZoom(canvas.getZoom()/1.1) ; 
}) ; 

$('#goRight').click(function(){ 
    //Need to implement 
}) ; 

$('#goLeft').click(function(){ 
    //Need to implement 
}) ; 

http://jsfiddle.net/hdramos/ux16013L/

+0

Können Sie das näher erläutern? Auf was mache ich die Anpassung? – d0001

Antwort

15

es mit Gelöst:

relativePan() absolutePan()

[Update]

$('#goRight').click(function(){ 
    var units = 10 ; 
    var delta = new fabric.Point(units,0) ; 
    canvas.relativePan(delta) ; 
}) ; 

$('#goLeft').click(function(){ 
    var units = 10 ; 
    var delta = new fabric.Point(-units,0) ; 
    canvas.relativePan(delta) ; 
}) ; 
$('#goUp').click(function(){ 
    var units = 10 ; 
    var delta = new fabric.Point(0,-units) ; 
    canvas.relativePan(delta) ; 
}) ; 

$('#goDown').click(function(){ 
    var units = 10 ; 
    var delta = new fabric.Point(0,units) ; 
    canvas.relativePan(delta) ; 
}); 

http://jsfiddle.net/ux16013L/2/

+2

Können Sie Beispielcode bereitstellen und Ihr JSFiddle aktualisieren? Vielen Dank! –

+0

Bitte versuchen Sie genau das Gleiche zu tun! – Brent

+1

Bitte siehe udpate. Das habe ich. – d0001

13

Ich weiß, es ist bereits beantwortet, aber ich musste eine Maus schwenken, also habe ich die Geige der angenommenen Antwort angepasst, um dies zu tun. Ich poste es hier für jeden, der so etwas tun muss. Dies ist nur die Hauptidee:

var panning = false; 
canvas.on('mouse:up', function (e) { 
    panning = false; 
}); 

canvas.on('mouse:down', function (e) { 
    panning = true; 
}); 
canvas.on('mouse:move', function (e) { 
    if (panning && e && e.e) { 
     var units = 10; 
     var delta = new fabric.Point(e.e.movementX, e.e.movementY); 
     canvas.relativePan(delta); 
    } 
}); 

Hier ist die Geige: http://jsfiddle.net/gncabrera/hkee5L6d/5/

+0

Dies scheint nicht in IE zu arbeiten. Aus der Sicht von e.evementX und e.movementY existiert es in der IE-Version von fabric.js nicht. Schnell umgesehen und gefunden http: // stackoverflow.com/questions/40355425/fabricjs-ist-mir-nicht-geben-mir-Bewegung-und-Bewegung-zu-einem-Bild-in-ie-wie auch immer – Insight

0

Wenn Sie nur in der Anzeige die Leinwand wollen schwenken, und nicht die Position der Elemente zu ändern, können Sie verwenden this solution.

Die Idee ist es, eine feste Größe Container mit CSS von overflow: hidden, die eine Leinwand im Inneren hat. Die Palette verschiebt die Leinwand in den Container, sodass der Benutzer jedes Mal verschiedene Bereiche der aufgebrauchten Leinwand sehen kann.

6

Hier ist meine Lösung für Leinwand Zoom (mit Mausrad) und schwenken (mit links/oben/rechts/unten Tasten oder Umschalttaste + Maus nach links unten + Maus bewegen).

https://jsfiddle.net/milanhlinak/7s4w0uLy/8/

<!DOCTYPE html> 
<html> 

<head> 
    <script type="text/javascript" src="lib/jquery-3.1.1.min.js"></script> 
    <script type="text/javascript" src="lib/fabric.min.js"></script> 
</head> 

<body> 

    <canvas id="canvas" style="border: 1px solid #cccccc"></canvas> 

    <script> 
     var Direction = { 
      LEFT: 0, 
      UP: 1, 
      RIGHT: 2, 
      DOWN: 3 
     }; 

     var zoomLevel = 0; 
     var zoomLevelMin = 0; 
     var zoomLevelMax = 3; 

     var shiftKeyDown = false; 
     var mouseDownPoint = null; 

     var canvas = new fabric.Canvas('canvas', { 
      width: 500, 
      height: 500, 
      selectionKey: 'ctrlKey' 
     }); 

     canvas.add(new fabric.Rect({ 
      left: 100, 
      top: 100, 
      width: 50, 
      height: 50, 
      fill: '#faa' 

     })); 
     canvas.add(new fabric.Rect({ 
      left: 300, 
      top: 300, 
      width: 50, 
      height: 50, 
      fill: '#afa' 
     })); 

     canvas.on('mouse:down', function (options) { 
      var pointer = canvas.getPointer(options.e, true); 
      mouseDownPoint = new fabric.Point(pointer.x, pointer.y); 
     }); 
     canvas.on('mouse:up', function (options) { 
      mouseDownPoint = null; 
     }); 
     canvas.on('mouse:move', function (options) { 
      if (shiftKeyDown && mouseDownPoint) { 
       var pointer = canvas.getPointer(options.e, true); 
       var mouseMovePoint = new fabric.Point(pointer.x, pointer.y); 
       canvas.relativePan(mouseMovePoint.subtract(mouseDownPoint)); 
       mouseDownPoint = mouseMovePoint; 
       keepPositionInBounds(canvas); 
      } 
     }); 
     fabric.util.addListener(document.body, 'keydown', function (options) { 
      if (options.repeat) { 
       return; 
      } 
      var key = options.which || options.keyCode; // key detection 
      if (key == 16) { // handle Shift key 
       canvas.defaultCursor = 'move'; 
       canvas.selection = false; 
       shiftKeyDown = true; 
      } else if (key === 37) { // handle Left key 
       move(Direction.LEFT); 
      } else if (key === 38) { // handle Up key 
       move(Direction.UP); 
      } else if (key === 39) { // handle Right key 
       move(Direction.RIGHT); 
      } else if (key === 40) { // handle Down key 
       move(Direction.DOWN); 
      } 
     }); 
     fabric.util.addListener(document.body, 'keyup', function (options) { 
      var key = options.which || options.keyCode; // key detection 
      if (key == 16) { // handle Shift key 
       canvas.defaultCursor = 'default'; 
       canvas.selection = true; 
       shiftKeyDown = false; 
      } 
     }); 
     jQuery('.canvas-container').on('mousewheel', function (options) { 
      var delta = options.originalEvent.wheelDelta; 
      if (delta != 0) { 
       var pointer = canvas.getPointer(options.e, true); 
       var point = new fabric.Point(pointer.x, pointer.y); 
       if (delta > 0) { 
        zoomIn(point); 
       } else if (delta < 0) { 
        zoomOut(point); 
       } 
      } 
     }); 

     function move(direction) { 
      switch (direction) { 
      case Direction.LEFT: 
       canvas.relativePan(new fabric.Point(-10 * canvas.getZoom(), 0)); 
       break; 
      case Direction.UP: 
       canvas.relativePan(new fabric.Point(0, -10 * canvas.getZoom())); 
       break; 
      case Direction.RIGHT: 
       canvas.relativePan(new fabric.Point(10 * canvas.getZoom(), 0)); 
       break; 
      case Direction.DOWN: 
       canvas.relativePan(new fabric.Point(0, 10 * canvas.getZoom())); 
       break; 
      } 
      keepPositionInBounds(canvas); 
     } 


     function zoomIn(point) { 
      if (zoomLevel < zoomLevelMax) { 
       zoomLevel++; 
       canvas.zoomToPoint(point, Math.pow(2, zoomLevel)); 
       keepPositionInBounds(canvas); 
      } 
     } 

     function zoomOut(point) { 
      if (zoomLevel > zoomLevelMin) { 
       zoomLevel--; 
       canvas.zoomToPoint(point, Math.pow(2, zoomLevel)); 
       keepPositionInBounds(canvas); 
      } 
     } 

     function keepPositionInBounds() { 
      var zoom = canvas.getZoom(); 
      var xMin = (2 - zoom) * canvas.getWidth()/2; 
      var xMax = zoom * canvas.getWidth()/2; 
      var yMin = (2 - zoom) * canvas.getHeight()/2; 
      var yMax = zoom * canvas.getHeight()/2; 

      var point = new fabric.Point(canvas.getWidth()/2, canvas.getHeight()/2); 
      var center = fabric.util.transformPoint(point, canvas.viewportTransform); 

      var clampedCenterX = clamp(center.x, xMin, xMax); 
      var clampedCenterY = clamp(center.y, yMin, yMax); 

      var diffX = clampedCenterX - center.x; 
      var diffY = clampedCenterY - center.y; 

      if (diffX != 0 || diffY != 0) { 
       canvas.relativePan(new fabric.Point(diffX, diffY)); 
      } 
     } 

     function clamp(value, min, max) { 
      return Math.max(min, Math.min(value, max)); 
     } 
    </script> 

</body> 

</html> 
2

Ich habe ein Beispiel auf Github fabric.js Leinwand Schwenken und Zoomen mit: https://sabatinomasala.github.io/fabric-clipping-demo/

Der Code für das Panning Verhalten ist folgende: https://github.com/SabatinoMasala/fabric-clipping-demo/blob/master/src/classes/Panning.js

Es ist ein einfache Erweiterung auf der fabric.Canvas.prototype, mit der Sie "Drag-Modus" auf der Zeichenfläche wie folgt umschalten:

canvas.toggleDragMode(true); // Start panning 
canvas.toggleDragMode(false); // Stop panning 

Schauen Sie sich das folgende Codeschnipsel an. Die Dokumentation ist im gesamten Code verfügbar.

const STATE_IDLE = 'idle'; 
 
const STATE_PANNING = 'panning'; 
 
fabric.Canvas.prototype.toggleDragMode = function(dragMode) { 
 
    // Remember the previous X and Y coordinates for delta calculations 
 
    let lastClientX; 
 
    let lastClientY; 
 
    // Keep track of the state 
 
    let state = STATE_IDLE; 
 
    // We're entering dragmode 
 
    if (dragMode) { 
 
    // Discard any active object 
 
    this.discardActiveObject(); 
 
    // Set the cursor to 'move' 
 
    this.defaultCursor = 'move'; 
 
    // Loop over all objects and disable events/selectable. We remember its value in a temp variable stored on each object 
 
    this.forEachObject(function(object) { 
 
     object.prevEvented = object.evented; 
 
     object.prevSelectable = object.selectable; 
 
     object.evented = false; 
 
     object.selectable = false; 
 
    }); 
 
    // Remove selection ability on the canvas 
 
    this.selection = false; 
 
    // When MouseUp fires, we set the state to idle 
 
    this.on('mouse:up', function(e) { 
 
     state = STATE_IDLE; 
 
    }); 
 
    // When MouseDown fires, we set the state to panning 
 
    this.on('mouse:down', (e) => { 
 
     state = STATE_PANNING; 
 
     lastClientX = e.e.clientX; 
 
     lastClientY = e.e.clientY; 
 
    }); 
 
    // When the mouse moves, and we're panning (mouse down), we continue 
 
    this.on('mouse:move', (e) => { 
 
     if (state === STATE_PANNING && e && e.e) { 
 
     // let delta = new fabric.Point(e.e.movementX, e.e.movementY); // No Safari support for movementX and movementY 
 
     // For cross-browser compatibility, I had to manually keep track of the delta 
 

 
     // Calculate deltas 
 
     let deltaX = 0; 
 
     let deltaY = 0; 
 
     if (lastClientX) { 
 
      deltaX = e.e.clientX - lastClientX; 
 
     } 
 
     if (lastClientY) { 
 
      deltaY = e.e.clientY - lastClientY; 
 
     } 
 
     // Update the last X and Y values 
 
     lastClientX = e.e.clientX; 
 
     lastClientY = e.e.clientY; 
 

 
     let delta = new fabric.Point(deltaX, deltaY); 
 
     this.relativePan(delta); 
 
     this.trigger('moved'); 
 
     } 
 
    }); 
 
    } else { 
 
    // When we exit dragmode, we restore the previous values on all objects 
 
    this.forEachObject(function(object) { 
 
     object.evented = (object.prevEvented !== undefined) ? object.prevEvented : object.evented; 
 
     object.selectable = (object.prevSelectable !== undefined) ? object.prevSelectable : object.selectable; 
 
    }); 
 
    // Reset the cursor 
 
    this.defaultCursor = 'default'; 
 
    // Remove the event listeners 
 
    this.off('mouse:up'); 
 
    this.off('mouse:down'); 
 
    this.off('mouse:move'); 
 
    // Restore selection ability on the canvas 
 
    this.selection = true; 
 
    } 
 
}; 
 

 
// Create the canvas 
 

 
let canvas = new fabric.Canvas('fabric') 
 
canvas.backgroundColor = '#f1f1f1'; 
 

 
// Add a couple of rects 
 

 
let rect = new fabric.Rect({ 
 
    width: 100, 
 
    height: 100, 
 
    fill: '#f00' 
 
}); 
 
canvas.add(rect) 
 

 
rect = new fabric.Rect({ 
 
    width: 200, 
 
    height: 200, 
 
    top: 200, 
 
    left: 200, 
 
    fill: '#f00' 
 
}); 
 
canvas.add(rect) 
 

 
// Handle dragmode change 
 

 
let dragMode = false; 
 
$('#dragmode').change(_ => { 
 
    dragMode = !dragMode; 
 
    canvas.toggleDragMode(dragMode); 
 
});
<div> 
 
    <label for="dragmode"> 
 
    Enable panning 
 
    <input type="checkbox" id="dragmode" name="dragmode" /> 
 
    </label> 
 
</div> 
 
<canvas width="300" height="300" id="fabric"></canvas> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.15/fabric.min.js"></script>