0

How can I draw a canvas rectangle with fill color AND 4 different border colors on each side?

4

2 回答 2

3

您可以向 canvas.context 添加一个新方法来绘制您的多色矩形。

在此处输入图像描述

你通过它的原型在 canvas.context 上定义一个新方法:

CanvasRenderingContext2D.prototype.myNewMethod = function(){ ... };

在新方法中,您可以使用任何上下文绘图命令来绘制所需的形状。

请注意,在 myNewMethod 内部,“this”指的是 canvas.context,因此您可以这样绘制:

this.lineTo(x,y)    // not context.lineTo

您的花哨的矩形是一个相当简单的绘图,除了斜接的侧笔画。

每个侧边笔划都绘制为实心梯形:

function trapezoid(context,color,x1,y1,x2,y2,x3,y3,x4,y4){
    context.beginPath();
    context.moveTo(x1,y1);
    context.lineTo(x2,y2);
    context.lineTo(x3,y3);
    context.lineTo(x4,y4);
    context.closePath();
    context.fillStyle=color;
    context.fill();
}

您喜欢的新矩形方法 (rainbowRect) 就像 context.fillRect 一样被调用。

context.rainbowRect(100,50,100,50,"gold","red","blue","green","purple");

这是一个完整的例子:

$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");


    // Add a rainbowRect function to the context prototype
    // This method is used alone like context.fillRect
    // This method is not used within a context.beginPath
    // NOTE: this addition must always be run before it is used in code
    CanvasRenderingContext2D.prototype.rainbowRect = function (x,y,w,h,fillColor,tColor,rColor,bColor,lColor){

        // use existing fillStyle if fillStyle is not supplied
        fillColor=fillColor||this.fillStyle;

        // use existing strokeStyle if any strokeStyle is not supplied
        var ss=this.strokeStyle;
        tColor=tColor||ss;
        rColor=rColor||ss;
        bColor=bColor||ss;
        lColor=lColor||ss;


        // context will be modified, so save it
        this.save();

        // miter the lines
        this.lineJoin="miter";

        // helper function: draws one side's trapezoidal "stroke"
        function trapezoid(context,color,x1,y1,x2,y2,x3,y3,x4,y4){
            context.beginPath();
            context.moveTo(x1,y1);
            context.lineTo(x2,y2);
            context.lineTo(x3,y3);
            context.lineTo(x4,y4);
            context.closePath();
            context.fillStyle=color;
            context.fill();
        }

        // context lines are always drawn half-in/half-out
        // so context.lineWidth/2 is used a lot
        var lw=this.lineWidth/2;

        // shortcut vars for boundaries
        var L=x-lw;
        var R=x+lw;
        var T=y-lw;
        var B=y+lw;

        // top
        trapezoid(this,tColor,  L,T,  R+w,T,  L+w,B,  R,B );

        // right
        trapezoid(this,rColor,  R+w,T,  R+w,B+h,  L+w,T+h,  L+w,B );

        // bottom
        trapezoid(this,bColor,  R+w,B+h,  L,B+h,  R,T+h,  L+w,T+h );

        // left
        trapezoid(this,lColor,  L,B+h,  L,T,  R,B,  R,T+h );

        // fill
        this.fillStyle=fillColor;
        this.fillRect(x,y,w,h);

        // be kind -- always rewind (old vhs reference!)
        this.restore();
        // don't let this path leak
        this.beginPath();
        // chain
        return(this);
    };


    // testing
    ctx.lineWidth=20;
    ctx.rainbowRect(100,50,100,50,"gold","red","blue","green","purple");



}); // end $(function(){});
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas" width=300 height=150></canvas>

于 2013-09-30T18:40:17.847 回答
0

不幸的是,您不能像使用 css 那样绘制矩形的边框。您可以使用 stroke() 方法,但它只为每一边绘制一种颜色的“边框”。所以,我想,您可以通过在矩形附近绘制线条来手动绘制边框。

于 2013-09-30T10:06:21.593 回答