如何使用fabricjs进行平移和缩放?我尝试过使用zoomToPoint和setZoom方法,但它们不能用于平移。一旦我开始使用不同的缩放点,我就开始遇到麻烦了。
$('#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
}) ;
答案 0 :(得分:17)
使用:
解决它relativePan() absolutePan()
[更新]
$('#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) ;
});
答案 1 :(得分:14)
我知道它已经回答了,但我不得不做一个鼠标平移,所以我调整了接受答案的小提琴。我在这里发布给任何必须做这样的事情的人。这只是主要想法:
On Holy Wars and a Plea for Peace
Cohen, D.
Computer
答案 2 :(得分:7)
这是我的画布缩放(使用鼠标滚轮)和平移(使用左/上/右/下键或Shift键+鼠标左下+鼠标移动)的解决方案。
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>
答案 3 :(得分:2)
我在Github上有一个使用fabric.js Canvas平移和缩放的示例:https://sabatinomasala.github.io/fabric-clipping-demo/
负责平移行为的代码如下:https://github.com/SabatinoMasala/fabric-clipping-demo/blob/master/src/classes/Panning.js
它是MyTuple
上的一个简单扩展程序,可让您切换“拖动模式”&#39;在画布上如下:
fabric.Canvas.prototype
请查看以下代码段,整个代码中都提供了文档。
canvas.toggleDragMode(true); // Start panning
canvas.toggleDragMode(false); // Stop panning
&#13;
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);
});
&#13;
答案 4 :(得分:0)
如果您只想在显示中平移画布,而不是更改元素的位置, 你可以使用this solution。
我们的想法是拥有一个固定大小的容器,其中css为var cargo = async.queue(function (task, callback) {
setTimeout(
connectStream(task)
, 50000);
callback();
}, 1);
for(var j = 0; j < TeamList.length; j++) {
cargo.push(TeamList[j], function (err) {
});
,其中包含一个展开的画布。平移将在容器内移动画布,以便用户每次都能看到展开画布的不同区域。