我有一个Fabric.js画布,我想实现软件包通常使用“手工”工具进行的全画布平移。这是当你按下一个鼠标按钮,然后移动到画布上,同时按住鼠标按钮,画布的可见部分也相应地发生了变化。
你可以看到在这个视频里我想要达到的目标。
为了实现这个功能,我编写了以下代码:
$(canvas.wrapperEl).on('mousemove', function(evt) {
if (evt.button == 2) { // 2 is the right mouse button
canvas.absolutePan({
x: evt.clientX,
y: evt.clientY
});
}
});
但不起作用。您可以看到在这个视频里发生了什么。
如何按照以下顺序修改代码:
发布于 2015-12-25 08:16:23
一种简单的方法是计算鼠标事件之间的光标位移,并将其传递给relativePan
。
观察如何使用上一个鼠标事件的screenX
和screenY
属性来计算当前鼠标事件的相对位置:
function startPan(event) {
if (event.button != 2) {
return;
}
var x0 = event.screenX,
y0 = event.screenY;
function continuePan(event) {
var x = event.screenX,
y = event.screenY;
fc.relativePan({ x: x - x0, y: y - y0 });
x0 = x;
y0 = y;
}
function stopPan(event) {
$(window).off('mousemove', continuePan);
$(window).off('mouseup', stopPan);
};
$(window).mousemove(continuePan);
$(window).mouseup(stopPan);
$(window).contextmenu(cancelMenu);
};
function cancelMenu() {
$(window).off('contextmenu', cancelMenu);
return false;
}
$(canvasWrapper).mousedown(startPan);
我们在mousedown
上开始摇摄,在mousemove
上继续摇摄。在mouseup
上,我们取消了摇摄;我们还取消了mouseup
-cancelling函数本身。
右键单击菜单(也称为上下文菜单)将通过返回false
取消.菜单取消功能也取消了自己。因此,如果您随后单击画布包装之外的内容,则上下文菜单将工作。
这里有一页演示了这种方法:
http://michaellaszlo.com/so/fabric-pan/
您将在织物画布上看到三个图像(加载图像可能需要一两分钟)。您将能够使用标准的织物功能。你可以左键点击图片来移动它们,拉伸它们,旋转它们。但是当您在画布容器内右键单击时,您可以用鼠标将整个织物帆布平移。
发布于 2017-10-21 09:52:01
我有一个使用fabric.js画布平移的Github示例:https://sabatinomasala.github.io/fabric-clipping-demo/
负责摇摄行为的代码如下:https://github.com/SabatinoMasala/fabric-clipping-demo/blob/master/src/classes/Panning.js
它是fabric.Canvas.prototype
上的一个简单扩展,它允许您在画布上切换“拖动模式”,如下所示:
canvas.toggleDragMode(true); // Start panning
canvas.toggleDragMode(false); // Stop panning
看看下面的片段,文档在整个代码中都是可用的。
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>
发布于 2015-12-26 12:55:40
我在jsfiddle上做了一个例子,我们实际上可以将整个画布和它的所有对象拖到父div中,就像图片一样,我将尝试一步一步地解释它。
canvas.defaultCursor = 'url(" http://maps.gstatic.com/intl/en_us/mapfiles/openhand_8_8.cur") 15 15, crosshair';
c.重写__onMouseDown函数,以更改关闭的游标(末尾)。
fabric.Canvas.prototype.__onMouseDown =函数(E){ //只接受左击变量isLeftClick =‘哪’?e.which === 1: e.button === 1;if (!isLeftClick && !fabric.isTouchSupported) {返回;} if (this.isDrawingMode) { this._onMouseDownInDrawingMode(e);} //忽略,如果此时正在转换某个对象,如果(this._currentTransform) {返回;} var ==== this.findTarget(e),指针= this.getPointer(e,true);//保存指针以检查__onMouseUp事件this._previousPointer =指针;var shouldRender =this._shouldRender(目标、指针),shouldGroup = this._shouldGroup(e,目标);if (this._shouldClearSelection(e,目标)){ this._clearSelection(e,目标,指针);} if (shouldGroup) { this._handleGrouping(e,目标);shouldGroup= this.getActiveGroup();} if (target & target.selectable &shouldGroup){ this._beforeTransform(e,target);this._setupCurrentTransform(e,target);} //我们必须将活动图像放置在顶层画布shouldRender & this.renderAll();this.fire(‘鼠标:向下’,{塔吉特:目标,e: e });塔吉特&target.fire(鼠标向下,{ e: e });如果(!canvas.getActiveObject()\x{canvas.getActiveGroup()){ flag=true;//将光标更改为closedhand.cur canvas.defaultCursor = 'url("8.cur“) 15,十字头发‘;}//如果弹琴示例:https://jsfiddle.net/tornado1979/up48rxLs/
你可能比我更幸运,在你的浏览器,但它肯定会在你的现场应用程序工作。
不管怎样,我希望能帮上忙,祝你好运。
https://stackoverflow.com/questions/34423822
复制相似问题