本文介绍了无论如何,是否可以使Fabric对象自动对齐在Fabric.js上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个编辑器的项目中,我正在使用Fabric.js,但我不知道如何使canvas对象自动对齐.

有没有使像这样的画布对象与另一个对象自动对齐的示例?

快照示例的图像
来自其他网站的自动捕捉示例

链接在这里:
自动捕捉示例网站

Im working on a project of building a editor, i am using the Fabric.js, but i don know how to make the canvas object auto align.

Is there any example of making canvas object auto align with another object like this?

image of snap example
auto snap example from other site

link here:
auto snap example site

推荐答案

我正在做同一件事.这似乎是一个很常见的功能请求,所以我想我会分享我的工作成果.它可以使用一些改进.例如,我注意到如果您对红色框进行缩放,则不会应用该缩放,并且它的对齐方式也不正确.但是,我认为它很好地展示了基本原理,您可以对其进行详细说明以满足您的需求.

I was working on the same thing. This seems to be a pretty common feature request so I thought I'd share what I worked out. It could use some refinement. For instance, I've noticed if you scale the red box, the scale is not applied and it doesn't align right. However, I think it demonstrates the basic principal well and you can elaborate on it to fit your needs.

(注意:2017年8月1日:致力于在GitHub上放置更全面的代码.( https: //github.com/JerrodV/FabricObjectAlignment )即将推出更多详细信息!)

(Note: 8/1/2017: Working to place a more comprehensive code base on GitHub. (https://github.com/JerrodV/FabricObjectAlignment) More Details Soon!)

您可以在此处

HTML:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <canvas id="c" height="600" width="600" style="border:1px solid #c1c1c1;"></canvas>
    </div>
    </form>
    <script src="Scripts/jquery-3.1.1.min.js"></script>
    <script src="Scripts/fabric.min.js"></script>
    <script src="Scripts/default.js"></script>
</body>
</html>

JavaScript:

Javascript:

Def = {
    canvas: null,    
    rect: null,
    lines: {
        top: null, 
        left: null,
        right: null,
        bottom: null
    },
    init: function () {
        Def.canvas = new fabric.Canvas('c');

        Def.canvas.on('object:moving', Def.events.objectMoving);

        Def.canvas.add(new fabric.Rect({
            height: 100,
            width: 100,
            top: 100,
            left: 200,
            fill: 'black',
            selectable: false
        }));

        Def.canvas.add(new fabric.Rect({
            height: 100,
            width: 100,
            top: 300,
            left: 100,
            fill: 'black',
            selectable: false
        }));        

        Def.rect = new fabric.Rect({
            height: 100,
            width: 100,
            top: 200,
            left: 250,
            fill: 'red'
        });

        Def.canvas.add(Def.rect);
    },
    events: {
        objectMoving: function (e) {
            //Get the object being manipulated
            var obj = e.target;

            //Set up an object representing its current position
            var curPos = {
                top: parseInt(obj.get('top')),
                left: parseInt(obj.get('left')),
                right: parseInt(obj.get('left') + obj.get('width')),
                bottom: parseInt(obj.get('top') + obj.get('height'))
            };

            //Set up an object that will let us be able to keep track of newly created lines
            var matches = {
                top: false,
                left: false,
                right: false,
                bottom: false
            }

            //Get the objects from the canvas
            var objects = Def.canvas.getObjects();

            //For each object
            for (var i in objects) {

                //If the object we are looing at is a line or the object being manipulated, skip it
                if (objects[i] === obj || objects[i].get('type') === 'line') { continue; }

                //Set up an object representing the position of the canvas object
                var objPos = {
                    top: parseInt(objects[i].get('top')),
                    left: parseInt(objects[i].get('left')),
                    right: parseInt(objects[i].get('left') + obj.get('width')),
                    bottom: parseInt(objects[i].get('top') + obj.get('height'))
                }

                //Look at all 4 sides of the object and see if the object being manipulated aligns with that side.

                //Top////////////////////////////////////
                if (Def.inRange(objPos.top, curPos.top)) {
                    //We match. If we don't already have aline on that side, add one.
                    if (!Def.lines.top) {
                        Def.drawLine('top', objPos.top);
                        //Keep track of the fact we found a match so we don't remove the line prematurely.
                        matches.top = true;
                        //Snap the object to the line
                        obj.set('top', objPos.top).setCoords();
                    }
                }               
                //Left////////////////////////////////////
                if (Def.inRange(objPos.left, curPos.left)) {
                    if (!Def.lines.left) {
                        Def.drawLine('left', objPos.left);                        
                        matches.left = true;
                        obj.set('left', objPos.left).setCoords();
                    }
                }                
                //Right////////////////////////////////////
                if (Def.inRange(objPos.right, curPos.right)) {
                    if (!Def.lines.right) {
                        Def.drawLine('right', objPos.right);                        
                        matches.right = true;                        
                        obj.set('left', objPos.right - objects[i].get('width')).setCoords();
                    }
                }                
                //Bottom////////////////////////////////////
                if (Def.inRange(objPos.bottom, curPos.bottom)) {
                    if (!Def.lines.bottom) {
                        Def.drawLine('bottom', objPos.bottom);                        
                        matches.bottom = true;
                        obj.set('top', objPos.bottom - objects[i].get('height')).setCoords();
                    }
                }

                //Look at the side we matched on. If we did not match, and we have a line, remove the line.
                for (var j in matches) {
                    var m = matches[j];
                    var line = Def.lines[j]; 
                    if (!m && line) {
                        Def.canvas.remove(line);
                        Def.lines[j] = null;
                    }

                }

            }
            Def.canvas.renderAll();
        }
    },
    drawLine: function (side, pos) {
        var ln = null
        switch (side) {
            case 'top':
                ln = new fabric.Line([Def.canvas.get('width'), 0, 0, 0], {
                    left: 0,
                    top: pos,
                    stroke: 'rgb(178, 207, 255)'
                });
                Def.lines.top = ln;
                break;
            case 'left':
                ln = new fabric.Line([0, Def.canvas.get('height'), 0, 0], {
                    left: pos,
                    top: 0,
                    stroke: 'rgb(178, 207, 255)'
                });
                Def.lines.left = ln;
                break;
            case 'right':
                ln = new fabric.Line([0, Def.canvas.get('height'), 0, 0], {
                    left: pos,
                    top: 0,
                    stroke: 'rgb(178, 207, 255)'
                });
                Def.lines.right = ln;
                break;
            case 'bottom':
                ln = new fabric.Line([Def.canvas.get('width'), 0, 0, 0], {
                    left: 0,
                    top: pos,
                    stroke: 'rgb(178, 207, 255)'
                });
                Def.lines.bottom = ln;
                break;
        }
        Def.canvas.add(ln).renderAll();
    },
    alignTolerance : 6,
    inRange: function (val1, val2) {
        if ((Math.max(val1, val2) - Math.min(val1, val2)) <= Def.alignTolerance) { return true; }        
        else { return false; }
    }
};

$(Def.init);

我希望您觉得这很有用.祝你好运!

I hope you find this useful. Good Luck!

这篇关于无论如何,是否可以使Fabric对象自动对齐在Fabric.js上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 16:21