cssでスライドして移動していくアニメーションについてです。
以下のコードでコンボボックスで「1ページ」を押して起動したときに
本来ならば 「1ページ(赤)」→「0ページ(黒)」→「1ページ(赤)」 で止まるコードを書いたのはずですが,setAttributeで行った2回目のCSSアニメーションのanimation-fill-mode: forwards;が効かず 「1ページ(赤)」→「0ページ(黒)」→「1ページ(赤)」→一瞬で「2ページ(ピンク)」 になってしまうのですが,
どうすればよいでしょうか?
※コマンドの動きの特性※
・現在位置が[1ページ13ページ]の状態で[2ページ13ページ]を選択して実行した場合は途中のページを通過しながら直接移動。
・現在位置が[2ページ~13ページ]の状態で[1ページ]を選択して実行した場合は途中のページを通過し,更に一旦「1ページ」を通過してから「0ページ(黒)」まで巻き上げてから「1ページ」に巻き戻るという動作をする。
・現在位置が[1ページ]の状態で[1ページ]を選択して実行した場合は「0ページ(黒)」まで巻き上げてから「1ページ」に巻き戻るという動作をする。
・再選択可能。
・意図的にすべての動作において止まるたびに一瞬少し過ぎてから戻るように動くアニメーションをする。
html
1<div class="parent"> 2<span class="child" id="box"> 3 <div style=" width:592px;height:400px; background-color: #000;">0ページ</div> 4 <div style=" width:592px;height:400px; background-color: #ff7f7f;">1ページ</div> 5 <div style=" width:592px;height:400px; background-color: #ff7fbf;">2ページ</div> 6 <div style=" width:592px;height:400px; background-color:#ff7fff;">3ページ</div> 7 <div style=" width:592px;height:400px; background-color: #bf7fff;">4ページ</div> 8 <div style=" width:592px;height:400px; background-color: #7f7fff;">5ページ</div> 9 <div style=" width:592px;height:400px; background-color: #7fbfff;">6ページ</div> 10 <div style=" width:592px;height:400px; background-color:#7fffff;">7ページ</div> 11 <div style=" width:592px;height:400px; background-color: #7fffbf;">8ページ</div> 12 <div style=" width:592px;height:400px; background-color:#7fff7f;">9ページ</div> 13 <div style=" width:592px;height:400px; background-color: #bfff7f;">10ページ</div> 14 <div style=" width:592px;height:400px; background-color: #ffff7f;">11ページ</div> 15 <div style=" width:592px;height:400px; background-color:#ffbf7f;">12ページ</div> 16 <div style=" width:592px;height:400px; background-color:#000;">13ページ</div> 17</span> 18</div> 19 20<input type="button" onclick="selected();" value=" 起動 " id="btn2"/> 21<select id="divno"> 22<option value="0" disabled >選択</option> 23<option value="1" selected>1ページ</option> 24<option value="2" >2ページ</option> 25<option value="3">3ページ</option> 26<option value="4">4ページ</option> 27<option value="5">5ページ</option> 28<option value="6">6ページ</option> 29<option value="7">7ページ</option> 30<option value="8">8ページ</option> 31<option value="9">9ページ</option> 32<option value="10">10ページ</option> 33<option value="11">11ページ</option> 34<option value="12">12ページ</option> 35</select>
JS
1var x, y; // box の座標 2 3 // コンボボックス 4 function selected() { 5 const objBox = document.getElementById("box"); 6 const cssStyle = window.getComputedStyle(objBox); 7 y = parseInt(cssStyle.top.match(/(.*)px/)[1]); 8 9 let anim = ''; 10 let divnofrom = (y / -400); // 現在の表示位置 11 let divnoto = document.getElementById('divno').selectedIndex; // 移動先の表示位置 12 let move = 0; // 移動距離 13 if (2 > divnoto){ 14 move = (divnofrom - divnoto + 1); 15 anim = 'moveUp' + move; 16 }else if (divnofrom < divnoto){ 17 move = (divnoto - divnofrom); 18 anim = 'moveDown' + move; 19 }else if (divnofrom > divnoto){ 20 move = (divnofrom - divnoto); 21 anim = 'moveUp' + move; 22 } 23 24 if (anim !== '') { 25 objBox.style.animationDuration = move + 's'; // アニメの実行速度設定 26 objBox.style.animationName = anim; // アニメ開始 27 btnsDisabled(true); // ボタン無効化 28 } 29 } 30 31 // animation 終了時の処理 32 document.addEventListener('animationend', () => { 33 let divnofrom = (y / -400); // 現在の表示位置 34 let divnoto = document.getElementById('divno').selectedIndex; // 移動先の表示位置 35 36 const objBox = document.getElementById("box"); 37 const cssStyle = window.getComputedStyle(objBox); 38 const arr = cssStyle.transform.match(/((.*))/)[1].split(","); // 文字列 matrix(a, b, c, d, cx, cy) を分解 39 y += parseInt(arr[5]); // transform.y の値を加える 40 41 if (2 > divnoto){ 42 objBox.setAttribute("rel" , "endmode0"); // この行を追加 43 }else if (divnofrom < divnoto){ 44 objBox.setAttribute("rel" , "endmode1"); // この行を追加 45 }else if (divnofrom > divnoto){ 46 objBox.setAttribute("rel" , "endmode2"); // この行を追加 47 } 48 49 objBox.style.transform = ''; // アニメした transform を消す 50 objBox.style.top = y + 'px'; 51 objBox.style.animationName = ''; // animationName を消す。こうしないと、次回に同じ方向のアニメが効かない。 52 objBox.style.animationDuration = ''; 53 objBox.style.animationFillMode = ''; 54 btnsDisabled(false); // ボタン有効化 55 56 }); 57 58 59 // 矢印ボタンの有効化/無効化 60 function btnsDisabled(arg) { 61 let btns = document.getElementsByTagName("input"); 62 for (let i = 0; i < btns.length; i++) { 63 btns[i].disabled = arg; 64 } 65 document.getElementById('divno').disabled = arg; // コンボボックス 66 }
css
1 2*[rel="endmode0"]{ 3animation-name: endmove0; 4animation-duration: 2s; 5 animation-timing-function: linear; 6 animation-fill-mode: forwards; 7} 8*[rel="endmode1"]{ 9animation-name: endmove1; 10animation-duration: 1s; 11 animation-timing-function: linear; 12 animation-fill-mode: forwards; 13} 14*[rel="endmode2"]{ 15animation-name: endmove2; 16animation-duration: 1s; 17 animation-timing-function: linear; 18 animation-fill-mode: forwards; 19} 20 21div.parent { 22 position: relative; 23 width: 592px; 24 height: 400px; 25 border: 1px solid #ddd; 26 overflow: hidden; 27} 28span.child { 29 position: absolute; 30 width : 592px; 31 height: 5600px; 32 left: 0px; 33 top:-400px; 34 animation-iteration-count: 1; 35 animation-timing-function: linear; 36 animation-fill-mode: forwards; 37} 38 39@keyframes endmove0 { 40 50% { transform:translateY(-420px); } 41 100% { transform:translateY(-400px); }} 42@keyframes endmove1 { 43 0% { transform:translateY(0px); } 44 5% { transform:translateY(-20px); } 45 100% { transform:translateY(0px);}} 46@keyframes endmove2 { 47 0% { transform:translateY(0px); } 48 5% { transform:translateY(20px); } 49 100% { transform:translateY(0px);}} 50 51 52@keyframes moveDown1 { 530% { transform:translateY(0px); } 54 100% { transform:translateY(-400px); }} 55@keyframes moveDown2 { 56 100% { transform:translateY(-800px); }} 57@keyframes moveDown3 { 58 100% { transform:translateY(-1200px); }} 59@keyframes moveDown4 { 60 100% { transform:translateY(-1600px); }} 61@keyframes moveDown5 { 62 100% { transform:translateY(-2000px); }} 63@keyframes moveDown6 { 64 100% { transform:translateY(-2400px); }} 65@keyframes moveDown7 { 66 100% { transform:translateY(-2800px); }} 67@keyframes moveDown8 { 68 100% { transform:translateY(-3200px); }} 69@keyframes moveDown9 { 70 100% { transform:translateY(-3600px); }} 71@keyframes moveDown10 { 72 100% { transform:translateY(-4000px); }} 73@keyframes moveDown11 { 74 100% { transform:translateY(-4400px); }} 75@keyframes moveDown12 { 76 100% { transform:translateY(-4800px); }} 77 78 79@keyframes moveUp1 { 80 100% { transform:translateY(400px); }} 81@keyframes moveUp2 { 82 100% { transform:translateY(800px); }} 83@keyframes moveUp3 { 84 100% { transform:translateY(1200px); }} 85@keyframes moveUp4 { 86 100% { transform:translateY(1600px); }} 87@keyframes moveUp5 { 88 100% { transform:translateY(2000px); }} 89@keyframes moveUp6 { 90 100% { transform:translateY(2400px); }} 91@keyframes moveUp7 { 92 100% { transform:translateY(2800px); }} 93@keyframes moveUp8 { 94 100% { transform:translateY(3200px); }} 95@keyframes moveUp9 { 96 100% { transform:translateY(3600px); }} 97@keyframes moveUp10 { 98 100% { transform:translateY(4000px); }} 99@keyframes moveUp11 { 100 100% { transform:translateY(4400px); }} 101@keyframes moveUp12 { 102 100% { transform:translateY(4800px); }}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/14 11:29 編集
2020/12/14 13:08
2020/12/15 06:30
2020/12/15 06:45