简体   繁体   中英

Get exact coordinates of canvas drawing?

I'm building an Android style pattern unlock for the web. I'm using the canvas element and based on the coordinates I color in a ring. However, the script isn't working correctly. It only changes the ring color for a tiny part of the ring.

Codepen: http://codepen.io/anon/pen/cxenk

Code:

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
var canvas, ctx, flag = false,
    prevX = 0,
    currX = 0,
    prevY = 0,
    currY = 0,
    dot_flag = false;

var x = "#000",
    y = 1;

function init() {
    canvas = document.getElementById('can');
    ctx = canvas.getContext("2d");
    w = canvas.width;
    h = canvas.height;

    canvas.addEventListener("mousemove", function (e) {
        findxy('move', e)
    }, false);
    canvas.addEventListener("mousedown", function (e) {
        findxy('down', e)
    }, false);
    canvas.addEventListener("mouseup", function (e) {
        findxy('up', e)
    }, false);
    canvas.addEventListener("mouseout", function (e) {
        findxy('out', e)
    }, false);
}

function coor1() {
    var element = document.getElementById('patternlockbutton1');
    var position = element.getBoundingClientRect();
    var x = position.left;
    var y = position.top;
    x = x;
    y = y;
    xend = x + 33;
    yend = y + 33;

    var coordinatesPoint1 = [];
    for(x ; x <= xend ; x++) {
        for(y ; y <= yend ; y++) {
            var coorXY = x+"-"+y;
            coordinatesPoint1.push(coorXY);     
        }
    }
    return coordinatesPoint1;
} 
function coor2() {
    var element = document.getElementById('patternlockbutton2');
    var position = element.getBoundingClientRect();
    var x = position.left;
    var y = position.top;
    x = x;
    y = y;
    xend = x + 33;
    yend = y + 33;

    var coordinatesPoint2 = [];
    for(x ; x <= xend ; x++) {
        for(y ; y <= yend ; y++) {
            var coorXY = x+"-"+y;
            coordinatesPoint2.push(coorXY);     
        }
    }
    return coordinatesPoint2;
} 
function coor3() {
    var element = document.getElementById('patternlockbutton3');
    var position = element.getBoundingClientRect();
    var x = position.left;
    var y = position.top;
    x = x;
    y = y;
    xend = x + 33;
    yend = y + 33;

    var coordinatesPoint3 = [];
    for(x ; x <= xend ; x++) {
        for(y ; y <= yend ; y++) {
            var coorXY = x+"-"+y;
            coordinatesPoint3.push(coorXY);     
        }
    }
    return coordinatesPoint3;
} 


function draw() {
    ctx.beginPath();
    ctx.moveTo(prevX, prevY);
    ctx.lineTo(currX, currY);
    ctx.strokeStyle = x;
    ctx.lineWidth = y;
    ctx.stroke();
    var i = 0;
    var k = 0;

var currentXY = currX+"-"+currY;
if ($.inArray(currentXY, coor1()) > 0) {
    $("#patternlockbutton1").addClass("touched");
} else if ($.inArray(currentXY, coor2()) > -1) {
    $("#patternlockbutton2").addClass("touched");
} else if ($.inArray(currentXY, coor3()) > -1) {
    $("#patternlockbutton3").addClass("touched");
} else if ($.inArray(currentXY, coor4()) > -1) {
    $("#patternlockbutton4").addClass("touched");
} 

ctx.closePath();
}

function erase() {
    var m = confirm("Want to clear");
    if (m) {
        ctx.clearRect(0, 0, w, h);
        document.getElementById("canvasimg").style.display = "none";
    }
}

function findxy(res, e) {
    if (res == 'down') {
        prevX = currX;
        prevY = currY;
        currX = e.clientX - canvas.offsetLeft;
        currY = e.clientY - canvas.offsetTop;

        flag = true;
        dot_flag = true;
        if (dot_flag) {
            ctx.beginPath();
            ctx.fillStyle = x;
            ctx.fillRect(currX, currY, 2, 2);
            ctx.closePath();
            dot_flag = false;
        }
    }
    if (res == 'up' || res == "out") {
        flag = false;
    }
    if (res == 'move') {
        if (flag) {
            prevX = currX;
            prevY = currY;
            currX = e.clientX - canvas.offsetLeft;
            currY = e.clientY - canvas.offsetTop;
            console.log(currX, currY);
            draw();
        }
    }
}

