marqueeをCSS,JAVASCRIPTで代替する(*入れ子がある場合)
下記のソースコードは、marqueeのいくつかの機能をボタンでコントロールさせることを、
CSSとJavascriptで代替させたものです。描写は、ヘビの左右の動きと,移動速度を調節
させるだけのシンプルなものです。これに、"舌を上下にちょろちょろさせる"動きと、
"尻尾(*ここでは、音符記号)を上下にパタパタさせる"動きを加える場合、どのように
ソースコードを書き加えればいいのでしょうか。ご教示ください。
<!DOCTYPE html>
<html>
<head>
<style>
.option{color:red;}
[data-marquee]{ display: inline-block;
transform: translateX(-100%); }
.marquee_container { overflow-x: hidden; }
.DIRECTION {
color: white;
background: black;
}
.BLINK {
animation: blink 1s step-end infinite normal;
}
@keyframes blink {
0% { color: red; }
50% { color: transparent; }
}
</style>
</head>
<body>
<div id="myMarquee" class="marquee_container">
<div id="hello" data-marquee="left" data-marquee-sec="10">
<span id="tongue" class="option" style="font-size:10px"> ~</span>>゜~~~~<span id="note" class="option">♪</span>
</div>
</div>
<p>
<button id="blinkL" class="DIRECTION BLINK" type="button" onClick="hello.dataset.marquee='left'; marquee(hello); marLeft();">
←
</button>
☆
<select id='marSpeed' name="speedSelector" onchange='marSpeed(this)'>
<option value='Faster'> Faster</option>
<option value='Normal Speed' selected> (Normal)</option>
<option value='Slower'> Slower</option>
<option value='Stop'>―STOP―</option>
<option value='Reset'> RESET</option>
</select>
☆
<button id="blinkR" class="DIRECTION" type="button" onClick="hello.dataset.marquee='right'; marquee(hello); marRight();">
→
</button>
</p>
<script type="text/javascript">
function marLeft() {
document.getElementById("blinkL").classList.add("BLINK");
document.getElementById("blinkR").classList.remove("BLINK");
}
function marRight() {
document.getElementById("blinkR").classList.add("BLINK");
document.getElementById("blinkL").classList.remove("BLINK");
}
function setDefaultSetting(){
// 左方向に10秒かけて1週する
hello.dataset.marquee='left';
hello.dataset.marqueeSec='10';
// ボタンの点灯
marLeft();
// (Normal) を選択した状態にする
document.getElementById('marSpeed').options[1].selected = true;
// 元の位置に戻す
hello.style.transform = "translateX(-100%)";
hello.style.transition = "transform 0s linear 0s";
}
function marSpeed(opt){
var selectedIndex = opt.selectedIndex;
hello.dataset.marqueeSec='10';
marquee(hello);
document.getElementById('blinkL').disabled=false;
document.getElementById('blinkR').disabled=false;
if(selectedIndex==0){
hello.dataset.marqueeSec='5';
marquee(hello);
}
else if(selectedIndex==2){
hello.dataset.marqueeSec='20';
marquee(hello);
}
else if(selectedIndex==3){
document.getElementById('blinkL').disabled=true;
document.getElementById('blinkR').disabled=true;
document.getElementById('blinkL').classList.remove("BLINK");
document.getElementById('blinkR').classList.remove("BLINK");
hello.dataset.marquee='stop';
marquee(hello);
}
else if(selectedIndex==4){
setDefaultSetting();
marquee(hello);
}
}
function marquee(elm_or_event){
"use strict";
function current(){
return getComputedStyle(elm).transform.split(",")[4] || 0;
}
function to(px, sec){
elm.style.transform = "translateX(" + px + "px)";
elm.style.transition = "transform " + sec + "s linear 0s";
}
function scroll(px){
elm.addEventListener("transitionend", marquee, false);
to(px, Math.abs((px - current())/right * elm.dataset.marqueeSec));
}
var elm = elm_or_event.target || elm_or_event;
var right = elm.parentElement.getBoundingClientRect().width;
var left = -elm.getBoundingClientRect().width;
elm.removeEventListener("transitionend", marquee, false);
to(current(), 0);
if(elm.dataset.marquee == "stop"){
return;
}
if(current()+1 >= right){
to(left, 0);
}
else if(current()-1 <= left){
to(right, 0);
}
scroll((elm.dataset.marquee == "left") ? left : right);
}
marquee(hello);
</script>
</body>
</html>