Canvas Scratchcard ..坐标

时间:2017-07-18 08:58:15

标签: canvas responsive scratchcard

你好,任何人都可以帮帮我。

所以我使用canvas创建一个刮刮卡效果。当我通过使用CSS将宽度设置为100%来使画布响应时,划痕坐标似乎关闭了。有没有人知道如何解决这个问题,因为我已将画布宽度设置为与图像宽度相同的宽度?

(function() {

var image = { 
  'back': { 'url':'DAY1.jpg', 'img':null },
    'front': { 'url':'COVER.jpg', 'img':null }
};

var canvas = {'temp':null, 'draw':null}; 

var mouseDown = false;


function getLocalCoords(elem, ev) {
    var ox = 0, oy = 0;
    var first;
    var pageX, pageY;


    while (elem != null) {
        ox += elem.offsetLeft;
        oy += elem.offsetTop;
        elem = elem.offsetParent;
    }

    if (ev.hasOwnProperty('changedTouches')) {
        first = ev.changedTouches[0];
        pageX = first.pageX;
        pageY = first.pageY;
    } else {
        pageX = ev.pageX;
        pageY = ev.pageY;
    }

    return { 'x': pageX - ox, 'y': pageY - oy };
}


function recompositeCanvases() {
    var main = document.getElementById('maincanvas');
    var tempctx = canvas.temp.getContext('2d');
    var mainctx = main.getContext('2d');

    canvas.temp.width = canvas.temp.width; 

    tempctx.drawImage(canvas.draw, 0, 0);


    tempctx.globalCompositeOperation = 'source-atop';
    tempctx.drawImage(image.back.img, 0, 0);


    mainctx.drawImage(image.front.img, 0, 0);
    mainctx.drawImage(canvas.temp, 0, 0);
}


function scratchLine(can, x, y, fresh) {
    var ctx = can.getContext('2d');
    ctx.lineWidth = 50;
    ctx.lineCap = ctx.lineJoin = 'round';
    ctx.strokeStyle = '#f00'; // can be any opaque color
    if (fresh) {
        ctx.beginPath();

        ctx.moveTo(x+0.01, y);
    }
    ctx.lineTo(x, y);
    ctx.stroke();
}



function setupCanvases() {
    var c = document.getElementById('maincanvas');

    c.width = image.back.img.width;
    c.height = image.back.img.height;


    canvas.temp = document.createElement('canvas');
    canvas.draw = document.createElement('canvas');
    canvas.temp.width = canvas.draw.width = c.width;
    canvas.temp.height = canvas.draw.height = c.height;

    recompositeCanvases();

    function mousedown_handler(e) {
        var local = getLocalCoords(c, e);
        mouseDown = true;

        scratchLine(canvas.draw, local.x, local.y, true);
        recompositeCanvases();

        if (e.cancelable) { e.preventDefault(); } 
        return false;
    };


    function mousemove_handler(e) {
        if (!mouseDown) { return true; }

        var local = getLocalCoords(c, e);

        scratchLine(canvas.draw, local.x, local.y, false);
        recompositeCanvases();

        if (e.cancelable) { e.preventDefault(); } 
        return false;
    };


    function mouseup_handler(e) {
        if (mouseDown) {
            mouseDown = false;
            if (e.cancelable) { e.preventDefault(); } 
            return false;
        }

        return true;
    };

    c.addEventListener('mousedown', mousedown_handler, false);
    c.addEventListener('touchstart', mousedown_handler, false);

    window.addEventListener('mousemove', mousemove_handler, false);
    window.addEventListener('touchmove', mousemove_handler, false);

    window.addEventListener('mouseup', mouseup_handler, false);
    window.addEventListener('touchend', mouseup_handler, false);
}


function loadingComplete() {
    var loading = document.getElementById('loading');
    var main = document.getElementById('main');

    loading.className = 'hidden';
    main.className = '';
}


function loadImages() {
    var loadCount = 0;
    var loadTotal = 0;
    var loadingIndicator;

    function imageLoaded(e) {
        loadCount++;

        if (loadCount >= loadTotal) {
            setupCanvases();
            loadingComplete();
        }
    }

    for (k in image) if (image.hasOwnProperty(k))
        loadTotal++;

    for (k in image) if (image.hasOwnProperty(k)) {
        image[k].img = document.createElement('img'); 
        image[k].img.addEventListener('load', imageLoaded, false);
        image[k].img.src = image[k].url;
    }
}


window.addEventListener('load', function() {
    var resetButton = document.getElementById('resetbutton');

    loadImages();

    resetButton.addEventListener('click', function() {

            canvas.draw.width = canvas.draw.width;
            recompositeCanvases()

            return false;
        }, false);

}, false);

})();

1 个答案:

答案 0 :(得分:0)

您需要更改鼠标/触摸坐标比例以匹配画布分辨率

// in your function
function getLocalCoords(elem, ev) {
    var ox = 0, oy = 0;
    var first;
    var pageX, pageY;

    //==============================================================
    // Add the following to get the bounding box of the canvas
    // assuming elem is the canvas
    const bounds = elem.getBoundingClientRect();
    const canEl = elem;  // save canvas element for use further down
    //--------------------------------------------------------------

    // your code....
    while (elem != null) {
        ox += elem.offsetLeft;
        oy += elem.offsetTop;
        elem = elem.offsetParent;
    }

    if (ev.hasOwnProperty('changedTouches')) {
        first = ev.changedTouches[0];
        pageX = first.pageX;
        pageY = first.pageY;
    } else {
        pageX = ev.pageX;
        pageY = ev.pageY;
    }

    //==============================================================
    // add these two lines to scale to match the canvas coordinates
    pageX = ((pageX - ox) / bounds.width) * canEl.width;
    pageY = ((pageY - oy) / bounds.height) * canEl.height;

    // and modify your code to
    return { 'x': pageX, 'y': pageY };
    //--------------------------------------------------------------
}