main#home-page(data-wrapper="", role="main")
.container-fluid
h2.font-sz-4xl.font-sans.font-600 Playback Controls
.jumbotron.jumbotron-fluid.my-2.p-4.rounded-lg.box-shadow.text-dark.bg-warning
.playback-demo
- for (let i = 0; i < 5; i ++) {
.contain
.el
.el-initial
- }
.controls.row.mx-0.mt-5.align-items-center
.col-2
button#playstate-toggle.btn.btn-light(
type="button",
title="Play/Pause Toggle",
data-playstate="paused"
)
i.fa.fa-play(aria-hidden="true")
i.fa.fa-pause(aria-hidden="true")
i.fa.fa-redo(aria-hidden="true")
span.text-center(id=`progress-output`) 0
input#progress.col-10.form-control-range(
type="range",
value="0",
min="0",
max="100",
steps="0.0001"
)
View Compiled
html,
body {
font-family: Manrope, sans-serif;
}
.div {
@apply bg-blue-400 w-10 h-10 rounded relative m-2;
--size: 8vmin;
width: var(--size);
height: var(--size);
}
.el,
.el-initial {
--size: 4vmin;
width: var(--size);
height: var(--size);
margin: 5px;
background: #616aff;
position: relative;
}
.svg {
margin: auto;
display: block;
width: 500px;
height: 300px;
max-height: 100vh;
max-width: 100%;
& path {
stroke: #fff2b1;
stroke-dasharray: 400 400;
stroke-dashoffset: 0;
}
}
.el-initial {
opacity: 0.6;
position: absolute;
display: block;
margin-top: 0;
top: 0;
}
.animation-container {
transition: background-color 0.5s ease;
background-color: rgba(0, 0, 0, 0.085);
border-radius: 5px;
padding: 5px;
cursor: pointer;
&:hover {
background-color: rgba(255, 255, 255, 0.25);
}
}
.contain {
position: relative;
}
.animation-container + .animation-container {
margin-top: 2em;
}
input[type="range"] {
width: 100%;
padding: 0;
margin: 0;
}
html:not(.unsupported) .support {
display: none;
}
.col-2 {
display: flex;
justify-content: space-between;
align-items: center;
}
#playstate-toggle[data-playstate="running"] {
.fa-play,
.fa-redo {
display: none;
}
}
#playstate-toggle[data-playstate="paused"] {
.fa-pause,
.fa-redo {
display: none;
}
}
#playstate-toggle[data-playstate="finished"] {
.fa-play,
.fa-pause {
display: none;
}
}
View Compiled
import { animate } from "https://cdn.skypack.dev/@okikio/animate";
(() => {
let containerSel = ".playback-demo";
let playstateEl = document.querySelector(
"#playstate-toggle"
) as HTMLInputElement;
let progressEl = document.querySelector("#progress") as HTMLInputElement;
let progressOutputEl = document.querySelector("#progress-output");
let progressValue = progressEl.value;
let oldState: AnimationPlayState;
let DOMNodes = document.querySelectorAll(`${containerSel} .el`);
let anim = animate({
target: DOMNodes,
transform: ["translateX(0px)", "translateX(300px)"],
opacity(index, total, element) {
return [0, (index + 1) / total];
},
fillMode: "both",
easing: "out-cubic",
loop: 1,
speed: 1,
direction: "alternate",
delay(index) {
return ((index + 1) * 500) / 2;
},
duration(index: number) {
return (index + 1) * 500;
},
padEndDelay: true,
autoplay: true
});
let updatePlayState = () => {
oldState = anim.getPlayState();
playstateEl.setAttribute("data-playstate", oldState);
};
anim.on("finish begin", updatePlayState).on("update", (progress) => {
progressEl.value = `` + progress.toFixed(4);
progressOutputEl.textContent = `${Math.round(progress)}%`;
});
playstateEl.addEventListener("click", () => {
if (anim.is("running")) anim.pause();
else if (anim.is("finished")) anim.reset();
else anim.play();
updatePlayState();
});
progressEl.addEventListener("input", (e) => {
let percent = Number(progressEl.value);
anim.pause();
anim.setProgress(percent);
});
progressEl.addEventListener("change", () => {
oldState !== "paused" ? anim.play() : anim.pause();
updatePlayState();
});
})();
View Compiled