QA@IT

『トグルボタン』を使って、付いてくる物体を"追従⇔分離"させるコードの書き方

8182 PV

下記のコードは、マウスポインターに物体(時計)が付いて行くものです。
これに、『トグルボタン』を使って"追従⇔分離"させたいのですが、
どのように書き加えればいいでしょうか。うまく行っていたのですが、
誤ってコードに別コードを上書きしてしまい、その上に書き方を忘れてしまったのです。
どなたか教えていただけませんか。


<!DOCTYPE html>
<html>
<head>
    <style>
        body {
  font-family: Helvetica, Arial, sans-serif;
}

.Face {
  position: absolute;
  height: 10;
  widdth: 10;
  text-align: center;
  font-size: 1em;
  color: #0000ff;
}

.Hours {
  position: absolute;
  width: 16px;
  height: 16px;
  font-family: Arial;
  font-size: 16px;
  color: #000000;
  text-align: center;
  font-weight: bold;
}

.Minutes {
  position: absolute;
  width: 16px;
  height: 16px;
  font-family: Arial;
  font-size: 16px;
  color: #000000;
  text-align: center;
  font-weight: bold;
}

.Seconds {
  position: absolute;
  width: 16px;
  height: 16px;
  font-family: Arial;
  font-size: 16px;
  color: #ff0000;
  text-align: center;
  font-weight: bold;
}

.Date {
  position: absolute;
  height: 10;
  width: 10;
  font-size: 1em;
  color: #00ff00;
}
    </style>
    <script src="/scripts/snippet-javascript-console.min.js?v=1"></script>
    </head>
<body>
    <div id="clock">
    <div id="Od" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
    <div id="Of" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
    <div id="Oh" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
    <div id="Om" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
    <div id="Os" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
</div>
    <script type="text/javascript">
        "use strict";

function $(sel) {
  return document.getElementById(sel);
}

function $$(sel) {
  return document.getElementsByClassName(sel);
}

function setPosition(element, y, x) {
  element.style.top = y + 'px';
  element.style.left = x + 'px';
}

const CLOCK_HEIGHT = 40,
    CLOCK_WIDTH = 40,
    CLOCK_FROM_MOUSE_Y = 0,
    CLOCK_FROM_MOUSE_X = 100;

const H = '...'.split('');
const M = '....'.split('');
const S = '.....'.split('');
const SPEED = 0.6,
    FACES = '1 2 3 4 5 6 7 8 9 10 11 12'.split(' ');
const HAND_HEIGHT = CLOCK_HEIGHT / 4.5; 
const HAND_WIDTH = CLOCK_WIDTH / 4.5;
const HAND_Y = -7,
    HAND_X = -2.5,
    STEP = 0.03;

var ymouse = 0,
    xmouse = 0;
var currStep = 0;
var lastBasePositions = [];

