2012-02-14 85 views
2

我在畫布上用下面的代碼畫出手繪筆畫。我需要檢查有多少畫布覆蓋了筆畫。什麼是檢查的好方法?我能想到的唯一的事情就是計算鼠標向上事件中具有特定顏色的像素數量。但它是跛腳,因爲它很慢...如何計算繪製區域的面積?

任何幫助嗎?

$(document).ready(function(){ 
    var draw = false; 
    var x_prev = null, y_prev = null; 
    var canvas = document.getElementById("canvas"); 
    var context = canvas.getContext("2d"); 
    canvas.mousedown(function(e){ 
     draw = true; 
     x_prev = e.pageX - this.offsetLeft; 
     y_prev = e.pageY - this.offsetTop; 
    }); 
    window.mouseup(function(){draw=false}); 
    canvas.mousemove(function(e){ 
     if(draw){ 
      context.beginPath(); 
      context.moveTo(e.pageX - this.offsetLeft, e.pageY - this.offsetTop); 
      context.lineTo(x_prev, y_prev); 
      context.stroke(); 
      context.closePath(); 
      x_prev = e.pageX - this.offsetLeft; 
      y_prev = e.pageY - this.offsetTop; 
     } 
    }); 
+0

線條有多厚?另外,你是否會考慮抗鋸齒? – Blender 2012-02-14 03:53:45

+0

任意粗。但厚度是硬編碼的。我不太在意反鋸齒,我只是需要一些能給我一個很好的近似值。這是一款遊戲,我不需要高精度。 – akonsu 2012-02-14 03:55:59

+0

你打算如何處理線重疊?你可以使用'area + = thickness * sqrt((e.pageX - this.offsetLeft - x_prev)^ 2 +(e.pageY - this.offsetTop - y_prev)^ 2);',但這並不代表相交的線。 – Blender 2012-02-14 04:00:05

回答

1

電腦是快速。對於我來說,繪製時每幀重複計算特定阿爾法像素的數量似乎很快。這裏自己測試一下:http://jsfiddle.net/ZC8cB/3/

相關代碼:

var w = canvas.attr('width'), 
    h = canvas.attr('height'), 
    area = w * h; 

function updateArea() { 
    var data = context.getImageData(0, 0, w, h).data; 
    for (var ct=0, i=3, len=data.length; i<len; i+=4) if (data[i]>50) ct++; 
    $fill.html(ct); 
    $pct.html((100 * ct/area).toFixed(2)); 
} 

如果這真的是太慢了,你可以選擇更新區域所有其他鼠標移動,每三個鼠標移動等,或在間隔定時器。例如,這裏是一個非常,略微修改後的版本,只有更新每隔十鼠標移動:http://jsfiddle.net/ZC8cB/4/

如果計數的單個幀速度太慢—因爲你有一個緩慢的計算機或巨大的帆布或兩者—那麼你就可以在一幀中獲取ImageData並且每個更新幀計數像素的特定部分。

+0

我最終做了同樣的事情,除了我在「鼠標移動」事件上掃描畫布。 – akonsu 2012-02-17 13:57:17

1

將面積定量爲線寬大小的正方形並計算繪製期間遇到的唯一正方形的數量。

var thickness = 4 
var height = .. 
var width = .. 
var drawn = [] 
var covered = 0; 

canvas.mousemove(function(e) { 

    var x = e.pageX - this.ofsetLeft; 
    var y = e.pageY - this.offsetTop; 
    x = parseInt(x/width) * (width/thickness) 
    y = parseInt(y/height) * (height/thickness) 
    id = x + y * parseInt(thickness/width) 
    if (!drawn[ id ]) { 
     drawn[ id ] = 1; 
     covered++; 
    } 

} 

您可以通過總平方數除以覆蓋正方形拿得出面積百分比

var a = covered/((width/thickness) * (height/thickness)) 
+0

謝謝你的回答,請你解釋一下這段代碼嗎? – akonsu 2012-02-16 03:08:14

+0

它非常簡單,它保持一個網格,用於跟蹤鼠標在繪製時行進過多少個方格(厚度定義了尺寸)。被覆蓋的計數器計算塗色正方形的數量。 – 2012-02-17 08:46:59

+0

謝謝。這可以爲我工作,除非鼠標移動速度過快,並且事件處理程序未針對軌跡中的所有點調用(這就是爲什麼我在代碼中使用moveTo()和lineTo())的情況。 – akonsu 2012-02-17 13:56:36