Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/90.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用javascript向html画布添加高亮显示或标记功能_Javascript_Html_Html5 Canvas - Fatal编程技术网

使用javascript向html画布添加高亮显示或标记功能

使用javascript向html画布添加高亮显示或标记功能,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,我正在制作一个核物理网络游戏。我在画布上画了一张核素图。我手动创建了每个同位素,并输入了它们对应的同位素名称。下面是一个样本,因为有500多种同位素。我必须手动完成这项工作,因为“网格”必须是正常核素图的形式。下一步我需要做的是创建某种函数,当单击同位素时,该函数将突出显示同位素,或者在单击同位素时在同位素上放置一个“标记”。当点击不同的同位素时,取消高亮显示或移动标记。我做这件事已经有一段时间了,但我想不出来。有人知道我怎样才能做到这一点吗 // hydrogen ctx.fillRe

我正在制作一个核物理网络游戏。我在画布上画了一张核素图。我手动创建了每个同位素,并输入了它们对应的同位素名称。下面是一个样本,因为有500多种同位素。我必须手动完成这项工作,因为“网格”必须是正常核素图的形式。下一步我需要做的是创建某种函数,当单击同位素时,该函数将突出显示同位素,或者在单击同位素时在同位素上放置一个“标记”。当点击不同的同位素时,取消高亮显示或移动标记。我做这件事已经有一段时间了,但我想不出来。有人知道我怎样才能做到这一点吗

  // 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