function initialize() {
  for (var i = 0; i < FACES.length; ++i) {
    lastBasePositions[i] = {x:0, y:0};
  }

  var html = '';
  // Face wrapper
  html = '';
  for (var i = 0; i < FACES.length; ++i) {
    html += '<div class="Face">' + FACES[i] + '</div>';
  }
  $('Of').children[0].innerHTML = html;

  // Hours wrapper
  html = '';
  for (var i = 0; i < H.length; ++i) {
    html += '<div class="Hours">' + H[i] + '</div>';
  } 
  $('Oh').children[0].innerHTML = html;

  // Minute wrapper
  html = '';
  for (var i = 0; i < M.length; ++i) {
    html += '<div class="Minutes">' + M[i] + '</div>';
  }
  $('Om').children[0].innerHTML = html;

  // Seconds wrapper
  html = '';
  for (var i = 0; i < S.length; ++i) {
    html += '<div class="Seconds">' + S[i] + '</div>';
  }
  $('Os').children[0].innerHTML = html;

  // Mouse move event handler
  document.onmousemove = function(evnt) {
    ymouse = evnt.clientY + CLOCK_FROM_MOUSE_Y;
    xmouse = evnt.clientX + CLOCK_FROM_MOUSE_X;
  };

  requestAnimationFrame(ClockAndAssign);
}
var lastYearPositions = [{x:0, y:0}];
var lastYearString = ' ';
var lastYearMonthDateDay = '';
function updateYear(currentDate, scrll) {
  var yearString = lastYearString;
  if (currentDate.getHours() < 21) {
    if (lastYearMonthDateDay != 'wa1')
      yearString = currentDate.toLocaleDateString("ja-JP-u-ca-japanese", { era: "long", year: "numeric", month: "numeric", day: "numeric", weekday: "long"  }).
          replace(/\u200e/g, "").replace(" ", "");
    lastYearMonthDateDay = 'wa1';
  } else {
    if (lastYearMonthDateDay != 'wa2')
      yearString = currentDate.toLocaleDateString("ja-JP-u-ca-japanese", { era: "long", year: "numeric", month: "numeric", day: "numeric", weekday: "long"  }).
          replace(/\u200e/g, "").replace(" ", "");
    lastYearMonthDateDay = 'wa2';
  }

  var yearLength = lastYearPositions.length;
  if (yearString != lastYearString) {
    lastYearString = yearString;        
    var yearCharacters = yearString.split('');
    yearLength = yearCharacters.length;

    // Date wrapper
    var html = '';
    for (var i = 0; i < yearLength; ++i) {
      html += '<div class="Date">' + yearCharacters[i] + '</div>';
    }
    $('Od').children[0].innerHTML = html;
  }
  var positions = [{}];
  var lastPosition = lastYearPositions[0];
  positions[0].y = lastPosition.y + ((ymouse) - lastPosition.y) * SPEED;
  positions[0].x = lastPosition.x + ((xmouse) - lastPosition.x) * SPEED;
  for (var i = 1; i < yearLength; ++i) {
    lastPosition = i < lastYearPositions.length ?
        lastYearPositions[i] :
        lastYearPositions[lastYearPositions.length - 1];
    positions[i] = {};
    positions[i].y = lastPosition.y + (positions[i-1].y - lastPosition.y) * SPEED;
    positions[i].x = lastPosition.x + (positions[i-1].x - lastPosition.x) * SPEED;
  }
  for (var i = 0; i < yearLength; ++i) {
    var radian = currStep + i * (360 / yearLength) * Math.PI / 180;
    setPosition($$('Date')[i],
                Math.round(positions[i].y) + CLOCK_HEIGHT * 1.5 * Math.sin(radian) + scrll,
                Math.round(positions[i].x) + CLOCK_WIDTH * 1.5 * Math.cos(radian));
  }
  lastYearPositions = positions;
  currStep -= STEP;
}

function ClockAndAssign() {
  var date = new Date();
  var secs = date.getSeconds();
  var sec = -1.57 + Math.PI * secs / 30;
  var mins = date.getMinutes();
  var min = -1.57 + Math.PI * mins / 30;
  var hr = date.getHours();
  var hrs = -1.575 + Math.PI * hr / 6 + Math.PI * parseInt(date.getMinutes(), 10) / 360;
  $('Od').style.top = window.document.body.scrollTop;
  $('Of').style.top = window.document.body.scrollTop;
  $('Oh').style.top = window.document.body.scrollTop;
  $('Om').style.top = window.document.body.scrollTop;
  $('Os').style.top = window.document.body.scrollTop;
  var scrll = 0;

  var positions = [{}];
  var lastPosition = lastBasePositions[0];
  positions[0].y = (lastPosition.y + (ymouse - lastPosition.y) * SPEED);
  positions[0].x = (lastPosition.x + (xmouse - lastPosition.x) * SPEED);
  for (var i = 1; i < FACES.length; ++i) {
    lastPosition = lastBasePositions[i];
    positions[i] = {};
    positions[i].y = (lastPosition.y + (positions[i - 1].y - lastPosition.y) * SPEED);
    positions[i].x = (lastPosition.x + (positions[i - 1].x - lastPosition.x) * SPEED);
  }
  lastBasePositions = positions;

  var split = 360 / FACES.length;
  for (var i = 0; i < FACES.length; ++i) {
    var radian = -1.0471 + i * split * Math.PI / 180;
    setPosition($$('Face')[i],
                positions[i].y + CLOCK_HEIGHT * Math.sin(radian) + scrll,
                positions[i].x + CLOCK_WIDTH * Math.cos(radian));
  }
  for (var i = 0; i < H.length; ++i) {
    setPosition($$('Hours')[i],
                positions[i].y + HAND_Y + (i * HAND_HEIGHT) * Math.sin(hrs) + scrll,
                positions[i].x + HAND_X + (i * HAND_WIDTH) * Math.cos(hrs));
  }
  for (var i = 0; i < M.length; ++i) {
    setPosition($$('Minutes')[i],
                positions[i].y + HAND_Y + (i * HAND_HEIGHT) * Math.sin(min) + scrll,
                positions[i].x + HAND_X + (i * HAND_WIDTH) * Math.cos(min));
  }
  for (var i = 0; i < S.length; ++i) {
    setPosition($$('Seconds')[i],
                positions[i].y + HAND_Y + (i * HAND_HEIGHT) * Math.sin(sec) + scrll,
                positions[i].x + HAND_X + (i * HAND_WIDTH) * Math.cos(sec));
  }
  updateYear(date, scrll);
  requestAnimationFrame(ClockAndAssign);
}

