简体   繁体   English

鼠标在画布上跟随的图像

[英]Image following a mouse on a canvas

I want to have an image follow the mouse around the canvas, which is fairly easy, but the catch is that I want my canvas to change with screen resolution (it is set using CSS to be 70vw). 我想让图像跟随鼠标围绕在画布上,这非常简单,但是要注意的是,我希望画布以屏幕分辨率进行更改(使用CSS设置为70vw)。

When the resolution decreases and the window becomes smaller this means that using a normal method of using clientX doesn't work. 当分辨率降低且窗口变小时,这意味着使用常规的clientX方法无效。 My code so far is this: 到目前为止,我的代码是这样的:

var mouseX = e.clientX/document.documentElement.clientWidth * 1920;
var mouseY = e.clientY/document.documentElement.clientHeight * 943;

This tries to convert the users clientX into the value it would be on a 1920x1080 monitor. 这试图将用户clientX转换为1920x1080监视器上的值。 However, this isn't really accurate and doesn't work very well on even 1920x1080 monitors. 但是,这并不是很准确,即使在1920x1080显示器上也无法很好地工作。 Any help would be appreciated. 任何帮助,将不胜感激。

I took my snippet from my answer to create a full screen canvas . 我从答案中摘录了片段,以创建全屏画布

I added this for mouse movement: 我为鼠标移动添加了此代码:

let User = { x: 0, y: 0 };

//controles if the mouse is moving
window.addEventListener(
    "mousemove",
    e => {
        User.x = e.clientX;
        User.y = e.clientY;
    },
    false
);

