优化画布绘制以形成连续路径 [英] Optimize canvas drawing to make a continuous path

查看:173
本文介绍了优化画布绘制以形成连续路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个用红色填充画布'网格方块的脚本。
我正在寻找如何优化我的脚本以连续填充方块的提示,而不是像这里一样砍掉:



我试图分离并合并一些函数,但无法找到解决方案。
这是

 <!doctype html> 
< html>
< head>
< link rel =stylesheettype =text / cssmedia =allhref =css / reset.css/> < ;! - reset css - >
< script type =text / javascriptsrc =http://code.jquery.com/jquery.min.js>< / script>

< style>
body {background-color:ivory; }
canvas {border:1px solid red;}
< / style>

< script>
$(function(){

var canvas = document.getElementById(canvas);
var context = canvas.getContext(2d);

var canvasOffset = $(#canvas)。offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;


var wt = canvas.width;
var ht = canvas.height;
var down = false;

var lastX = -20;
var lastY = -20;

var points = [];

var draw = function(e){};


draw。 started = false;

var count;


函数interpolateLine(startX,startY,endX,endY){

var lastForX;
var lastForY;
//
for(var pct = 0; pct< = 1; pct + = 0.06){
var dx = endX-startX;
var dy = endY-startY;
var X = startX + dx * pct;
var Y = startY + dy * pct;
if(!(X == lastForX&& Y = = lastForY)){
draw.ColorCell(X,Y);
}
lastForX = X;
lastForY = Y;
}

}


draw.ColorCell = function(x,y){
var rw = x - 1;
var rh = y - 1;
rw = rw - rw%5 + 0.5;
rh = rh - rh%5 + 0.5;
context.fillStyle =red;
context.fillRect(rw,rh,5,5);
};


draw.single = function(e){
var mouseX = parseInt(e.clientX-offsetX);
var mouseY = parseInt(e.clientY-offsetY);
draw.ColorCell(mouseX,mouseY);
};


// mousemove
draw.move = function(e){

if(!down){return;}

//获取当前鼠标位置
var mouseX = parseInt(e.clientX-offsetX);
var mouseY = parseInt(e.clientY-offsetY);

//如果我们没有离开这个XY,那么如果(mouseX == lastX&& mouseY == lastY){return;},请不要再处理


//当运行下面的for循环时,
//多次迭代将找不到新的网格单元
//所以lastForX / lastForY会让我们跳过重复的XY
var lastForX = lastX;
var lastForY = lastY;

//从最后一个鼠标移动位置
//沿着一条线走到当前的mousemove位置。
//然后为我们在walk
上传递的任何单元格着色(var pct = 0; pct< = 1; pct + = 0.06){
var dx = mouseX-lastX;
var dy = mouseY-lastY;
var X = parseInt(lastX + dx * pct);
var Y = parseInt(lastY + dy * pct);
if(!(X == lastForX&& Y == lastForY)){
draw.ColorCell(X,Y);
}
lastForX = X;
lastForY = Y;
}

//将此鼠标位置设置为下一个mousemove的起始位置
lastX = mouseX;
lastY = mouseY;
};


// mousedown
draw.start = function(e){
e.preventDefault();
lastX = parseInt(e.clientX-offsetX);
lastY = parseInt(e.clientY-offsetY);
down = true;
};


// mouseup
draw.stop = function(e){
e.preventDefault();
down = false;
};


function grid(){
context.strokeStyle =#f0f0f0;
var h = 2.5;
var p = 2.5;
context.strokeRect(0.5,0.5,5,5);
for(i = 0; i< wt; i + = p){
p * = 2;
context.drawImage(canvas,p,0);
}
for(i = 0; i< ht; i + = h){
h * = 2;
context.drawImage(canvas,0,h);
}
}


canvas.addEventListener('mouseup',draw.stop,false);
canvas.addEventListener('mouseout',draw.stop,false);
canvas.addEventListener('mousedown',draw.start,false);
canvas.addEventListener('click',draw.single,false);
canvas.addEventListener('mousemove',draw.move,false);

grid();

}); // end $(function(){});
< / script>

< / head>

< body>
< canvas id =canvaswidth = 501 height = 301>< / canvas>
< / body>
< / html>


This is a script for filling canvas' grid squares with red color. I'm looking for tips how to optimize my script to fill squares continuously, without chopping like here:

I tried to separate and merge some functions, but can't find a solution. Here's the updated jsFiddle and my code:


HTML:

<canvas id="plan" width="501px" height="301px"></canvas>

JavaScript (updated):

var canvas = document.getElementById('plan');
var context = canvas.getContext('2d'),
    wt = canvas.width,
    ht = canvas.height;
var down = false;
var draw = function (e) {};

window.onload = grid();

var oldPos = {
    mX: 0,
    mY: 0
};

var dPos = {
    mX: 0,
    mY: 0
};

var curPos = {
    mX: 0,
    mY: 0
};

draw.to = function (X, Y) {
    oldPos = getMousePos(canvas, e); //update position
    var mposX = X,
        mposY = Y;
    mposX = mposX - mposX % 5;
    mposY = mposY - mposY % 5;
    context.fillStyle = "red";
    context.fillRect(mposX + 0.5, mposY + 0.5, 5, 5);
};

draw.single = function (e) {
    oldPos = getMousePos(canvas, e);
    var mpos = getMousePos(canvas, e);
    mpos.mX = mpos.mX - mpos.mX % 5;
    mpos.mY = mpos.mY - mpos.mY % 5;
    context.fillStyle = "red";
    context.fillRect(mpos.mX + 0.5, mpos.mY + 0.5, 5, 5);
};

draw.move = function (e) {
    if (down) {
        curPos = getMousePos(canvas, e);
        dPos.mX = Math.abs(curPos.mX - oldPos.mX); // distance between old & new (delta X)
        dPos.mY = Math.abs(curPos.mY - oldPos.mY); // delta Y
        if (dPos.mX >= 5 || dPos.mY >= 5) { // if the distance is bigger than 5px hz OR 5px vertical
            lightIntermediateSquares(oldPos.mX, oldPos.mY, curPos.mX, curPos.mY); // ^ connect them
        } else {
            draw.single(e); // simple
        }
    }
};

draw.start = function (e) {
    e.preventDefault();
    down = true;
    draw.single(e);
};

draw.stop = function (e) {
    down = false;
};

function lightIntermediateSquares(startX, startY, endX, endY) {
    for (var pct = 0; pct <= 1; pct += 0.03) {
        var dx = endX - startX;
        var dy = endY - startY;
        var X = startX + dx * pct;
        var Y = startY + dy * pct;
        draw.to(X, Y); // is it okay?
    }
}

function grid() {
    context.strokeStyle = "#f0f0f0";
    var h = 2.5,
        p = 2.5;
    context.strokeRect(0.5, 0.5, 5, 5);
    for (i = 0; i < wt; i += p) {
        p *= 2;
        context.drawImage(canvas, p, 0);
    }
    for (i = 0; i < ht; i += h) {
        h *= 2;
        context.drawImage(canvas, 0, h);
    }
}

function getMousePos(canvas, e) {
    var rect = canvas.getBoundingClientRect();
    return {
        mX: e.clientX - rect.left - 1,
        mY: e.clientY - rect.top - 1
    };
}

canvas.addEventListener('mouseup', draw.stop, false);
canvas.addEventListener('mousedown', draw.start, false);
canvas.addEventListener('mousemove', draw.move, false);
canvas.addEventListener('mouseout', draw.stop, false);

解决方案

Here's how to light the missing squares

Calculate a line between the previous mousemove and the current mousemove position.

Then walk that line using interpolation and color any grid squares that the line crosses.

        // walk along a line from the last mousemove position
        // to the current mousemove position.
        // Then color any cells we pass over on our walk
        for(var pct=0;pct<=1;pct+=0.06){
              var dx = mouseX-lastX;
              var dy = mouseY-lastY;
              var X = parseInt(lastX + dx*pct);
              var Y = parseInt(lastY + dy*pct);
              if( !(X==lastForX && Y==lastForY) ){ 
                  draw.ColorCell(X,Y); 
              }

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/WvuHL/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var context=canvas.getContext("2d");

    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;


    var wt = canvas.width;
    var ht = canvas.height;
    var down = false;

    var lastX=-20;
    var lastY=-20;

    var points=[];

    var draw = function (e) {};


    draw.started = false;

    var count;


    function interpolateLine(startX,startY,endX,endY){

        var lastForX;
        var lastForY;
        //
        for(var pct=0;pct<=1;pct+=0.06){
              var dx = endX-startX;
              var dy = endY-startY;
              var X = startX + dx*pct;
              var Y = startY + dy*pct;
              if( !(X==lastForX && Y==lastForY) ){ 
                  draw.ColorCell(X,Y); 
              }
              lastForX=X;
              lastForY=Y;
        }

    }


    draw.ColorCell=function(x,y){
        var rw = x - 1;
        var rh = y - 1;
        rw = rw - rw % 5 + 0.5;
        rh = rh - rh % 5 + 0.5;
        context.fillStyle = "red";
        context.fillRect( rw, rh, 5, 5);
    };


    draw.single = function (e) {
        var mouseX=parseInt(e.clientX-offsetX);
        var mouseY=parseInt(e.clientY-offsetY);
        draw.ColorCell(mouseX,mouseY);
    };


    // mousemove
    draw.move = function (e) {

        if(!down){return;}

        // get the current mouse position
        var mouseX=parseInt(e.clientX-offsetX);
        var mouseY=parseInt(e.clientY-offsetY);

        // if we haven't moved off this XY, then don't bother processing further
        if(mouseX==lastX && mouseY==lastY){return;}

        // When running the for-loop below,
        // many iterations will not find a new grid-cell
        // so lastForX/lastForY will let us skip duplicate XY
        var lastForX=lastX;
        var lastForY=lastY;

        // walk along a line from the last mousemove position
        // to the current mousemove position.
        // Then color any cells we pass over on our walk
        for(var pct=0;pct<=1;pct+=0.06){
              var dx = mouseX-lastX;
              var dy = mouseY-lastY;
              var X = parseInt(lastX + dx*pct);
              var Y = parseInt(lastY + dy*pct);
              if( !(X==lastForX && Y==lastForY) ){ 
                  draw.ColorCell(X,Y); 
              }
              lastForX=X;
              lastForY=Y;
        }

        // set this mouse position as starting position for next mousemove
        lastX=mouseX;
        lastY=mouseY;    
    };


    // mousedown
    draw.start = function (e) {
        e.preventDefault();
        lastX=parseInt(e.clientX-offsetX);
        lastY=parseInt(e.clientY-offsetY);
        down = true;
    };


    // mouseup
    draw.stop = function (e) {
        e.preventDefault();
        down = false;
    };


    function grid() {
        context.strokeStyle = "#f0f0f0";
        var h = 2.5;
        var p = 2.5;
        context.strokeRect(0.5, 0.5, 5, 5);
        for (i = 0; i < wt; i += p) {
            p *= 2;
            context.drawImage(canvas, p, 0);
        }
        for (i = 0; i < ht; i += h) {
            h *= 2;
            context.drawImage(canvas, 0, h);
        }
    }


    canvas.addEventListener('mouseup', draw.stop, false);
    canvas.addEventListener('mouseout', draw.stop, false);
    canvas.addEventListener('mousedown', draw.start, false);
    canvas.addEventListener('click', draw.single, false);
    canvas.addEventListener('mousemove', draw.move, false);

    grid();

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=501 height=301></canvas>
</body>
</html>

这篇关于优化画布绘制以形成连续路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