【问题标题】:Simple Button in HTML5 canvasHTML5 画布中的简单按钮
【发布时间】:2014-08-14 13:58:05
【问题描述】:

我是 Javascript 新手,我正在制作一个基于 Web 的项目 (HTML) 凭借我的基本知识,我设法创建了一个表单并在其上绘制了一个矩形。

我现在希望能够单击矩形,像使用按钮一样使用它,但我似乎找不到任何可以帮助我的教程或答案。

这是我的矩形的代码:

function Playbutton(top, left, width, height, lWidth, fillColor, lineColor) {
    context.beginPath();
    context.rect(250, 350, 200, 100); 
    context.fillStyle = '#FFFFFF'; 
    context.fillStyle = 'rgba(225,225,225,0.5)';
    context.fillRect(25,72,32,32);
    context.fill(); 
    context.lineWidth = 2;
    context.strokeStyle = '#000000'; 
    context.stroke();
    context.closePath();
    context.font = '40pt Kremlin Pro Web';
    context.fillStyle = '#000000';
    context.fillText('Start', 345, 415);
  }

我知道您需要找到 x,y 坐标和鼠标位置才能单击矩形区域。但我真的被困在这一点上。 这可能真的很简单也很合乎逻辑,但我们都必须经过这个阶段。

【问题讨论】:

  • 我了解到您想在画布上绘制按钮。是否对此有特殊需求,或者我建议您使用 HTML <input type="submit" /> 标签并通过 CSS 设置样式,这将是标准方式。然后处理任何鼠标事件等,而无需浏览器进一步配置。
  • 如果您需要在画布元素上执行此操作,这是一个很好的答案:stackoverflow.com/questions/9880279/…。我自己会在 css 中使用
  • 我也建议你使用 HTML 和 CSS 作为之前的海报所建议的布局。对于 JavaScript 部分,我建议您使用 jQuery。这是一个非常易于使用的库。在您的示例中使用画布绘制东西用于更高级的东西。目前很少有网站使用它。
  • 感谢您的回答。总结一下我的项目,我成功地在画布上绘制了一个足球场(与世界杯相关),并绘制了 8 件功能齐全的 T 恤,可在球员选择颜色时用作按钮。一旦两支球队都选择了他们的球衣颜色。出现“播放”按钮,这是我似乎无法“可点击”的按钮。我已经看过使用

标签: javascript html canvas


【解决方案1】:

Path2d 可能很有趣,尽管它是实验性的:

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/isPointInPath

基本上,您会将所有绘图都放入一个路径中,然后使用 .isPointInPath 方法进行检查。对于您所描述的矩形,您可以非常简单地进行数学运算,但这样做的好处是您可以设置复杂的路径,它会为您进行碰撞检测:

//get canvas/context
const canvas = document.getElementById("myCanvas")
const context = canvas.getContext("2d")

//create your shape data in a Path2D object
const path = new Path2D()
path.rect(250, 350, 200, 100)
path.rect(25,72,32,32)
path.closePath()

//draw your shape data to the context
context.fillStyle = "#FFFFFF"
context.fillStyle = "rgba(225,225,225,0.5)"
context.fill(path)
context.lineWidth = 2
context.strokeStyle = "#000000"
context.stroke(path)

function getXY(canvas, event){ //adjust mouse click to canvas coordinates
  const rect = canvas.getBoundingClientRect()
  const y = event.clientY - rect.top
  const x = event.clientX - rect.left
  return {x:x, y:y}
}

document.addEventListener("click",  function (e) {
  const XY = getXY(canvas, e)
  //use the shape data to determine if there is a collision
  if(context.isPointInPath(path, XY.x, XY.y)) {
    // Do Something with the click
    alert("clicked in rectangle")
  }
}, false)

jsFiddle

【讨论】:

    【解决方案2】:

    你的想法是对的。
    您可以通过多种方式解决此问题,例如使用 cmets 中建议的 html 按钮。

    但如果您确实需要处理画布内的点击事件,您可以执行以下操作:

    向画布添加点击处理程序,当鼠标指针位于边界矩形内时,您可以触发点击功能:

    //Function to get the mouse position
    function getMousePos(canvas, event) {
        var rect = canvas.getBoundingClientRect();
        return {
            x: event.clientX - rect.left,
            y: event.clientY - rect.top
        };
    }
    //Function to check whether a point is inside a rectangle
    function isInside(pos, rect){
        return pos.x > rect.x && pos.x < rect.x+rect.width && pos.y < rect.y+rect.height && pos.y > rect.y
    }
    
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');
    //The rectangle should have x,y,width,height properties
    var rect = {
        x:250,
        y:350,
        width:200,
        height:100
    };
    //Binding the click event on the canvas
    canvas.addEventListener('click', function(evt) {
        var mousePos = getMousePos(canvas, evt);
    
        if (isInside(mousePos,rect)) {
            alert('clicked inside rect');
        }else{
            alert('clicked outside rect');
        }   
    }, false);
    

    jsFiddle

    【讨论】:

    • 非常感谢@A1rPun,这是我最初的想法。我已经尝试过这段代码,不幸的是它仍然不想被点击。但我现在走在正确的路线上,所以希望我现在能够更快地解决它,因为几周前我对 T 恤使用了相同的功能 (getMousePos),并且它们可以工作
    • 很高兴它对您有所帮助,但是 jsFiddle 不适合您吗?
    • 我确实在 jsFiddle 上工作,但不在我的其他代码中。我似乎没有改变任何东西,但语法保持正确
    • 还是不行,我收到的错误信息是:Uncaught TypeError: Cannot read property 'x' of undefined
    • isInside 函数需要一个具有 x,y,widthheight 属性的对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多