JavaScript - 如何在 Canvas 上绘图并获取跟随鼠标的图像

标签 javascript image canvas mousemove

我从这个网站得到了很多帮助,但我似乎在将所有这些帮助放在一起时遇到了问题。具体来说,在 JS 中,我知道如何

a) 在 Canvas 上绘制图像

b) 创建一个跟随光标的矩形 ( Drawing on a canvas ) 和 ( http://billmill.org/static/canvastutorial/ball.html )

c) 绘制一个矩形作为背景

我不明白的是如何使用矩形作为背景,然后在 Canvas 上绘制图像(png)并让它跟随光标。

到目前为止我所拥有的看起来像这样:

var canvas = document.getElementByID('canvas');
var ctx = canvas.getContext('2d');
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var bgColor = '#FFFFFF';
var cirColor = '#000000';

clear = function() {
    ctx.clearRect(0, 0, WIDTH, HEIGHT);
}

drawIMG = function(x,y,r) {
    ctx.fillStyle = cirColor;
    ctx.beginPath();
    ctx.arc(x, y, r, 0, Math.PI*2, true);
    ctx.closePath();
    ctx.fill();
}

draw = function() {
    ctx.fillStyle = bgColor;
    clear();
    ctx.fillRect(0, 0, WIDTH, HEIGHT);
    drawIMG(150, 150, 30);
    drawIMG(300, 500, 12);
};

draw();

这将在 HTML5 Canvas 元素中绘制,其高度和宽度在 HTML 中指定,因此是可变的,在 (150,150) 和 (300,500) 处的两个黑色圆圈下方有一个 Canvas 大小的白色矩形。它做得非常好。

但是,我不知道如何让 JS 在光标后面绘制一个 .png 。就像我说的,我已经能够单独完成大部分步骤,但我不知道如何将它们组合起来。例如,我知道我必须这样做

img = new Image();

然后

img.src = 'myPic.png';

在某个时刻。它们需要与位置修饰符结合使用,例如

var xPos = pos.clientX;
var yPos = pos.clientY;
ctx.drawImage(img, xPos, yPos);

但我不知道如何在保留上面写的任何其他内容(特别是背景)的同时做到这一点。

感谢您的耐心阅读所有内容。我已经起床有一段时间了,我担心我的大脑太煎熬了,如果它脱光衣服做玛卡瑞娜,我也认不出答案。如果您能给我提供任何帮助,我将不胜感激,但我认为最好有一个可行的示例。我是编程宗教的入门者,并且仍然通过无耻地复制然后修改来学习最好的东西。

无论怎样,我提前对您表示乐观的感谢。

最佳答案

首先,我制作了跟随鼠标的动画紫色火焰。点击(编辑不再存在)here检查一下。

在继续之前,我建议您查看以下网站: http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/

William讲述canvas动画的基本技巧

http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ Paul Irish 谈论了以 60 fps 的速度旋转的递归动画函数。

使用他们的两个教程对于动画来说是一个很好的开始。

现在,根据我的理解,您需要一个“背景”和一个跟随光标的动画。您应该记住的第一件事是,一旦您在 Canvas 上绘制,无论您在其上绘制什么,都会替换。因此,我注意到会导致性能问题的第一件事是清除整个 Canvas ,而不是需要清除的内容。

您需要做的是记住移动元素的位置和大小。它采取什么形式并不重要,因为您的 clearRect() 应该完全删除它。

现在您可能会问,如果我在背景中的矩形上绘图会怎样。那么这会导致一个问题。你有两个解决方案。 (a) 清除背景并清除移动动画,然后以相同的顺序再次将它们绘制回来,或者 (b) 由于您知道背景永远不会移动,因此使用 position = Absolute 创建第二个 Canvas , z-index = -1 ,其位置与第一个 Canvas 相同。

这样您就不必担心背景,而可以专注于当前正在进行的动画。

<小时/>

现在回到编码部分,您要做的第一件事就是复制 Paul Irish 的递归函数:

(function() {
    var lastTime = 0;
    var vendors = ['webkit', 'moz'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame =
          window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

那么问题来了,怎么用呢?如果你去here您可以查看它是如何完成的:

function fireLoop()
{
    window.requestAnimationFrame(fireLoop);
    fire.update();
    fire.render();
    console.log('you spin me right round baby right round');
    follow();

}

这是我使用的循环。 Paul Irish 的函数每秒都会调用主循环。在这个循环中。我更新信息,选择需要绘制的正确动画,然后在 Canvas 上绘制(删除前一个元素后)。

follow函数是为动画选择下一个坐标的函数。您必须更改此部分,因为您不想移动 Canvas 而是移动动画。您可以使用相同的代码,但需要将位置应用到要在 Canvas 上绘制的位置。

function follow()
{
        $(fireCanvas).offset({
            top: getTop(),
            left: getLeft()
        });

}

function getTop()
{
    var off = $(fireCanvas).offset();
    if(off.top != currentMousePos.y - $(fireCanvas).height() + 10)
    {
        if(off.top > currentMousePos.y - $(fireCanvas).height() + 10)
        {
            return off.top - 1;
        }
        else
        {
            return off.top + 1;
        }
    }
}
function getLeft()
{
    var off = $(fireCanvas).offset();
    if(off.left != currentMousePos.x - $(fireCanvas).width()/2)
    {
        if(off.left > currentMousePos.x - $(fireCanvas).width()/2)
        {
            return off.left - 1;
        }
        else
        {
            return off.left + 1;
        }     
    }
}
var currentMousePos = { x: -1, y: -1 };
$(document).mousemove(function(event) {
    currentMousePos.x = event.pageX;
    currentMousePos.y = event.pageY;
});

如果您希望我深入了解任何具体内容,请告诉我。

关于JavaScript - 如何在 Canvas 上绘图并获取跟随鼠标的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24227275/

相关文章:

javascript - 某些链接上的 FancyBox 导航

javascript - 使用 One Drive API 的错误 JSON 请求

java - 如何使用小程序同时播放音频文件和显示图像?

jquery - mask 图像对于 div css 来说太大了

php - 转换 BBCode 文本时检查图像大小

javascript - Canvas.toDataURL 不适用于移动 Safari iOS?

javascript - 在 jQuery 中显示/隐藏子列表项

javascript - Promise 可以在 Node 中转发吗

javascript - 如何为模块编写 Typescript 类定义

iOS 阻止默认图像对焦