【问题标题】:Move object within canvas boundary limit在画布边界限制内移动对象
【发布时间】:2014-05-19 13:58:57
【问题描述】:

我试图限制画布内的移动对象,但是在顶部和左侧的限制区域中移动对象时遇到了一些困难,当我将对象缩放得更大时,我也无法限制移动画布左侧和顶部的对象

canvas.observe("object:moving", function(e) {
  var obj = e.target;
  // if object is too big ignore
  if(obj.currentHeight > obj.canvas.height || obj.currentWidth > obj.canvas.width) {
    return;
  }

  var halfw = obj.currentWidth/2;
  var halfh = obj.currentHeight/2;
  var bounds = {
    tl: {x: halfw, y:halfh},
    br: {x: obj.canvas.width-halfw, y: obj.canvas.height-halfh}
  };

  // top-left  corner
  if(obj.top < bounds.tl.y || obj.left < bounds.tl.x) {
    obj.top = Math.max(obj.top, bounds.tl.y);
    obj.left = Math.max(obj.left, bounds.tl.x )
  }
        
  // bot-right corner
  if(obj.top > bounds.br.y || obj.left > bounds.br.x) {
    obj.top = Math.min(obj.top, bounds.br.y);
    obj.left = Math.min(obj.left, bounds.br.x)
  }
});

