问题描述
我正在努力解决这个问题。我有一个在画布上随机移动的箭头。它平稳旋转并向下一个X / Y位置移动。大。如何让我的圆形物体始终出现在箭头前面;就好像箭头在它的尖端上握住圆圈一样。
I'm struggling with the maths on this one. I have an arrow that moves randomly around the canvas. It rotates smoothly and moves towards the next X/Y position. Great. How can I make my circle object always appear just in front of the arrow; like as if the arrow is holding the circle on it's tip.
这是我的代码:
player.prototype.draw = function (w, h, ctx) {
ctx.beginPath();
ctx.save();
ctx.fillStyle = '#E50000';
if (this.XPercent !== 0 && this.YPercent !== 0) {
// ** moves at correct angle (no rotation involved)
// Get the difference between the points
var tx = this.nextXPercent - this.XPercent;
var ty = this.nextYPercent - this.YPercent;
// Add the x and y areas then get the square root
var dist = Math.sqrt(tx * tx + ty * ty);
var newX = (tx / dist) * 0.1;
var newY = (ty / dist) * 0.1;
this.XPercent = this.XPercent + (isNaN(newX) ? 0 : newX);
this.YPercent = this.YPercent + (isNaN(newY) ? 0 : newY);
}
var currentX = (w / 100) * this.XPercent;
var currentY = (h / 100) * this.YPercent;
ctx.translate(currentX - (playerWidth / 2), currentY);
currentX = (playerWidth / 2);
currentY = 0;
// now rotate smoothly
ctx.rotate(this.getRotation2(w, h, ctx) * Math.PI / 180);
ctx.moveTo(currentX, currentY);
ctx.lineTo(currentX - playerWidth, currentY - (playerHeight / 2));
ctx.lineTo(currentX - playerWidth, currentY + (playerHeight / 2));
ctx.fill();
ctx.restore();
ctx.closePath();
};
上面的箭头移动而没有旋转。我的轮换方法如下:
The above moves the arrow around with no rotation. My rotation method is as follows:
player.prototype.getRotation2 = function (w, h, ctx) {
var y2 = this.nextYPercent;
var y1 = this.YPercent.toFixed(0);
var x2 = this.nextXPercent;
var x1 = this.XPercent.toFixed(0);
if (x1 == x2 && y2 == y1) {
return this.angle;
}
var Xdiff = y2 - y1;
var Ydiff = x2 - x1;
this.angle %= 360;
var rads = Math.atan2(y2 - y1, x2 - x1);
var targetAngle = rads * (180 / Math.PI);
targetAngle = (targetAngle + 360) % 360;
if (this.angle != targetAngle) {
var netAngle = (this.angle - targetAngle + 360) % 360;
var delta = Math.min(Math.abs(netAngle - 360), netAngle, 5);
var sign = (netAngle - 180) >= 0 ? 1 : -1;
this.angle += sign * delta + 360;
this.angle %= 360;
if (this.hasBall) {
// This is where we should position the circle at correct angle
gameBall.XPercent = this.XPercent + ???
gameBall.YPercent = this.YPercent + ???
}
}
return this.angle;
};
推荐答案
继续使用箭头和向右在箭头的末尾画出球。
Just continue using the transformation you have for the arrow and go "right" to draw the ball at the end of the arrow.
我建议将绘图和转换操作分开。这样你就可以单向绘制箭头,而不必担心它的位置或旋转。可以使用标志作为方法的参数来添加球。
I would suggest separating the drawing and transformation operations. This way you can draw the arrow is a single way without worrying about its location or rotation. The ball can be added using a flag as argument to the method.
示例
var ctx = c.getContext("2d"), radius = 7;
function drawShape() {
// Always draw with (0,0) as basis, this will rotate at tail.
// If rotate at head, just offset the values so head is at (0,0)
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(50, 0);
ctx.moveTo(50, 0);
ctx.lineTo(40, -5);
ctx.lineTo(40, 5);
ctx.fill();
// add circle at tip
ctx.moveTo(60 + radius, 0);
ctx.arc(60, 0, radius, 0, 6.28);
ctx.stroke();
}
// just to add action for the demo
window.onmousemove = function(e) {
var rect = c.getBoundingClientRect(),
x = e.clientX - rect.left,
y = e.clientY - rect.top,
dx = x - c.width*0.5,
dy = y - c.height*0.5,
a = Math.atan2(dy, dx);
ctx.clearRect(0,0,c.width,c.height)
ctx.translate(c.width*0.5, c.height*0.5);
ctx.rotate(a);
drawShape();
ctx.setTransform(1,0,0,1,0,0);
}
<canvas id=c></canvas>
这篇关于如何在Javascript& ;; 2d中在对象前面绘制圆圈HTML5画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!