2016-11-09 2 views
0

В принципе мне нужно создать текстуру спада для заданного многоугольника. Например, это изображение У меня естьНарисуйте градиентный скос вокруг полигона

enter image description here

Что мне нужно, чтобы создать это, но с коническим градиентом от белого к черному, рассмотрим зеленую часть в качестве градиента.

enter image description here

У меня есть координаты всех вершин и толщину скоса. Я использую HTML5 2d canvas. В основном наиболее очевидным решением было бы рассчитать расстояние каждого пикселя до многоугольника и, если оно находится в пределах параметра толщины, рассчитать цвет и цвет пикселя. Но это тяжелые вычисления и будут медленными, даже для самых маленьких текстур для моих нужд. Итак, есть ли какие-либо трюки, которые я могу сделать с холстом, чтобы достичь этого?

ответ

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

 Смежные вопросы

  • Нет связанных вопросов^_^