Javascript 如何使用Fabric.js实现画布平移

Javascript 如何使用Fabric.js实现画布平移,javascript,canvas,fabricjs,panning,Javascript,Canvas,Fabricjs,Panning,我有一个Fabric.js画布,我想实现软件包通常使用“手动”工具进行的完整画布平移。这是当你按下一个鼠标按钮,然后在画布上移动,同时按住鼠标按钮,画布的可见部分相应地改变 你可以看到我想要达到的目标 为了实现此功能,我编写了以下代码: $(canvas.wrapperEl).on('mousemove', function(evt) { if (evt.button == 2) { // 2 is the right mouse button canvas.absolu

我有一个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
        });
    }
});
但它不起作用。你可以看到发生了什么

如何按顺序修改代码:

  • 让平移像第一个视频中那样工作

  • 是否允许事件处理程序使用该事件?当用户按下或释放鼠标右键时,它应该防止上下文菜单出现


  • 不确定FabricJS,但可能是这样的:

  • 要使其像第一个视频中那样工作:

    通过使用CSS
    cursor
    属性,使用javascript在
    mousedown
    mouseup
    事件上切换它

  • 事件处理程序使用事件(当用户释放鼠标右键时,阻止上下文菜单出现):

    使用javascript,我们在
    contextmenu
    事件上返回
    false

  • 代码:有点小问题(*)

    使用jQuery

    使用原始javascript

    var test=document.getElementById('test');
    test.addEventListener('mousedown',函数(e){
    如果(e.按钮==2){
    //如果单击鼠标右键,请将光标形状设置为“抓取”
    this.style.cursor='grabbing';
    }
    });
    test.addEventListener('mouseup',function(){
    //将光标形状设置为默认值
    this.style.cursor='default';
    });
    test.oncontextmenu=函数(){
    //右键单击时禁用关联菜单
    返回false;
    
    }
    根据鼠标移动平移织物画布的一种简单方法是计算鼠标事件之间的光标位移,并将其传递给
    relativePan

    观察如何使用上一个鼠标事件的
    screenX
    screenY
    属性来计算当前鼠标事件的相对位置:

    功能启动面板(事件){
    如果(event.button!=2){
    返回;
    }
    var x0=event.screenX,
    y0=事件。屏幕显示;
    函数continuePan(事件){
    var x=event.screenX,
    y=event.screenY;
    fc.relativePan({x:x-x0,y:y-y0});
    x0=x;
    y0=y;
    }
    功能停止(事件){
    $(窗口).off('mousemove',continuePan);
    $(窗口).off('mouseup',stopPan);
    };
    $(窗口).mousemove(continuePan);
    $(窗口).mouseup(stopPan);
    $(窗口).contextmenu(取消菜单);
    };
    函数取消菜单(){
    $(窗口).off('contextmenu',cancelMenu);
    返回false;
    }
    $(画布包装器).mousedown(startPan);
    
    我们在
    mousedown
    上开始平移,然后在
    mousemove
    上继续平移。在
    mouseup
    上,我们取消平移;我们还取消了
    mouseup
    -取消函数本身

    右键单击菜单(也称为上下文菜单)通过返回
    false
    来取消。菜单取消功能也会自动取消。因此,如果随后在画布包装器外部单击,则上下文菜单将起作用

    以下是一页演示此方法:


    您将在织物画布上看到三个图像(加载图像可能需要一两分钟)。您将能够使用标准结构功能。您可以在图像上单击鼠标左键来移动、拉伸和旋转图像。但是,当您在画布容器中单击鼠标右键时,您可以用鼠标平移整个织物画布。

    我在JSFIDLE上做了一个示例,我们实际上可以将整个画布及其所有对象拖动到父div中,如图所示,我将尝试一步一步地解释它

  • 首先,我下载了阻力库jquery.dradscroll.js,你可以在网上找到它。这是一个很小的js文件,只需稍作修改即可帮助我们完成任务。 下载链接:

  • 创建容纳画布的容器

      <div class="content">
        <canvas id="c" width="600" height="700" ></canvas>    
      </div>
    
  • javascript:

    a。创建画布

    b。设置默认光标,当光标位于画布上时,打开手

    canvas.defaultCursor='url(“http://maps.gstatic.com/intl/en_us/mapfiles/openhand_8_8.cur)15,十字准线“

    c。覆盖_onMouseDown函数,以更改关闭和光标(在末尾)

  • 重写_onMouseUp事件,将光标更改回openhand

       fabric.Canvas.prototype.__onMouseUp = function(e){
           if(flag){
              canvas.defaultCursor = 'url(" http://maps.gstatic.com/intl/en_us/mapfiles/openhand_8_8.cur") 15 15, crosshair';
              flag=false;
           }
        };
    
  • 初始化dragScroll()以处理承载画布的内容:

        $('.content').dragScroll({});
    
  • 对jquery.dragScroll.js文件进行一些小更改,以便了解何时拖动画布以及何时不拖动画布。在mousedown()事件中,我们添加一个if语句来检查是否有活动对象或组。如果为true,则不进行画布拖动

       $($scrollArea).mousedown(function (e) {
        if (canvas.getActiveObject() || canvas.getActiveGroup()) {
            console.log('no drag');return;
        } else {                                             
           console.log($('body'));
            if (typeof options.limitTo == "object") {
                for (var i = 0; i < options.limitTo.length; i++) {
                    if ($(e.target).hasClass(options.limitTo[i])) {
                        doMousedown(e);
                    }
                }
            } else {
                doMousedown(e);
            }
        }
    });
    
  • 如果我们不想让滚动条可见:

        .content{
       overflow:hidden;
       width:400px;
       height:400px;
    
    }

  • 不过有一个小问题,JSFIDLE只接受https库,因此它会阻止fabricjs,除非您从“”添加它,但它仍然会在某些时候阻止它(至少在我的chrome和mozilla上)

  • JSFIDLE示例:

    在你的浏览器上,你可能比我幸运,但在你的live应用程序上,它肯定会起作用

    反正,
    希望对您有所帮助,祝您好运。

    我在Github上有一个使用fabric.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=函数(dragMode){
    //还记得上次吗
    
       $($scrollArea).mousedown(function (e) {
        if (canvas.getActiveObject() || canvas.getActiveGroup()) {
            console.log('no drag');return;
        } else {                                             
           console.log($('body'));
            if (typeof options.limitTo == "object") {
                for (var i = 0; i < options.limitTo.length; i++) {
                    if ($(e.target).hasClass(options.limitTo[i])) {
                        doMousedown(e);
                    }
                }
            } else {
                doMousedown(e);
            }
        }
    });
    
      function doMousedown(e) {
    
            e.preventDefault();
            down = true;
            x = e.pageX;
            y = e.pageY;        
            top = e.target.parentElement.parentElement.scrollTop; // .content
            left = e.target.parentElement.parentElement.scrollLeft;// .content
        }
    
        .content{
       overflow:hidden;
       width:400px;
       height:400px;
    
    canvas.toggleDragMode(true); // Start panning
    canvas.toggleDragMode(false); // Stop panning