0

ユーザーが時間を選択するために使用できるアナログ時計の入力方法を作成しています。ユーザーは内側の円をクリックして短針 (時) を設定し、外側の円をクリックして長針 (分) を設定できます。

ジャバスクリプト時計

問題は、ユーザーが時計の任意のポイントをクリックできるため、針の無効な位置を選択できることです。これを検出する方法(アルゴリズム)はありますか?

window.addEvent('domready', function()
{
  var handLong = [10, 20, 30, 40, 50, 60, 70, 80];
  var handShort = [10, 20, 30, 40, 50];

  injectHands('clock', handShort, handLong);

  $('clock').addEvent('click', function(e)
  {
    var x = correctX(e.page.x - e.target.getPosition().x, true);
    var y = correctY(e.page.y - e.target.getPosition().y, true);

    var angle = calculateAngle(x, y);

    // grote wijzer positioneren
    if (insideOuter(x, y))
    {
      moveHand(handLong, 'Long', angle);
    }
    // kleine wijzer positioneren
    else if (insideInner(x, y))
    {
      moveHand(handShort, 'Short', angle);
    }
  });
});

// Valt punt (x, y) binnen een cirkel met middenpunt (x, y) en radius r
function insideCircle(pointX, pointY, circleX, circleY, radius)
{
  dX = pointX - circleX;
  dY = pointY - circleY;

  return ((dX * dX) + (dY * dY)) <= (radius * radius);
}

// Valt punt (x, y) (enkel) binnen de buitenste cirkel (grote wijzer)
function insideOuter(pointX, pointY)
{
  return !insideInner(pointX, pointY) && insideCircle(pointX, pointY, 0, 0, 100);
}

// Valt punt (x, y) (enkel) binnen de binnenste cirkel (grote wijzer)
function insideInner(pointX, pointY)
{
  return insideCircle(pointX, pointY, 0, 0, 50);
}

// corrigeer x as (100 => 0) (0 => 100)
function correctX(x, nn)
{
  if (nn)
  {
    return x - 100;
  }
  return x + 100;
}

// corrigeer y as (100 => 0) (0 => 100)
function correctY(y, nn)
{
  if (nn)
  {
    return -y + 100;
  }
  return Math.abs(y - 100);
}

function calculateAngle(x, y)
{
  if ((x >= 0) && (y >= 0))
  {
    return Math.atan(x / y) * (180 / Math.PI);
  }
  else if (((x >= 0) && (y < 0)) || ((x < 0) && (y < 0)))
  {
    return 180 + Math.atan(x / y) * (180 / Math.PI);
  }
  else if ((x < 0) && (y >= 0))
  {
    return 360 - Math.abs(Math.atan(x / y) * (180/ Math.PI));
  }
}

function roundAngleByMinute(angle)
{
}

function calculateX(angle, hypotenuse)
{
  return Math.sin((Math.PI / 180) * angle) * hypotenuse;
}

function calculateY(angle, hypotenuse)
{
  return Math.cos((Math.PI / 180) * angle) * hypotenuse;
}

function injectHands(div, handShort, handLong)
{
  for (var i = 0; i < handShort.length; i++)
  {
    $(div).grab(new Element('img', {src: 'images/red_8x8.png', class: 'hands handShort', id: 'handShort-' + handShort[i]}));
  }
  for (var i = 0; i < handLong.length; i++)
  {
    $(div).grab(new Element('img', {src: 'images/blue_8x8.png', class: 'hands handLong', id: 'handLong-' + handLong[i]}));
  }

  $(div).grab(new Element('img', {src: 'images/black_8x8.png', class: 'hands', id: 'hand-center'}));

  $$('img.hands').hide();
  $('hand-center').show();
}

function moveHand(hand, whichHand, angle)
{
  for (var i = 0; i < hand.length; i++)
  {
    var hypotenuse = hand[i];
    var x = calculateX(angle, hypotenuse) - 5;
    var y = calculateY(angle, hypotenuse) + 5;
    var left = correctX(x);
    var top = correctY(y);

    $('hand' + whichHand + '-' + hypotenuse).set('styles', {'left': left + 'px', 'top': top + 'px'});
  }
  $$('img.hand' + whichHand).show();
}
4

2 に答える 2

3

時針を合わせると分針が分かります。救助への三角法!分針を設定するときは、分針が選択した位置に進むと想定し、それに応じて時針を調整します。

分針は、モジュロ演算子が機能するのと同じように、時針の角度の関数を示します...

逆の方法でも機能します。分針の角度が与えられた場合、可能な時針の角度は 12 個しかありません。現在の時針の角度に最も近いものを選択してください...

于 2011-03-02T16:19:20.770 に答える