【问题标题】:speech buble html5 canvas js语音气泡html5画布js
【发布时间】:2014-02-06 18:03:31
【问题描述】:

我正在尝试使用可拖动处理程序绘制语音气泡。 这就是我所拥有的:

  • (x,y) - 气泡左下角坐标
  • 气泡的长度
  • 气泡的宽度
  • (x1,y1) 处理程序端的坐标

为了便于理解,下图:

当所有坐标都已知时,我知道如何在画布中绘制它。这很简单。 Tutorial

function drawBubble(ctx, x, y, w, h, radius)
{
  var r = x + w;
  var b = y + h;
  ctx.beginPath();
  ctx.strokeStyle="black";
  ctx.lineWidth="2";
  ctx.moveTo(x+radius, y);
  ctx.lineTo(x+radius/2, y-10);
  ctx.lineTo(x+radius * 2, y);
  ctx.lineTo(r-radius, y);
  ctx.quadraticCurveTo(r, y, r, y+radius);
  ctx.lineTo(r, y+h-radius);
  ctx.quadraticCurveTo(r, b, r-radius, b);
  ctx.lineTo(x+radius, b);
  ctx.quadraticCurveTo(x, b, x, b-radius);
  ctx.lineTo(x, y+radius);
  ctx.quadraticCurveTo(x, y, x+radius, y);
  ctx.stroke();
}

Example in jsFiddle

但问题是 - 如何找到图片上显示的红点的坐标。 (x,y) 和 (x1,y1) 都是已知的,但是当用户拖动气泡或处理程序时会发生变化。在所有情况下,处理程序都应该看起来很漂亮。

如果有人能分享代码就好了,这对我来说有点复杂。 提前致谢!

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    您可以保留角落并绘制固定到给定点的指向位。您只需要计算正确的连接点即可。

    // This is an example with the connection points 20px apart.
    // The px and py variables here come from the onmousemove event.
    // Finally, this part here is only for the top part of the bubble,
    // you have watch for 4 different scenarios, depending on where
    // the mouse is and thus what the pointing bit should aim for.
    ...
    var con1 = Math.min(Math.max(x+radius,px-10),r-radius-20);
    var con2 = Math.min(Math.max(x+radius+20,px+10),r-radius);
    ...
    if(py < y) dir = 2;
    ...
    ctx.moveTo(x+radius,y);
    if(dir==2){
     ctx.lineTo(con1,y);
     ctx.lineTo(px,py);
     ctx.lineTo(con2,y);
     ctx.lineTo(r-radius,y);
    }
    else ctx.lineTo(r-radius,y);
    ctx.quadraticCurveTo(r,y,r,y+radius);
    ...
    

    像这样:

    Draggable Bubble

    尝试点击气泡来拖动指针。

    【讨论】:

      【解决方案2】:

      已经为您计算了句柄,因此只需通过以下修改来保留其坐标:

      function drawBubble(ctx, x, y, w, h, radius) {
      
          ...snipped...
      
          var handle = {
              x1: x + radius,
              y1: y,
              x2: x + radius / 2,
              y2: y - 10,
              x3: x + radius * 2,
              y3: y
          }
          ctx.moveTo(handle.x1, handle.y1);
          ctx.lineTo(handle.x2, handle.y2);
          ctx.lineTo(handle.x3, handle.y3);
      
          ...snipped...
      
          return handle;
      }
      

      Modified fiddle here

      这是获取句柄坐标的一种方法。

      为了更进一步,我们可以修改上述函数,使其也接受handle 参数。

      这样您可以选择提供句柄设置或使用默认计算的设置:

      function drawBubble(ctx, x, y, w, h, radius, handle) {
      
          ...snipped...
      
          /// use given handle settings or calculate a default one:
          handle = handle || {
              x1: x + radius,
              y1: y,
              x2: x + radius / 2,
              y2: y - 10,
              x3: x + radius * 2,
              y3: y
          }
          ctx.moveTo(handle.x1, handle.y1);
          ctx.lineTo(handle.x2, handle.y2);
          ctx.lineTo(handle.x3, handle.y3);
      
          ...snipped...
      
          return handle;
      }
      

      为了使用它,您首先通过将 null 或 false 传递给函数来获取默认计算句柄。

      然后使用这些坐标来绘制周围的位置。对于每次移动,清除并重绘画布,但这次将修改后的句柄参数提供给函数:

      /// first time:
      var handle = null,  /// first time use default handle
          ...;
      
      handle = drawBubble(ctx, x, y, w, h, radius, handle);
      

      然后在你的鼠标操作中:

      /// modify and update bubble:
      handle = drawBubble(ctx, x, y, w, h, radius, handle);
      

      希望这会有所帮助!

      【讨论】:

      • 看起来很神奇,需要打领带才能弄清楚如何使用它
      • 不,当用户拖动气泡处理程序端点时问题没有解决我们应该重新计算处理程序的所有三个点,我们不能一次又一次地使用(x1,y1)和(x3,y3)如何计算这些点是最初的麻烦
      • @ProstoTrader 试试这个:jsfiddle.net/AbdiasSoftware/V92Gn/685 在初始调用句柄之后将包含当前点,您可以修改这些点并将其传回函数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多