2016-11-09 5 views
0

基本的に、与えられたポリゴンに対してフォールオフテクスチャを作成する必要があります。例えば、これは私が作成する必要がポリゴンの周りにグラデーションベベルを描く

enter image description here

何持っているイメージはこれですが、白から黒へのベベル勾配で、勾配と緑の部分を考えてみましょう。

enter image description here

私は、すべての頂点の座標とベベルの厚さを持っています。 HTML5 2Dキャンバスを使用してレンダリングしています。基本的に最も明白な解決策は、ポリゴンまでのピクセルの距離をすべて計算し、それがthicknessパラメータ内にある場合は、ピクセルの色と色を計算します。しかし、それは重い計算であり、私のニーズにとって可能な限り小さなテクスチャであっても、遅くなるでしょう。これを達成するためにキャンバスでできることは何ですか?

答えて

1

ポリゴンのアウトラインをストロークの幅を変えて描画し、各ステップの色を幅を変えて変更します。

スニペットにはその1つの方法が示されています。ラインと2つのポリゴンを描画することは、 "マイター" と "ラウンド"

"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)")

に参加します
関連する問題