feat: Enhance animations for feature and value icons, and update platform row stagger logic

This commit is contained in:
Matt Batchelder
2026-04-05 20:09:21 -04:00
parent 2548179a8d
commit 4e833fd836
3 changed files with 49 additions and 174 deletions

View File

@@ -1,22 +1,24 @@
/**
* Feature Section Card Animator
* Staggered scroll-reveal entrance + icon pop-in for .feature-section cards.
* Staggered scroll-reveal entrance + icon pop-in for .feature-section and
* .value-section cards, plus stagger for .platform-row elements.
* Coordinates with the main.js scroll-hidden/visible system:
* 1. Sets --scroll-delay CSS custom property on each card so main.js's
* 1. Sets --scroll-delay CSS custom property on each card/row so main.js's
* scroll-visible transition fires at staggered intervals.
* 2. Uses MutationObserver to detect when scroll-visible is applied, then
* triggers the icon-pop animation on the card's .feature-icon.
* triggers the icon-pop animation on the card's .feature-icon or .value-icon.
* 3. Resets the delay to 0s after the entrance so hover interactions stay snappy.
*/
(function () {
'use strict';
var STAGGER = 0.08; // seconds between each card's entrance
var ROW_STAGGER = 0.12; // slightly longer stagger for platform-row blocks
document.addEventListener('DOMContentLoaded', function () {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
// 1. Assign incrementing --scroll-delay to every card within a feature-section.
// 1. Assign incrementing --scroll-delay to every card within a feature/value-section.
// The block renders .grid-2/.grid-3/.grid-4 wrappers (no .feature-section class).
// main.js's .scroll-visible rule reads this via var(--scroll-delay, 0s).
document.querySelectorAll('.grid-2, .grid-3, .grid-4').forEach(function (grid) {
@@ -25,6 +27,21 @@
});
});
// 1b. Assign incrementing --scroll-delay to .platform-row elements grouped
// by their parent container, so rows in the same section stagger in sequence.
var rowGroups = new Map();
document.querySelectorAll('.platform-row').forEach(function (row) {
var parent = row.parentElement;
if (!parent) return;
if (!rowGroups.has(parent)) rowGroups.set(parent, []);
rowGroups.get(parent).push(row);
});
rowGroups.forEach(function (rows) {
rows.forEach(function (row, i) {
row.style.setProperty('--scroll-delay', (i * ROW_STAGGER).toFixed(2) + 's');
});
});
// 2. Watch for scroll-visible being added to each card.
var cards = document.querySelectorAll('.grid-2 .oribi-card, .grid-3 .oribi-card, .grid-4 .oribi-card');
if (!cards.length) return;
@@ -37,7 +54,8 @@
mo.unobserve(card);
// Trigger icon pop ~150ms after the card itself starts fading in.
var icon = card.querySelector('.feature-icon');
// Supports both .feature-icon (feature-cards) and .value-icon (value-cards).
var icon = card.querySelector('.feature-icon') || card.querySelector('.value-icon');
if (icon) {
var cardDelay = parseFloat(card.style.getPropertyValue('--scroll-delay')) || 0;
icon.style.animationDelay = (cardDelay + 0.15).toFixed(2) + 's';