2015-12-11 64 views
3

如何畫周圍的任何形狀的帆布內部和外部邊界?吸取內部和外部邊界周圍任何帆布形狀

我上的HTML畫布繪製好幾只中風的形狀,我想提醒他們周圍的內部和外部邊界。例如

草案: shapes with and without inner/outer border

是否有一個通用的,爲什麼這樣做對任何形狀(假設它是一個封閉的只中風型)?

回答

4

兩種方法

沒有內置的方式來做到這一點,有一些我使用兩種編程的方式。第一個問題很複雜,涉及擴大和縮小路徑,然後沿着這條路徑前進。這適用於大多數情況,但在複雜情況下會失敗,並且解決方案有很多變數和選項來解決這些複雜問題以及如何處理它們。

兩個

,我下面介紹的是使用ctx.globalCompositeOperation設置屏蔽掉你想繪製或不是第二個最簡單的方法就更好了。當筆畫沿着中心繪製並且填充填充到中心時,可以以所需寬度的兩倍來繪製筆畫,然後掩蔽或掩蓋內部或外部部分。

當你開始創建非常複雜的圖像作爲掩蔽(環球綜合操作)將與那些已經被吸引干擾這不會成爲問題。

爲了簡化您可以創建第二畫布的大小與原來的暫存空間相同的過程。然後,您可以在劃傷畫布上繪製形狀,然後將劃過的畫布拖到工作區域上。

雖然這種方法是不一樣快計算膨脹或收縮的路徑,它不會從面臨的路徑移動點模糊度受到影響。此方法也不會爲內部或外部邊緣創建具有正確線條連接或斜線的線條,因爲您必須使用其他方法。對於大多數目的而言,掩蔽是一個很好的解決方案。

下面是掩模方法的演示來繪製的內部或外部的路徑。如果通過在填充中繪製筆畫來修改蒙版,則還可以設置偏移量,以便輪廓線或內聯線將偏移多個像素。我已經離開了你。 (提示添加描邊並在繪製蒙版時將線寬設置爲偏移距離的兩倍)。

var demo = function(){ 
 
    
 
    /** fullScreenCanvas.js begin **/ 
 
    var canvas = (function() { 
 
     canvas = document.getElementById("canv"); 
 
     if(canvas !== null){ 
 
      document.body.removeChild(canvas); 
 
     } 
 
     // creates a blank image with 2d context 
 
     canvas = document.createElement("canvas"); 
 
     canvas.id = "canv";  
 
     canvas.width = window.innerWidth; 
 
     canvas.height = window.innerHeight; 
 
     canvas.style.position = "absolute"; 
 
     canvas.style.top = "0px"; 
 
     canvas.style.left = "0px"; 
 
     canvas.style.zIndex = 1000; 
 
     canvas.ctx = canvas.getContext("2d"); 
 
     document.body.appendChild(canvas); 
 
     return canvas; 
 
    })(); 
 
    var ctx = canvas.ctx; 
 
    /** fullScreenCanvas.js end **/ 
 
    
 
    
 
    
 
    /** CreateImage.js begin **/ 
 
    // creates a blank image with 2d context 
 
    var createImage = function(w,h){ 
 
     var image = document.createElement("canvas"); 
 
     image.width = w; 
 
     image.height =h; 
 
     image.ctx = image.getContext("2d"); 
 
     return image; 
 
    } 
 
    /** CreateImage.js end **/ 
 
    
 
    
 
    
 
    // define a shape for demo 
 
    var shape = [0.1,0.1,0.9,0.1,0.5,0.5,0.8,0.9,0.1,0.9]; 
 
    
 
    // draws the shape as a stroke 
 
    var strokeShape = function (ctx) { 
 
     var w, h, i; 
 
     w = canvas.width; 
 
     h = canvas.height; 
 
     ctx.beginPath(); 
 
     ctx.moveTo(shape[0] *w, shape[1] *h) 
 
     for (i = 2; i < shape.length; i += 2) { 
 
      ctx.lineTo(shape[i] * w, shape[i + 1] * h); 
 
     } 
 
     ctx.closePath(); 
 
     ctx.stroke(); 
 
    } 
 
    // draws the shape as filled 
 
    var fillShape = function (ctx) { 
 
     var w, h, i;  
 
     w = canvas.width; 
 
     h = canvas.height; 
 
     
 
     ctx.beginPath(); 
 
     ctx.moveTo(shape[0] * w,shape[1] * h) 
 
     for (i = 2; i < shape.length; i += 2) { 
 
      ctx.lineTo(shape[i]*w,shape[i+1]*h); 
 
     } 
 
     ctx.closePath(); 
 
     ctx.fill(); 
 
    } 
 
    
 
    var drawInOutStroke = function(width,style,where){ 
 
     // clear the workspace 
 
     workCtx.ctx.globalCompositeOperation ="source-over"; 
 
     workCtx.ctx.clearRect(0, 0, workCtx.width, workCtx.height); 
 
     
 
     // set the width to double 
 
     workCtx.ctx.lineWidth = width*2; 
 
     workCtx.ctx.strokeStyle = style; 
 
     
 
     // fill colour does not matter here as its not seen 
 
     workCtx.ctx.fillStyle = "white"; 
 
     
 
     // can use any join type 
 
     workCtx.ctx.lineJoin = "round"; 
 
     
 
     // draw the shape outline at double width 
 
     strokeShape(workCtx.ctx); 
 
     
 
     // set comp to in. 
 
     // in means leave only pixel that are both in the source and destination 
 
     if (where.toLowerCase() === "in") { 
 
      workCtx.ctx.globalCompositeOperation ="destination-in"; 
 
     } else { 
 
      // out means only pixels on the destination that are not part of the source 
 
      workCtx.ctx.globalCompositeOperation ="destination-out"; 
 
     } 
 
     fillShape(workCtx.ctx); 
 
     ctx.drawImage(workCtx, 0, 0); 
 
    } 
 
    
 
    // clear in case of resize 
 
    ctx.globalCompositeOperation ="source-over"; 
 
    ctx.clearRect(0,0,canvas.width,canvas.height); 
 
    
 
    // create the workspace canvas 
 
    var workCtx = createImage(canvas.width, canvas.height); 
 
    
 
    // draw the outer stroke 
 
    drawInOutStroke((canvas.width + canvas.height)/45, "black", "out"); 
 
    
 
    // draw the inner stroke 
 
    drawInOutStroke((canvas.width + canvas.height)/45, "red", "in"); 
 
    
 
    // draw the shape outline just to highlight the effect 
 
    ctx.strokeStyle = "white"; 
 
    ctx.lineJoin = "round"; 
 
    ctx.lineWidth = (canvas.width + canvas.height)/140; 
 

 
    strokeShape(ctx); 
 
    
 
}; 
 
// run the demo 
 
demo(); 
 
// incase fullscreen redraw it all 
 
window.addEventListener("resize",demo)