【问题标题】:How to set a stroke on only certain side?如何仅在某一侧设置笔画?
【发布时间】:2015-05-14 06:38:37
【问题描述】:

有没有办法只在画布对象的一侧进行描边?例如,我只想为顶部提供中风。

当我申请"strokeWidth:1" 时,它会应用于所有方面。我还没有找到任何属性或方法来解决我的问题。

【问题讨论】:

    标签: fabricjs


    【解决方案1】:

    对于已定义的方面,没有任何方法。您可以在图像后面添加一个矩形,使其看起来像一个边框。例如“上边框”宽度10px:

    var canvas = new fabric.Canvas('c');
    var radius = 150;
    
    fabric.Image.fromURL('http://cdn.younghollywood.com/images/stories/newsIMG/wenn/20140901/wenn21338105_46_4145_8.jpg', function(oImg) {
        oImg.scale(1.0).set({
            left: 50,
            top: 50,
            width: 200,
            height: 200
        });
    
        canvas.add(oImg);
        canvas.renderAll();
    });
    
    var border = new fabric.Rect({ 
        width: 200, 
        height: 200+10, 
        left: 50, 
        top: 40,
        fill: "#FFFFFF"
    });
    
    canvas.add(border);
    canvas.renderAll();
    

    小提琴:http://jsfiddle.net/q6Y6k/11/

    否则,请检查:How to set a stroke-width:1 on only certain sides of SVG shapes?

    【讨论】:

      【解决方案2】:

      我找到了使用strokeDashArray 的解决方案。

      var canvas = new fabric.Canvas('c');
      
      var border = new fabric.Rect({ 
          width: 200, 
          height: 100, 
          left: 50, 
          top: 40,
          fill: "#FFFFFF",
          strokeWidth: 1,
          stroke: '#333',
          strokeDashArray: [200, 100] // same as [width, height]
      
      });
      
      canvas.add(border);
      canvas.renderAll();
      

      jsFiddle 的答案是here

      您可以根据此答案找到任何类型的自定义边框的解决方案。

      【讨论】:

        【解决方案3】:

        遇到了同样的问题。必须重写 _render() 方法并单独绘制线条,而不是一次全部绘制。

        let canvas = new fabric.Canvas("my-canvas");
        canvas.setBackgroundColor("#ccc");
        
        fabric.RectWithBorders = fabric.util.createClass(fabric.Rect, {
          type: "rectWithBorders",
          borderTop: true,
          borderBottom: true,
          borderLeft: true,
          borderRight: false,
        
          initialize: function (options, borderOptions) {
            this.callSuper("initialize", options);
            this.borderTop = borderOptions.borderTop;
            this.borderBottom = borderOptions.borderBottom;
            this.borderLeft = borderOptions.borderLeft;
            this.borderRight = borderOptions.borderRight;
         },
         _render: function (ctx) {
            const originalStroke = this.stroke;
            var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0,
            ry = this.ry ? Math.min(this.ry, this.height / 2) : 0,
            w = this.width,
            h = this.height,
            x = -this.width / 2,
            y = -this.height / 2,
            isRounded = rx !== 0 || ry !== 0,
            k = 1 - 0.5522847498;
        
        // Border Top
        ctx.beginPath();
        this.stroke = this.borderTop ? originalStroke : null;
        ctx.moveTo(x + rx, y);
        ctx.lineTo(x + w - rx, y);
        isRounded &&
          this.borderRight &&
          ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);
        ctx.moveTo(x + w, y + h - ry);
        ctx.closePath();
        this._renderPaintInOrder(ctx);
        
        // Border Right
        ctx.beginPath();
        this.stroke = this.borderRight ? originalStroke : null;
        ctx.moveTo(x + w, y + ry);
        ctx.lineTo(x + w, y + h - ry);
        isRounded &&
          this.borderBottom &&
          ctx.bezierCurveTo(
            x + w,
            y + h - k * ry,
            x + w - k * rx,
            y + h,
            x + w - rx,
            y + h
          );
        ctx.moveTo(x + rx, y + h);
        ctx.closePath();
        this._renderPaintInOrder(ctx);
        
        // Border Bottom
        ctx.beginPath();
        this.stroke = this.borderBottom ? originalStroke : null;
        ctx.moveTo(x + w - rx, y + h);
        ctx.lineTo(x + rx, y + h);
        isRounded &&
          this.borderLeft &&
          ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);
        ctx.moveTo(x, y + ry);
        ctx.closePath();
        this._renderPaintInOrder(ctx);
        
        // Border Left
        ctx.beginPath();
        this.stroke = this.borderLeft ? originalStroke : null;
        ctx.moveTo(x, y + h - ry);
        ctx.lineTo(x, y + ry);
        isRounded &&
          this.borderTop &&
          ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);
        ctx.moveTo(x + w - rx, y);
        ctx.closePath();
        
        this._renderPaintInOrder(ctx);
        }
        });
        
        canvas.add(
          new fabric.RectWithBorders({
           width: 150,
           height: 150,
           left: 25,
           top: 25,
           fill: "transparent",
           strokeWidth: 1,
           stroke: "#333"
           }, 
           {borderTop: false, borderBottom: true,
            borderLeft: true, borderRight: true})
         );
        

        不确定它对性能的影响。尚未完全测试,因为以后不需要。

        对于 Demo fabricjs border sides 可以查看这个codepen

        【讨论】:

          猜你喜欢
          • 2012-02-17
          • 1970-01-01
          • 1970-01-01
          • 2013-03-02
          • 2016-04-15
          • 2011-08-11
          • 1970-01-01
          相关资源
          最近更新 更多