dan*_*ski 5 javascript css jquery canvas html5-canvas
我试图用箭头指向我的鼠标光标在javascript中.现在它只是猛烈旋转,而不是指向光标.
这是我的代码的小提琴:https://jsfiddle.net/pk1w095s/
以下是自己的代码:
var cv = document.createElement('canvas');
cv.width = 1224;
cv.height = 768;
document.body.appendChild(cv);
var rotA = 0;
var ctx = cv.getContext('2d');
var arrow = new Image();
var cache;
arrow.onload = function() {
cache = this;
ctx.drawImage(arrow, cache.width/2, cache.height/2);
};
arrow.src = 'https://d30y9cdsu7xlg0.cloudfront.net/png/35-200.png';
var cursorX;
var cursorY;
document.onmousemove = function(e) {
cursorX = e.pageX;
cursorY = e.pageY;
ctx.save(); //saves the state of canvas
ctx.clearRect(0, 0, cv.width, cv.height); //clear the canvas
ctx.translate(cache.width, cache.height); //let's translate
var centerX = cache.x + cache.width / 2;
var centerY = cache.y + cache.height / 2;
var angle = Math.atan2(e.pageX - centerX, -(e.pageY - centerY)) * (180 / Math.PI);
ctx.rotate(angle);
ctx.drawImage(arrow, -cache.width / 2, -cache.height / 2, cache.width, cache.height); //draw the image
ctx.restore(); //restore the state of canvas
};
Run Code Online (Sandbox Code Playgroud)
在第一个例子中,摆脱转换到度 - 函数Math.atan2
和ctx.rotate
函数都需要弧度.
这修复了疯狂旋转 - 你仍然有一些数学错误,通过从数学中分割出绘图最容易整理出来.
下面的函数绘制旋转给定角度的箭头:
// NB: canvas rotations go clockwise
function drawArrow(angle) {
ctx.clearRect(0, 0, cv.width, cv.height);
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate(-Math.PI / 2); // correction for image starting position
ctx.rotate(angle);
ctx.drawImage(arrow, -arrow.width / 2, -arrow.height / 2);
ctx.restore();
}
Run Code Online (Sandbox Code Playgroud)
并且onmove
处理程序只是指出了方向.
document.onmousemove = function(e) {
var dx = e.pageX - centerX;
var dy = e.pageY - centerY;
var theta = Math.atan2(dy, dx);
drawArrow(theta);
};
Run Code Online (Sandbox Code Playgroud)
请注意,在画布上,Y轴指向下方(与正常的笛卡尔坐标相反),因此旋转最终顺时针方向而不是逆时针方向.
工作演示在https://jsfiddle.net/alnitak/5vp0syn5/
由于现有的(Alnitak 的)答案存在一些问题。
pageX
、pageY
属性是相对于页面左上角的,而不是整个文档。如果您滚动页面,则箭头将不再指向鼠标。或者您可以使用鼠标事件 clientX, clientY 属性将鼠标坐标保存到客户端(整个)页面左上角,因此您不需要更正滚动。这是一个“最佳实践”解决方案。
核心功能绘制一个看一个点的图像lookx
,looky
var drawImageLookat(img, x, y, lookx, looky){
ctx.setTransform(1, 0, 0, 1, x, y); // set scale and origin
ctx.rotate(Math.atan2(looky - y, lookx - x)); // set angle
ctx.drawImage(img,-img.width / 2, -img.height / 2); // draw image
ctx.setTransform(1, 0, 0, 1, 0, 0); // restore default not needed if you use setTransform for other rendering operations
}
Run Code Online (Sandbox Code Playgroud)
该演示展示了如何使用requestAnimationFrame
以确保仅在 DOM 准备好渲染时才渲染,getBoundingClientRect
用于获取鼠标相对于画布的位置。
左上角的计数器显示有多少鼠标事件已触发而无需渲染。非常缓慢地移动鼠标,计数器不会增加。以正常速度移动鼠标,您会看到每隔几秒钟就可以生成 100 个不需要的渲染事件。第二个数字是大约在 1/1000 秒内节省的时间,百分比是随着时间的推移节省的渲染时间。
var drawImageLookat(img, x, y, lookx, looky){
ctx.setTransform(1, 0, 0, 1, x, y); // set scale and origin
ctx.rotate(Math.atan2(looky - y, lookx - x)); // set angle
ctx.drawImage(img,-img.width / 2, -img.height / 2); // draw image
ctx.setTransform(1, 0, 0, 1, 0, 0); // restore default not needed if you use setTransform for other rendering operations
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2216 次 |
最近记录: |