【问题讨论】:

    标签: javascript canvas fabricjs


    【解决方案1】:
    canvas.on('object:moving', function (e) {
      var obj = e.target;
      // if object is too big ignore
      if(obj.currentHeight > obj.canvas.height || obj.currentWidth > obj.canvas.width){
        return;
      }
      obj.setCoords();
      // top-left  corner
      if(obj.getBoundingRect().top < 0 || obj.getBoundingRect().left < 0){
        obj.top = Math.max(obj.top, obj.top-obj.getBoundingRect().top);
        obj.left = Math.max(obj.left, obj.left-obj.getBoundingRect().left);
      }
      // bot-right corner
      if(obj.getBoundingRect().top+obj.getBoundingRect().height  > obj.canvas.height || obj.getBoundingRect().left+obj.getBoundingRect().width  > obj.canvas.width){
        obj.top = Math.min(obj.top, obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top);
        obj.left = Math.min(obj.left, obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left);
      }
    });
    

    【讨论】:

    • 我见过的最佳解决方案。
    • 如果您需要允许将对象部分移动到画布边界之外,请参阅下面的增强功能
    • 不错!是否可以覆盖织物功能,这样会影响所有织物画布?
    【解决方案2】:

    在这里你可以找到解决方案:-

    var canvas = window._canvas = new fabric.Canvas('c');
    canvas.selection = false;
    
    fabric.Object.prototype.set({
        transparentCorners: false,
        cornerColor: 'red',
        cornerSize: 12,
        padding: 0
    });
    text = new fabric.Text('Sample',{
        top: canvas.height/2,
        left: canvas.width/2,
        fill: '#000000'
    });
    
    canvas.add(text);
    canvas.setActiveObject(text);
    
    canvas.observe('object:scaling', function (e) {
        var obj = e.target;
      if(obj.getHeight() > obj.canvas.height || obj.getWidth() > obj.canvas.width){
        obj.setScaleY(obj.originalState.scaleY);
        obj.setScaleX(obj.originalState.scaleX);        
      }
      obj.setCoords();
      if(obj.getBoundingRect().top - (obj.cornerSize / 2) < 0 || 
         obj.getBoundingRect().left -  (obj.cornerSize / 2) < 0) {
        obj.top = Math.max(obj.top, obj.top-obj.getBoundingRect().top + (obj.cornerSize / 2));
        obj.left = Math.max(obj.left, obj.left-obj.getBoundingRect().left + (obj.cornerSize / 2));    
      }
      if(obj.getBoundingRect().top+obj.getBoundingRect().height + obj.cornerSize  > obj.canvas.height || obj.getBoundingRect().left+obj.getBoundingRect().width + obj.cornerSize  > obj.canvas.width) {
    
        obj.top = Math.min(obj.top, obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top - obj.cornerSize / 2);
        obj.left = Math.min(obj.left, obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left - obj.cornerSize /2);    
      }
    });
    
    canvas.observe('object:moving', function (e) {
        var obj = e.target;
      if(obj.getHeight() > obj.canvas.height || obj.getWidth() > obj.canvas.width){
        obj.setScaleY(obj.originalState.scaleY);
        obj.setScaleX(obj.originalState.scaleX);        
      }
      obj.setCoords();
      if(obj.getBoundingRect().top - (obj.cornerSize / 2) < 0 || 
         obj.getBoundingRect().left -  (obj.cornerSize / 2) < 0) {
        obj.top = Math.max(obj.top, obj.top-obj.getBoundingRect().top + (obj.cornerSize / 2));
        obj.left = Math.max(obj.left, obj.left-obj.getBoundingRect().left + (obj.cornerSize / 2));    
      }
      if(obj.getBoundingRect().top+obj.getBoundingRect().height + obj.cornerSize  > obj.canvas.height || obj.getBoundingRect().left+obj.getBoundingRect().width + obj.cornerSize  > obj.canvas.width) {
    
        obj.top = Math.min(obj.top, obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top - obj.cornerSize / 2);
        obj.left = Math.min(obj.left, obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left - obj.cornerSize /2);    
      }
    });
    

    http://jsfiddle.net/jw1827fm/1/

    【讨论】:

    • 对于 1.7.11 版本的我来说,比例尺不适用。首先,您需要使用{stateful : true,} 构建织物画布。其次,我不得不使用_stateProperties 而不是originalState。第三,这些更改后您需要obj.saveState();
    【解决方案3】:

    只需在你的 js 文件中添加以下代码,并根据你的画布高度和宽度更改缩放 X(left) 和 Y(top) 的值。

    // canvas moving limit 
    
    canvas.observe("object:moving", function(e){
          var obj = e.target;
             // if object is too big ignore
    
            var halfw = obj.currentWidth/2;
            var halfh = obj.currentHeight/2;
            var bounds = {tl: {x: halfw, y:halfh},
                br: {x: obj.canvas.width , y: obj.canvas.height }
            };
    
            // top-left  corner
    
    
    
                // alert("text");
            if(obj.top < bounds.tl.y || obj.left < bounds.tl.x){
                obj.top = Math.max(obj.top, '10'  );
                obj.left = Math.max(obj.left , '50' ) 
            }
    
    
            // bot-right corner
            if(obj.top > bounds.br.y || obj.left > bounds.br.x ){
                obj.top = Math.min(obj.top, '360'  );  
                obj.left = Math.min(obj.left, '470' )  
            }
    
    });
    // end canvas moving limit
    

    【讨论】:

    • 是否有强制对象离开画布的方法?
    • 在堆栈上提问
    • 这只是是或否的问题,如果是,那么如何?不需要额外的问题。 Stack 有非常自私的社区版主,如果我只是问问题,他们会以否定的方式结束问题。
    【解决方案4】:

    我只是修改了 Balaji 的代码,现在效果更好了

    canvas.on('object:moving', function (e) {
        var obj = e.target;
    
         // if object is too big ignore
        if(obj.getScaledHeight() > obj.canvas.height || obj.getScaledWidth() > obj.canvas.width){
            return;
        }        
        obj.setCoords();        
        // top-left  corner
        if(obj.getBoundingRect().top < 0 || obj.getBoundingRect().left < 0){
            obj.top = Math.max(obj.top, obj.top-obj.getBoundingRect().top);
            obj.left = Math.max(obj.left, obj.left-obj.getBoundingRect().left);
        }
        // bot-right corner
        if(obj.getBoundingRect().top+obj.getBoundingRect().height  > obj.canvas.height || obj.getBoundingRect().left+obj.getBoundingRect().width  > obj.canvas.width){
            obj.top = Math.min(obj.top, obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top);
            obj.left = Math.min(obj.left, obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left);
        }});
    

    【讨论】:

      【解决方案5】:

      由于我需要这个,这里是我基于 Balaji 的代码设置偏移量的过度工作函数,因此对象只能部分显示在画布中。

      canvas.on('object:moving', function (e) {
            var obj = e.target;
      
            // if object is too big ignore
            if(obj.currentHeight > obj.canvas.height || obj.currentWidth > obj.canvas.width){
                return;
            }        
      
            // set offset for moving out the canvas (20 % of object persists in canvas)
            var offsetWidth = obj.getBoundingRect().width * 0.8;
            var offsetHeight = obj.getBoundingRect().height * 0.8;
      
            obj.setCoords();        
      
            // top-left  corner
            if(obj.getBoundingRect().top < -offsetHeight || obj.getBoundingRect().left < -offsetWidth){
                obj.top = Math.max(obj.top, obj.top-(obj.getBoundingRect().top+offsetHeight));
                obj.left = Math.max(obj.left, obj.left-(obj.getBoundingRect().left+offsetWidth));
            }
            // bot-right corner
            if(obj.getBoundingRect().top+obj.getBoundingRect().height  > obj.canvas.height + offsetHeight || obj.getBoundingRect().left+obj.getBoundingRect().width  > obj.canvas.width + offsetWidth){
                obj.top = Math.min(obj.top, obj.canvas.height-obj.getBoundingRect().height+obj.top-obj.getBoundingRect().top+offsetHeight);
                obj.left = Math.min(obj.left, obj.canvas.width-obj.getBoundingRect().width+obj.left-obj.getBoundingRect().left+offsetWidth);
            }
      });      
      

      【讨论】:

        【解决方案6】:

        只是稍微修改了 Balaji 和 Surya T 的代码,所以它现在可以完全处理画布缩放设置。

           _self.layer.on('object:moving', function (e) {
                var obj = e.target;
        
                obj.setCoords();
                var curZoom = obj.canvas.getZoom();
        
                //
                // if object is too big ignore
                if(obj.getScaledHeight() > obj.canvas.height || obj.getScaledWidth() > obj.canvas.width){
                    return;
                }
        
                // top-left  corner
                if(obj.getBoundingRect().top < 0 || obj.getBoundingRect().left < 0){
                    obj.top = Math.max(obj.top*curZoom, obj.top*curZoom-obj.getBoundingRect().top)/curZoom;
                    obj.left = Math.max(obj.left*curZoom, obj.left*curZoom-obj.getBoundingRect().left)/curZoom;
                }
                // bot-right corner
                if(obj.getBoundingRect().top+obj.getBoundingRect().height  > obj.canvas.height || obj.getBoundingRect().left+obj.getBoundingRect().width  > obj.canvas.width){
                    obj.top = Math.min(obj.top*curZoom, obj.canvas.height-obj.getBoundingRect().height+obj.top*curZoom-obj.getBoundingRect().top)/curZoom;
                    obj.left = Math.min(obj.left*curZoom, obj.canvas.width-obj.getBoundingRect().width+obj.left*curZoom-obj.getBoundingRect().left)/curZoom;
                }
            });
        

        【讨论】:

          猜你喜欢
          • 2018-06-24
          • 1970-01-01
          • 2017-11-25
          • 2015-12-19
          • 2017-05-18
          • 2012-03-20
          • 1970-01-01
          • 2014-11-12
          • 1970-01-01
          相关资源
          最近更新 更多