【问题标题】:Canvas: Rectangles -- Snap to grid / Snap to objects画布:矩形——对齐网格/对齐对象
【发布时间】:2014-02-18 13:25:38
【问题描述】:

我设法通过以下方式操纵 Fabric.js 以添加快照和缩放到网格功能:

var grid = 100;
//Snap to Grid
canvas.on('object:moving', function (options) {
    options.target.set({
        left: Math.round(options.target.left / grid) * grid,
        top: Math.round(options.target.top / grid) * grid
    });
});
canvas.on('object:scaling', function (options) {
    options.target.set({
        left: Math.round(options.target.left / grid) * grid,
        top: Math.round(options.target.top / grid) * grid
    });
});

现在我想为对象添加快照功能。我的想法是检查两个对象的交集,然后以某种方式锁定运动。我知道这不是最好的尝试,但至少它会捕捉到它,但不再允许将对象移开。并且:现在它没有很好地实施。见:http://jsfiddle.net/gcollect/y9kyq/

我有三个问题:

  1. “snap”不能很好地工作,因为对象 left 属性以某种方式依赖于指针。通过拖动对象并观察我的控件输出进行复制。例如,当将红色矩形移动到位置 left:62 时,矩形不会与蓝色矩形相交,仍然可以移开。如何重新加载矩形的实际左值。由于我对齐网格线,它位于左侧:100 而不是左侧:62。
  2. 知道如何向对象功能添加快照吗?并禁止路口?
  3. 如何检查 n 个对象而不是两个对象?

感谢您的 cmets。

PS: jsfiddle 示例没有显示缩放到网格功能,因为它需要 Fabric.js 在线操作:11100

var distroundedforgrid = Math.round(dist/100)*100;      
      transform.newScaleX = Math.round((transform.original.scaleX * distroundedforgrid / lastDist)*10)/10;
      transform.newScaleY = Math.round((transform.original.scaleY * distroundedforgrid / lastDist)*10)/10;

      target.set('scaleX', transform.newScaleX);
      target.set('scaleY', transform.newScaleY);
    }

【问题讨论】:

  • 很遗憾,到目前为止,我在捕捉对象功能方面没有任何进展。

标签: javascript canvas fabricjs


【解决方案1】:

我想办法解决 x 轴上对象的对齐问题,并将研究 y 轴的解决方案。 See JSfiddle here.

当我检测到一个交叉点时,我通过为活动对象设置一个新的“左”值来做到这一点。

        if (options.target.isContainedWithinObject(obj)||options.target.intersectsWithObject(obj)||obj.isContainedWithinObject(options.target)) {

            var distx = ((obj.left + obj.width)/2) - ((options.target.left + options.target.width)/2);
            var disty = ((obj.top + obj.height)/2) - ((options.target.top + options.target.height)/2);                  

            if (distx > 0){
                options.target.left = obj.left - options.target.width;
            } else {
                options.target.left = obj.left + obj.width;
            }

        }

【讨论】:

  • 现在我在修改对象的高度或宽度后遇到了一些问题,然后尝试捕捉它们。由于旧值,对象仍会在对象内相交和对齐。我需要渲染新的对象吗?
  • 小提琴是否有可能再次被看到?
  • 嗨史蒂夫格林,这里是同一个例子。我仍然没有设法解决问题。如果你能提供帮助会很酷。问题从第 59 行开始。在 distx 行中添加注释以查看错误行为。 jsfiddle.net/gcollect/XCX9A
【解决方案2】:

对于那些仍然对解决方案感兴趣的人: 我在这里解决了:https://stackoverflow.com/a/22649022/3207478 见 jsfiddle:http://jsfiddle.net/gcollect/FD53A/

使用.oCoords.tl .tr .bl. and .br solved it.

【讨论】:

    【解决方案3】:

    有关基于网格的重新缩放,请参阅thisJSfiddle

    function snapScaling(options) {
        var target = options.target;
        var type = canvas.getActiveObject().get('type');
        var corner = target.__corner;
        var w = target.getWidth();
        var h = target.getHeight();
        var snap = {   // Closest snapping points
          top: Math.round(target.top / grid) * grid,
          left: Math.round(target.left / grid) * grid,
          bottom: Math.round((target.top + h) / grid) * grid,
          right: Math.round((target.left + w) / grid) * grid,
        };
        snap.height = snap.top - snap.bottom;
        if(snap.height < 0) {
          snap.height *= - 1;
        }
        snap.width = snap.left - snap.right;
        if(snap.width < 0) {
          snap.width *= - 1;
        }
        switch (corner) {
          case 'mt':
          case 'mb':
              target.top = snap.top;
              target.height = snap.height;
              target.scaleY = 1;
            break;
          case 'ml':
          case 'mr':
            target.left = snap.left;
            target.width = snap.width;
            target.scaleX = 1;
            break;
          case 'tl':
          case 'bl':
          case 'tr':
          case 'br':
            target.top = snap.top;
            target.left = snap.left;
    
            target.height = snap.height;
            target.width = snap.width;
    
            target.scaleY = 1;
            target.scaleX = 1;
        }
    
        if(type == 'ellipse') {
          target.rx = (target.width / 2);
          target.ry = (target.height / 2);
        }
      }
    

    【讨论】:

    • 这很好,但是当对象旋转 90 度并且您尝试使用顶部控件中的一个(现在在侧面)进行缩放时会中断。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多