@squeditor/squeditor-framework 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +106 -0
- package/package.json +36 -0
- package/php/functions.php +92 -0
- package/project-template/package.json +29 -0
- package/project-template/postcss.config.js +6 -0
- package/project-template/squeditor.config.js +81 -0
- package/project-template/src/404.php +21 -0
- package/project-template/src/assets/css/squeditor-icons.css +4719 -0
- package/project-template/src/assets/css/tailwind.css +3 -0
- package/project-template/src/assets/css/uikit-components.css +14586 -0
- package/project-template/src/assets/js/gsap-advanced.js +26 -0
- package/project-template/src/assets/js/gsap-init.js +672 -0
- package/project-template/src/assets/js/gsap-modules/cursor-preview.js +132 -0
- package/project-template/src/assets/js/gsap-modules/cursor.js +456 -0
- package/project-template/src/assets/js/gsap-modules/loop-panels.js +78 -0
- package/project-template/src/assets/js/gsap-modules/marquee.js +106 -0
- package/project-template/src/assets/js/gsap-modules/pinned-panels.js +105 -0
- package/project-template/src/assets/js/gsap-modules/scroll-to.js +54 -0
- package/project-template/src/assets/js/gsap-modules/swipe-slider.js +121 -0
- package/project-template/src/assets/js/gsap-modules/text-mask.js +93 -0
- package/project-template/src/assets/js/gsap-modules/tilt.js +70 -0
- package/project-template/src/assets/js/main.js +302 -0
- package/project-template/src/assets/js/uikit-components.js +18171 -0
- package/project-template/src/assets/scss/_base.scss +140 -0
- package/project-template/src/assets/scss/_components.scss +165 -0
- package/project-template/src/assets/scss/_config.scss +13 -0
- package/project-template/src/assets/scss/_functions.scss +81 -0
- package/project-template/src/assets/scss/_tokens.scss +229 -0
- package/project-template/src/assets/scss/_transitions.scss +36 -0
- package/project-template/src/assets/scss/_uikit-overrides.scss +187 -0
- package/project-template/src/assets/scss/_uikit_dynamic.scss +43 -0
- package/project-template/src/assets/scss/_utilities.scss +31 -0
- package/project-template/src/assets/scss/custom.scss +10 -0
- package/project-template/src/assets/scss/main.scss +11 -0
- package/project-template/src/assets/static/fonts/squeditor-icons/squeditor-icons.eot +0 -0
- package/project-template/src/assets/static/fonts/squeditor-icons/squeditor-icons.svg +1183 -0
- package/project-template/src/assets/static/fonts/squeditor-icons/squeditor-icons.ttf +0 -0
- package/project-template/src/assets/static/fonts/squeditor-icons/squeditor-icons.woff +0 -0
- package/project-template/src/config/site-config.php +34 -0
- package/project-template/src/data/blog.php +21 -0
- package/project-template/src/data/portfolio.php +23 -0
- package/project-template/src/data/team.php +23 -0
- package/project-template/src/index.php +57 -0
- package/project-template/src/init.php +19 -0
- package/project-template/src/page-templates/base.php +39 -0
- package/project-template/src/page-templates/body-scripts.php +26 -0
- package/project-template/src/page-templates/head.php +47 -0
- package/project-template/src/page-templates/transition.php +45 -0
- package/project-template/src/sections/cards/cards-grid.php +34 -0
- package/project-template/src/sections/cards/cards-horizontal.php +28 -0
- package/project-template/src/sections/cta/cta-banner.php +34 -0
- package/project-template/src/sections/cta/cta-newsletter.php +19 -0
- package/project-template/src/sections/footer/layout-01.php +35 -0
- package/project-template/src/sections/header/layout-01.php +36 -0
- package/project-template/src/sections/hero/hero-centered.php +44 -0
- package/project-template/src/sections/hero/hero-split.php +132 -0
- package/project-template/src/sections/hero/hero-video.php +22 -0
- package/project-template/src/sections/sidebar/sidebar-right.php +11 -0
- package/project-template/src/template-parts/breadcrumbs.php +17 -0
- package/project-template/src/template-parts/footer.php +74 -0
- package/project-template/src/template-parts/header.php +120 -0
- package/project-template/src/template-parts/mega-menu.php +7 -0
- package/project-template/src/template-parts/nav.php +16 -0
- package/project-template/src/template-parts/page-title-bar.php +14 -0
- package/project-template/tailwind.config.js +26 -0
- package/project-template/vite.config.js +67 -0
- package/scripts/build-components.js +109 -0
- package/scripts/copy-static.js +150 -0
- package/scripts/dev-router.php +23 -0
- package/scripts/dev.js +55 -0
- package/scripts/get-port.js +27 -0
- package/scripts/package-customer.js +278 -0
- package/scripts/package-dist.js +54 -0
- package/scripts/scaffold.js +72 -0
- package/scripts/snapshot.js +74 -0
- package/uikit-manifest.json +248 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
// src/assets/js/main.js
|
|
2
|
+
import './gsap-init.js';
|
|
3
|
+
import './gsap-advanced.js';
|
|
4
|
+
// SCSS is imported directly in base.php for development (to prevent FOUC) and loaded via <link> in production.
|
|
5
|
+
|
|
6
|
+
// Remove the dev server FOUC shield
|
|
7
|
+
if (document.documentElement.classList.contains('js-fouc')) {
|
|
8
|
+
setTimeout(() => { document.documentElement.classList.remove('js-fouc'); }, 50);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Add custom JavaScript here
|
|
12
|
+
|
|
13
|
+
import { gsap } from 'gsap';
|
|
14
|
+
|
|
15
|
+
function initMathPathTransition(pathSelector) {
|
|
16
|
+
const overlay = document.querySelector('.sq-page-transition');
|
|
17
|
+
const paths = document.querySelectorAll(pathSelector);
|
|
18
|
+
if (!overlay || !paths.length) return null;
|
|
19
|
+
|
|
20
|
+
let numPoints = 10;
|
|
21
|
+
let numPaths = paths.length; // curve=2, wave=1
|
|
22
|
+
let delayPointsMax = 0.3;
|
|
23
|
+
let delayPerPath = 0.25;
|
|
24
|
+
let isRevealing = true;
|
|
25
|
+
let pointsDelay = [];
|
|
26
|
+
let allPoints = [];
|
|
27
|
+
|
|
28
|
+
for (let i = 0; i < numPaths; i++) {
|
|
29
|
+
let points = [];
|
|
30
|
+
allPoints.push(points);
|
|
31
|
+
for (let j = 0; j < numPoints; j++) {
|
|
32
|
+
points.push(100);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function render() {
|
|
37
|
+
for (let i = 0; i < numPaths; i++) {
|
|
38
|
+
let path = paths[i];
|
|
39
|
+
let points = allPoints[i];
|
|
40
|
+
let d = "";
|
|
41
|
+
|
|
42
|
+
d += isRevealing ? `M 0 0 V ${points[0]} C` : `M 0 100 V ${points[0]} C`;
|
|
43
|
+
|
|
44
|
+
for (let j = 0; j < numPoints - 1; j++) {
|
|
45
|
+
let p = (j + 1) / (numPoints - 1) * 100;
|
|
46
|
+
let cp = p - (1 / (numPoints - 1) * 100) / 2;
|
|
47
|
+
d += ` ${cp} ${points[j]} ${cp} ${points[j + 1]} ${p} ${points[j + 1]}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
d += isRevealing ? ` V 0 H 0` : ` V 100 H 0`;
|
|
51
|
+
path.setAttribute("d", d);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 1. ENTER ANIMATION
|
|
56
|
+
isRevealing = true;
|
|
57
|
+
for (let i = 0; i < numPaths; i++) {
|
|
58
|
+
for (let j = 0; j < numPoints; j++) { allPoints[i][j] = 100; }
|
|
59
|
+
}
|
|
60
|
+
render();
|
|
61
|
+
overlay.classList.add('is-active');
|
|
62
|
+
ariaHidden(overlay, false);
|
|
63
|
+
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
const entryTl = gsap.timeline({
|
|
66
|
+
onUpdate: render,
|
|
67
|
+
onComplete: () => {
|
|
68
|
+
overlay.classList.remove('is-active');
|
|
69
|
+
ariaHidden(overlay, true);
|
|
70
|
+
},
|
|
71
|
+
defaults: { ease: "expo.inOut", duration: 1.2 }
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
for (let i = 0; i < numPoints; i++) pointsDelay[i] = Math.random() * delayPointsMax;
|
|
75
|
+
|
|
76
|
+
for (let i = 0; i < numPaths; i++) {
|
|
77
|
+
let points = allPoints[i];
|
|
78
|
+
let pathDelay = delayPerPath * (numPaths - i - 1);
|
|
79
|
+
for (let j = 0; j < numPoints; j++) {
|
|
80
|
+
entryTl.to(points, { [j]: 0, ease: "expo.out" }, pointsDelay[j] + pathDelay);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, 100);
|
|
84
|
+
|
|
85
|
+
// 2. RETURN EXIT FUNCTION
|
|
86
|
+
return function playExit(href) {
|
|
87
|
+
isRevealing = false;
|
|
88
|
+
for (let i = 0; i < numPaths; i++) {
|
|
89
|
+
for (let j = 0; j < numPoints; j++) { allPoints[i][j] = 100; }
|
|
90
|
+
}
|
|
91
|
+
render();
|
|
92
|
+
|
|
93
|
+
overlay.classList.add('is-active');
|
|
94
|
+
ariaHidden(overlay, false);
|
|
95
|
+
|
|
96
|
+
const exitTl = gsap.timeline({
|
|
97
|
+
onUpdate: render,
|
|
98
|
+
onComplete: () => { window.location.href = href; },
|
|
99
|
+
defaults: { ease: "expo.inOut", duration: 1.2 }
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
for (let i = 0; i < numPoints; i++) pointsDelay[i] = Math.random() * delayPointsMax;
|
|
103
|
+
|
|
104
|
+
for (let i = 0; i < numPaths; i++) {
|
|
105
|
+
let points = allPoints[i];
|
|
106
|
+
let pathDelay = delayPerPath * i;
|
|
107
|
+
for (let j = 0; j < numPoints; j++) {
|
|
108
|
+
exitTl.to(points, { [j]: 0, ease: "expo.inOut" }, pointsDelay[j] + pathDelay);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function initSlideTransition() {
|
|
115
|
+
const overlay = document.querySelector('.sq-page-transition');
|
|
116
|
+
const slide = document.querySelector('.sq-transition-slide');
|
|
117
|
+
if (!overlay || !slide) return null;
|
|
118
|
+
|
|
119
|
+
overlay.classList.add('is-active');
|
|
120
|
+
ariaHidden(overlay, false);
|
|
121
|
+
gsap.set(slide, { yPercent: 0 }); // Covering screen
|
|
122
|
+
|
|
123
|
+
setTimeout(() => {
|
|
124
|
+
gsap.to(slide, {
|
|
125
|
+
yPercent: -100, // Pull up off screen
|
|
126
|
+
duration: 1.2,
|
|
127
|
+
ease: "expo.inOut",
|
|
128
|
+
onComplete: () => {
|
|
129
|
+
overlay.classList.remove('is-active');
|
|
130
|
+
ariaHidden(overlay, true);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}, 100);
|
|
134
|
+
|
|
135
|
+
return function playExit(href) {
|
|
136
|
+
gsap.set(slide, { yPercent: 100 }); // Stage at bottom
|
|
137
|
+
overlay.classList.add('is-active');
|
|
138
|
+
ariaHidden(overlay, false);
|
|
139
|
+
|
|
140
|
+
gsap.to(slide, {
|
|
141
|
+
yPercent: 0, // Push up to cover screen
|
|
142
|
+
duration: 1.2,
|
|
143
|
+
ease: "expo.inOut",
|
|
144
|
+
onComplete: () => { window.location.href = href; }
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function initBlindsTransition() {
|
|
150
|
+
const overlay = document.querySelector('.sq-page-transition');
|
|
151
|
+
const blinds = document.querySelectorAll('.blind-strip');
|
|
152
|
+
if (!overlay || !blinds.length) return null;
|
|
153
|
+
|
|
154
|
+
overlay.classList.add('is-active');
|
|
155
|
+
ariaHidden(overlay, false);
|
|
156
|
+
gsap.set(blinds, { yPercent: 0 });
|
|
157
|
+
|
|
158
|
+
setTimeout(() => {
|
|
159
|
+
gsap.to(blinds, {
|
|
160
|
+
yPercent: -100,
|
|
161
|
+
duration: 1.0,
|
|
162
|
+
stagger: 0.1,
|
|
163
|
+
ease: "expo.inOut",
|
|
164
|
+
onComplete: () => {
|
|
165
|
+
overlay.classList.remove('is-active');
|
|
166
|
+
ariaHidden(overlay, true);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}, 100);
|
|
170
|
+
|
|
171
|
+
return function playExit(href) {
|
|
172
|
+
gsap.set(blinds, { yPercent: 100 });
|
|
173
|
+
overlay.classList.add('is-active');
|
|
174
|
+
ariaHidden(overlay, false);
|
|
175
|
+
|
|
176
|
+
gsap.to(blinds, {
|
|
177
|
+
yPercent: 0,
|
|
178
|
+
duration: 1.0,
|
|
179
|
+
stagger: 0.1,
|
|
180
|
+
ease: "expo.inOut",
|
|
181
|
+
onComplete: () => { window.location.href = href; }
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function initWaveTransition() {
|
|
187
|
+
const overlay = document.querySelector('.sq-page-transition');
|
|
188
|
+
const path = document.querySelector('.sq-transition-path');
|
|
189
|
+
if (!overlay || !path) return null;
|
|
190
|
+
|
|
191
|
+
// Based on codepen.md logic, but strictly animating properties via GSAP generic object tweening
|
|
192
|
+
// because morphSVG requires both paths to have identical anchor point counts reliably.
|
|
193
|
+
|
|
194
|
+
// We animate a 'progress' value and interpolate the path strings.
|
|
195
|
+
// The curve handles 3 main points: [Left Y, Center Control Y, Right Y]
|
|
196
|
+
// M 0 {L} V {C} Q 50 {CC} 100 {C} V {R} z (approx logic)
|
|
197
|
+
|
|
198
|
+
// Easier approach matching the CodePen but doing the 3 anchor interpolation natively.
|
|
199
|
+
// Mid point pulls up: M 0 100 V 50 Q 50 0 100 50 V 100 z
|
|
200
|
+
let isRevealing = true;
|
|
201
|
+
|
|
202
|
+
// Anchor object to tween
|
|
203
|
+
let wavePoints = {
|
|
204
|
+
sideY: 100,
|
|
205
|
+
curveY: 100
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
function renderWave() {
|
|
209
|
+
// Build the cubic/quad curve natively to avoid MorphSVG shape matching errors
|
|
210
|
+
const d = `M 0 100 V ${wavePoints.sideY} Q 50 ${wavePoints.curveY} 100 ${wavePoints.sideY} V 100 z`;
|
|
211
|
+
|
|
212
|
+
// If we are revealing the page upward, we actually want the shape to pull *off* the top.
|
|
213
|
+
// The above path anchors to the bottom. So to pull off the top, we need to flip the anchor.
|
|
214
|
+
const dReveal = `M 0 0 V ${wavePoints.sideY} Q 50 ${wavePoints.curveY} 100 ${wavePoints.sideY} V 0 z`;
|
|
215
|
+
|
|
216
|
+
path.setAttribute("d", isRevealing ? dReveal : d);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// 1. ENTER ANIMATION (Page Load - Reversing the upward sweep)
|
|
220
|
+
isRevealing = true;
|
|
221
|
+
wavePoints.sideY = 100;
|
|
222
|
+
wavePoints.curveY = 100;
|
|
223
|
+
renderWave(); // Fully covered
|
|
224
|
+
|
|
225
|
+
overlay.classList.add('is-active');
|
|
226
|
+
ariaHidden(overlay, false);
|
|
227
|
+
|
|
228
|
+
setTimeout(() => {
|
|
229
|
+
let entryTl = gsap.timeline({
|
|
230
|
+
onUpdate: renderWave,
|
|
231
|
+
onComplete: () => {
|
|
232
|
+
overlay.classList.remove('is-active');
|
|
233
|
+
ariaHidden(overlay, true);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Pull up to -2 over two stages, ensuring it fully clears the screen
|
|
238
|
+
entryTl.to(wavePoints, { sideY: 50, curveY: 100, ease: "power2.in", duration: 0.45 })
|
|
239
|
+
.to(wavePoints, { sideY: -2, curveY: -2, ease: "power2.out", duration: 0.45 });
|
|
240
|
+
}, 100);
|
|
241
|
+
|
|
242
|
+
// 2. RETURN EXIT FUNCTION
|
|
243
|
+
return function playExit(href) {
|
|
244
|
+
isRevealing = false;
|
|
245
|
+
wavePoints.sideY = 100;
|
|
246
|
+
wavePoints.curveY = 100;
|
|
247
|
+
renderWave(); // Start empty at bottom
|
|
248
|
+
|
|
249
|
+
overlay.classList.add('is-active');
|
|
250
|
+
ariaHidden(overlay, false);
|
|
251
|
+
|
|
252
|
+
let exitTl = gsap.timeline({
|
|
253
|
+
onUpdate: renderWave,
|
|
254
|
+
onComplete: () => { window.location.href = href; }
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// Push up to -2 over two stages to fully clear internal rendering boundaries
|
|
258
|
+
exitTl.to(wavePoints, { sideY: 50, curveY: -2, ease: "power2.in", duration: 0.45 })
|
|
259
|
+
.to(wavePoints, { sideY: -2, curveY: -2, ease: "power2.out", duration: 0.45 });
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function initPageTransitions() {
|
|
264
|
+
const transitionType = document.body.dataset.sqTransition || 'disabled';
|
|
265
|
+
if (transitionType === 'disabled') return;
|
|
266
|
+
|
|
267
|
+
let triggerExit = null;
|
|
268
|
+
|
|
269
|
+
if (transitionType === 'curve') triggerExit = initMathPathTransition('.shape-overlays__path');
|
|
270
|
+
else if (transitionType === 'wave') triggerExit = initWaveTransition();
|
|
271
|
+
else if (transitionType === 'slide') triggerExit = initSlideTransition();
|
|
272
|
+
else if (transitionType === 'blinds') triggerExit = initBlindsTransition();
|
|
273
|
+
|
|
274
|
+
if (!triggerExit) return;
|
|
275
|
+
|
|
276
|
+
// --- SHARED LINK INTERCEPTION ---
|
|
277
|
+
document.addEventListener('click', (e) => {
|
|
278
|
+
const link = e.target.closest('a');
|
|
279
|
+
if (!link) return;
|
|
280
|
+
|
|
281
|
+
const href = link.getAttribute('href');
|
|
282
|
+
if (!href || href.startsWith('#') || href.startsWith('javascript:') || link.getAttribute('target') === '_blank') return;
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
const url = new URL(link.href, window.location.origin);
|
|
286
|
+
if (url.origin !== window.location.origin) return;
|
|
287
|
+
if (url.pathname === window.location.pathname && url.hash) return;
|
|
288
|
+
} catch (err) { return; }
|
|
289
|
+
|
|
290
|
+
e.preventDefault();
|
|
291
|
+
triggerExit(href);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function ariaHidden(el, bool) {
|
|
296
|
+
if (bool) el.setAttribute('aria-hidden', 'true');
|
|
297
|
+
else el.removeAttribute('aria-hidden');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
301
|
+
initPageTransitions();
|
|
302
|
+
});
|