initialize();
    </script>
</body>
</html>

関連箇所は、以下の部分です。

  // Mouse move event handler
  document.onmousemove = function(evnt) {
    ymouse = evnt.clientY + CLOCK_FROM_MOUSE_Y;
    xmouse = evnt.clientX + CLOCK_FROM_MOUSE_X;
  };
  requestAnimationFrame(ClockAndAssign);

ボタンは、次のような感じです。

 <input id="tog" type="button" value="STALK" onclick="toggle();">

回答

単純にtoggle()ないでフラグON/OFF
mousemoveイベントでフラグをみて追従する/しない

では?

編集 履歴 (0)
  • アドバイスをありがとうございました。
    フラグを立てて、簡潔に書いて動いてくれていたのですが、
    何度やってもうまく行きません。お手数ですが、該当箇所だけでも
    書いていただけませんでしょうか。
    -

何十回も同じようなことを書いていたのですが、やっとうまく行きました。
なぜ同じことを書いていたのに、うまく行かなかったのか、その原因が分かりません。
スクリプト内の"function Mouse(evnt){}"と"function follow(){}"が関連箇所です。

<!DOCTYPE html>
<html>
<head>
    <style>
        body {
  font-family: Helvetica, Arial, sans-serif;
}

.Face {
  position: absolute;
  height: 10;
  widdth: 10;
  text-align: center;
  font-size: 1em;
  color: #0000ff;
}

.Hours {
  position: absolute;
  width: 16px;
  height: 16px;
  font-family: Arial;
  font-size: 16px;
  color: #000000;
  text-align: center;
  font-weight: bold;
}

.Minutes {
  position: absolute;
  width: 16px;
  height: 16px;
  font-family: Arial;
  font-size: 16px;
  color: #000000;
  text-align: center;
  font-weight: bold;
}

.Seconds {
  position: absolute;
  width: 16px;
  height: 16px;
  font-family: Arial;
  font-size: 16px;
  color: #ff0000;
  text-align: center;
  font-weight: bold;
}

.Date {
  position: absolute;
  height: 10;
  width: 10;
  font-size: 1em;
  color: #00ff00;
}
    </style>

    </head>

<body>
    <div id="clock">
    <div id="Od" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
    <div id="Of" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
    <div id="Oh" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
    <div id="Om" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
    <div id="Os" style="position:absolute;top:0px;left:0px">
        <div style="position:relative">
        </div>
    </div>
</div>

<div style="position:absolute; bottom:8%; width:100%; text-align:center;">
 <input id="tog" type="button" value="BREAK" onclick="follow();">
</div>

    <script type="text/javascript">
        "use strict";

function $(sel) {
  return document.getElementById(sel);
}

function $$(sel) {
  return document.getElementsByClassName(sel);
}

function setPosition(element, y, x) {
  element.style.top = y + 'px';
  element.style.left = x + 'px';
}

