使用javascript向html画布添加高亮显示或标记功能
我正在制作一个核物理网络游戏。我在画布上画了一张核素图。我手动创建了每个同位素,并输入了它们对应的同位素名称。下面是一个样本,因为有500多种同位素。我必须手动完成这项工作,因为“网格”必须是正常核素图的形式。下一步我需要做的是创建某种函数,当单击同位素时,该函数将突出显示同位素,或者在单击同位素时在同位素上放置一个“标记”。当点击不同的同位素时,取消高亮显示或移动标记。我做这件事已经有一段时间了,但我想不出来。有人知道我怎样才能做到这一点吗使用javascript向html画布添加高亮显示或标记功能,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,我正在制作一个核物理网络游戏。我在画布上画了一张核素图。我手动创建了每个同位素,并输入了它们对应的同位素名称。下面是一个样本,因为有500多种同位素。我必须手动完成这项工作,因为“网格”必须是正常核素图的形式。下一步我需要做的是创建某种函数,当单击同位素时,该函数将突出显示同位素,或者在单击同位素时在同位素上放置一个“标记”。当点击不同的同位素时,取消高亮显示或移动标记。我做这件事已经有一段时间了,但我想不出来。有人知道我怎样才能做到这一点吗 // hydrogen ctx.fillRe
// hydrogen
ctx.fillRect(21, 960, 25, 25);
ctx.fillRect(46, 960, 25, 25);
ctx.strokeRect(71, 960, 25, 25);
ctx.strokeRect(96, 960, 25, 25);
ctx.strokeRect(121, 960, 25, 25);
ctx.strokeRect(146, 960, 25, 25);
ctx.strokeRect(171, 960, 25, 25);
//
ctx.fillStyle = 'white';
ctx.fillText("1H", 23, 980, 15, 15);
ctx.fillStyle = 'white';
ctx.fillText("2H", 48, 980, 15, 15);
ctx.fillStyle = 'black';
ctx.fillText("3H", 73, 980, 15, 15);
ctx.fillStyle = 'black';
ctx.fillText("4H", 98, 980, 15, 15);
ctx.fillStyle = 'black';
ctx.fillText("5H", 123, 980, 15, 15);
ctx.fillStyle = 'black';
ctx.fillText("6H", 148, 980, 15, 15);
ctx.fillStyle = 'black';
ctx.fillText("7H", 173, 980, 15, 15);
在这里,我创建了一个演示,演示如何创建一个hitbox。当脚本运行时,点击框将由画布上具有随机位置的正方形表示 在脚本中,我们使用
mousedown
和mouseup
事件侦听器来确定用户何时按下和释放鼠标。鼠标向下移动时,鼠标的x
和y
坐标是相对于画布的大小计算的。通过这种方式计算,您可以得到画布上已单击的确切像素。然后将该值存储在全局变量中
您需要知道点击框的x
、y
、宽度和高度,因为您需要确定点击的x
和y
是否在作为点击框的正方形内
在下面的演示中,只要单击并释放单击,视图就会重新呈现。mouseData
state changes en将在新渲染中显示。然后,如果mouseData.position
坐标位于框内,则渲染将针对命中框求值,并根据该求值更改颜色
然后释放鼠标会触发另一次重新渲染,将单击状态更改为false并显示hitbox的原始状态
这就是它的基本原理,一个坐标的平方,它检测点击的像素是否在这个平方内,如果在这个平方内,它会做些什么
const canvas=document.querySelector('#canvas');
const context=canvas.getContext('2d');
常数squareSideSize=50;
canvas.width=canvas.offsetWidth;
canvas.height=canvas.offsetHeight;
//将数据存储在鼠标单击上。
让mouseData={
点击:错,
位置:[//此处我们将单击的x和y存储为[x,y]
}
/**
*生成最小值和最大值之间的随机数。
*只是为了画出这个盒子。
*/
const getRandomInt=(min,max)=>Math.floor(Math.random()*(max-min+1))+min;
/**
*返回具有x和y坐标的数组
*基于单击事件。
*/
常量getMousePositionOnCanvas=({clientX,clientY})=>{
const canvasRect=canvas.getBoundingClientRect();
const x=clientX-canvasRect.left;
const y=clientY-canvasRect.top;
返回[x,y];
};
/**
*确定来自单击的x和y是否在
*正方形的x、y、宽度和高度。
*返回true或false。
*/
常数isInHitbox=([x,y],平方)=>(
(x>=square.x&&x=square.y&&y{
mouseData.clicked=true;//将单击状态设置为true。
mouseData.position=getMousePositionOnCanvas(事件);//获取相对于画布的单击位置。
render();//使用单击状态进行渲染。
});
//监听mousemove并更新位置。
canvas.addEventListener('mousemove',event=>{
if(mouseData.clicked==true){//仅在单击时执行操作。
mouseData.position=getMousePositionOnCanvas(事件);//更新鼠标位置。
render();//使用更新的鼠标位置进行渲染。
}
})
//倾听鼠标悬停并清除单击位置。
canvas.addEventListener('mouseup',event=>{
mouseData.clicked=false;//将单击状态设置为false。
mouseData.position.length=0;//重置位置。
render();//呈现未锁定状态。
});
/**
*在画布上清除和绘制的渲染函数。
*在这里,我们根据我们收集的数据来确定要绘制的内容
*从鼠标中收集。
*/
函数render(){
requestAnimationFrame(()=>{
const{x,y,width,height}=square;//获取正方形的所有尺寸。
const{clicked,position}=mouseData;//获取鼠标的数据。
context.clearRect(0,0,canvas.width,canvas.height);//清除画布以进行干净的重新渲染。
//默认白色。
context.fillStyle='white';
//检查鼠标是否已单击,以及
//位置在hitbox内。请更改颜色
//如果是真的。
如果(单击===true&&isInHitbox(位置,正方形)){
context.fillStyle='green';
}
//画一个点击框。
fillRect(x,y,宽度,高度);
});
}
//初始渲染。
render();
html,
身体{
宽度:100%;
身高:100%;
保证金:0;
框大小:边框框;
}
身体{
填充:10px;
}
帆布{
宽度:100%;
身高:100%;
背景:#000000;
}
我创建这些函数是为了在画布上画一个圆圈,并能够跟踪鼠标位置,测试它是否在圆圈上,然后倾听向下和向上的点击以拖动它。如果项目中还有其他绘图元素,在本例中,我的同位素都有520个,你只需要将这些代码放在你的ur redraw函数,否则在移动cirlce后,所有其他内容都会消失
var cw=canvas.width;
var ch=canvas.height;
document.body.appendChild(canvas);
// used to calc canvas position relative to window
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }
canvas.onresize=function(e){ reOffset(); }
// save relevant information about shapes drawn on the canvas
var shapes=[];
// define one circle and save it in the shapes[] array
shapes.push( {x:300, y:275, radius:10} );
var isDragging=false;
var startX,startY;
// hold the index of the shape being dragged (if any)
var selectedShapeIndex;
// draw the shapes on the canvas
drawAll();
// listen for mouse events
canvas.onmousedown=handleMouseDown;
canvas.onmousemove=handleMouseMove;
canvas.onmouseup=handleMouseUp;
canvas.onmouseout=handleMouseOut;
// given mouse X & Y (mx & my) and shape object
// return true/false whether mouse is inside the shape
function isMouseInShape(mx,my,shape){
if(shape.radius){
// this is a circle
var dx=mx-shape.x;
var dy=my-shape.y;
// math test to see if mouse is inside circle
if(dx*dx+dy*dy<shape.radius*shape.radius){
// yes, mouse is inside this circle
return(true);
}
}
// the mouse isn't in any of the shapes
return(false);
}
function handleMouseDown(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// calculate the current mouse position
startX=parseInt(e.clientX-offsetX);
startY=parseInt(e.clientY-offsetY);
// test mouse position against all shapes
// post result if mouse is in a shape
for(var i=0;i<shapes.length;i++){
if(isMouseInShape(startX,startY,shapes[i])){
// the mouse is inside this shape
// select this shape
selectedShapeIndex=i;
// set the isDragging flag
isDragging=true;
// and return (==stop looking for
// further shapes under the mouse)
return;
}
}
}
function handleMouseUp(e){
// return if we're not dragging
if(!isDragging){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// the drag is over -- clear the isDragging flag
isDragging=false;
}
function handleMouseOut(e){
// return if we're not dragging
if(!isDragging){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// the drag is over -- clear the isDragging flag
isDragging=false;
}
function handleMouseMove(e){
// return if we're not dragging
if(!isDragging){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// calculate the current mouse position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// how far has the mouse dragged from its previous mousemove position?
var dx=mouseX-startX;
var dy=mouseY-startY;
// move the selected shape by the drag distance
var selectedShape=shapes[selectedShapeIndex];
selectedShape.x+=dx;
selectedShape.y+=dy;
// clear the canvas and redraw all shapes
drawAll();
// update the starting drag position (== the current mouse position)
startX=mouseX;
startY=mouseY;
}
// clear the canvas and
// redraw all shapes in their current positions
function drawAll(){
ctx.clearRect(0,0,cw,ch);
for(var i=0;i<shapes.length;i++){
var shape=shapes[i];
if(shape.radius){
// it's a circle
ctx.beginPath();
ctx.arc(shape.x,shape.y,shape.radius,0,Math.PI*2);
ctx.fillStyle=shape.color;
ctx.fill();
}
}
var cw=canvas.width;
var ch=画布高度;
document.body.appendChild(画布);
//用于计算画布相对于窗口的位置
函数reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
onscroll=函数(e){reOffset();}
onresize=函数(e){reOffset();}
canvas.onresize=函数(e){reOffset();}
//保存有关在画布上绘制的形状的相关信息
v