実現したいこと
ボックスをクリックしたら2秒かけてボックスが右に500px、下に300pxの位置に動くようにしたい。
ボックスが動き終わったら、ボックスをクリックしても反応しずにリセットボタンをクリックすると、
リセットするようにした。
アニメーション中に二重処理が起きないように制御したい。
似たような質問がteratallにも掲載されているが、それを試してもやりたい動きにはならなかったので、質問します。
発生している問題・分からないこと
JavaScriptでsetInterval、clearInterval、flag関数を用いて、やると二重動作が起きなくなるのではないかと考えています。
そこで、下記のようなコードを入力したがボックスが動いた後にボックスをクリックしても、
また動き出してしまう。
該当のソースコード
JavaScript,html
1<!DOCTYPE html> 2<html> 3<head> 4<meta charset="UTF-8"> 5<title>lesson02 アニメーション1</title> 6<link rel="stylesheet" type="text/css" href="base.css"> 7</head> 8<body> 9<div id="wrapper"> 10<button id ="reset">リセット</button> 11<div id="box"> 12<p>box</p> 13</div><!-- box --> 14</div><!-- wrapper --> 15 16<script> 17function slideAnimation(target, moveX, moveY, duration) { // スライドアニメーションを申請する 18if(target.getAttribute("animating") !== null) return; // アニメーション中なら何もしない 19target.setAttribute("animating", ""); // 要素がアニメーション中であることを表す 20const startTime = performance.now(); // アニメーションを開始した時間を保存 21const intervalId = setInterval(slide, 1000 / 60); // 1秒/60フレーム=60fpsでslide関数を実行 22function slide() { // 経過時間に合わせて位置を変更する 23const nowTime = performance.now(); // 今の時間を保存 24const diffTime = nowTime - startTime; // 経過時間を保存 25if(diffTime >= duration) { // 経過時間がduration以上なら 26translate(target, moveX, moveY); // スライドの最後の状態にする(位置ズレ解消のため) 27target.removeAttribute("animating", ""); // 要素がアニメーション中でないことを表す 28clearInterval(intervalId); // インターバルを削除 29return; 30} 31const nowX = (moveX / duration) * diffTime, // 現在いるべきx座標を表す 32nowY = (moveY / duration) * diffTime; // 現在いるべきy座標を表す 33translate(target, nowX, nowY); // 現在いるべき座標の状態にする 34} 35} 36function translate(target, x, y) { // 位置をずらすための関数 37target.style.transform = `translate(${x}px, ${y}px)`; 38} 39 40document.querySelector("#box").addEventListener("click", e => { 41slideAnimation(e.currentTarget, 500, 300, 2000); // #boxを右に500px下に300pxを2000ミリ秒かけてスライドさせる 42}); 43document.querySelector("#reset").addEventListener("click", () => { 44translate(box, 0, 0); // #boxの位置をリセットする 45}); 46</script> 47</body> 48</html>
css
1@charset "UTF-8"; 2/* reset */ 3body, h1, h2, h3, h4, h5, h6, p, address, 4ul, ol, li, dl, dt, dd, img, form, table, tr, th, td { 5 margin: 0; 6 padding: 0; 7 border: none; 8 font-style: normal; 9 font-weight: normal; 10 font-size: 100%; 11 text-align: left; 12 list-style-type: none; 13 border-collapse: collapse; 14} 15 16textarea { font-size: 100%; vertical-align:middle;} 17img { border-style: none; display: block; } 18hr { display: none; } 19em{font-style: normal} 20input{line-height:auto;vertical-align:middle;} 21strong.more{color:#c30} 22a{text-decoration: none;} 23 24html { 25 26} 27 28body { 29 font-family:'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ',Meiryo,'MS Pゴシック',sans-serif; 30} 31 32* { 33 -webkit-box-sizing: border-box; 34 -moz-box-sizing: border-box; 35 -o-box-sizing: border-box; 36 -ms-box-sizing: border-box; 37 box-sizing: border-box; 38} 39 40/* 上の部分は気にせずここから書く */ 41#box { 42 width: 320px; 43 height: 180px; 44 background-color: #fdd; 45 cursor: pointer; 46} 47 48#box p { 49 line-height: 180px; 50 font-size: 32px; 51 text-align: center; 52} 53
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
flag関数を用いて、やってみたり、clearIntervalの内容を変えてみたが、動作終了後でも、ボックスをクリックすると、また動き出してしまう。
また、打ったコードによっては、ボックスが動かなくなってしまったケースもあった。
補足
特になし
回答2件
あなたの回答
tips
プレビュー