【问题标题】:HTML Canvas Compositing: Reveal canvas image underneath another canvasHTML Canvas Compositing:在另一个画布下显示画布图像
【发布时间】:2021-12-11 11:50:13
【问题描述】:

我是 HTML 画布元素的新手,但最近两天一直在使用它。我在 Django 中工作,我的任务是显示隐藏在另一个画布(纯白色矩形)下方的图像(加载到画布上)当鼠标在画布堆栈上移动时。两个画布的宽度和高度完全相同。

我还希望能够在“擦除”顶部画布(显示下方的图像)时设置光标的形状(方形或圆形)和尺寸。

我看过the answer to a similar question,但对链接小提琴中编写的javascript有点迷茫。我的 HandleMouseMove 函数是我最初尝试识别顶部画布中的鼠标位置。任何指导将不胜感激,并提前致谢。这是我目前所拥有的:

window.onload = function() {
    //Create Bottom canvas & context
    var canvas = document.getElementById('canvas');
    var ctxB = canvas.getContext('2d');
    
    //Create Top canvas & context
    var canvas2 = document.getElementById('canvas2');
    var ctxT = canvas2.getContext('2d');

    //Set waterfall image variable
    var waterfall = document.getElementById('waterfall');

    //Set canvas w&h properties
    canvas.width = canvas2.width = waterfall.width;
    canvas.height = canvas2.height = waterfall.height;

    //Populate Bottom canvas with image
    ctxB.drawImage(waterfall, 0, 0, canvas.width, canvas.height);

    //Populate Top canvas with white rectangle
    ctxT.fillStyle = "white";
    ctxT.fillRect(0, 0, canvas2.width, canvas2.height);
}
        
//Show Coordinates of mouse on Top canvas
function HandleMouseMove(event) {
    var x = event.clientX;
    var y = event.clientY;
    var coords = x + ", " + y;
    document.getElementById("demo").innerHTML = coords;  
}

//Erase Top canvas to reveal waterfall
#stack {
    position: relative;
}
#stack > canvas {
    position: absolute;
    display: block;
    width: 40%;
    margin-left: auto;
    margin-right: auto;
    margin-top: 25px;
}
<!DOCTYPE html>
{% load static %}
<html>
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="{% static 'entrance/entrance.css' %}">
        <script src="{% static 'entrance/entrance.js' %}"></script>
    </head>

    <body>
        <p hidden>
            <img src="{% static 'entrance/Waterfall.jpg' %}" alt="issue here" id="waterfall" />
        </p>
        <p id="demo"></p>
        <div id="stack">
            <canvas id="canvas"></canvas>
            <canvas id="canvas2" onmousemove="HandleMouseMove(event)"></canvas>
        </div>
    </body>
</html>

【问题讨论】:

    标签: html canvas mousemove


    【解决方案1】:

    window.onload = function() {
        //Create Bottom canvas & context
        var canvas = document.getElementById('canvas');
        var ctxB = canvas.getContext('2d');
        
        //Create Top canvas & context
        var canvas2 = document.getElementById('canvas2');
        var ctxT = canvas2.getContext('2d');
    
        //Set waterfall image variable
        var waterfall = document.getElementById('waterfall');
    
        //Set canvas w&h properties
        canvas.width = canvas2.width = waterfall.width;
        canvas.height = canvas2.height = waterfall.height;
    
        //Populate Bottom canvas with image
        ctxB.drawImage(waterfall, 0, 0, canvas.width, canvas.height);
    
        //Populate Top canvas with white rectangle
        ctxT.fillStyle = "white";
        ctxT.fillRect(0, 0, canvas2.width, canvas2.height);
        
    
        canvas2.addEventListener('mousemove', event => {
          var x = event.offsetX;
          var y = event.offsetY;
          var coords = x + ", " + y;
          document.getElementById("demo").innerHTML = coords;
    
          //Erase Top canvas to reveal waterfall
          const eraseSize = 15;
          ctxT.clearRect(x - eraseSize/2, y - eraseSize/2, eraseSize, eraseSize);
        })
    }
    #stack {
        position: relative;
    }
    #stack > canvas {
        position: absolute;
        display: block;
        margin-left: auto;
        margin-right: auto;
        margin-top: 25px;
    }
    <p hidden>
        <img src="http://vignette4.wikia.nocookie.net/plantsvszombies/images/8/8f/Kiwi_bird.png" alt="issue here" id="waterfall" />
    </p>
    <p id="demo"></p>
    <div id="stack">
        <canvas id="canvas"></canvas>
        <canvas id="canvas2"></canvas>
    </div>

    若要改变形状,请为顶部画布设置globalCompositeOperation = 'destination-out'

    ctxT.globalCompositeOperation = 'destination-out';
    

    然后画出你想要的任何形状。比如一个圆圈:

    ctxT.beginPath();
    ctxT.arc(x, y, eraseSize, 0, Math.PI*2, false);
    ctxT.fill();
    ctxT.closePath();
    

    而不是

    ctxT.clearRect(x - eraseSize/2, y - eraseSize/2, eraseSize, eraseSize);
    

    【讨论】:

    • 非常感谢!这正是我所需要的,而且我喜欢代码量如此之少——非常优雅。再次感谢您抽出宝贵时间提供帮助!
    猜你喜欢
    • 2019-05-29
    • 2015-08-12
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    相关资源
    最近更新 更多