Adds a 'See it in motion' section on the Tokunia landing page with the rendered motion-design video (re-encoded 44MB -> ~20MB via ffmpeg libx264 CRF 23, same resolution/duration) and poster frame. Autoplay muted on load, tap/click the overlay button to unmute (browsers block unmuted autoplay anyway), styled to match the page's dark ink/receipt aesthetic.
78 lines
2.1 KiB
JavaScript
78 lines
2.1 KiB
JavaScript
/**
|
|
* The receipt prints itself, once, when it first scrolls into view — each
|
|
* `[data-line]` gets an index the stylesheet turns into an animation delay.
|
|
*
|
|
* The `js` class is what arms the hidden-until-printed state, so a page with
|
|
* JS disabled (or a reduced-motion reader, handled in CSS) simply shows the
|
|
* finished receipt.
|
|
*/
|
|
(function () {
|
|
"use strict";
|
|
|
|
var root = document.documentElement;
|
|
var receipt = document.querySelector(".receipt");
|
|
if (!receipt) return;
|
|
|
|
var lines = receipt.querySelectorAll("[data-line]");
|
|
if (!lines.length) return;
|
|
|
|
root.classList.add("js");
|
|
Array.prototype.forEach.call(lines, function (el, i) {
|
|
el.style.setProperty("--i", String(i));
|
|
});
|
|
|
|
var print = function () {
|
|
receipt.classList.add("receipt--printing");
|
|
};
|
|
|
|
if (!("IntersectionObserver" in window)) {
|
|
print();
|
|
return;
|
|
}
|
|
|
|
var io = new IntersectionObserver(
|
|
function (entries) {
|
|
entries.forEach(function (entry) {
|
|
if (!entry.isIntersecting) return;
|
|
print();
|
|
io.disconnect();
|
|
});
|
|
},
|
|
{ threshold: 0.2 },
|
|
);
|
|
io.observe(receipt);
|
|
})();
|
|
|
|
/**
|
|
* The reel loads muted (browsers block unmuted autoplay anyway) and the
|
|
* overlay button is the only way to turn sound on — clicking it just flips
|
|
* `video.muted` and mirrors the state onto the button for the icon/label.
|
|
*/
|
|
(function () {
|
|
"use strict";
|
|
|
|
var video = document.querySelector(".reel__video");
|
|
var button = document.querySelector(".reel__sound");
|
|
if (!video || !button) return;
|
|
|
|
var label = button.querySelector(".reel__sound-label");
|
|
|
|
var render = function () {
|
|
var unmuted = !video.muted;
|
|
button.classList.toggle("is-unmuted", unmuted);
|
|
button.setAttribute("aria-pressed", String(unmuted));
|
|
if (label) label.textContent = unmuted ? "Sound off" : "Sound on";
|
|
};
|
|
|
|
button.addEventListener("click", function () {
|
|
video.muted = !video.muted;
|
|
if (!video.muted) {
|
|
// Some browsers pause autoplay once it's no longer silent.
|
|
video.play().catch(function () {});
|
|
}
|
|
render();
|
|
});
|
|
|
|
render();
|
|
})();
|