我有以下分配问题,我很难解决:
到目前为止,我已经创建了两个圆圈,但是,我在制作它的部分时遇到了问题,因此可以拖动两个圆圈但不能离开画布。我非常确定这应该是通过事件监听器来完成的,但我无法弄清楚如何对此进行编码。非常感谢一些帮助或见解。
到目前为止我所拥有的:
<!DOCTYPE html>
<html>
<head>
<script>
window.onload = draw;
function draw(){
var canvas = document.getElementById("circleCanvas");
var ctx = canvas.getContext("2d");
ctx.arc(100,75,50,0,2*Math.PI);
ctx.fillStyle = "green";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.arc(100,200,50,0,2*Math.PI);
ctx.fillStyle = "blue";
ctx.fill();
ctx.stroke();
ctx.closePath();
}
</script>
</head>
<body>
<canvas id="circleCanvas" width="500" height="500"></canvas>
</body>
</html>
&#13;
答案 0 :(得分:2)
通过聆听鼠标事件创建鼠标对象并设置鼠标位置和按钮状态。
创建一个圆圈数组,描述每个圆圈的位置和大小。
创建一个绘制圆的函数。在该功能中,您可以检查圆圈是否超出界限,如果是,则移动它。
创建一个位置搜索功能,可以检查每个圆圈以及它与点之间的距离。如果圆圈位于该点之下(dist
创建一个动画循环,每隔1/60秒重绘一次画布。在该检查中,鼠标是否已关闭。如果是,而不是拖动任何东西,看看鼠标是否在圆圈上。如果选择该圈子进行拖动。当鼠标向上时,放下圆圈。
由于这是一项任务,我们不应该只给你解决方案。但是,当我们不被允许寻求帮助时,学校是生命中的唯一时间,也就是我们最需要帮助的时候。我认为你对学习和学习感兴趣,在很多情况下都是最好的。
如果您有任何疑问,请询问
"use strict";
const canvas = document.createElement("canvas");
canvas.height = innerHeight;
canvas.width = innerWidth;
canvas.style.position = "absolute";
canvas.style.top = canvas.style.left = "0px";
const ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
ctx.font = "48px arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
var w = canvas.width;
var h = canvas.height;
var renderUpdate = true; // flags if there is a need to render
var globalTime = 0;
const mouse = {
x:0,y:0,button:false
};
const circles = [{
x : 100,
y : 100,
radius : 40,
col : "red",
lineWidth : 4,
highlight : false,
},{
x : 200,
y : 100,
radius : 40,
col : "green",
lineWidth : 4,
highlight : false,
},
];
var closestCircle; // holds result of function findClosestCircle2Point
const drag = { // if dragging this holds the circle being dragged
circle : null,
offsetX : 0, // distance from mouse to circle center when drag started
offsetY : 0,
}
const message = { // a message to inform of problems.
time : 120, // 60 ticks per second
text: "Click drag circles",
}
// adds mouse events listeners
canvas.addEventListener("mousemove",mouseEvent)
canvas.addEventListener("mousedown",mouseEvent)
canvas.addEventListener("mouseup",mouseEvent)
// function to handle all mouse events
function mouseEvent(e){
var m = mouse;
var bounds = canvas.getBoundingClientRect();
m.x = e.clientX - bounds.left;
m.y = e.clientY - bounds.top;
if(e.type === "mousedown"){
m.button = true;
}else if(e.type === "mouseup"){
m.button = false;
}
renderUpdate = true; // flag that there could be a render change.
}
// this finds the closest circle under x,y if nothing under the point then retVal.circle = null
function findClosestCircle2Point(x, y, retVal){
if(retVal === undefined){
retVal = {};
}
var minDist = Infinity;
var dist;
var xx,yy;
retVal.circle = null;
for(var i = 0; i < circles.length; i ++){
xx = x - circles[i].x;
yy = y - circles[i].y;
dist = Math.sqrt(xx*xx+yy*yy);
if(dist < minDist && dist <= circles[i].radius){
minDist = dist;
retVal.circle = circles[i];
}
}
return retVal;
}
// this draws a circle, adds highlight if needed and makes sure the circle does not go outside the canvas
function drawCircle(circle){
var c = circle;
var rad = c.radius + c.lineWidth / 2; // get radius plus half line width
// keep circle inside canvas
c.x = c.x - rad < 0 ? c.x = rad : c.x + rad >= w ? c.x = w-rad : c.x;
c.y = c.y - rad < 0 ? c.y = rad : c.y + rad >= h ? c.y = h-rad : c.y;
ctx.lineWidth = 4;
if(c.highlight){ // highlight the circle if needed
ctx.strokeStyle = "#0F0";
ctx.globalAlpha = 0.5;
ctx.beginPath();
ctx.arc(c.x,c.y,c.radius + c.lineWidth,0,Math.PI * 2);
ctx.stroke();
c.highlight = false;
}
// draw the circle
ctx.fillStyle = c.col;
ctx.strokeStyle = c.col;
ctx.globalAlpha = 0.5;
ctx.beginPath();
ctx.arc(c.x,c.y,c.radius,0,Math.PI * 2);
ctx.fill();
ctx.globalAlpha = 1;
ctx.stroke();
}
// main update function
function update(time){
globalTime = time;
requestAnimationFrame(update); // get the next animation frame.
if(!renderUpdate ){ // don't render if there is no need
return;
}
renderUpdate = false;
ctx.clearRect(0,0,w,h);
// when not dragging look for the closest circle under the mouse and highlight it
if(drag.circle === null){
closestCircle = findClosestCircle2Point(mouse.x,mouse.y,closestCircle);
if(closestCircle.circle !== null){
closestCircle.circle.highlight = true;
}
}
if(mouse.button){ // if the mouse is down start dragging if circle is under mouse
if(drag.circle === null){
if(closestCircle.circle !== null){
drag.circle = closestCircle.circle;
drag.offsetX = mouse.x - drag.circle.x;
drag.offsetY = mouse.y - drag.circle.y;
}else{
mouse.button = false;
}
}else{
drag.circle.x = mouse.x - drag.offsetX;
drag.circle.y = mouse.y - drag.offsetY;
}
}else{ // drop circle
drag.circle = null;
}
for(var i = 0; i < circles.length; i ++){ // draw all circles
drawCircle(circles[i]);
}
// display any messages if needed.
if(message.time > 0){
message.time -= 1;
ctx.fillStyle = "black";
ctx.fillText(message.text,w/2,h/2);
renderUpdate = true; // while message is up need to render.
}
}
requestAnimationFrame(update); // start the whole thing going.
&#13;
答案 1 :(得分:0)
HTML5画布没有您绘制的对象的事件侦听器。一旦它们被光栅化(绘制),它们就只是图像上的像素。
这意味着你必须独立处理画布的点击,然后通过javascript对象处理屏幕上的事件,然后重绘画布。像fabric.js这样的框架使得这非常轻松。 http://fabricjs.com/
还有其他框架,但如果您不想要框架,则需要您管理自己的场景,执行点击检测以自行对象事件处理等。