Uncomment: cvs.ctx.drawImage(image, User.x, User.y); 取消注释: cvs.ctx.drawImage(image, User.x, User.y); in the ShowImage() function to draw an image at the mouse x and y position. ShowImage()函数中可以在鼠标的x和y位置绘制图像。
Mind to replace the path of the image source: image.src = "Your/Path/To/Image.png"; 注意替换图像源的路径: image.src = "Your/Path/To/Image.png";

 /** * @author RensvWalstijn. GitHub: https://github.com/RensvWalstijn * Sets the canvas properties. * @param {object} Cvs Give the html canvas Id. * @param {boolean} Fullscreen Change the canvas fullscreen default false. * @param {string} Dimension Change the canvas dimension default "2d". * @return {object} */ function NewCanvas(cvs, fullscreen, dimension) { if (!dimension) dimension = "2d"; var ctx = cvs.getContext(dimension); if (fullscreen) { cvs.style.position = "fixed"; cvs.style.left = cvs.x = 0; cvs.style.top = cvs.y = 0; } else { var rect = cvs.getBoundingClientRect(); cvs.x = rect.left; cvs.y = rect.top; } cvs.ctx = ctx; cvs.dimension = dimension; cvs.fullscreen = fullscreen; return cvs; } /** * @author RensvWalstijn. GitHub: https://github.com/RensvWalstijn * Updates the canvas width and hight. * @param {object} Cvs NewCanvas() object. * @param {boolean} Clear Change the canvas clear default true. */ function UpdateCvs(cvs) { if (cvs.fullscreen) { //if the width is not the same resize the canvas width if (window.innerWidth != cvs.width) { cvs.width = window.innerWidth; } //if the height is not the same resize the canvas height if (window.innerHeight != cvs.height) { cvs.height = window.innerHeight; } } else { let rect = cvs.getBoundingClientRect(); cvs.x = rect.left; cvs.y = rect.top; } } function ClearCvs(cvs) { if (cvs.dimension == "2d") // set fillRect to clearRect to clear all of the canvas // fillRect is used here to show the full canvas cvs.ctx.fillRect(0, 0, cvs.width, cvs.height); } /** * @author RensvWalstijn. GitHub: https://github.com/RensvWalstijn * get html element by id. * @param {string} id give the html element id. * @return {object} document.getElementById(id); */ function GetId(id) { return document.getElementById(id) } // To create your canvas object. var canvas = NewCanvas(GetId("yourCanvasId"), true); // If you want to update your canvas size use this: window.addEventListener("resize", function() { UpdateCvs(canvas); }); let User = { x: 0, y: 0 }; //controles if the mouse is moving window.addEventListener( "mousemove", e => { User.x = e.clientX; User.y = e.clientY; }, false ); // Set it to current width UpdateCvs(canvas); ClearCvs(canvas); // create an image let image = new Image(); image.src = "Your/Path/To/Image.png"; function ShowImage(cvs) { // Use this line to draw your image. // cvs.ctx.drawImage(image, User.x, User.y); // Shows where your image will be drawn. cvs.ctx.clearRect(User.x, User.y, 100, 100); } function Update() { ClearCvs(canvas); ShowImage(canvas); // keeps it looping window.requestAnimationFrame(Update) } // Init the loop Update(); 
 <canvas id="yourCanvasId"></canvas> 

You can't scale the canvas using CSS in the way that you think. 您无法以您认为的方式使用CSS缩放画布。 A canvas is basically a more advanced image. 画布基本上是一种更高级的图像。 Scaling the canvas via CSS just stretches the canvas the same way an image would stretch. 通过CSS缩放画布只会像缩放图像一样拉伸画布。 To change the canvas height and width , you need to change it's height and width attributes in the tag or via code. 要更改画布的heightwidth ,您需要在标记中或通过代码更改其heightwidth属性。 This will physically change the canvas to the size that you want without scaling and/or stretching. 这将物理上将画布更改为所需的尺寸,而无需缩放和/或拉伸。

That being said, we can use this to watch for window size changes and resize the canvas when the window changes. 话虽如此,我们可以使用它来监视窗口大小的更改,并在窗口更改时调整画布的大小。

window.addEventListener('resize', e => {
  canvas.width = window.innerWidth
  canvas.height = window.innerHeight
})

With some basic math, we can calculate what a 70% width would be, it would be done like this 通过一些基本的数学运算,我们可以计算出70%的宽度,它将像这样完成

window.addEventListener('resize', e => {
  canvas.width = window.innerWidth * 0.7
  canvas.height = window.innerHeight
})

The next thing we need to do is get the local position of the mouse on the canvas, which can be done using mousePosition - canvasOffset like this 我们需要做的下一件事是获取鼠标在画布上的局部位置,可以使用mousePosition - canvasOffset这样完成

let x = e.clientX - canvas.offsetLeft
let y = e.clientY - canvas.offsetTop

When all is said and done, we end up with something like this (To see it in action press run then click on Full Page and you will see the canvas resize): 说完所有内容后,我们将得到以下内容(要在运行中查看它,请按运行,然后单击“整Full Page ,您将看到画布的大小调整):

 const canvas = document.querySelector('canvas') const ctx = canvas.getContext('2d') // Set the inital height and width of the canvas canvas.width = window.innerWidth canvas.height = window.innerHeight canvas.addEventListener('mousemove', e => { ctx.clearRect(0, 0, canvas.width, canvas.height) // Get the local x/y coordinates of the mouse on the canvas let x = e.clientX - canvas.offsetLeft let y = e.clientY - canvas.offsetTop // Draw a dot where the mouse is ctx.beginPath(); ctx.arc(x, y, 10, 0, 2 * Math.PI, false); ctx.fillStyle = 'white'; ctx.fill(); }) // Update the height and width when the window size changes window.addEventListener('resize', e => { canvas.width = window.innerWidth canvas.height = window.innerHeight }) 
 body { padding: 0; margin: 0; } canvas { background-color: black; display: block; } 
 <canvas></canvas> 

In this example below, we use a canvas that is 70% the width and height of the screen and center it with CSS. 在下面的示例中,我们使用屏幕宽度和高度的70%的画布,并使用CSS将其居中。 However, we never touch the height/width with css because it will mess up the canvas' coordinate system. 但是,我们永远不要用css触摸height/width ,因为它会弄乱画布的坐标系。 This part is done with JavaScript. 这部分是使用JavaScript完成的。

 const canvas = document.querySelector('canvas') const ctx = canvas.getContext('2d') // Set the inital height and width of the canvas canvas.width = window.innerWidth * 0.7 canvas.height = window.innerHeight * 0.7 canvas.addEventListener('mousemove', e => { ctx.clearRect(0, 0, canvas.width, canvas.height) // Get the local x/y coordinates of the mouse on the canvas let x = e.clientX - canvas.offsetLeft let y = e.clientY - canvas.offsetTop // Draw a dot where the mouse is ctx.beginPath(); ctx.arc(x, y, 10, 0, 2 * Math.PI, false); ctx.fillStyle = 'white'; ctx.fill(); }) // Update the height and width when the window size changes window.addEventListener('resize', e => { canvas.width = window.innerWidth * 0.7 canvas.height = window.innerHeight * 0.7 }) 
 body { padding: 0; margin: 0; } canvas { background-color: black; display: block; position: absolute; left: 0; right: 0; bottom: 0; top: 0; margin: auto; } 
 <canvas></canvas> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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