function print(){
    var c = document.getElementById("can");
    var ctx = c.getContext("2d");
    var imgData = ctx.getImageData(10,10,50,50);
    console.log(imgData);
}

</script>
<style>
    .patternlockbutton{
        border-color: red;
        background-color: transparent;
        background-repeat:no-repeat;
        display:block;
        width:33px;
        height:33px;
        float:left;
        margin:26px;
        -ms-touch-action: none;
        border-style: solid;
        border-width: 5px;
        -webkit-border-top-left-radius: 50px;
        -webkit-border-top-right-radius: 50px;
        -moz-border-radius-topleft: 50px;
        -moz-border-radius-topright: 50px;
        border-top-left-radius: 50px;
        border-top-right-radius: 50px;
        -webkit-border-bottom-left-radius: 50px;
        -webkit-border-bottom-right-radius: 50px;
        -moz-border-radius-bottomleft: 50px;
        -moz-border-radius-bottomright: 50px;
        border-bottom-left-radius: 50px;
        border-bottom-right-radius: 50px;
    }
    .touched{
        border-color: red;
        background-color: red;
        background-repeat:no-repeat;
        display:block;
        width:33px;
        height:33px;
        float:left;
        margin:26px;
        -ms-touch-action: none;
        border-width: 5px;
        -webkit-border-top-left-radius: 50px;
        -webkit-border-top-right-radius: 50px;
        -moz-border-radius-topleft: 50px;
        -moz-border-radius-topright: 50px;
        border-top-left-radius: 50px;
        border-top-right-radius: 50px;
        -webkit-border-bottom-left-radius: 50px;
        -webkit-border-bottom-right-radius: 50px;
        -moz-border-radius-bottomleft: 50px;
        -moz-border-radius-bottomright: 50px;
        border-bottom-left-radius: 50px;
        border-bottom-right-radius: 50px;
    }
    #can {
        position: absolute;
        left: 0;
        top: 0;
        z-index: 99;
        display: block;
    }
</style>
</head>
<body onload="init()">
    <div style="width:300px;height:400px; position: relative;">
        <div class="patternlockbutton" id="patternlockbutton1"></div>
        <div class="patternlockbutton" id="patternlockbutton2"></div>
        <div class="patternlockbutton" id="patternlockbutton3"></div>
        <div class="patternlockbutton" id="patternlockbutton4"></div>
        <div class="patternlockbutton" id="patternlockbutton5"></div>
        <div class="patternlockbutton" id="patternlockbutton6"></div>
        <div class="patternlockbutton" id="patternlockbutton7"></div>
        <div class="patternlockbutton" id="patternlockbutton8"></div>
        <div class="patternlockbutton" id="patternlockbutton9"></div>
        <canvas id="can" width="300px" height="400px"></canvas>
    </div>
    <input type="button" value="clear" id="clr" size="23" onclick="erase()" style="position:absolute;top:55%;left:15%;">
    <button onclick="print()">Console.log</button>
</body>
</html>

There are multiple issues in your code, the biggest one is all the code duplication.

The quickest probably fix for your issue is making sure that your coordinates are integer values by rounding them.

var x = Math.round(position.left);
var y = Math.round(position.top);

That should fix the issue you are facing right now.

However , there are a lot of ways you can make your code work better. For example, I would remove all the coorX functions are write a general one. I would also check the intervals in a different way. Quick example below where I check the intervals in a simpler way.

function buttonCoords(id) { // replaces the coorX functions, takes element id as parameter
    var element = document.getElementById(id);
    var position = element.getBoundingClientRect();    
    var x = position.left;
    var y = position.top;
    xend = x + 33;
    yend = y + 33;

    return {
        top: y,
        bottom: yend,
        left: x,
        right: xend
    };    
}

and in the draw() function, you check the coordinates something like this:

var coords = buttonCoords('patternlockbutton1')
if (currX >= coords.left && currX <= coords.right && currY >= coords.top && currY <= coords.bottom) {
    $("#patternlockbutton1").addClass("touched");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM