在多边形周围绘制渐变斜角

时间:2016-11-09 21:38:23

标签: html5 html5-canvas textures

基本上我需要为给定的多边形创建一个衰减纹理。例如,这是我的图像

enter image description here

我需要创建的是这个,但是从白色到黑色的斜角渐变,将绿色部分视为渐变。

enter image description here

我已经获得了所有顶点的坐标和斜角的厚度。我使用HTML5 2d画布进行渲染。基本上最明显的解决方案是计算每个像素到多边形的距离,如果它在厚度参数范围内,则计算像素的颜色和颜色。但是那个繁重的计算会很慢,即使对于我需要的最小可能纹理也是如此。那么我有什么技巧可以用帆布来实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

只需在不同的笔触宽度下绘制多边形的轮廓,从而改变每个步骤宽度的颜色。

该代码段显示了一种方法。绘制2个具有线连接“miter”和“round”的多边形

 "use strict";

const canvas = document.createElement("canvas"); 
canvas.height = innerHeight;
canvas.width = innerWidth;
canvas.style.position = "absolute"; 
canvas.style.top = canvas.style.left = "0px";
const ctx = canvas.getContext("2d");
document.body.appendChild(canvas);

// poly to draw
var poly = [0.1,0.2,0.4,0.5,0.2,0.8];
var poly1 = [0.6,0.1,0.9,0.5,0.8,0.9];

// convert rgb style colour to array
function rgb2Array(rgb){
    var arr1 = rgb.split("(")[1].split(")")[0].split(",");
    var arr = [];
    while(arr1.length > 0){
        arr.push(Number(arr1.shift()));
    }
    return arr;
}
// convert array to rgb colour
function array2rgb(arr){
    return "rgb("+Math.floor(arr[0])+","+Math.floor(arr[1])+","+Math.floor(arr[2])+")"
}

// lerps array from to. Amount is from 0 @ from 1 @ to. res = is the resulting array
function lerpArr(from,to,amount,res){
    var i = 0;
    if(res === undefined){
        res = [];
    }
    while(i < from.length){
        res[i] = (to[i]-from[i]) * amount + from[i];    
        i++;
    }
    return res;
}

// draw gradient outline
// poly is the polygon verts
// width is the outline width
// fillStyle is the polygon fill style
// rgb1 is the outer colour
// rgb2 is the inner colour of the outline gradient
function drawGradientOutline(poly,width,fillStyle,rgb1,rgb2){
    ctx.beginPath();
    var i = 0;
    var w = canvas.width;
    var h = canvas.height;
    ctx.moveTo(poly[i++] * w,poly[i++] * h);
    while(i < poly.length){
        ctx.lineTo(poly[i++] * w,poly[i++] * h);
    }
    ctx.closePath();
    var col1 = rgb2Array(rgb1);
    var col2 = rgb2Array(rgb2);
    
    i = width * 2;
    var col = [];
    while(i > 0){
        ctx.lineWidth = i;
        ctx.strokeStyle = array2rgb(lerpArr(col1,col2,1- i / (width * 2),col));
        ctx.stroke();
        i -= 1;
    }
    ctx.fillStyle = fillStyle;
    ctx.fill();
}
ctx.clearRect(0,0,canvas.width,canvas.height)
ctx.lineJoin = "miter";
drawGradientOutline(poly,20,"black","rgb(255,0,0)","rgb(255,255,0)")
ctx.lineJoin = "round";
drawGradientOutline(poly1,20,"black","rgb(255,0,0)","rgb(255,255,0)")