var CLOCK_HEIGHT = 40,
    CLOCK_WIDTH = 40,
    CLOCK_FROM_MOUSE_Y = -200,
    CLOCK_FROM_MOUSE_X = 0;

var H = '...'.split('');
var M = '....'.split('');
var S = '.....'.split('');
var SPEED = 0.6,
    FACES = '1 2 3 4 5 6 7 8 9 10 11 12'.split(' ');
var HAND_HEIGHT = CLOCK_HEIGHT / 4.5; 
var HAND_WIDTH = CLOCK_WIDTH / 4.5;
var HAND_Y = -7,
    HAND_X = -2.5,
    STEP = 0.03;

var ymouse = 0,
    xmouse = 180;
var currStep = 520;
var lastBasePositions = [];

function initialize() {
  for (var i = 0; i < FACES.length; ++i) {
    lastBasePositions[i] = {x:0, y:0};
  }

  var html = '';
  // Face wrapper
  html = '';
  for (var i = 0; i < FACES.length; ++i) {
    html += '<div class="Face">' + FACES[i] + '</div>';
  }
  $('Of').children[0].innerHTML = html;

  // Hours wrapper
  html = '';
  for (var i = 0; i < H.length; ++i) {
    html += '<div class="Hours">' + H[i] + '</div>';
  } 
  $('Oh').children[0].innerHTML = html;

  // Minute wrapper
  html = '';
  for (var i = 0; i < M.length; ++i) {
    html += '<div class="Minutes">' + M[i] + '</div>';
  }
  $('Om').children[0].innerHTML = html;

  // Seconds wrapper
  html = '';
  for (var i = 0; i < S.length; ++i) {
    html += '<div class="Seconds">' + S[i] + '</div>';
  }
  $('Os').children[0].innerHTML = html;

// Mouse move event handler
function Mouse(evnt) 
{
        ymouse = evnt.clientY + CLOCK_FROM_MOUSE_Y;
        xmouse = evnt.clientX + CLOCK_FROM_MOUSE_X;
}
  document.onmousemove = Mouse;
  requestAnimationFrame(ClockAndAssign);

var flg=true;
function follow(){ 
   flg = !flg; 
document.getElementById("tog").value=flg?"BREAK":"FOLLOW";
document.onmousemove = flg?Mouse:null;
}
document.getElementById("tog").onclick=follow;
}


var lastYearPositions = [{x:0, y:0}];
var lastYearString = ' ';
var lastYearMonthDateDay = '';
function updateYear(currentDate, scrll) {
  var yearString = lastYearString;
  if (currentDate.getHours() < 21) {
    if (lastYearMonthDateDay != 'wa1')
      yearString = currentDate.toLocaleDateString("ja-JP-u-ca-japanese", { era: "long", year: "numeric", month: "numeric", day: "numeric", weekday: "long"  }).
          replace(/\u200e/g, "").replace(" ", "");
    lastYearMonthDateDay = 'wa1';
  } else {
    if (lastYearMonthDateDay != 'wa2')
      yearString = currentDate.toLocaleDateString("ja-JP-u-ca-japanese", { era: "long", year: "numeric", month: "numeric", day: "numeric", weekday: "long"  }).
          replace(/\u200e/g, "").replace(" ", "");
    lastYearMonthDateDay = 'wa2';
  }

  var yearLength = lastYearPositions.length;
  if (yearString != lastYearString) {
    lastYearString = yearString;        
    var yearCharacters = yearString.split('');
    yearLength = yearCharacters.length;

    // Date wrapper
    var html = '';
    for (var i = 0; i < yearLength; ++i) {
      html += '<div class="Date">' + yearCharacters[i] + '</div>';
    }
    $('Od').children[0].innerHTML = html;
  }
  var positions = [{}];
  var lastPosition = lastYearPositions[0];
  positions[0].y = lastPosition.y + ((ymouse) - lastPosition.y) * SPEED;
  positions[0].x = lastPosition.x + ((xmouse) - lastPosition.x) * SPEED;
  for (var i = 1; i < yearLength; ++i) {
    lastPosition = i < lastYearPositions.length ?
        lastYearPositions[i] :
        lastYearPositions[lastYearPositions.length - 1];
    positions[i] = {};
    positions[i].y = lastPosition.y + (positions[i-1].y - lastPosition.y) * SPEED;
    positions[i].x = lastPosition.x + (positions[i-1].x - lastPosition.x) * SPEED;
  }
  for (var i = 0; i < yearLength; ++i) {
    var radian = currStep + i * (360 / yearLength) * Math.PI / 180;
    setPosition($$('Date')[i],
                Math.round(positions[i].y) + CLOCK_HEIGHT * 1.5 * Math.sin(radian) + scrll,
                Math.round(positions[i].x) + CLOCK_WIDTH * 1.5 * Math.cos(radian));
  }
  lastYearPositions = positions;
  currStep -= STEP;
}

