Add device animation functionality to platform row and enhance CSS for visual effects
This commit is contained in:
@@ -1984,6 +1984,348 @@ p:last-child { margin-bottom: 0; }
|
||||
.platform-row.reverse .platform-visual { order: unset; }
|
||||
}
|
||||
|
||||
/* ── 10b. Device Animator ───────────────────────────────────── */
|
||||
.platform-visual.has-anim {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
font-size: inherit;
|
||||
}
|
||||
.da-stage {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
}
|
||||
/* Each device panel – hidden by default, centred in stage */
|
||||
.da-device {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) scale(0.88);
|
||||
opacity: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
transition: opacity 0.55s cubic-bezier(0.4,0,0.2,1),
|
||||
transform 0.55s cubic-bezier(0.4,0,0.2,1);
|
||||
will-change: opacity, transform;
|
||||
}
|
||||
.da-device.is-active {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
.da-device.is-leaving {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%) scale(1.07);
|
||||
}
|
||||
/* Screen surface */
|
||||
.da-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 2px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background:
|
||||
repeating-linear-gradient(
|
||||
180deg,
|
||||
transparent,
|
||||
transparent 3px,
|
||||
rgba(0,0,0,0.10) 3px,
|
||||
rgba(0,0,0,0.10) 4px
|
||||
),
|
||||
linear-gradient(135deg, #0c1016 0%, #151c28 60%, #0c1016 100%);
|
||||
}
|
||||
.da-screen::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -20%;
|
||||
left: -10%;
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
background: radial-gradient(ellipse, rgba(74,222,128,0.12) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
}
|
||||
@keyframes da-scan {
|
||||
0% { top: -6%; opacity: 0; }
|
||||
5% { opacity: 1; }
|
||||
95% { opacity: 1; }
|
||||
100% { top: 106%; opacity: 0; }
|
||||
}
|
||||
.da-screen::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, transparent, rgba(74,222,128,0.28), transparent);
|
||||
animation: da-scan 3s linear infinite;
|
||||
pointer-events: none;
|
||||
}
|
||||
/* Device label */
|
||||
.da-label {
|
||||
display: block;
|
||||
margin-top: 11px;
|
||||
font-size: 0.68rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-text-muted);
|
||||
text-align: center;
|
||||
}
|
||||
/* ── Tablet ────────────────────────────────────── */
|
||||
.da-tablet .da-body {
|
||||
width: 128px;
|
||||
height: 194px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 2px solid var(--color-border);
|
||||
border-radius: 14px;
|
||||
padding: 10px 8px 14px;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
box-shadow: 0 16px 48px rgba(0,0,0,0.50);
|
||||
}
|
||||
.da-tablet .da-body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background: var(--color-border);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.da-tablet .da-body::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 36px;
|
||||
height: 3px;
|
||||
background: var(--color-border);
|
||||
border-radius: 2px;
|
||||
}
|
||||
/* ── Small Monitor ─────────────────────────────── */
|
||||
.da-monitor-sm .da-body {
|
||||
width: 236px;
|
||||
height: 146px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 5px solid var(--color-bg-alt);
|
||||
border-radius: 6px;
|
||||
outline: 1px solid var(--color-border);
|
||||
padding: 3px;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
box-shadow: 0 10px 36px rgba(0,0,0,0.50);
|
||||
}
|
||||
.da-monitor-sm .da-body::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -9px;
|
||||
right: 8px;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: var(--color-primary);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 5px var(--color-primary);
|
||||
}
|
||||
.da-monitor-sm .da-stand,
|
||||
.da-monitor-lg .da-stand { display: flex; flex-direction: column; align-items: center; }
|
||||
.da-monitor-sm .da-stem {
|
||||
width: 14px;
|
||||
height: 20px;
|
||||
background: var(--color-bg-alt);
|
||||
border-left: 1px solid var(--color-border);
|
||||
border-right: 1px solid var(--color-border);
|
||||
}
|
||||
.da-monitor-sm .da-base {
|
||||
width: 68px;
|
||||
height: 5px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 3px;
|
||||
}
|
||||
/* ── Large Monitor ─────────────────────────────── */
|
||||
.da-monitor-lg .da-body {
|
||||
width: 298px;
|
||||
height: 177px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 4px solid var(--color-bg-alt);
|
||||
border-radius: 6px;
|
||||
outline: 1px solid var(--color-border);
|
||||
padding: 3px;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
box-shadow: 0 12px 40px rgba(0,0,0,0.50);
|
||||
}
|
||||
.da-monitor-lg .da-stem {
|
||||
width: 16px;
|
||||
height: 26px;
|
||||
background: var(--color-bg-alt);
|
||||
border-left: 1px solid var(--color-border);
|
||||
border-right: 1px solid var(--color-border);
|
||||
}
|
||||
.da-monitor-lg .da-base {
|
||||
width: 88px;
|
||||
height: 5px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 3px;
|
||||
}
|
||||
/* ── TV ────────────────────────────────────────── */
|
||||
.da-tv .da-body {
|
||||
width: 320px;
|
||||
height: 188px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 4px solid var(--color-bg-alt);
|
||||
border-radius: 6px 6px 4px 4px;
|
||||
outline: 1px solid var(--color-border);
|
||||
padding: 3px;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
box-shadow: 0 14px 48px rgba(0,0,0,0.55);
|
||||
}
|
||||
.da-tv .da-body::after {
|
||||
content: '\25B6';
|
||||
position: absolute;
|
||||
bottom: -13px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 8px;
|
||||
color: rgba(74,222,128,0.7);
|
||||
}
|
||||
.da-tv .da-feet { display: flex; justify-content: space-between; width: 180px; }
|
||||
.da-tv .da-foot {
|
||||
width: 12px;
|
||||
height: 8px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
/* ── Projector ─────────────────────────────────── */
|
||||
.da-projector .da-proj-layout { display: flex; flex-direction: column; align-items: center; }
|
||||
.da-projector .da-proj-body {
|
||||
width: 156px;
|
||||
height: 62px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 10px 10px 8px 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 14px;
|
||||
gap: 10px;
|
||||
box-shadow: 0 6px 20px rgba(0,0,0,0.45);
|
||||
position: relative;
|
||||
}
|
||||
.da-projector .da-proj-body::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 10px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background: var(--color-primary);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 6px var(--color-primary);
|
||||
}
|
||||
.da-projector .da-proj-body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 8px;
|
||||
width: 28px;
|
||||
height: 8px;
|
||||
background: repeating-linear-gradient(
|
||||
90deg,
|
||||
var(--color-border) 0px,
|
||||
var(--color-border) 2px,
|
||||
transparent 2px,
|
||||
transparent 5px
|
||||
);
|
||||
border-radius: 1px;
|
||||
}
|
||||
.da-projector .da-lens {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
background: #080c12;
|
||||
border: 2px solid var(--color-border);
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
box-shadow: inset 0 0 8px rgba(0,0,0,0.8);
|
||||
}
|
||||
.da-projector .da-lens::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 5px;
|
||||
background: radial-gradient(circle at 35% 35%, rgba(74,222,128,0.30) 0%, #080c12 65%);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.da-projector .da-beam {
|
||||
width: 240px;
|
||||
height: 50px;
|
||||
clip-path: polygon(31% 0%, 69% 0%, 100% 100%, 0% 100%);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(74,222,128,0.07) 0%,
|
||||
rgba(74,222,128,0.02) 100%
|
||||
);
|
||||
}
|
||||
.da-projector .da-proj-screen {
|
||||
width: 240px;
|
||||
height: 72px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
padding: 3px;
|
||||
box-shadow: 0 4px 14px rgba(0,0,0,0.40);
|
||||
}
|
||||
/* ── Video Wall (2×2) ──────────────────────────── */
|
||||
.da-vwall .da-vwall-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
gap: 5px;
|
||||
background: #0a0d12;
|
||||
padding: 5px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 14px 48px rgba(0,0,0,0.60);
|
||||
}
|
||||
.da-vwall .da-panel {
|
||||
width: 148px;
|
||||
height: 90px;
|
||||
background: var(--color-bg-alt);
|
||||
border: 2px solid var(--color-bg-alt);
|
||||
padding: 2px;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
overflow: hidden;
|
||||
}
|
||||
.da-vwall .da-panel:nth-child(2) .da-screen::after { animation-delay: -0.75s; }
|
||||
.da-vwall .da-panel:nth-child(3) .da-screen::after { animation-delay: -1.5s; }
|
||||
.da-vwall .da-panel:nth-child(4) .da-screen::after { animation-delay: -2.25s; }
|
||||
/* ── Responsive scale-down ─────────────────────── */
|
||||
@media (max-width: 900px) {
|
||||
.da-device { transform: translate(-50%,-50%) scale(0.76); }
|
||||
.da-device.is-active { transform: translate(-50%,-50%) scale(0.84); }
|
||||
.da-device.is-leaving { transform: translate(-50%,-50%) scale(0.91); }
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.da-device { transform: translate(-50%,-50%) scale(0.56); }
|
||||
.da-device.is-active { transform: translate(-50%,-50%) scale(0.64); }
|
||||
.da-device.is-leaving { transform: translate(-50%,-50%) scale(0.70); }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.da-device { transition: none; }
|
||||
.da-screen::after { animation: none; }
|
||||
}
|
||||
|
||||
/* ── 11. Page Hero (inner pages) ───────────────────────────── */
|
||||
.page-hero {
|
||||
background: #111111;
|
||||
|
||||
@@ -610,3 +610,68 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
paintBg();
|
||||
start();
|
||||
})();
|
||||
|
||||
/* ── Device Animator ──────────────────────────────────────────────────────── */
|
||||
(function () {
|
||||
const DEVICES = [
|
||||
'da-tablet', 'da-monitor-sm', 'da-monitor-lg',
|
||||
'da-tv', 'da-projector', 'da-vwall'
|
||||
];
|
||||
const DWELL = 2500; // ms each device is shown
|
||||
|
||||
document.querySelectorAll('.da-stage').forEach(function (stage) {
|
||||
let current = 0;
|
||||
let timer = null;
|
||||
|
||||
// Collect the 6 device panels
|
||||
const panels = DEVICES.map(function (cls) {
|
||||
return stage.querySelector('.' + cls);
|
||||
});
|
||||
|
||||
function show(idx) {
|
||||
panels.forEach(function (el, i) {
|
||||
if (!el) return;
|
||||
el.classList.toggle('is-active', i === idx);
|
||||
el.classList.remove('is-leaving');
|
||||
});
|
||||
}
|
||||
|
||||
function advance() {
|
||||
const leaving = current;
|
||||
current = (current + 1) % DEVICES.length;
|
||||
if (panels[leaving]) panels[leaving].classList.add('is-leaving');
|
||||
show(current);
|
||||
setTimeout(function () {
|
||||
if (panels[leaving]) panels[leaving].classList.remove('is-leaving');
|
||||
}, 600);
|
||||
}
|
||||
|
||||
function startCycle() {
|
||||
if (timer) return;
|
||||
timer = setInterval(advance, DWELL);
|
||||
}
|
||||
|
||||
function stopCycle() {
|
||||
clearInterval(timer);
|
||||
timer = null;
|
||||
}
|
||||
|
||||
// Honour reduced-motion preference: show first device statically
|
||||
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
show(0);
|
||||
return;
|
||||
}
|
||||
|
||||
show(0);
|
||||
startCycle();
|
||||
|
||||
// Pause when scrolled out of view to save resources
|
||||
if ('IntersectionObserver' in window) {
|
||||
new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (e) {
|
||||
e.isIntersecting ? startCycle() : stopCycle();
|
||||
});
|
||||
}, { threshold: 0.2 }).observe(stage);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -553,6 +553,7 @@ add_action( 'init', function () {
|
||||
'imgUrl' => [ 'type' => 'string', 'default' => '' ],
|
||||
'imgAlt' => [ 'type' => 'string', 'default' => '' ],
|
||||
'imgWidth' => [ 'type' => 'number', 'default' => 300 ],
|
||||
'deviceAnim' => [ 'type' => 'boolean', 'default' => false ],
|
||||
],
|
||||
'supports' => $block_supports,
|
||||
'render_callback' => 'oribi_render_platform_row',
|
||||
@@ -1346,6 +1347,17 @@ function oribi_render_platform_row( $a ) {
|
||||
$visual_html = '<img src="' . esc_url( $img_url ) . '" alt="' . esc_attr( $img_alt ) . '" style="' . esc_attr( $img_style ) . '">';
|
||||
}
|
||||
$visual_cls = 'platform-visual has-img';
|
||||
} elseif ( ! empty( $a['deviceAnim'] ) ) {
|
||||
$da = '<div class="da-stage" aria-hidden="true">';
|
||||
$da .= '<div class="da-device da-tablet"><div class="da-body"><div class="da-screen"></div></div><span class="da-label">Tablet</span></div>';
|
||||
$da .= '<div class="da-device da-monitor-sm"><div class="da-body"><div class="da-screen"></div></div><div class="da-stand"><div class="da-stem"></div><div class="da-base"></div></div><span class="da-label">Small Monitor</span></div>';
|
||||
$da .= '<div class="da-device da-monitor-lg"><div class="da-body"><div class="da-screen"></div></div><div class="da-stand"><div class="da-stem"></div><div class="da-base"></div></div><span class="da-label">Large Monitor</span></div>';
|
||||
$da .= '<div class="da-device da-tv"><div class="da-body"><div class="da-screen"></div></div><div class="da-feet"><div class="da-foot"></div><div class="da-foot"></div></div><span class="da-label">TV</span></div>';
|
||||
$da .= '<div class="da-device da-projector"><div class="da-proj-layout"><div class="da-proj-body"><div class="da-lens"></div></div><div class="da-beam"></div><div class="da-proj-screen"><div class="da-screen"></div></div></div><span class="da-label">Projector</span></div>';
|
||||
$da .= '<div class="da-device da-vwall"><div class="da-vwall-grid"><div class="da-panel"><div class="da-screen"></div></div><div class="da-panel"><div class="da-screen"></div></div><div class="da-panel"><div class="da-screen"></div></div><div class="da-panel"><div class="da-screen"></div></div></div><span class="da-label">Video Wall</span></div>';
|
||||
$da .= '</div>';
|
||||
$visual_html = $da;
|
||||
$visual_cls = 'platform-visual has-anim';
|
||||
} else {
|
||||
$visual_html = oribi_render_icon( $a['visual'] ?? '' );
|
||||
$visual_cls = 'platform-visual';
|
||||
|
||||
Reference in New Issue
Block a user