2017-03-03 1 views
1

Ich benutze Fabric.js mit React/Redux und ich versuche, den folgenden Effekt auf der Leinwand zu erzielen: (Hinweis ich habe 2 Lineale an Oben und links, die sich beim Schwenken nicht bewegen sollten, nur horizontal und vertikal).Fabric.js Positionselemente relativ zu getZoom() und getWidth()/getHeight()

Dies ist ein Video von der Effekt, den ich zu bekommen versuche: https://vid.me/qs5Q

ich den folgenden Code haben:

var canvas = new fabric.Canvas('c'); 
var topRuler = new fabric.Text('this is the top ruler', { 
    top: 0, 
    left: 60, 
    selectable: false 
}); 
var leftRuler = new fabric.Text('this is the left ruler', { 
    top: 150, 
    left: -125, 
    selectable: false 
}); 
var circle = new fabric.Circle({ 
    radius: 20, 
    fill: 'green', 
    left: 180, 
    top: 100 
}); 
var triangle = new fabric.Triangle({ 
    fill: 'green', 
    left: 150, 
    top: 170 
}); 
var panning = false; 
var panningOn = false; 
leftRuler.setAngle(-90).setCoords(); 
canvas.add(circle, triangle, topRuler, leftRuler); 
canvas.renderAll(); 

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

canvas.on('mouse:down', function(e) { 
if (panningOn) panning = true; 
}); 

canvas.on('mouse:move', function(e) { 
    if (panning && e && e.e) { 
    moveX = e.e.movementX; 
    moveY = e.e.movementY; 
    topRuler.set({ 
    top: topRuler.top - moveY, 
    left: topRuler.left - moveX 
    }); 

    leftRuler.set({ 
    top: leftRuler.top - moveY, 
    left: leftRuler.left - moveX 
    }); 
    canvas.relativePan(new fabric.Point(moveX, moveY)); 
    } 
}); 
$('#toggle').click(function() { 
    panningOn = !panningOn; 
    canvas.selection = !panningOn; 
    canvas.defaultCursor = 'default'; 
    $('#toggle').html('Turn Panning ON'); 
    if (panningOn) { 
    $('#toggle').html('Turn Panning OFF'); 
    canvas.defaultCursor = 'move'; 
    } 
}); 

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

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

Dies ist ein Arbeits JSFiddle: https://jsfiddle.net/z3p8utmc/19/ Der Code, da ich nicht abgeschlossen ist weiß nicht genau, wie man die Lineale positioniert, versucht, mit ViewPort, Canvas-Größe, etc. zu spielen, aber es ist nicht gelungen, den gleichen Effekt zu erzielen.

Vielen Dank für die Hilfe.

Antwort

1

Hier ist ein Screenshot der Ergebnisse:

FabricJS - Rulers: Zooming & Panning, based on Video

hier die beiden Funktionen Zoom:

/* ZOOM FUNCTIONS */ 
$('#zoomIn').click(function() { 
    rectangle.set({ 
    width: rectangle.width * 1.1, 
    height: rectangle.height * 1.1 
    }); 
    rectangle.setCoords(); 
    textSample.set({ 
    top: 60 + (textSample.top - 60) * 1.1, 
    left: 60 + (textSample.left - 60) * 1.1, 
    scaleX: textSample.scaleX * 1.1, 
    scaleY: textSample.scaleY * 1.1 
    }); 
    textSample.setCoords(); 
    setPins(); 
    addLeftRuler(); 
    addTopRuler(); 
    resizeCanvas(); 
}); 
$('#zoomOut').click(function() { 
    rectangle.set({ 
    width: rectangle.width/1.1, 
    height: rectangle.height/1.1 
    }); 
    rectangle.setCoords(); 
    textSample.set({ 
    top: 60 + (textSample.top - 60)/1.1, 
    left: 60 + (textSample.left - 60)/1.1, 
    scaleX: textSample.scaleX/1.1, 
    scaleY: textSample.scaleY/1.1 
    }) 
    textSample.setCoords(); 
    setPins(); 
    addLeftRuler(); 
    addTopRuler(); 
    resizeCanvas(); 
}); 

Panning wird mit einer Steuer 3rd-Party gemacht, und die traditionelle Art und Weise, da Das ist das, was das Video zeigt (und Sie wollten) - obere und linke Lineale werden an ihrem Platz gehalten, indem sie ihre Positionen aktualisieren, während das Scrollen stattfindet.

Zoomen erfolgt durch Skalieren der einzelnen Objekte basierend auf Punkt (60, 60) - wie im Video. Die Pins werden zurückgesetzt, die Lineale werden neu skaliert und die Größe der Leinwand wird nach Bedarf angepasst.

Der Trick besteht darin, alles zu berechnen und neu zu berechnen, da Benutzeraktionen ausgeführt und Ereignisse ausgelöst werden.

Hoffentlich bringt dies Ihnen die Leinwandgrundlage, auf der Sie aufbauen müssen.

Hier ist eine funktionierende JSFiddle, https://jsfiddle.net/rekrah/hs6jL8d4/.

+0

Sehr geehrte (r) @Tim würden Sie bitte einen Blick auf diese bitte: http://stackoverflow.com/questions/42781527/fabric-js-draw-regular-octagon? –

+0

Wird tun, matey ... –