v1.0.1
MENU ANIMATIONS
ADVANCED EFFECTS
CORE BACKGROUND
UI SURECART
BUTTONS
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page Transition 004 Configurator - BricksFusion</title>
<style>
:root {
--background: #000;
--card-bg: #1e1e1e;
--card-bg-hover: #252525;
--text-primary: #f2f2f7;
--text-secondary: #8e8e93;
--accent: #b4ff99;
--accent-hover: #a1e588;
--border: #2c2c2e;
--shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
--track: #2c2c2e;
--thumb: #b4ff99;
--card-radius: 16px;
--input-radius: 8px;
--button-radius: 12px;
--transition: all 0.25s ease;
--font: 'Inter', BlinkMacSystemFont, "San Francisco", "Helvetica Neue", Helvetica, Arial, sans-serif;
--action-bar-height: 70px;
--success: #28a745;
--warning: #ffc107;
--danger: #dc3545;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font);
background-color: var(--background);
color: var(--text-primary);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding-bottom: var(--action-bar-height);
}
.action-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: var(--action-bar-height);
background: linear-gradient(145deg, #1a1a1a, #0f0f0f);
border-top: 1px solid var(--border);
z-index: 1000;
display: flex;
align-items: center;
padding: 0 1.5rem;
gap: 1rem;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(10px);
}
.breadcrumb {
display: flex;
align-items: center;
gap: 0.5rem;
flex: 1;
}
.breadcrumb-item {
color: var(--text-secondary);
font-size: var(--text-xs);
font-weight: 500;
text-decoration: none;
transition: var(--transition);
padding: 0.5rem 0.75rem;
border-radius: 6px;
}
.breadcrumb-item:hover {
color: var(--text-primary);
background-color: rgba(255, 255, 255, 0.05);
}
.breadcrumb-item.active {
color: var(--accent);
background-color: rgba(180, 255, 153, 0.1);
}
.breadcrumb-separator {
color: var(--text-secondary);
font-size: var(--text-xs);
opacity: 0.5;
}
.action-buttons {
display: flex;
align-items: center;
gap: 0.75rem;
}
.action-btn {
padding: 0.6rem 1rem;
background-color: var(--card-bg);
color: var(--text-primary);
font-family: var(--font);
font-size: var(--text-xs);
font-weight: 500;
border: 1px solid var(--border);
border-radius: var(--button-radius);
cursor: pointer;
transition: var(--transition);
display: flex;
align-items: center;
gap: 0.5rem;
text-decoration: none;
white-space: nowrap;
}
.action-btn:hover {
background-color: var(--card-bg-hover);
border-color: var(--accent);
transform: translateY(-1px);
}
.action-btn.primary {
background: linear-gradient(90deg, var(--accent), #a1e588);
border-color: var(--accent);
color: #000;
font-weight: 600;
}
.action-btn.primary:hover {
background: linear-gradient(90deg, var(--accent-hover), #90d477);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(180, 255, 153, 0.3);
}
.container {
max-width: 100%;
margin: 0 auto;
padding: 2rem 1.5rem;
}
.page-header {
text-align: center;
margin-bottom: 2rem;
}
.page-title {
font-size: 2.5rem;
font-weight: 700;
color: var(--text-primary);
margin-bottom: 0.5rem;
background: linear-gradient(90deg, var(--accent), #a1e588);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.page-subtitle {
font-size: var(--text-s);
color: var(--text-secondary);
font-weight: 500;
}
.instructions-toggle {
margin-bottom: 2rem;
}
.instructions-card {
background-color: var(--card-bg);
border: 1px solid var(--border);
border-radius: var(--card-radius);
box-shadow: var(--shadow);
overflow: hidden;
transition: var(--transition);
}
.instructions-header {
padding: 1rem 1.5rem;
cursor: pointer;
transition: var(--transition);
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid transparent;
}
.instructions-header:hover {
background-color: var(--card-bg-hover);
}
.instructions-card.expanded .instructions-header {
border-bottom-color: var(--border);
}
.instructions-title {
font-size: var(--text-s);
font-weight: 600;
}
.toggle-icon {
font-size: 1.2em;
transition: transform 0.3s ease;
}
.toggle-icon.expanded {
transform: rotate(180deg);
}
.instructions-content {
padding: 0 1.5rem;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease, padding 0.3s ease;
}
.instructions-content.show {
max-height: 500px;
padding: 1.5rem;
}
.instructions-grid {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
}
.how-to-use ol {
padding-left: 1.5rem;
}
.how-to-use li {
margin-bottom: 0.75rem;
font-size: var(--text-xs);
color: var(--text-secondary);
line-height: 1.6;
}
.how-to-use strong {
color: var(--text-primary);
font-weight: 600;
}
.how-to-use code {
background-color: rgba(50, 50, 50, 0.5);
padding: 0.2rem 0.5rem;
border-radius: 4px;
font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
font-size: var(--text-xs);
color: #b4ff99;
}
.content {
display: grid;
grid-template-columns: 1fr 500px;
gap: 2rem;
align-items: start;
}
.preview-section {
position: sticky;
top: 2rem;
}
.controls-section {
max-width: 500px;
}
.card {
background-color: var(--card-bg);
border-radius: var(--card-radius);
box-shadow: var(--shadow);
overflow: hidden;
margin-bottom: 1.5rem;
border: 1px solid var(--border);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
}
.preview-container {
height: 400px;
width: 100%;
position: relative;
overflow: hidden;
border-radius: var(--card-radius);
background-color: #000000;
border: 1px solid var(--border);
box-shadow: var(--shadow);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.preview-content {
color: white;
text-align: center;
font-weight: bold;
font-size: var(--text-s);
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
}
.preview-controls {
position: absolute;
top: 1rem;
right: 1rem;
display: flex;
gap: 0.5rem;
z-index: 10;
}
.preview-btn {
padding: 0.5rem;
background-color: rgba(0, 0, 0, 0.7);
color: white;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 6px;
cursor: pointer;
transition: var(--transition);
font-size: var(--text-xs);
backdrop-filter: blur(5px);
}
.preview-btn:hover {
background-color: var(--accent);
border-color: var(--accent);
color: #000;
}
.preview-btn svg {
width: 18px;
height: 18px;
stroke: currentColor;
}
.background-selector-wrapper {
position: relative;
display: inline-block;
}
.background-selector-btn {
position: relative;
}
.background-selector-btn:hover {
background-color: rgba(180, 255, 153, 0.2);
border-color: var(--accent);
box-shadow: 0 0 8px rgba(180, 255, 153, 0.3);
}
.hidden-color-input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
z-index: 1;
}
.card-heading {
padding: 1rem 1.5rem;
font-size: var(--text-s);
font-weight: 600;
border-bottom: 1px solid var(--border);
letter-spacing: 0.3px;
display: flex;
justify-content: space-between;
align-items: center;
}
.card-actions {
display: flex;
gap: 0.5rem;
}
.card-action-btn {
padding: 0.4rem 0.8rem;
background-color: transparent;
color: var(--text-secondary);
border: 1px solid var(--border);
border-radius: 6px;
cursor: pointer;
font-size: var(--text-xs);
transition: var(--transition);
}
.card-action-btn:hover {
color: var(--text-primary);
border-color: var(--accent);
background-color: rgba(180, 255, 153, 0.1);
}
.card-content {
padding: 1.5rem;
}
.control-group {
margin-bottom: 1.5rem;
position: relative;
}
.control-group:last-child {
margin-bottom: 0;
}
.control-label {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.75rem;
}
.label-text {
font-size: var(--text-xs);
font-weight: 500;
letter-spacing: 0.2px;
display: flex;
align-items: center;
gap: 0.5rem;
}
.help-tooltip {
cursor: help;
opacity: 0.7;
transition: var(--transition);
}
.help-tooltip:hover {
opacity: 1;
color: var(--accent);
}
.value-display {
display: flex;
align-items: center;
gap: 0.5rem;
}
.value-text {
font-size: var(--text-xs);
color: var(--text-secondary);
background-color: rgba(50, 50, 50, 0.5);
padding: 2px 8px;
border-radius: 4px;
min-width: 45px;
text-align: center;
}
.reset-btn {
padding: 0.2rem 0.4rem;
background-color: transparent;
color: var(--text-secondary);
border: 1px solid var(--border);
border-radius: 4px;
cursor: pointer;
font-size: 10px;
transition: var(--transition);
}
.reset-btn:hover {
color: var(--danger);
border-color: var(--danger);
background-color: rgba(220, 53, 69, 0.1);
}
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 6px;
background: var(--track);
border-radius: 3px;
outline: none;
margin: 0.8rem 0;
position: relative;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
background: var(--thumb);
border-radius: 50%;
cursor: pointer;
transition: var(--transition);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
input[type="range"]::-webkit-slider-thumb:hover {
transform: scale(1.2);
box-shadow: 0 0 10px rgba(180, 255, 153, 0.5);
}
.color-list {
display: flex;
flex-direction: column;
gap: 1rem;
margin-bottom: 1.5rem;
}
.color-row {
display: flex;
align-items: center;
gap: 1.25rem;
padding: 1rem 1.25rem;
background-color: rgba(30, 30, 30, 0.7);
border: 1px solid var(--border);
border-radius: var(--input-radius);
transition: var(--transition);
}
.color-row:hover {
border-color: var(--accent);
box-shadow: 0 0 0 1px rgba(180, 255, 153, 0.1);
}
.color-picker-container {
position: relative;
width: 40px;
height: 40px;
border-radius: 8px;
overflow: hidden;
border: 2px solid var(--border);
cursor: pointer;
transition: var(--transition);
flex-shrink: 0;
background: var(--card-bg);
display: flex;
align-items: center;
justify-content: center;
--selected-color: #000000;
}
.color-picker-container:hover {
border-color: var(--accent);
transform: scale(1.05);
box-shadow: 0 0 12px rgba(180, 255, 153, 0.3);
}
.color-picker-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--selected-color, #000000);
border-radius: 6px;
transition: var(--transition);
}
input[type="color"] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
cursor: pointer;
background: transparent;
opacity: 0;
z-index: 2;
}
.color-input-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.color-label {
font-size: 10px;
font-weight: 500;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-left: 0.25rem;
}
.color-input {
padding: 0.5rem 0.75rem;
background-color: rgba(0, 0, 0, 0.3);
border: 1px solid var(--border);
border-radius: 6px;
color: var(--text-primary);
font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
font-size: 12px;
transition: var(--transition);
min-width: 0;
}
.color-input:focus {
border-color: var(--accent);
box-shadow: 0 0 0 1px rgba(180, 255, 153, 0.2);
outline: none;
}
.color-input.invalid {
border-color: var(--danger);
box-shadow: 0 0 0 1px rgba(220, 53, 69, 0.2);
}
.hex-input,
.hsl-input {
width: 100%;
}
.color-input-group:nth-child(2) {
flex: 0.3;
}
.color-input-group:nth-child(3) {
flex: 0.7;
}
select {
width: 100%;
padding: 0.75rem;
border: 1px solid var(--border);
border-radius: var(--input-radius);
font-family: var(--font);
font-size: var(--text-xs);
color: var(--text-primary);
background-color: var(--card-bg);
margin-bottom: 0.75rem;
outline: none;
transition: var(--transition);
}
select:focus {
border-color: var(--accent);
box-shadow: 0 0 0 2px rgba(180, 255, 153, 0.2);
}
.notification {
position: fixed;
bottom: calc(var(--action-bar-height) + 1rem);
left: 50%;
background-color: var(--success);
color: white;
padding: 0.75rem 1rem;
border-radius: var(--input-radius);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
z-index: 1001;
transform: translate(-50%, 200px);
opacity: 0;
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease;
font-size: var(--text-xs);
font-weight: 500;
max-width: 320px;
word-wrap: break-word;
line-height: 1.4;
text-align: center;
}
.notification.show {
transform: translate(-50%, 0);
opacity: 1;
}
.PageTransition004-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10;
overflow: hidden;
pointer-events: none;
}
.PageTransition004-frame {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
transform: translate3d(0, -100%, 0);
transition: transform 1.2s cubic-bezier(0.645, 0.045, 0.355, 1);
will-change: transform;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
contain: layout style paint;
backface-visibility: hidden;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: var(--text-s);
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
.PageTransition004-frame::before {
content: "New Page";
z-index: 1;
}
.PageTransition004-frame.PageTransition004-active {
transform: translate3d(0, 0, 0);
}
.PageTransition004-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.2);
opacity: 0;
transition: opacity 0.3s ease;
}
.PageTransition004-overlay.PageTransition004-active {
opacity: 1;
}
@media (max-width: 1200px) {
.content {
grid-template-columns: 1fr;
gap: 1.5rem;
}
.preview-section {
position: static;
}
.controls-section {
max-width: 100%;
}
}
@media (max-width: 768px) {
.action-bar {
flex-direction: column;
height: auto;
min-height: var(--action-bar-height);
padding: 0.75rem;
}
.breadcrumb {
order: 1;
width: 100%;
}
.action-buttons {
order: 2;
width: 100%;
justify-content: center;
flex-wrap: wrap;
}
body {
padding-bottom: calc(var(--action-bar-height) + 20px);
}
.notification {
bottom: calc(var(--action-bar-height) + 2rem);
max-width: 280px;
transform: translate(-50%, 250px);
}
.notification.show {
transform: translate(-50%, 0);
opacity: 1;
}
.color-row {
flex-direction: column;
align-items: stretch;
gap: 1rem;
padding: 1rem;
}
.color-picker-container {
align-self: center;
margin-bottom: 0.5rem;
}
.color-input-group {
align-items: stretch;
}
.hex-input,
.hsl-input {
width: 100%;
}
.preview-container {
height: 300px;
}
.action-btn {
font-size: 11px;
padding: 0.5rem 0.8rem;
}
.page-title {
font-size: 2rem;
}
}
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
button:focus-visible,
input:focus-visible,
.action-btn:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: var(--background);
}
::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--accent);
}
.loading {
opacity: 0.6;
pointer-events: none;
position: relative;
}
.loading::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
margin: -10px 0 0 -10px;
border: 2px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="action-bar">
<nav class="breadcrumb">
<a href="https://bricksfusion.com" class="breadcrumb-item">Home</a>
<span class="breadcrumb-separator">›</span>
<a href="https://bricksfusion.com/transition-pages/" class="breadcrumb-item">Transition Pages</a>
<span class="breadcrumb-separator">›</span>
<span class="breadcrumb-item active">Page Transition 004</span>
</nav>
<div class="action-buttons">
<button class="action-btn primary" id="download-config" title="Copy JavaScript code (Ctrl+D)" data-protection-animation="true">
<span>⬇</span>
Copy JS
</button>
</div>
</div>
<div class="container">
<div class="page-header">
<h1 class="page-title">Page Transition 004</h1>
<p class="page-subtitle">Interactive page transitions for Bricks Builder</p>
</div>
<div class="instructions-toggle">
<div class="instructions-card" id="instructions-card">
<div class="instructions-header" id="instructions-toggle">
<div class="instructions-title">
How to Use & Code Information
</div>
<span class="toggle-icon">â–¼</span>
</div>
<div class="instructions-content" id="instructions-content">
<div class="instructions-grid">
<div class="how-to-use">
<ol>
<li>Customize your page transition effect using the controls below</li>
<li>Click <strong>Copy JS</strong> to copy the JavaScript code to clipboard</li>
<li>Go to your <strong>Template</strong> (Header/Footer) that appears on all pages</li>
<li>Click <strong>Manage</strong> → <strong>Page Settings</strong> → <strong>Custom Code</strong></li>
<li>Paste the code in <strong>Body (Footer) Scripts</strong> section</li>
<li>The smooth transition effect will now appear automatically when visitors navigate between pages on your website</li>
</ol>
</div>
</div>
</div>
</div>
</div>
<div class="content">
<section class="preview-section">
<div class="preview-container" id="transition-preview">
<div class="preview-content">Click here to test the transition effect</div>
<div class="preview-controls">
<button class="preview-btn" id="randomize-transition" title="Randomize (R)">🎲</button>
<div class="background-selector-wrapper">
<button class="preview-btn background-selector-btn" id="background-selector">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polygon points="12,2 2,7 12,12 22,7"/>
<polyline points="2,17 12,22 22,17"/>
<polyline points="2,12 12,17 22,12"/>
</svg>
</button>
<input type="color" id="preview-background-picker" class="hidden-color-input" value="#000000" title="Change Preview Background (B)">
</div>
</div>
<div class="PageTransition004-container" id="previewTransitionContainer">
<div id="previewFrame" class="PageTransition004-frame"></div>
<div class="PageTransition004-overlay" id="previewOverlay"></div>
</div>
</div>
</section>
<section class="controls-section">
<div class="card">
<div class="card-heading">
Transition Settings
<div class="card-actions">
<button class="card-action-btn" id="reset-transition" title="Reset Transition Settings">↺</button>
</div>
</div>
<div class="card-content">
<div class="control-group">
<div class="control-label">
<span class="label-text">
Animation Direction
<span class="help-tooltip" title="Direction of the transition animation">ℹ</span>
</span>
</div>
<select id="animation-direction">
<option value="top">From Top</option>
<option value="bottom">From Bottom</option>
<option value="left">From Left</option>
<option value="right">From Right</option>
</select>
</div>
<div class="control-group">
<div class="control-label">
<span class="label-text">
Desktop Duration
<span class="help-tooltip" title="Duration of transition on desktop devices">ℹ</span>
</span>
<div class="value-display">
<span class="value-text"><span id="desktop-duration-value">1.2</span>s</span>
<button class="reset-btn" onclick="resetParameter('desktop-duration', 1.2)">↺</button>
</div>
</div>
<input type="range" id="desktop-duration" min="0.5" max="3" step="0.1" value="1.2">
</div>
<div class="control-group">
<div class="control-label">
<span class="label-text">
Mobile Duration
<span class="help-tooltip" title="Duration of transition on mobile devices">ℹ</span>
</span>
<div class="value-display">
<span class="value-text"><span id="mobile-duration-value">0.8</span>s</span>
<button class="reset-btn" onclick="resetParameter('mobile-duration', 0.8)">↺</button>
</div>
</div>
<input type="range" id="mobile-duration" min="0.3" max="2" step="0.1" value="0.8">
</div>
<div class="control-group">
<div class="control-label">
<span class="label-text">
Easing Function
<span class="help-tooltip" title="Animation easing curve">ℹ</span>
</span>
</div>
<select id="easing-function">
<option value="cubic-bezier(0.645, 0.045, 0.355, 1)">Smooth (Default)</option>
<option value="ease">Easy</option>
<option value="ease-in">Ease In</option>
<option value="ease-out">Ease Out</option>
<option value="ease-in-out">Ease In Out</option>
<option value="cubic-bezier(0.25, 0.46, 0.45, 0.94)">Ease Custom</option>
<option value="cubic-bezier(0.68, -0.55, 0.265, 1.55)">Back</option>
<option value="cubic-bezier(0.175, 0.885, 0.32, 1.275)">Back Smooth</option>
</select>
</div>
</div>
</div>
<div class="card">
<div class="card-heading">
Overlay Settings
<div class="card-actions">
<button class="card-action-btn" id="reset-overlay" title="Reset Overlay Settings">↺</button>
</div>
</div>
<div class="card-content">
<div class="control-group">
<div class="control-label">
<span class="label-text">
Overlay Opacity
<span class="help-tooltip" title="Transparency of the overlay">ℹ</span>
</span>
<div class="value-display">
<span class="value-text"><span id="overlay-opacity-value">0.2</span></span>
<button class="reset-btn" onclick="resetParameter('overlay-opacity', 0.2)">↺</button>
</div>
</div>
<input type="range" id="overlay-opacity" min="0" max="0.8" step="0.05" value="0.2">
</div>
<div class="control-group">
<div class="control-label">
<span class="label-text">
Overlay Fade Duration
<span class="help-tooltip" title="Speed of overlay fade effect">ℹ</span>
</span>
<div class="value-display">
<span class="value-text"><span id="overlay-fade-value">0.3</span>s</span>
<button class="reset-btn" onclick="resetParameter('overlay-fade', 0.3)">↺</button>
</div>
</div>
<input type="range" id="overlay-fade" min="0.1" max="1" step="0.1" value="0.3">
</div>
<div class="control-group">
<div class="control-label">
<span class="label-text">Overlay Color</span>
</div>
<div class="color-list">
<div class="color-row">
<div class="color-picker-container" style="--selected-color: #000000;">
<input type="color" id="overlay-color" value="#000000">
</div>
<div class="color-input-group">
<span class="color-label">HEX</span>
<input type="text" class="color-input hex-input" id="overlay-color-hex" value="#000000" placeholder="#000000">
</div>
<div class="color-input-group">
<span class="color-label">HSL</span>
<input type="text" class="color-input hsl-input" id="overlay-color-hsl" placeholder="hsl(0, 0%, 0%)">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-heading">
Advanced Settings
<div class="card-actions">
<button class="card-action-btn" id="reset-advanced" title="Reset Advanced Settings">↺</button>
</div>
</div>
<div class="card-content">
<div class="control-group">
<div class="control-label">
<span class="label-text">
Navigation Delay
<span class="help-tooltip" title="Delay before navigation occurs">ℹ</span>
</span>
<div class="value-display">
<span class="value-text"><span id="navigation-delay-value">50</span>ms</span>
<button class="reset-btn" onclick="resetParameter('navigation-delay', 50)">↺</button>
</div>
</div>
<input type="range" id="navigation-delay" min="0" max="200" step="10" value="50">
</div>
<div class="control-group">
<div class="control-label">
<span class="label-text">
Performance Mode
<span class="help-tooltip" title="Optimization level for animation performance">ℹ</span>
</span>
</div>
<select id="performance-mode">
<option value="standard">Standard</option>
<option value="optimized">Optimized (will-change)</option>
<option value="gpu">GPU Accelerated</option>
</select>
</div>
</div>
</div>
</section>
</div>
</div>
<div class="notification" id="notification"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
let transitionConfig = {
animationDirection: "top",
desktopDuration: 1.2,
mobileDuration: 0.8,
easingFunction: "cubic-bezier(0.645, 0.045, 0.355, 1)",
overlayOpacity: 0.2,
overlayFade: 0.3,
overlayColor: "#000000",
navigationDelay: 50,
performanceMode: "standard"
};
const defaultConfig = { ...transitionConfig };
function updateConfig() {
updatePreviewStyles();
saveConfiguration();
}
function initializePreview() {
updateConfig();
}
function getTransformByDirection(direction, isActive = false) {
if (isActive) return 'translate3d(0, 0, 0)';
const transforms = {
'top': 'translate3d(0, -100%, 0)',
'bottom': 'translate3d(0, 100%, 0)',
'left': 'translate3d(-100%, 0, 0)',
'right': 'translate3d(100%, 0, 0)'
};
return transforms[direction] || transforms['top'];
}
function updatePreviewStyles() {
const rgbColor = hexToRgb(transitionConfig.overlayColor);
const container = document.getElementById('previewTransitionContainer');
const frame = document.getElementById('previewFrame');
const overlay = document.getElementById('previewOverlay');
let willChange = 'transform';
if (transitionConfig.performanceMode === 'optimized') {
willChange = 'transform';
} else if (transitionConfig.performanceMode === 'gpu') {
willChange = 'transform, opacity';
}
if (frame) {
frame.style.transform = getTransformByDirection(transitionConfig.animationDirection, false);
frame.style.transition = `transform ${transitionConfig.desktopDuration}s ${transitionConfig.easingFunction}`;
frame.style.willChange = willChange;
frame.style.contain = 'layout style paint';
frame.style.backfaceVisibility = 'hidden';
}
if (overlay) {
overlay.style.backgroundColor = `rgba(${rgbColor.r}, ${rgbColor.g}, ${rgbColor.b}, ${transitionConfig.overlayOpacity})`;
overlay.style.transition = `opacity ${transitionConfig.overlayFade}s ease`;
}
}
function testTransition() {
const container = document.getElementById('previewTransitionContainer');
const frame = document.getElementById('previewFrame');
const overlay = document.getElementById('previewOverlay');
if (!container || !frame || !overlay) return;
frame.classList.remove('PageTransition004-active');
overlay.classList.remove('PageTransition004-active');
frame.style.transform = getTransformByDirection(transitionConfig.animationDirection, false);
setTimeout(() => {
overlay.classList.add('PageTransition004-active');
frame.style.transform = getTransformByDirection(transitionConfig.animationDirection, true);
frame.classList.add('PageTransition004-active');
setTimeout(() => {
overlay.classList.remove('PageTransition004-active');
setTimeout(() => {
frame.classList.remove('PageTransition004-active');
frame.style.transform = getTransformByDirection(transitionConfig.animationDirection, false);
}, transitionConfig.navigationDelay);
}, transitionConfig.desktopDuration * 1000);
}, 100);
}
function generateJavaScriptCode() {
const rgbColor = hexToRgb(transitionConfig.overlayColor);
const initialTransform = getTransformByDirection(transitionConfig.animationDirection, false);
const activeTransform = getTransformByDirection(transitionConfig.animationDirection, true);
let willChangeRule = '\n will-change: transform;';
let additionalProps = '\n contain: layout style paint;\n backface-visibility: hidden;';
if (transitionConfig.performanceMode === 'gpu') {
willChangeRule = '\n will-change: transform, opacity;';
}
return `<div class="PageTransition004-container" id="PageTransition004Container">
<iframe id="PageTransition004Frame" class="PageTransition004-frame"></iframe>
<div class="PageTransition004-overlay"></div>
</div>
<style>
.PageTransition004-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2147483647;
overflow: hidden;
pointer-events: none;
}
.PageTransition004-frame {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
transform: ${initialTransform};
transition: transform ${transitionConfig.desktopDuration}s ${transitionConfig.easingFunction};${willChangeRule}${additionalProps}
}
.PageTransition004-frame.PageTransition004-active {
transform: ${activeTransform};
}
.PageTransition004-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(${rgbColor.r}, ${rgbColor.g}, ${rgbColor.b}, ${transitionConfig.overlayOpacity});
opacity: 0;
transition: opacity ${transitionConfig.overlayFade}s ease;
}
.PageTransition004-overlay.PageTransition004-active {
opacity: 1;
}
@media (max-width: 768px) {
.PageTransition004-frame {
transition-duration: ${transitionConfig.mobileDuration}s;
}
}
</style>
<script>
(function() {
'use strict';
const transitionContainer = document.getElementById('PageTransition004Container');
const transitionFrame = document.getElementById('PageTransition004Frame');
const transitionOverlay = transitionContainer.querySelector('.PageTransition004-overlay');
let isTransitioning = false;
function cleanup() {
transitionFrame.removeEventListener('transitionend', handleTransitionEnd);
transitionFrame.onload = null;
isTransitioning = false;
}
function handleTransitionEnd() {
transitionOverlay.classList.remove('PageTransition004-active');
setTimeout(() => {
cleanup();
window.location.href = transitionFrame.src;
}, ${transitionConfig.navigationDelay});
}
function startTransition(url) {
if (isTransitioning) return;
isTransitioning = true;
transitionContainer.style.pointerEvents = 'auto';
transitionFrame.src = url;
transitionFrame.onload = () => {
requestAnimationFrame(() => {
transitionOverlay.classList.add('PageTransition004-active');
transitionFrame.classList.add('PageTransition004-active');
});
};
transitionFrame.addEventListener('transitionend', handleTransitionEnd, { once: true });
}
function handleLinkClick(e) {
const link = e.currentTarget;
if (link.origin === window.location.origin && !link.hasAttribute('target') && !isTransitioning) {
e.preventDefault();
startTransition(link.href);
}
}
function attachLinkListeners() {
document.querySelectorAll('a').forEach(link => {
link.removeEventListener('click', handleLinkClick);
link.addEventListener('click', handleLinkClick);
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', attachLinkListeners);
} else {
attachLinkListeners();
}
window.addEventListener('beforeunload', cleanup);
})();
<\/script>`;
}
function generateFullSectionJSON() {
return "";
}
function copyJsToClipboard() {
const jsCode = generateJavaScriptCode();
navigator.clipboard.writeText(jsCode)
.then(() => {
showNotification('JavaScript code copied to clipboard!');
})
.catch(err => {
try {
const textArea = document.createElement('textarea');
textArea.value = jsCode;
textArea.style.position = 'fixed';
textArea.style.opacity = '0';
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
showNotification('JavaScript code copied to clipboard!');
} catch (fallbackErr) {
showNotification('Failed to copy to clipboard. Please try again.', 'error');
}
});
}
function showNotification(message, type = 'success') {
const notification = document.getElementById('notification');
notification.textContent = message;
notification.className = `notification ${type}`;
notification.offsetHeight;
notification.style.visibility = 'visible';
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
setTimeout(() => {
if (!notification.classList.contains('show')) {
notification.style.visibility = 'hidden';
}
}, 400);
}, 3000);
}
function generateRandomTransition() {
const directions = ['top', 'bottom', 'left', 'right'];
const easings = [
'cubic-bezier(0.645, 0.045, 0.355, 1)',
'ease',
'ease-in',
'ease-out',
'ease-in-out',
'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
'cubic-bezier(0.175, 0.885, 0.32, 1.275)'
];
const performances = ['standard', 'optimized', 'gpu'];
transitionConfig.animationDirection = directions[Math.floor(Math.random() * directions.length)];
transitionConfig.desktopDuration = Math.round((Math.random() * 2.5 + 0.5) * 10) / 10;
transitionConfig.mobileDuration = Math.round((Math.random() * 1.7 + 0.3) * 10) / 10;
transitionConfig.easingFunction = easings[Math.floor(Math.random() * easings.length)];
transitionConfig.overlayOpacity = Math.round((Math.random() * 0.8) * 100) / 100;
transitionConfig.overlayFade = Math.round((Math.random() * 0.9 + 0.1) * 10) / 10;
transitionConfig.overlayColor = generateRandomColor();
transitionConfig.navigationDelay = Math.floor(Math.random() * 200);
transitionConfig.performanceMode = performances[Math.floor(Math.random() * performances.length)];
updateAllInputs();
updateConfig();
showNotification('Random transition generated!');
}
function generateRandomColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0');
}
function updateAllInputs() {
document.getElementById('animation-direction').value = transitionConfig.animationDirection;
document.getElementById('desktop-duration').value = transitionConfig.desktopDuration;
document.getElementById('mobile-duration').value = transitionConfig.mobileDuration;
document.getElementById('easing-function').value = transitionConfig.easingFunction;
document.getElementById('overlay-opacity').value = transitionConfig.overlayOpacity;
document.getElementById('overlay-fade').value = transitionConfig.overlayFade;
document.getElementById('navigation-delay').value = transitionConfig.navigationDelay;
document.getElementById('performance-mode').value = transitionConfig.performanceMode;
document.getElementById('desktop-duration-value').textContent = transitionConfig.desktopDuration;
document.getElementById('mobile-duration-value').textContent = transitionConfig.mobileDuration;
document.getElementById('overlay-opacity-value').textContent = transitionConfig.overlayOpacity;
document.getElementById('overlay-fade-value').textContent = transitionConfig.overlayFade;
document.getElementById('navigation-delay-value').textContent = transitionConfig.navigationDelay;
updateColorInputs('overlay-color', transitionConfig.overlayColor);
}
function updateColorInputs(colorId, color) {
const colorInput = document.getElementById(colorId);
const hexInput = document.getElementById(`${colorId}-hex`);
const hslInput = document.getElementById(`${colorId}-hsl`);
if (colorInput && hexInput && hslInput) {
colorInput.value = color;
hexInput.value = color;
hslInput.value = `hsl(${hexToHsl(color).h}, ${hexToHsl(color).s}%, ${hexToHsl(color).l}%)`;
hexInput.classList.remove('invalid');
hslInput.classList.remove('invalid');
const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
if (colorPickerContainer) {
colorPickerContainer.style.setProperty('--selected-color', color);
}
}
}
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function hexToHsl(hex) {
const r = parseInt(hex.slice(1, 3), 16) / 255;
const g = parseInt(hex.slice(3, 5), 16) / 255;
const b = parseInt(hex.slice(5, 7), 16) / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return {
h: Math.round(h * 360),
s: Math.round(s * 100),
l: Math.round(l * 100)
};
}
function hslToHex(hsl) {
const match = hsl.match(/hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/);
if (!match) return null;
let h = parseInt(match[1]) / 360;
let s = parseInt(match[2]) / 100;
let l = parseInt(match[3]) / 100;
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
};
let r, g, b;
if (s === 0) {
r = g = b = l;
} else {
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
const toHex = (c) => {
const hex = Math.round(c * 255).toString(16);
return hex.length === 1 ? '0' + hex : hex;
};
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
function isValidHex(hex) {
return /^#[0-9A-F]{6}$/i.test(hex);
}
function isValidHsl(hsl) {
return /^hsl\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*\)$/i.test(hsl);
}
function formatHex(value) {
let hex = value.replace(/[^0-9A-Fa-f#]/g, '');
if (!hex.startsWith('#')) {
hex = '#' + hex;
}
if (hex.length > 7) {
hex = hex.substring(0, 7);
}
return hex.toUpperCase();
}
function formatHsl(value) {
const cleanValue = value.replace(/[^\d,\s]/g, '');
const numbers = cleanValue.match(/\d+/g);
if (!numbers || numbers.length < 3) {
const partialMatch = value.match(/(\d+)/g);
if (partialMatch && partialMatch.length >= 1) {
const h = Math.min(360, Math.max(0, parseInt(partialMatch[0]) || 0));
const s = Math.min(100, Math.max(0, parseInt(partialMatch[1]) || 50));
const l = Math.min(100, Math.max(0, parseInt(partialMatch[2]) || 50));
return `hsl(${h}, ${s}%, ${l}%)`;
}
return value;
}
let h = Math.min(360, Math.max(0, parseInt(numbers[0])));
let s = Math.min(100, Math.max(0, parseInt(numbers[1])));
let l = Math.min(100, Math.max(0, parseInt(numbers[2])));
return `hsl(${h}, ${s}%, ${l}%)`;
}
window.resetParameter = function(parameterId, defaultValue) {
const element = document.getElementById(parameterId);
if (element) {
element.value = defaultValue;
const valueElement = document.getElementById(`${parameterId}-value`);
if (valueElement) {
valueElement.textContent = defaultValue;
}
switch (parameterId) {
case 'desktop-duration':
transitionConfig.desktopDuration = defaultValue;
break;
case 'mobile-duration':
transitionConfig.mobileDuration = defaultValue;
break;
case 'overlay-opacity':
transitionConfig.overlayOpacity = defaultValue;
break;
case 'overlay-fade':
transitionConfig.overlayFade = defaultValue;
break;
case 'navigation-delay':
transitionConfig.navigationDelay = defaultValue;
break;
}
updateConfig();
showNotification(`${parameterId.replace(/-/g, ' ')} reset to default`);
}
};
function setupColorInputHandlers(colorId, configProperty) {
const colorInput = document.getElementById(colorId);
const hexInput = document.getElementById(`${colorId}-hex`);
const hslInput = document.getElementById(`${colorId}-hsl`);
if (!colorInput || !hexInput || !hslInput) return;
hslInput.value = `hsl(${hexToHsl(colorInput.value).h}, ${hexToHsl(colorInput.value).s}%, ${hexToHsl(colorInput.value).l}%)`;
colorInput.addEventListener('input', () => {
const color = colorInput.value;
hexInput.value = color;
hslInput.value = `hsl(${hexToHsl(color).h}, ${hexToHsl(color).s}%, ${hexToHsl(color).l}%)`;
hexInput.classList.remove('invalid');
hslInput.classList.remove('invalid');
transitionConfig[configProperty] = color;
const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
colorPickerContainer.style.setProperty('--selected-color', color);
updateConfig();
});
hexInput.addEventListener('input', (e) => {
let hex = e.target.value;
hex = formatHex(hex);
e.target.value = hex;
if (isValidHex(hex)) {
colorInput.value = hex;
hslInput.value = `hsl(${hexToHsl(hex).h}, ${hexToHsl(hex).s}%, ${hexToHsl(hex).l}%)`;
transitionConfig[configProperty] = hex;
e.target.classList.remove('invalid');
hslInput.classList.remove('invalid');
const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
colorPickerContainer.style.setProperty('--selected-color', hex);
updateConfig();
} else {
e.target.classList.add('invalid');
}
});
hexInput.addEventListener('blur', (e) => {
if (!isValidHex(e.target.value)) {
e.target.value = colorInput.value;
e.target.classList.remove('invalid');
}
});
hslInput.addEventListener('input', (e) => {
let hsl = e.target.value;
if (isValidHsl(hsl)) {
const hex = hslToHex(hsl);
if (hex) {
colorInput.value = hex;
hexInput.value = hex;
transitionConfig[configProperty] = hex;
e.target.classList.remove('invalid');
hexInput.classList.remove('invalid');
const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
colorPickerContainer.style.setProperty('--selected-color', hex);
updateConfig();
return;
}
}
e.target.classList.add('invalid');
});
hslInput.addEventListener('blur', (e) => {
let hsl = e.target.value;
if (!isValidHsl(hsl) && hsl.trim()) {
const formatted = formatHsl(hsl);
if (isValidHsl(formatted)) {
e.target.value = formatted;
const hex = hslToHex(formatted);
if (hex) {
colorInput.value = hex;
hexInput.value = hex;
transitionConfig[configProperty] = hex;
e.target.classList.remove('invalid');
hexInput.classList.remove('invalid');
updateConfig();
return;
}
}
}
if (!isValidHsl(e.target.value)) {
e.target.value = `hsl(${hexToHsl(colorInput.value).h}, ${hexToHsl(colorInput.value).s}%, ${hexToHsl(colorInput.value).l}%)`;
e.target.classList.remove('invalid');
}
});
}
function saveConfiguration() {
try {
localStorage.setItem('bricksfusion-pagetransition004-config', JSON.stringify(transitionConfig));
} catch (e) {
}
}
function loadConfiguration() {
try {
const saved = localStorage.getItem('bricksfusion-pagetransition004-config');
if (saved) {
const savedConfig = JSON.parse(saved);
Object.assign(transitionConfig, savedConfig);
updateAllInputs();
updateConfig();
}
} catch (e) {
}
}
function initializeUI() {
const instructionsToggle = document.getElementById('instructions-toggle');
const instructionsContent = document.getElementById('instructions-content');
const instructionsCard = document.getElementById('instructions-card');
const toggleIcon = instructionsToggle.querySelector('.toggle-icon');
instructionsToggle.addEventListener('click', () => {
const isVisible = instructionsContent.classList.contains('show');
if (isVisible) {
instructionsContent.classList.remove('show');
instructionsCard.classList.remove('expanded');
toggleIcon.classList.remove('expanded');
} else {
instructionsContent.classList.add('show');
instructionsCard.classList.add('expanded');
toggleIcon.classList.add('expanded');
}
});
document.getElementById('download-config').addEventListener('click', () => {
copyJsToClipboard();
});
document.getElementById('randomize-transition').addEventListener('click', () => {
generateRandomTransition();
});
const backgroundPicker = document.getElementById('preview-background-picker');
const previewContainer = document.getElementById('transition-preview');
backgroundPicker.addEventListener('input', (e) => {
const selectedColor = e.target.value;
previewContainer.style.backgroundColor = selectedColor;
showNotification(`Preview background changed to ${selectedColor}`);
});
previewContainer.style.backgroundColor = '#000000';
previewContainer.addEventListener('click', testTransition);
document.getElementById('reset-transition').addEventListener('click', () => {
transitionConfig.animationDirection = defaultConfig.animationDirection;
transitionConfig.desktopDuration = defaultConfig.desktopDuration;
transitionConfig.mobileDuration = defaultConfig.mobileDuration;
transitionConfig.easingFunction = defaultConfig.easingFunction;
document.getElementById('animation-direction').value = defaultConfig.animationDirection;
document.getElementById('desktop-duration').value = defaultConfig.desktopDuration;
document.getElementById('mobile-duration').value = defaultConfig.mobileDuration;
document.getElementById('easing-function').value = defaultConfig.easingFunction;
document.getElementById('desktop-duration-value').textContent = defaultConfig.desktopDuration;
document.getElementById('mobile-duration-value').textContent = defaultConfig.mobileDuration;
updateConfig();
showNotification('Transition settings reset');
});
document.getElementById('reset-overlay').addEventListener('click', () => {
transitionConfig.overlayOpacity = defaultConfig.overlayOpacity;
transitionConfig.overlayFade = defaultConfig.overlayFade;
transitionConfig.overlayColor = defaultConfig.overlayColor;
document.getElementById('overlay-opacity').value = defaultConfig.overlayOpacity;
document.getElementById('overlay-fade').value = defaultConfig.overlayFade;
document.getElementById('overlay-opacity-value').textContent = defaultConfig.overlayOpacity;
document.getElementById('overlay-fade-value').textContent = defaultConfig.overlayFade;
updateColorInputs('overlay-color', defaultConfig.overlayColor);
updateConfig();
showNotification('Overlay settings reset');
});
document.getElementById('reset-advanced').addEventListener('click', () => {
transitionConfig.navigationDelay = defaultConfig.navigationDelay;
transitionConfig.performanceMode = defaultConfig.performanceMode;
document.getElementById('navigation-delay').value = defaultConfig.navigationDelay;
document.getElementById('performance-mode').value = defaultConfig.performanceMode;
document.getElementById('navigation-delay-value').textContent = defaultConfig.navigationDelay;
updateConfig();
showNotification('Advanced settings reset');
});
const rangeInputs = document.querySelectorAll('input[type="range"]');
rangeInputs.forEach(input => {
const valueElement = document.getElementById(`${input.id}-value`);
if (valueElement) {
valueElement.textContent = input.value;
}
input.addEventListener('input', () => {
if (valueElement) {
valueElement.textContent = input.value;
}
switch (input.id) {
case 'desktop-duration':
transitionConfig.desktopDuration = parseFloat(input.value);
break;
case 'mobile-duration':
transitionConfig.mobileDuration = parseFloat(input.value);
break;
case 'overlay-opacity':
transitionConfig.overlayOpacity = parseFloat(input.value);
break;
case 'overlay-fade':
transitionConfig.overlayFade = parseFloat(input.value);
break;
case 'navigation-delay':
transitionConfig.navigationDelay = parseInt(input.value);
break;
}
updateConfig();
});
});
const selectInputs = document.querySelectorAll('select');
selectInputs.forEach(select => {
select.addEventListener('change', () => {
switch (select.id) {
case 'animation-direction':
transitionConfig.animationDirection = select.value;
break;
case 'easing-function':
transitionConfig.easingFunction = select.value;
break;
case 'performance-mode':
transitionConfig.performanceMode = select.value;
break;
}
updateConfig();
});
});
setupColorInputHandlers('overlay-color', 'overlayColor');
document.addEventListener('keydown', (e) => {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
return;
}
if (e.ctrlKey || e.metaKey) {
switch (e.key.toLowerCase()) {
case 'd':
e.preventDefault();
const downloadBtn = document.getElementById('download-config');
if (downloadBtn && downloadBtn.hasAttribute('data-protection-animation')) {
downloadBtn.click();
} else {
copyJsToClipboard();
}
break;
}
} else {
switch (e.key.toLowerCase()) {
case 'r':
generateRandomTransition();
break;
case 'b':
document.getElementById('preview-background-picker').click();
break;
}
}
});
loadConfiguration();
initializePreview();
setTimeout(() => {
showNotification('BricksFusion Page Transition 004 Configurator loaded!');
}, 500);
}
initializeUI();
});
</script>
</body>
</html>Transition 004
Smooth page transition with customizable slide direction and overlay effect. New page slides from top, bottom, left, or right with configurable duration, easing, and overlay color. Features separate desktop and mobile durations, multiple easing functions, and performance optimizations. Perfect for creating seamless, professional navigation experiences across your entire website.
Slide Transition
Click anywhere to preview the slide effect.
Animation
Direction from which new page slides into view. Choose from top, bottom, left, or right. Top creates classic downward slide. Bottom produces upward reveal. Left slides from screen edge rightward. Right creates leftward motion. Direction affects visual flow and user perception. Consider content layout and brand identity when selecting direction.
Default: From Top
Duration of transition animation on desktop devices. Shorter values create snappy, quick transitions. Longer values produce smooth, cinematic motion. Balance speed with user expectations. Too fast feels jarring. Too slow reduces perceived performance. Desktop users typically prefer faster transitions than mobile.
Default: 1.2s (Range: 0.5-3s)
Duration of transition animation on mobile devices. Mobile connections often slower than desktop. Shorter transitions prevent user frustration during navigation. Consider touch interface patterns and mobile user behavior. Faster transitions feel more responsive on smaller screens. Typically 30-40% shorter than desktop duration for optimal experience.
Default: 0.8s (Range: 0.3-2s)
Animation timing curve controlling acceleration and deceleration. Smooth (default) provides professional, polished motion. Easy creates gentle, natural movement. Ease In starts slow, accelerates. Ease Out decelerates smoothly. Ease In Out combines both. Back functions create playful overshoot effect. Choose based on desired feel: professional, playful, or energetic. Easing dramatically affects perceived quality.
Default: Smooth (cubic-bezier)
Overlay
Transparency level of overlay appearing behind transitioning page. Higher values create darker, more prominent overlay. Lower values produce subtle, barely visible effect. Zero disables overlay completely. Use overlay to reduce visual noise and focus attention on incoming content. Dark overlays work well with light content. Consider accessibility and readability.
Default: 0.2 (Range: 0-0.8)
Speed at which overlay fades in and out during transition. Shorter creates instant appearance. Longer produces gradual, smooth fade. Coordinate with main transition duration for cohesive effect. Fast fades feel energetic. Slow fades feel elegant. Typically faster than main transition to establish context quickly before page slides in.
Default: 0.3s (Range: 0.1-1s)
Color of overlay layer appearing during transition. Black creates classic, professional dimming effect. White produces bright, clean fade. Brand colors maintain consistency. Choose colors matching overall design system. Opacity controls intensity regardless of color choice. Consider how color interacts with page content being transitioned. Dark colors generally safest choice for accessibility.
Default: Black (#000000)
Advanced
Delay before actual navigation occurs after transition completes. Brief delay allows transition to fully resolve before page load begins. Zero creates instant navigation. Small delays improve perceived smoothness. Large delays frustrate users. Use minimal delay for best performance. Helpful when coordinating with external scripts or analytics tracking. Most users won't notice delays under 100ms.
Default: 50ms (Range: 0-200ms)
Optimization level for animation rendering. Standard provides balanced performance for most sites. Optimized adds will-change property to hint browser about upcoming transforms. GPU Accelerated forces hardware acceleration for maximum smoothness on high-performance devices. Higher modes increase GPU usage. Choose based on target devices and performance requirements. Test on actual devices to ensure smooth experience.
Default: Standard
Performance & Usage
This transition uses CSS transforms and cubic-bezier easing for smooth GPU-accelerated animations. Lightweight implementation with minimal performance impact. Automatically intercepts all internal link clicks for consistent site-wide transitions. Includes mobile detection for optimized duration settings. Features iframe preloading to minimize wait time between pages. Add to header or footer template for global availability. Only one transition element needed per site. Works seamlessly with Bricks Builder and all modern browsers.