function ClockAndAssign() {
  var date = new Date();
  var secs = date.getSeconds();
  var sec = -1.57 + Math.PI * secs / 30;
  var mins = date.getMinutes();
  var min = -1.57 + Math.PI * mins / 30;
  var hr = date.getHours();
  var hrs = -1.575 + Math.PI * hr / 6 + Math.PI * parseInt(date.getMinutes(), 10) / 360;
  $('Od').style.top = window.document.body.scrollTop;
  $('Of').style.top = window.document.body.scrollTop;
  $('Oh').style.top = window.document.body.scrollTop;
  $('Om').style.top = window.document.body.scrollTop;
  $('Os').style.top = window.document.body.scrollTop;
  var scrll = 0;

  var positions = [{}];
  var lastPosition = lastBasePositions[0];
  positions[0].y = (lastPosition.y + (ymouse - lastPosition.y) * SPEED);
  positions[0].x = (lastPosition.x + (xmouse - lastPosition.x) * SPEED);
  for (var i = 1; i < FACES.length; ++i) {
    lastPosition = lastBasePositions[i];
    positions[i] = {};
    positions[i].y = (lastPosition.y + (positions[i - 1].y - lastPosition.y) * SPEED);
    positions[i].x = (lastPosition.x + (positions[i - 1].x - lastPosition.x) * SPEED);
  }
  lastBasePositions = positions;

  var split = 360 / FACES.length;
  for (var i = 0; i < FACES.length; ++i) {
    var radian = -1.0471 + i * split * Math.PI / 180;
    setPosition($$('Face')[i],
                positions[i].y + CLOCK_HEIGHT * Math.sin(radian) + scrll,
                positions[i].x + CLOCK_WIDTH * Math.cos(radian));
  }
  for (var i = 0; i < H.length; ++i) {
    setPosition($$('Hours')[i],
                positions[i].y + HAND_Y + (i * HAND_HEIGHT) * Math.sin(hrs) + scrll,
                positions[i].x + HAND_X + (i * HAND_WIDTH) * Math.cos(hrs));
  }
  for (var i = 0; i < M.length; ++i) {
    setPosition($$('Minutes')[i],
                positions[i].y + HAND_Y + (i * HAND_HEIGHT) * Math.sin(min) + scrll,
                positions[i].x + HAND_X + (i * HAND_WIDTH) * Math.cos(min));
  }
  for (var i = 0; i < S.length; ++i) {
    setPosition($$('Seconds')[i],
                positions[i].y + HAND_Y + (i * HAND_HEIGHT) * Math.sin(sec) + scrll,
                positions[i].x + HAND_X + (i * HAND_WIDTH) * Math.cos(sec));
  }
  updateYear(date, scrll);
  requestAnimationFrame(ClockAndAssign);
}

initialize();
    </script>
</body>
</html>
編集 履歴 (0)

こんな感じ??


var flgToggle=false;

// Mouse move event handler
document.onmousemove = function(evnt) {
   if(flgToggle){
      ymouse = evnt.clientY + CLOCK_FROM_MOUSE_Y;
      xmouse = evnt.clientX + CLOCK_FROM_MOUSE_X;
   }
};

function toggle(){ flgToggle = !flgToggle; }
編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。