首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建自定义模式刷

创建自定义模式刷
EN

Stack Overflow用户
提问于 2016-05-10 12:21:39
回答 1查看 922关注 0票数 0

在我的任务中,我需要使用Pattern Brush创建两种非常特定的Fabric.js类型

  1. 最后带有X的虚线。
  2. 一条简单的箭线。

我需要这两种类型的画笔在自由绘图模式。

任何指导或建议都会很有帮助。

这就是我试过的笔刷1号,但这并不能解决这个问题:

代码语言:javascript
复制
var hLinePatternBrush = new fabric.PatternBrush(canvas);
hLinePatternBrush.getPatternSrc = function() {

  var patternCanvas = fabric.document.createElement('canvas');
  patternCanvas.width = patternCanvas.height = 10;
  var ctx = patternCanvas.getContext('2d');

  ctx.strokeStyle = '#ffffff';
  ctx.strokeLineCap ="round";
  ctx.lineWidth = 5;
  ctx.beginPath();
  ctx.moveTo(5, 0);
  ctx.lineTo(5, 10);
  ctx.closePath();
  ctx.stroke();

  return patternCanvas;
};
canvas.freeDrawingBrush = hLinePatternBrush; 

至于笔刷2号,我一点也不知道。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-17 13:08:10

这是我对这个问题的实现。可能会对未来的人有所帮助。

代码语言:javascript
复制
fabric.Path.prototype.selectable = false;
    fabric.Triangle.prototype.selectable = false;
    fabric.Text.prototype.selectable = false;



    /* ------------------------ Player Path Brush --------------------- */


    var vLinePatternBrush = new fabric.PencilBrush(canvas);

    vLinePatternBrush.color = '#fff';
    if($("#line_type").val() == 'choose_type' || $("#line_type").val() == 'player_path' )
    {
        vLinePatternBrush.strokeDashArray = [5, 15];
    }
    else
    {
        vLinePatternBrush.strokeDashArray = [0,0];
    }

    vLinePatternBrush.hasControls = false;

    canvas.freeDrawingBrush = vLinePatternBrush;
    //canvas.freeDrawingBrush.color = '#fff';
    canvas.freeDrawingBrush.width = 4;

    //Choosing the Right Brush as per Users Requirement
    $("#line_type").change(function(e){
        if($("#line_type").val() == 'choose_type' || $("#line_type").val() == 'player_path' )
        {

            canvas.freeDrawingBrush = vLinePatternBrush;
            canvas.freeDrawingBrush.color = '#fff';
            canvas.freeDrawingBrush.width = 4;
            vLinePatternBrush.strokeDashArray = [5, 15];

        }
        else
        {
            var normalLine = new fabric['PencilBrush'](canvas);
            normalLine.strokeDashArray = [0,0];
            canvas.freeDrawingBrush = normalLine;
            canvas.freeDrawingBrush.color = '#fff';
            canvas.freeDrawingBrush.width = 4;
            console.log('here');
        }
    });

    // This is required to make sure that the objects can be selected if wrapped inside a path line.
    canvas.on('object:added', function(e) { 
        console.log(e);
        if(e.target.type == 'path' || e.target.type == 'text' || e.target.type == 'triangle')
        {
            console.log('Sending Object to Background');
            canvas.sendToBack(e.target);
        }
    });

//绘制路径后处理X和Arrow部分

代码语言:javascript
复制
canvas.on('path:created', function(path) {
    console.log(path);

    if($("#line_type").val() == 'choose_type' || $("#line_type").val() == 'player_path' )
    {
        console.log(path.path.path[(path.path.path.length -1)]);



        var x1 = path.path.path[0][1];
        var y1 = path.path.path[0][2];
        var x2 = path.path.path[(path.path.path.length -1)][1];
        var y2 = path.path.path[(path.path.path.length -1)][2];

        var angle = calcArrowAngle(x1,y1,x2,y2);
        angle = angle - 90;

        var text = new fabric.Text('+', { 
            left: path.path.path[(path.path.path.length -1)][1], 
            top: path.path.path[(path.path.path.length -1)][2], 
            fill: 'white',
            originX: 'center',
            originY: 'center',
            flipx: true,
            selectable: false,
            flipy: true,
            fontSize: 80,
            fontFamily: 'ABeeZee',
            fill: 'white',
            angle: angle,
            hasControls: false
        });

        canvas.add(text);
    }



    if($("#line_type").val() == 'ball_path' )
    {
        console.log(path.path.path[(path.path.path.length -1)]);

        var x1 = path.path.path[0][1];
        var y1 = path.path.path[0][2];
        var x2 = path.path.path[(path.path.path.length -1)][1];
        var y2 = path.path.path[(path.path.path.length -1)][2];

        var angle = calcArrowAngle(x2,y2,x1,y1);
        angle = angle - 90;

        arrow = new fabric.Triangle({
            left: (path.path.path[(path.path.path.length -1)][1] +  2),
            top: (path.path.path[(path.path.path.length -1)][2] + 2),
            originX: 'center',
            originY: 'center',
            hasBorders: false,
            hasControls: false,
            lockScalingX: true,
            lockScalingY: true,
            lockRotation: true,
            pointType: 'arrow_start',
            angle: angle,
            width: 15,
            height: 15,
            fill: 'white',
            hasControls: false

        });

        canvas.add(arrow);
    }
    // This is specific to my implementation for undo and redo. Once can ignore
    updateModifications(true);

});

在代码的第一部分中,我只是创建两个简单的pencilBrush,一个带有DottedLines,另一个是普通行

在第二部分中,我得到了路径结束的确切位置(可能不是最好的方法,但它对我有效)。一旦我得到了点,我就会在那个位置上放弃期望的形状。

CalcArrowAngle: Credits StackOverflow

代码语言:javascript
复制
function calcArrowAngle(x1, y1, x2, y2) {
        var angle = 0,
        x, y;

        x = (x2 - x1);
        y = (y2 - y1);

        if (x === 0) {
            angle = (y === 0) ? 0 : (y > 0) ? Math.PI / 2 : Math.PI * 3 / 2;
        } else if (y === 0) {
            angle = (x > 0) ? 0 : Math.PI;
        } else {
            angle = (x < 0) ? Math.atan(y / x) + Math.PI : (y < 0) ? Math.atan(y / x) + (2 * Math.PI) : Math.atan(y / x);
        }

        return (angle * 180 / Math.PI);
    }

我并不是说这是最好的方法。但它解决了手头的问题。

输出PNG:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37138419

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档