kmcom-nuxt-layers 2.2.11 → 2.2.13
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/docs/FALLOW-COMPLEXITY-DUPLICATION-AUDIT.md +65 -0
- package/docs/FEEDS.md +1 -2
- package/docs/IMPROVE-AUDIT-README.md +30 -0
- package/docs/IMPROVE-AUDIT-RESULTS.md +52 -0
- package/docs/IMPROVE-DEEP-AUDIT-RESULTS.md +81 -0
- package/docs/fallow-refactor/apps-debug.md +27 -0
- package/docs/fallow-refactor/apps-playground.md +46 -0
- package/docs/fallow-refactor/apps-visual-identity.md +41 -0
- package/docs/fallow-refactor/layers-animations.md +34 -0
- package/docs/fallow-refactor/layers-canvas.md +32 -0
- package/docs/fallow-refactor/layers-content.md +33 -0
- package/docs/fallow-refactor/layers-core.md +39 -0
- package/docs/fallow-refactor/layers-feeds.md +39 -0
- package/docs/fallow-refactor/layers-forms.md +30 -0
- package/docs/fallow-refactor/layers-layout.md +42 -0
- package/docs/fallow-refactor/layers-mailer.md +32 -0
- package/docs/fallow-refactor/layers-motion.md +27 -0
- package/docs/fallow-refactor/layers-navigation.md +31 -0
- package/docs/fallow-refactor/layers-page-transitions.md +30 -0
- package/docs/fallow-refactor/layers-routing.md +33 -0
- package/docs/fallow-refactor/layers-scripts.md +35 -0
- package/docs/fallow-refactor/layers-scroll.md +38 -0
- package/docs/fallow-refactor/layers-seo.md +32 -0
- package/docs/fallow-refactor/layers-shader.md +53 -0
- package/docs/fallow-refactor/layers-theme.md +33 -0
- package/docs/fallow-refactor/layers-transitions.md +27 -0
- package/docs/fallow-refactor/layers-typography.md +29 -0
- package/docs/fallow-refactor/layers-ui.md +27 -0
- package/docs/fallow-refactor/layers-visual.md +34 -0
- package/layers/animations/app/composables/useMagneticElement.ts +11 -9
- package/layers/animations/app/composables/useTiltEffect.ts +11 -9
- package/layers/animations/app/utils/pointerMotion.ts +31 -0
- package/layers/canvas/app/components/ShaderCanvas.vue +2 -2
- package/layers/content/app/composables/useCollectionItems.ts +28 -0
- package/layers/content/app/composables/useGalleryItems.ts +8 -14
- package/layers/content/app/composables/usePortfolioItems.ts +10 -18
- package/layers/core/app/composables/useBrowser.ts +9 -82
- package/layers/core/app/composables/useFeatures.ts +3 -27
- package/layers/core/app/plugins/init.ts +157 -135
- package/layers/core/app/utils/browserInfo.ts +115 -0
- package/layers/core/app/utils/featureClasses.ts +40 -0
- package/layers/core/app/utils/helpers.test.ts +51 -0
- package/layers/feeds/app/app.config.ts +4 -2
- package/layers/feeds/app/components/Feeds/Index.vue +229 -0
- package/layers/feeds/app/components/Feeds/RouteCard.vue +75 -0
- package/layers/feeds/app/plugins/feed-head.ts +27 -49
- package/layers/feeds/app/utils/feed-catalog.ts +184 -0
- package/layers/feeds/nuxt.config.ts +0 -1
- package/layers/feeds/package.json +1 -0
- package/layers/feeds/server/utils/content-adapter.test.ts +68 -0
- package/layers/feeds/server/utils/content-adapter.ts +2 -22
- package/layers/feeds/server/utils/feed-author.ts +32 -0
- package/layers/feeds/server/utils/feed-config.ts +88 -0
- package/layers/feeds/server/utils/feed-service.ts +11 -30
- package/layers/feeds/server/utils/feed-xml.ts +26 -0
- package/layers/feeds/server/utils/formats/rss.ts +10 -15
- package/layers/feeds/server/utils/formats.test.ts +71 -0
- package/layers/forms/app/components/Form/Field.vue +42 -30
- package/layers/forms/app/utils/fieldProps.ts +65 -0
- package/layers/layout/app/components/Layout/Grid/Item.vue +29 -146
- package/layers/layout/app/utils/gridPlacementStyle.ts +195 -0
- package/layers/mailer/app/types/mailer.ts +7 -25
- package/layers/mailer/server/utils/email.ts +28 -13
- package/layers/mailer/server/utils/hooks.ts +1 -20
- package/layers/navigation/app/composables/useSite.ts +2 -9
- package/layers/navigation/app/utils/site.ts +26 -0
- package/layers/routing/app/utils/resolveRoute.test.ts +47 -0
- package/layers/routing/app/utils/resolveRoute.ts +19 -10
- package/layers/scripts/app/composables/useAnalytics.ts +8 -41
- package/layers/scripts/app/composables/useGtm.ts +6 -13
- package/layers/scripts/app/utils/scriptClients.ts +70 -0
- package/layers/scroll/app/composables/useSmoothScroll.ts +9 -43
- package/layers/scroll/app/utils/scroll.ts +103 -0
- package/layers/seo/app/composables/useSeoConfig.ts +3 -9
- package/layers/seo/app/utils/seoConfig.ts +38 -0
- package/layers/shader/app/components/Material/AmbientAurora.client.vue +11 -33
- package/layers/shader/app/components/Material/AmbientFlow.client.vue +10 -37
- package/layers/shader/app/components/Material/AmbientGradientMesh.client.vue +10 -37
- package/layers/shader/app/components/Material/AmbientNebula.client.vue +12 -37
- package/layers/shader/app/components/Material/AmbientOcean.client.vue +9 -33
- package/layers/shader/app/components/Material/Gradient.client.vue +25 -46
- package/layers/shader/app/components/Material/Image.client.vue +10 -55
- package/layers/shader/app/components/Material/Node.client.vue +18 -5
- package/layers/shader/app/components/Material/Noise.client.vue +9 -43
- package/layers/shader/app/components/Preset/ThemeBubble.client.vue +2 -1
- package/layers/shader/app/components/Preset/ThemeFlow.client.vue +2 -1
- package/layers/shader/app/components/Preset/ThemeGradient.client.vue +2 -1
- package/layers/shader/app/components/Preset/ThemeLavaLamp.client.vue +2 -1
- package/layers/shader/app/components/Preset/ThemePlasma.client.vue +2 -1
- package/layers/shader/app/components/Preset/ThemeWave.client.vue +2 -1
- package/layers/shader/app/components/Shader/Background.client.vue +44 -24
- package/layers/shader/app/composables/useAmbientMaterials.ts +5 -1
- package/layers/shader/app/composables/useShader.ts +38 -23
- package/layers/shader/app/composables/useShaderGraph.ts +11 -6
- package/layers/shader/app/composables/useShaderMixBlend.ts +4 -4
- package/layers/shader/app/composables/useShaderRuntime.ts +0 -1
- package/layers/shader/app/composables/useShaderVec2.ts +2 -4
- package/layers/shader/app/composables/useThemePreset.ts +34 -8
- package/layers/shader/app/composables/useUniformWatchers.ts +15 -0
- package/layers/shader/app/composables/useUniforms.ts +0 -1
- package/layers/shader/app/shaders/common/blend.ts +4 -4
- package/layers/shader/app/shaders/common/effects.ts +38 -21
- package/layers/shader/app/shaders/common/grain.ts +46 -49
- package/layers/shader/app/shaders/common/lighting.ts +17 -15
- package/layers/shader/app/shaders/common/math.ts +2 -4
- package/layers/shader/app/shaders/common/nodes.ts +17 -0
- package/layers/shader/app/shaders/common/palette.ts +21 -11
- package/layers/shader/app/shaders/common/patterns.ts +25 -14
- package/layers/shader/app/shaders/common/shapes.ts +97 -88
- package/layers/shader/app/shaders/common/uv.ts +33 -34
- package/layers/shader/app/shaders/createMaterial.ts +92 -78
- package/layers/shader/app/shaders/layers/paperShading.ts +22 -10
- package/layers/shader/app/shaders/layers/shaderGradient.ts +46 -21
- package/layers/shader/app/utils/tsl/tween.ts +2 -4
- package/layers/shader/package.json +5 -1
- package/layers/theme/app/components/ThemePicker/Menu.vue +3 -25
- package/layers/theme/app/composables/useThemePreferenceModels.ts +39 -0
- package/layers/theme/server/plugins/theme-fouc.ts +1 -92
- package/layers/theme/server/utils/accent-css.ts +75 -0
- package/layers/typography/app/composables/typography.ts +3 -7
- package/layers/visual/app/composables/accent.ts +2 -9
- package/layers/visual/app/composables/gradient.ts +33 -46
- package/layers/visual/app/composables/picture.ts +2 -79
- package/layers/visual/app/utils/colorTokens.ts +23 -0
- package/layers/visual/app/utils/gradientStyle.ts +41 -0
- package/layers/visual/app/utils/responsiveSizes.ts +49 -0
- package/package.json +17 -5
- package/layers/feeds/server/routes/feed/discovery.get.ts +0 -29
|
@@ -1,49 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
function noop(): AnalyticsProxy {
|
|
7
|
-
return { track: () => {}, load: () => {} }
|
|
8
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
createAnalyticsClient,
|
|
3
|
+
resolveScriptTrigger,
|
|
4
|
+
type AnalyticsClient,
|
|
5
|
+
} from '../utils/scriptClients'
|
|
9
6
|
|
|
10
|
-
export function useAnalytics():
|
|
7
|
+
export function useAnalytics(): AnalyticsClient {
|
|
11
8
|
const { scriptsLayer } = useAppConfig()
|
|
12
9
|
const { hasConsent, consentRequired } = useScriptsConsent()
|
|
13
10
|
|
|
14
11
|
const provider = scriptsLayer?.analytics?.provider
|
|
15
12
|
const id = scriptsLayer?.analytics?.id
|
|
13
|
+
const trigger = resolveScriptTrigger(consentRequired, hasConsent)
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// Load on Nuxt ready unless consent is required and not yet granted
|
|
20
|
-
const trigger = consentRequired.value
|
|
21
|
-
? useScriptTriggerConsent({ consent: hasConsent })
|
|
22
|
-
: 'onNuxtReady'
|
|
23
|
-
|
|
24
|
-
if (provider === 'ga4') {
|
|
25
|
-
const ga = useScriptGoogleAnalytics({ id, scriptOptions: { trigger } })
|
|
26
|
-
return {
|
|
27
|
-
track: (event, params) => ga.proxy.gtag('event', event, params ?? {}),
|
|
28
|
-
load: () => ga.load(),
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (provider === 'plausible') {
|
|
33
|
-
const pl = useScriptPlausibleAnalytics({ domain: id, scriptOptions: { trigger } })
|
|
34
|
-
return {
|
|
35
|
-
track: (event, params) => pl.proxy.plausible(event, { props: params ?? {} }),
|
|
36
|
-
load: () => pl.load(),
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (provider === 'fathom') {
|
|
41
|
-
const fa = useScriptFathomAnalytics({ site: id, scriptOptions: { trigger } })
|
|
42
|
-
return {
|
|
43
|
-
track: (event) => fa.proxy.trackEvent(event, { _value: 0 }),
|
|
44
|
-
load: () => fa.load(),
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return noop()
|
|
15
|
+
return createAnalyticsClient(provider, id ?? '', trigger)
|
|
49
16
|
}
|
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import { createGtmClient, resolveScriptTrigger, type GtmClient } from '../utils/scriptClients'
|
|
2
|
+
|
|
3
|
+
export function useGtm(): GtmClient {
|
|
2
4
|
const { scriptsLayer } = useAppConfig()
|
|
3
5
|
const { hasConsent, consentRequired } = useScriptsConsent()
|
|
4
6
|
|
|
5
7
|
const gtmConfig = scriptsLayer?.gtm
|
|
6
|
-
if (!gtmConfig?.enabled
|
|
8
|
+
if (!gtmConfig?.enabled) {
|
|
7
9
|
return { push: () => {}, load: () => {} }
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
? useScriptTriggerConsent({ consent: hasConsent })
|
|
13
|
-
: 'onNuxtReady'
|
|
14
|
-
|
|
15
|
-
const gtm = useScriptGoogleTagManager({ id: gtmConfig.id, scriptOptions: { trigger } })
|
|
16
|
-
|
|
17
|
-
return {
|
|
18
|
-
push: (data: Record<string, unknown>) => gtm.proxy.dataLayer.push(data),
|
|
19
|
-
load: () => gtm.load(),
|
|
20
|
-
}
|
|
12
|
+
const trigger = resolveScriptTrigger(consentRequired, hasConsent)
|
|
13
|
+
return createGtmClient(gtmConfig.id, trigger)
|
|
21
14
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
export type ScriptTrigger = ReturnType<typeof useScriptTriggerConsent> | 'onNuxtReady'
|
|
4
|
+
|
|
5
|
+
export type AnalyticsClient = {
|
|
6
|
+
track: (event: string, params?: Record<string, unknown>) => void
|
|
7
|
+
load: () => void
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type GtmClient = {
|
|
11
|
+
push: (data: Record<string, unknown>) => void
|
|
12
|
+
load: () => void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function resolveScriptTrigger(consentRequired: Ref<boolean>, consent: Ref<boolean>) {
|
|
16
|
+
return consentRequired.value ? useScriptTriggerConsent({ consent }) : 'onNuxtReady'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function noopAnalyticsClient(): AnalyticsClient {
|
|
20
|
+
return { track: () => {}, load: () => {} }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// fallow-ignore-next-line complexity
|
|
24
|
+
export function createAnalyticsClient(
|
|
25
|
+
provider: string | null | undefined,
|
|
26
|
+
id: string,
|
|
27
|
+
trigger: ScriptTrigger
|
|
28
|
+
): AnalyticsClient {
|
|
29
|
+
if (!provider || !id) return noopAnalyticsClient()
|
|
30
|
+
|
|
31
|
+
if (provider === 'ga4') {
|
|
32
|
+
const ga = useScriptGoogleAnalytics({ id, scriptOptions: { trigger } })
|
|
33
|
+
return {
|
|
34
|
+
track: (event, params) => ga.proxy.gtag('event', event, params ?? {}),
|
|
35
|
+
load: () => ga.load(),
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (provider === 'plausible') {
|
|
40
|
+
const pl = useScriptPlausibleAnalytics({ domain: id, scriptOptions: { trigger } })
|
|
41
|
+
return {
|
|
42
|
+
track: (event, params) => pl.proxy.plausible(event, { props: params ?? {} }),
|
|
43
|
+
load: () => pl.load(),
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (provider === 'fathom') {
|
|
48
|
+
const fa = useScriptFathomAnalytics({ site: id, scriptOptions: { trigger } })
|
|
49
|
+
return {
|
|
50
|
+
track: (event) => fa.proxy.trackEvent(event, { _value: 0 }),
|
|
51
|
+
load: () => fa.load(),
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return noopAnalyticsClient()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function noopGtmClient(): GtmClient {
|
|
59
|
+
return { push: () => {}, load: () => {} }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function createGtmClient(id: string | undefined, trigger: ScriptTrigger): GtmClient {
|
|
63
|
+
if (!id) return noopGtmClient()
|
|
64
|
+
|
|
65
|
+
const gtm = useScriptGoogleTagManager({ id, scriptOptions: { trigger } })
|
|
66
|
+
return {
|
|
67
|
+
push: (data: Record<string, unknown>) => gtm.proxy.dataLayer.push(data),
|
|
68
|
+
load: () => gtm.load(),
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { Ref } from 'vue'
|
|
2
2
|
import type LocomotiveScroll from 'locomotive-scroll'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
4
|
+
import {
|
|
5
|
+
runLocomotiveScroll,
|
|
6
|
+
runNativeScroll,
|
|
7
|
+
type ScrollTarget,
|
|
8
|
+
type ScrollToOptions,
|
|
9
|
+
} from '../utils/scroll'
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Unified scroll composable using Locomotive Scroll v5 smooth scrolling
|
|
@@ -60,20 +59,14 @@ export function useSmoothScroll() {
|
|
|
60
59
|
locomotiveScroll.value?.start()
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
function scrollTo(target:
|
|
62
|
+
function scrollTo(target: ScrollTarget, options?: ScrollToOptions) {
|
|
64
63
|
if (!import.meta.client) return
|
|
65
64
|
|
|
66
65
|
if (locomotiveScroll.value) {
|
|
67
|
-
locomotiveScroll.value
|
|
68
|
-
offset: options?.offset ?? 0,
|
|
69
|
-
duration: options?.duration ?? 1.2,
|
|
70
|
-
immediate: options?.immediate ?? false,
|
|
71
|
-
lock: options?.lock ?? false,
|
|
72
|
-
...(options?.onComplete !== undefined && { onComplete: options.onComplete }),
|
|
73
|
-
})
|
|
66
|
+
runLocomotiveScroll(locomotiveScroll.value, target, options)
|
|
74
67
|
return
|
|
75
68
|
}
|
|
76
|
-
|
|
69
|
+
runNativeScroll(target, options)
|
|
77
70
|
}
|
|
78
71
|
|
|
79
72
|
function scrollToTop(options?: { duration?: number; immediate?: boolean }) {
|
|
@@ -102,30 +95,3 @@ export function useSmoothScroll() {
|
|
|
102
95
|
unlockScrolling,
|
|
103
96
|
}
|
|
104
97
|
}
|
|
105
|
-
|
|
106
|
-
function resolveScrollTarget(target: string | number | HTMLElement): number | null {
|
|
107
|
-
if (typeof target === 'number') return target
|
|
108
|
-
if (typeof target === 'string') {
|
|
109
|
-
const el = document.querySelector(target)
|
|
110
|
-
if (!el) return null
|
|
111
|
-
return el.getBoundingClientRect().top + window.scrollY
|
|
112
|
-
}
|
|
113
|
-
return target.getBoundingClientRect().top + window.scrollY
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function nativeScrollTo(target: string | number | HTMLElement, options?: ScrollToOptions) {
|
|
117
|
-
const base = resolveScrollTarget(target)
|
|
118
|
-
if (base === null) return
|
|
119
|
-
|
|
120
|
-
const targetPosition = base + (options?.offset ?? 0)
|
|
121
|
-
|
|
122
|
-
if (options?.immediate) {
|
|
123
|
-
window.scrollTo(0, targetPosition)
|
|
124
|
-
options?.onComplete?.()
|
|
125
|
-
return
|
|
126
|
-
}
|
|
127
|
-
window.scrollTo({ top: targetPosition, behavior: 'smooth' })
|
|
128
|
-
if (options?.onComplete) {
|
|
129
|
-
setTimeout(options.onComplete, options?.duration ?? 500)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type LocomotiveScroll from 'locomotive-scroll'
|
|
2
|
+
|
|
3
|
+
export type ScrollTarget = string | number | HTMLElement
|
|
4
|
+
|
|
5
|
+
export type ScrollToOptions = {
|
|
6
|
+
offset?: number | undefined
|
|
7
|
+
duration?: number | undefined
|
|
8
|
+
immediate?: boolean | undefined
|
|
9
|
+
lock?: boolean | undefined
|
|
10
|
+
onComplete?: (() => void) | undefined
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function resolveScrollOffset(options?: ScrollToOptions) {
|
|
14
|
+
return options?.offset ?? 0
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function resolveScrollDuration(options?: ScrollToOptions) {
|
|
18
|
+
return options?.duration ?? 1.2
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function resolveScrollImmediate(options?: ScrollToOptions) {
|
|
22
|
+
return options?.immediate ?? false
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function resolveScrollLock(options?: ScrollToOptions) {
|
|
26
|
+
return options?.lock ?? false
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function resolveScrollOnComplete(options?: ScrollToOptions) {
|
|
30
|
+
return options?.onComplete
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function resolveNativeScrollDelay(options?: ScrollToOptions) {
|
|
34
|
+
return options?.duration ?? 500
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type LocomotiveScrollOptions = Parameters<LocomotiveScroll['scrollTo']>[1]
|
|
38
|
+
|
|
39
|
+
export function normalizeScrollTarget(target: ScrollTarget): number | null {
|
|
40
|
+
if (typeof target === 'number') return target
|
|
41
|
+
const element = typeof target === 'string' ? document.querySelector(target) : target
|
|
42
|
+
if (!element) return null
|
|
43
|
+
return element.getBoundingClientRect().top + window.scrollY
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function normalizeScrollOptions(options?: ScrollToOptions) {
|
|
47
|
+
return {
|
|
48
|
+
offset: resolveScrollOffset(options),
|
|
49
|
+
duration: resolveScrollDuration(options),
|
|
50
|
+
immediate: resolveScrollImmediate(options),
|
|
51
|
+
lock: resolveScrollLock(options),
|
|
52
|
+
...(resolveScrollOnComplete(options) ? { onComplete: resolveScrollOnComplete(options) } : {}),
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function runImmediateScroll(targetPosition: number, onComplete?: () => void) {
|
|
57
|
+
window.scrollTo(0, targetPosition)
|
|
58
|
+
onComplete?.()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function runSmoothScroll(targetPosition: number, duration: number, onComplete?: () => void) {
|
|
62
|
+
window.scrollTo({ top: targetPosition, behavior: 'smooth' })
|
|
63
|
+
if (onComplete) {
|
|
64
|
+
setTimeout(onComplete, duration)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function buildLocomotiveScrollOptions(options?: ScrollToOptions): LocomotiveScrollOptions {
|
|
69
|
+
const scrollOptions: LocomotiveScrollOptions = {
|
|
70
|
+
offset: resolveScrollOffset(options),
|
|
71
|
+
duration: resolveScrollDuration(options),
|
|
72
|
+
immediate: resolveScrollImmediate(options),
|
|
73
|
+
lock: resolveScrollLock(options),
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const onComplete = resolveScrollOnComplete(options)
|
|
77
|
+
if (onComplete) {
|
|
78
|
+
scrollOptions.onComplete = onComplete
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return scrollOptions
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function runNativeScroll(target: ScrollTarget, options?: ScrollToOptions) {
|
|
85
|
+
const base = normalizeScrollTarget(target)
|
|
86
|
+
if (base === null) return
|
|
87
|
+
|
|
88
|
+
const targetPosition = base + resolveScrollOffset(options)
|
|
89
|
+
if (resolveScrollImmediate(options)) {
|
|
90
|
+
runImmediateScroll(targetPosition, resolveScrollOnComplete(options))
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
runSmoothScroll(targetPosition, resolveNativeScrollDelay(options), resolveScrollOnComplete(options))
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function runLocomotiveScroll(
|
|
98
|
+
scroll: LocomotiveScroll,
|
|
99
|
+
target: ScrollTarget,
|
|
100
|
+
options?: ScrollToOptions
|
|
101
|
+
) {
|
|
102
|
+
scroll.scrollTo(target, buildLocomotiveScrollOptions(options))
|
|
103
|
+
}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
+
import { resolveSeoConfig } from '../utils/seoConfig'
|
|
2
|
+
|
|
1
3
|
export function useSeoConfig() {
|
|
2
4
|
const site = useSiteConfig()
|
|
3
5
|
const { seoLayer } = useAppConfig()
|
|
4
|
-
|
|
5
|
-
return {
|
|
6
|
-
site,
|
|
7
|
-
ogImageComponent: seoLayer?.ogImage?.component ?? 'OgImageBasic',
|
|
8
|
-
ogImageProps: seoLayer?.ogImage?.props ?? {},
|
|
9
|
-
twitterCard: seoLayer?.twitterCard ?? 'summary_large_image',
|
|
10
|
-
schemaOrgEnabled: seoLayer?.schemaOrg?.enabled ?? true,
|
|
11
|
-
identity: seoLayer?.schemaOrg?.identity ?? null,
|
|
12
|
-
}
|
|
6
|
+
return resolveSeoConfig(site, seoLayer)
|
|
13
7
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { SiteConfig } from '#layers/core/app/types/site'
|
|
2
|
+
|
|
3
|
+
type SeoLayerConfig = {
|
|
4
|
+
ogImage?: {
|
|
5
|
+
component?: string
|
|
6
|
+
props?: Record<string, unknown>
|
|
7
|
+
}
|
|
8
|
+
twitterCard?: string
|
|
9
|
+
schemaOrg?: {
|
|
10
|
+
enabled?: boolean
|
|
11
|
+
identity?: unknown
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// fallow-ignore-next-line complexity
|
|
16
|
+
function resolveOgImageConfig(seoLayer?: SeoLayerConfig) {
|
|
17
|
+
return {
|
|
18
|
+
ogImageComponent: seoLayer?.ogImage?.component ?? 'OgImageBasic',
|
|
19
|
+
ogImageProps: seoLayer?.ogImage?.props ?? {},
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// fallow-ignore-next-line complexity
|
|
24
|
+
function resolveSchemaOrgConfig(seoLayer?: SeoLayerConfig) {
|
|
25
|
+
return {
|
|
26
|
+
schemaOrgEnabled: seoLayer?.schemaOrg?.enabled ?? true,
|
|
27
|
+
identity: seoLayer?.schemaOrg?.identity ?? null,
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function resolveSeoConfig(site: SiteConfig, seoLayer?: SeoLayerConfig) {
|
|
32
|
+
return {
|
|
33
|
+
site,
|
|
34
|
+
...resolveOgImageConfig(seoLayer),
|
|
35
|
+
twitterCard: seoLayer?.twitterCard ?? 'summary_large_image',
|
|
36
|
+
...resolveSchemaOrgConfig(seoLayer),
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { fbm2D, simplexNoise2D } from '../../shaders/common/noise'
|
|
19
19
|
import { cosinePalette } from '../../shaders/common/palette'
|
|
20
20
|
import type { TSLNode } from '../../shaders/types'
|
|
21
|
+
import { watchUniformProp } from '#layers/shader/app/composables/useUniformWatchers'
|
|
21
22
|
|
|
22
23
|
const {
|
|
23
24
|
speed = 1.0,
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
color1 = '#0a0a20',
|
|
26
27
|
color2 = '#00ff87',
|
|
27
28
|
color3 = '#60efff',
|
|
29
|
+
// fallow-ignore-next-line code-duplication
|
|
28
30
|
mouseX = 0.5,
|
|
29
31
|
mouseY = 0.5,
|
|
30
32
|
mouseInteraction = true,
|
|
@@ -51,39 +53,15 @@
|
|
|
51
53
|
const color2Uniform: TSLNode = uniform(new Color(color2))
|
|
52
54
|
const color3Uniform: TSLNode = uniform(new Color(color3))
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
)
|
|
63
|
-
watch(
|
|
64
|
-
() => mouseX,
|
|
65
|
-
(val) => (mouseXUniform.value = val)
|
|
66
|
-
)
|
|
67
|
-
watch(
|
|
68
|
-
() => mouseY,
|
|
69
|
-
(val) => (mouseYUniform.value = val)
|
|
70
|
-
)
|
|
71
|
-
watch(
|
|
72
|
-
() => mouseStrength,
|
|
73
|
-
(val) => (mouseStrengthUniform.value = val)
|
|
74
|
-
)
|
|
75
|
-
watch(
|
|
76
|
-
() => color1,
|
|
77
|
-
(val) => (color1Uniform.value = new Color(val))
|
|
78
|
-
)
|
|
79
|
-
watch(
|
|
80
|
-
() => color2,
|
|
81
|
-
(val) => (color2Uniform.value = new Color(val))
|
|
82
|
-
)
|
|
83
|
-
watch(
|
|
84
|
-
() => color3,
|
|
85
|
-
(val) => (color3Uniform.value = new Color(val))
|
|
86
|
-
)
|
|
56
|
+
watchUniformProp(() => speed, speedUniform)
|
|
57
|
+
watchUniformProp(() => intensity, intensityUniform)
|
|
58
|
+
watchUniformProp(() => mouseX, mouseXUniform)
|
|
59
|
+
watchUniformProp(() => mouseY, mouseYUniform)
|
|
60
|
+
watchUniformProp(() => mouseStrength, mouseStrengthUniform)
|
|
61
|
+
watchUniformProp(() => color1, color1Uniform, (val) => new Color(val))
|
|
62
|
+
watchUniformProp(() => color2, color2Uniform, (val) => new Color(val))
|
|
63
|
+
// fallow-ignore-next-line code-duplication
|
|
64
|
+
watchUniformProp(() => color3, color3Uniform, (val) => new Color(val))
|
|
87
65
|
|
|
88
66
|
const material = computed(() => {
|
|
89
67
|
const mat = new MeshBasicNodeMaterial()
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { fbm2D, ridgedFbm2d, warpedFbmCoords } from '../../shaders/common/noise'
|
|
19
19
|
import { cosinePalette } from '../../shaders/common/palette'
|
|
20
20
|
import type { TSLNode } from '../../shaders/types'
|
|
21
|
+
import { watchUniformProp } from '#layers/shader/app/composables/useUniformWatchers'
|
|
21
22
|
|
|
22
23
|
const {
|
|
23
24
|
speed = 1.0,
|
|
@@ -54,43 +55,15 @@
|
|
|
54
55
|
const color3Uniform: TSLNode = uniform(new Color(color3))
|
|
55
56
|
const color4Uniform: TSLNode = uniform(new Color(color4))
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
)
|
|
66
|
-
watch(
|
|
67
|
-
() => mouseX,
|
|
68
|
-
(val) => (mouseXUniform.value = val)
|
|
69
|
-
)
|
|
70
|
-
watch(
|
|
71
|
-
() => mouseY,
|
|
72
|
-
(val) => (mouseYUniform.value = val)
|
|
73
|
-
)
|
|
74
|
-
watch(
|
|
75
|
-
() => mouseStrength,
|
|
76
|
-
(val) => (mouseStrengthUniform.value = val)
|
|
77
|
-
)
|
|
78
|
-
watch(
|
|
79
|
-
() => color1,
|
|
80
|
-
(val) => (color1Uniform.value = new Color(val))
|
|
81
|
-
)
|
|
82
|
-
watch(
|
|
83
|
-
() => color2,
|
|
84
|
-
(val) => (color2Uniform.value = new Color(val))
|
|
85
|
-
)
|
|
86
|
-
watch(
|
|
87
|
-
() => color3,
|
|
88
|
-
(val) => (color3Uniform.value = new Color(val))
|
|
89
|
-
)
|
|
90
|
-
watch(
|
|
91
|
-
() => color4,
|
|
92
|
-
(val) => (color4Uniform.value = new Color(val))
|
|
93
|
-
)
|
|
58
|
+
watchUniformProp(() => speed, speedUniform)
|
|
59
|
+
watchUniformProp(() => intensity, intensityUniform)
|
|
60
|
+
watchUniformProp(() => mouseX, mouseXUniform)
|
|
61
|
+
watchUniformProp(() => mouseY, mouseYUniform)
|
|
62
|
+
watchUniformProp(() => mouseStrength, mouseStrengthUniform)
|
|
63
|
+
watchUniformProp(() => color1, color1Uniform, (val) => new Color(val))
|
|
64
|
+
watchUniformProp(() => color2, color2Uniform, (val) => new Color(val))
|
|
65
|
+
watchUniformProp(() => color3, color3Uniform, (val) => new Color(val))
|
|
66
|
+
watchUniformProp(() => color4, color4Uniform, (val) => new Color(val))
|
|
94
67
|
|
|
95
68
|
const material = computed(() => {
|
|
96
69
|
const mat = new MeshBasicNodeMaterial()
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
import { fbm2D, simplexNoise2D } from '../../shaders/common/noise'
|
|
21
21
|
import type { TSLNode } from '../../shaders/types'
|
|
22
|
+
import { watchUniformProp } from '#layers/shader/app/composables/useUniformWatchers'
|
|
22
23
|
|
|
23
24
|
const {
|
|
24
25
|
speed = 1.0,
|
|
@@ -55,43 +56,15 @@
|
|
|
55
56
|
const color3Uniform: TSLNode = uniform(new Color(color3))
|
|
56
57
|
const color4Uniform: TSLNode = uniform(new Color(color4))
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
)
|
|
67
|
-
watch(
|
|
68
|
-
() => mouseX,
|
|
69
|
-
(val) => (mouseXUniform.value = val)
|
|
70
|
-
)
|
|
71
|
-
watch(
|
|
72
|
-
() => mouseY,
|
|
73
|
-
(val) => (mouseYUniform.value = val)
|
|
74
|
-
)
|
|
75
|
-
watch(
|
|
76
|
-
() => mouseStrength,
|
|
77
|
-
(val) => (mouseStrengthUniform.value = val)
|
|
78
|
-
)
|
|
79
|
-
watch(
|
|
80
|
-
() => color1,
|
|
81
|
-
(val) => (color1Uniform.value = new Color(val))
|
|
82
|
-
)
|
|
83
|
-
watch(
|
|
84
|
-
() => color2,
|
|
85
|
-
(val) => (color2Uniform.value = new Color(val))
|
|
86
|
-
)
|
|
87
|
-
watch(
|
|
88
|
-
() => color3,
|
|
89
|
-
(val) => (color3Uniform.value = new Color(val))
|
|
90
|
-
)
|
|
91
|
-
watch(
|
|
92
|
-
() => color4,
|
|
93
|
-
(val) => (color4Uniform.value = new Color(val))
|
|
94
|
-
)
|
|
59
|
+
watchUniformProp(() => speed, speedUniform)
|
|
60
|
+
watchUniformProp(() => intensity, intensityUniform)
|
|
61
|
+
watchUniformProp(() => mouseX, mouseXUniform)
|
|
62
|
+
watchUniformProp(() => mouseY, mouseYUniform)
|
|
63
|
+
watchUniformProp(() => mouseStrength, mouseStrengthUniform)
|
|
64
|
+
watchUniformProp(() => color1, color1Uniform, (val) => new Color(val))
|
|
65
|
+
watchUniformProp(() => color2, color2Uniform, (val) => new Color(val))
|
|
66
|
+
watchUniformProp(() => color3, color3Uniform, (val) => new Color(val))
|
|
67
|
+
watchUniformProp(() => color4, color4Uniform, (val) => new Color(val))
|
|
95
68
|
|
|
96
69
|
const material = computed(() => {
|
|
97
70
|
const mat = new MeshBasicNodeMaterial()
|
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
import { fbm3D, hash21, ridgedFbm2d, voronoi2D } from '../../shaders/common/noise'
|
|
20
20
|
import { cosinePalette } from '../../shaders/common/palette'
|
|
21
21
|
import type { TSLNode } from '../../shaders/types'
|
|
22
|
+
import { watchUniformProp } from '#layers/shader/app/composables/useUniformWatchers'
|
|
22
23
|
|
|
23
24
|
const {
|
|
25
|
+
// fallow-ignore-next-line code-duplication
|
|
24
26
|
speed = 1.0,
|
|
25
27
|
intensity = 1.0,
|
|
26
28
|
color1 = '#1a0a2e',
|
|
@@ -55,43 +57,16 @@
|
|
|
55
57
|
const color3Uniform: TSLNode = uniform(new Color(color3))
|
|
56
58
|
const color4Uniform: TSLNode = uniform(new Color(color4))
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
() => mouseX,
|
|
69
|
-
(val) => (mouseXUniform.value = val)
|
|
70
|
-
)
|
|
71
|
-
watch(
|
|
72
|
-
() => mouseY,
|
|
73
|
-
(val) => (mouseYUniform.value = val)
|
|
74
|
-
)
|
|
75
|
-
watch(
|
|
76
|
-
() => mouseStrength,
|
|
77
|
-
(val) => (mouseStrengthUniform.value = val)
|
|
78
|
-
)
|
|
79
|
-
watch(
|
|
80
|
-
() => color1,
|
|
81
|
-
(val) => (color1Uniform.value = new Color(val))
|
|
82
|
-
)
|
|
83
|
-
watch(
|
|
84
|
-
() => color2,
|
|
85
|
-
(val) => (color2Uniform.value = new Color(val))
|
|
86
|
-
)
|
|
87
|
-
watch(
|
|
88
|
-
() => color3,
|
|
89
|
-
(val) => (color3Uniform.value = new Color(val))
|
|
90
|
-
)
|
|
91
|
-
watch(
|
|
92
|
-
() => color4,
|
|
93
|
-
(val) => (color4Uniform.value = new Color(val))
|
|
94
|
-
)
|
|
60
|
+
watchUniformProp(() => speed, speedUniform)
|
|
61
|
+
watchUniformProp(() => intensity, intensityUniform)
|
|
62
|
+
watchUniformProp(() => mouseX, mouseXUniform)
|
|
63
|
+
watchUniformProp(() => mouseY, mouseYUniform)
|
|
64
|
+
watchUniformProp(() => mouseStrength, mouseStrengthUniform)
|
|
65
|
+
watchUniformProp(() => color1, color1Uniform, (val) => new Color(val))
|
|
66
|
+
watchUniformProp(() => color2, color2Uniform, (val) => new Color(val))
|
|
67
|
+
watchUniformProp(() => color3, color3Uniform, (val) => new Color(val))
|
|
68
|
+
// fallow-ignore-next-line code-duplication
|
|
69
|
+
watchUniformProp(() => color4, color4Uniform, (val) => new Color(val))
|
|
95
70
|
|
|
96
71
|
const material = computed(() => {
|
|
97
72
|
const mat = new MeshBasicNodeMaterial()
|