检测画布中的鼠标点击位置 [英] Detect mouse click location within canvas

查看:167
本文介绍了检测画布中的鼠标点击位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个真正的问题,试图定义一个函数,我点击空的空间。到目前为止,我已经设法定义了我点击一个对象 - 其中有10 - 但现在我需要一个单独的函数,当我不点击任何对象。大致的想法可以在 http://deciballs.co.uk/experience.html 中找到。对象是环。我的代码在下面...任何想法?

I'm having a real issue trying to define a function for where I click on empty space. So far I have managed to define where I click on an object - of which there are 10 - but now I need a separate function for when I am not clicking on any of the objects. The general idea can be found at http://deciballs.co.uk/experience.html. The objects are the rings. My code is below... Any ideas?

var shapeObj = function (context, canvas, settingsBox, radius) {
    this.ctx = context;
    this.canvas = canvas;
    this.sBox = settingsBox;

    this.frequencies = new Array(220, 440, 1024, 2048);
    this.cols = new Array(255, 225, 200, 175, 150);
    this.strokes = new Array(1, 1.5, 2);
    this.waves = new Array('sine', 'sawtooth', 'triangle', 'square');

    this.properties = {
        dur: Math.random()*0.5,
        freq: this.frequencies[Math.floor(Math.random() * this.frequencies.length)],
        radius: radius,
        stroke: this.strokes[Math.floor(Math.random() * this.strokes.length)],
        speed: Math.random()*6-3,
        vol: Math.random()*10,
        col1: this.cols[Math.floor(Math.random() * this.cols.length)],
        col2: this.cols[Math.floor(Math.random() * this.cols.length)],
        col3: this.cols[Math.floor(Math.random() * this.cols.length)],
        alpha: 0,
        wave: this.waves[Math.floor(Math.random() * this.waves.length)],
        delay: 0 
    }

    this.x = Math.random()*this.ctx.canvas.width;
    this.y = Math.random()*this.ctx.canvas.height; 
    this.vx = 0.5;
    this.vy = 1;

    this.draw = function () {
        this.ctx.beginPath();
        this.ctx.arc(this.x, this.y, this.properties.radius, 0, Math.PI*2, false);
        this.ctx.closePath();
        this.ctx.stroke();
        this.ctx.fill();
    }

    this.clickTest = function (e) {
        var canvasOffset = this.canvas.offset();
        var canvasX = Math.floor(e.pageX-canvasOffset.left);
        var canvasY = Math.floor(e.pageY-canvasOffset.top);     
            var dX = this.x-canvasX;
            var dY = this.y-canvasY;
            var distance = Math.sqrt((dX*dX)+(dY*dY));
            if (distance < this.properties.radius) {
                this.manageClick();
            } else {
                this.properties.alpha = 0;
            }
    };

    this.manageClick = function () {
        this.sBox.populate(this.properties, this);
        var divs = document.getElementsByTagName('section');
        for(var i = 0, e = divs[0], n = divs.length; i < n; e = divs[++i]){
            e.className='class2';
        }
        this.properties.alpha = 0.5;
    }
}


推荐答案

完美的鼠标点击是有点棘手,我会分享我迄今为止已经创建的最防弹的鼠标代码。它可以在所有浏览器上使用所有方式的填充,边距,边框和附加组件(如stumbleupon顶部栏)。

Getting perfect mouse clicks is slightly tricky, I'll share the most bulletproof mouse code that I have created thus far. It works on all browsers will all manner of padding, margin, border, and add-ons (like the stumbleupon top bar).

// Creates an object with x and y defined,
// set to the mouse position relative to the state's canvas
// If you wanna be super-correct this can be tricky,
// we have to worry about padding and borders
// takes an event and a reference to the canvas
function getMouse(e, canvas) {
  var element = canvas, offsetX = 0, offsetY = 0, mx, my;

  // Compute the total offset. It's possible to cache this if you want
  if (element.offsetParent !== undefined) {
    do {
      offsetX += element.offsetLeft;
      offsetY += element.offsetTop;
    } while ((element = element.offsetParent));
  }

  // Add padding and border style widths to offset
  // Also add the <html> offsets in case there's a position:fixed bar (like the stumbleupon bar)
  // This part is not strictly necessary, it depends on your styling
  offsetX += stylePaddingLeft + styleBorderLeft + htmlLeft;
  offsetY += stylePaddingTop + styleBorderTop + htmlTop;

  mx = e.pageX - offsetX;
  my = e.pageY - offsetY;

  // We return a simple javascript object with x and y defined
  return {x: mx, y: my};
}



你会注意到我使用了一些未定义的变量功能。它们是:

You'll notice that I use some (optional) variables that are undefined in the function. They are:

  stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10)      || 0;
  stylePaddingTop  = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10)       || 0;
  styleBorderLeft  = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10)  || 0;
  styleBorderTop   = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10)   || 0;
  // Some pages have fixed-position bars (like the stumbleupon bar) at the top or left of the page
  // They will mess up mouse coordinates and this fixes that
  var html = document.body.parentNode;
  htmlTop = html.offsetTop;
  htmlLeft = html.offsetLeft;

我建议只计算一次,这就是为什么他们不在 getMouse 函数。

I'd recommend only computing those once, which is why they are not in the getMouse function.

调用 getMouse 一次,然后通过一个对象列表,检查每个对象与x和y。 Pseudocode:

You should really have a single function hat handles mouse clicks, calls getMouse once, and then goes though a list of objects, checking against each one with the x and y. Pseudocode:

function onMouseDown(e) {
  var mouse = getMouse(e, canvas)
  var l = myObjects.length;
  var found = false;

  // Maybe "deselect" them all right here

  for (var i = 0; i < l; i++) {
    if (distance sqrt to myObjects[i]) {
      found = true;
      myObjects[i].ManageClickOrWhateverYouWantHere()
    }
    break;
  }

  // And now we can know if we clicked on empty space or not!
  if (!found) {
    // No objects found at the click, so nothing has been clicked on
    // do some relevant things here because of that
    // I presume from your question this may be part of what you want
  }

}

这篇关于检测画布中的鼠标点击位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