2012-02-14 9 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

+0

произвольно толстый. но толщина жестко закодирована. Мне все равно, о сглаживании, мне просто нужно что-то, что дает мне хорошее приближение. это для игры, и мне не нужна высокая точность. – akonsu

+0

Как вы собираетесь обрабатывать перекрытия строк? Вы могли бы просто использовать 'area + = толщина * sqrt ((e.pageX - this.offsetLeft - x_prev)^2 + (e.pageY - this.offsetTop - y_prev)^2);', но это не учитывает линии, которые пересекаются. – Blender

ответ

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)); 
} 

Если это действительно слишком медленно, вы можете выбрать, чтобы обновить этот район все остальные MouseMove, каждый третий MouseMove и т.д., или на интервального таймера. Например, вот очень-слегка модифицированная версия, которая обновляет только каждый десятый MouseMove: http://jsfiddle.net/ZC8cB/4/

И если один кадр подсчета слишком медленно — потому что у вас медленный компьютер или огромный холста или как — то вы можете выберите ImageData в одном фрейме, и каждый кадр обновления подсчитает определенную часть пикселей.

+0

Я закончил тем же, за исключением того, что я просматриваю холст на событии «mouse up». – akonsu

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

+0

Его очень просто, он поддерживает сетку, которая отслеживает, сколько квадратов (толщина определяет размер) мышь перемещала во время рисования. Крытый счетчик подсчитывает количество окрашенных квадратов. –

+0

спасибо. это может работать для меня, за исключением случаев, когда мышь слишком быстро перемещается, а обработчик события не вызывается для всех точек траектории (именно поэтому я использую moveTo() и lineTo() в своем коде). – akonsu

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