@canvas3/nuxt 0.0.1

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.
Files changed (53) hide show
  1. package/README.md +70 -0
  2. package/dist/module.d.mts +5 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +32 -0
  5. package/dist/runtime/components/canvas3-image.vue +71 -0
  6. package/dist/runtime/components/canvas3-image.vue.d.ts +5 -0
  7. package/dist/runtime/components/canvas3-text.vue +95 -0
  8. package/dist/runtime/components/canvas3-text.vue.d.ts +11 -0
  9. package/dist/runtime/constants/default-canvas3-options.d.ts +40 -0
  10. package/dist/runtime/constants/default-canvas3-options.js +40 -0
  11. package/dist/runtime/constants/shaders/TextBlurFragment.glsl +126 -0
  12. package/dist/runtime/constants/shaders/TextBlurVertex.glsl +10 -0
  13. package/dist/runtime/constants/shaders/projectBlurFragment.glsl +143 -0
  14. package/dist/runtime/constants/shaders/projectBlurVertex.glsl +11 -0
  15. package/dist/runtime/constants/shaders/scrollFragment.glsl +7 -0
  16. package/dist/runtime/constants/shaders/scrollVertex.glsl +8 -0
  17. package/dist/runtime/directives/action-on-scroll.d.ts +2 -0
  18. package/dist/runtime/directives/action-on-scroll.js +42 -0
  19. package/dist/runtime/directives/canvas3-image-directive.client.d.ts +6 -0
  20. package/dist/runtime/directives/canvas3-image-directive.client.js +104 -0
  21. package/dist/runtime/directives/set-data-attributes.d.ts +3 -0
  22. package/dist/runtime/directives/set-data-attributes.js +34 -0
  23. package/dist/runtime/layouts/canvas3-layout.vue +44 -0
  24. package/dist/runtime/layouts/canvas3-layout.vue.d.ts +11 -0
  25. package/dist/runtime/plugin.d.ts +2 -0
  26. package/dist/runtime/plugin.js +3 -0
  27. package/dist/runtime/plugins/directives.d.ts +2 -0
  28. package/dist/runtime/plugins/directives.js +9 -0
  29. package/dist/runtime/server/tsconfig.json +3 -0
  30. package/dist/runtime/types/shaders.d.ts +4 -0
  31. package/dist/runtime/types/three-msdf-text-utils.d.ts +36 -0
  32. package/dist/runtime/types/types.d.ts +71 -0
  33. package/dist/runtime/types/types.js +0 -0
  34. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/TextLayout.d.ts +1 -0
  35. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/TextLayout.js +0 -0
  36. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/createIndices.d.ts +1 -0
  37. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/createIndices.js +0 -0
  38. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/index.d.ts +1 -0
  39. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/index.js +0 -0
  40. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/utils.d.ts +1 -0
  41. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/utils.js +0 -0
  42. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/vertices.d.ts +1 -0
  43. package/dist/runtime/utils/MSDFFont/MSDFTextGeometry/vertices.js +0 -0
  44. package/dist/runtime/utils/canvas3/canvas3.d.ts +65 -0
  45. package/dist/runtime/utils/canvas3/canvas3.js +512 -0
  46. package/dist/runtime/utils/canvas3/helpers.d.ts +12 -0
  47. package/dist/runtime/utils/canvas3/helpers.js +96 -0
  48. package/dist/runtime/utils/canvas3/scroll.d.ts +37 -0
  49. package/dist/runtime/utils/canvas3/scroll.js +191 -0
  50. package/dist/runtime/utils/exports.d.ts +10 -0
  51. package/dist/runtime/utils/exports.js +14 -0
  52. package/dist/types.d.mts +7 -0
  53. package/package.json +64 -0
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ <!--
2
+ Get your module up and running quickly.
3
+
4
+ Find and replace all on all files (CMD+SHIFT+F):
5
+ - Name: My Module
6
+ - Package name: my-module
7
+ - Description: My new Nuxt module
8
+ -->
9
+
10
+ # Canvas3 Nuxt Module
11
+
12
+ Nuxt module for ThreeJS integration and additional features
13
+
14
+ [//]: # (- [✨ &nbsp;Release Notes]&#40;/CHANGELOG.md&#41;)
15
+
16
+ [//]: # ( - [🏀 Online playground]&#40;https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue&#41;)
17
+
18
+ [//]: # ( - [📖 &nbsp;Documentation]&#40;https://example.com&#41;)
19
+
20
+ ## Features
21
+
22
+ [✨ &nbsp;Example use cases](https://canvas3.vercel.app/)
23
+
24
+ <!-- Highlight some of the features your module provide here -->
25
+
26
+ [//]: # (- ⛰ &nbsp;Foo)
27
+
28
+ [//]: # (- 🚠 &nbsp;Bar)
29
+
30
+ [//]: # (- 🌲 &nbsp;Baz)
31
+
32
+ ## Quick Setup
33
+
34
+ Install the module to your Nuxt application with one command:
35
+
36
+ ```bash
37
+ npx nuxi module add canvas3-nuxt
38
+ ```
39
+ That's it! You can now use Canvas3 module in your Nuxt app ✨
40
+
41
+ ## Contribution
42
+
43
+ <details>
44
+ <summary>Local development</summary>
45
+
46
+ ```bash
47
+ # Install dependencies
48
+ npm install
49
+
50
+ # Generate type stubs
51
+ npm run dev:prepare
52
+
53
+ # Develop with the playground
54
+ npm run dev
55
+
56
+ # Build the playground
57
+ npm run dev:build
58
+
59
+ # Run ESLint
60
+ npm run lint
61
+
62
+ # Run Vitest
63
+ npm run test
64
+ npm run test:watch
65
+
66
+ # Release new version
67
+ npm run release
68
+ ```
69
+
70
+ </details>
@@ -0,0 +1,5 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ declare const _default: _nuxt_schema.NuxtModule<_nuxt_schema.ModuleOptions, _nuxt_schema.ModuleOptions, false>;
4
+
5
+ export { _default as default };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "canvas-nuxt-layout",
3
+ "configKey": "canvas3Layout",
4
+ "version": "0.0.1",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "3.6.0"
8
+ }
9
+ }
@@ -0,0 +1,32 @@
1
+ import { defineNuxtModule, createResolver, addTemplate, addLayout, addComponent, addPlugin, addImports } from '@nuxt/kit';
2
+
3
+ const module = defineNuxtModule({
4
+ meta: {
5
+ name: "canvas-nuxt-layout",
6
+ configKey: "canvas3Layout"
7
+ },
8
+ setup(_, nuxt) {
9
+ const { resolve } = createResolver(import.meta.url);
10
+ const canvas3Layout = addTemplate({
11
+ src: resolve("./runtime/layouts/canvas3-layout.vue"),
12
+ filename: "layout.vue",
13
+ write: true
14
+ });
15
+ addLayout(canvas3Layout, "canvas3");
16
+ addComponent({
17
+ name: "Canvas3Image",
18
+ filePath: resolve("./runtime/components/canvas3-image.vue"),
19
+ global: true
20
+ });
21
+ addPlugin(resolve("./runtime/plugins/directives"));
22
+ addImports([
23
+ {
24
+ name: "Canvas3",
25
+ from: resolve("./runtime/utils/exports")
26
+ }
27
+ ]);
28
+ nuxt.options.alias["#canvas3-nuxt"] = resolve("./runtime");
29
+ }
30
+ });
31
+
32
+ export { module as default };
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <div class="webgl-img-wrapper">
3
+ <img
4
+ ref="image"
5
+ class="webgl-img"
6
+ :class="{ 'reduced-motion': reducedMotion ?? null }"
7
+ :alt="props.options.alt"
8
+ :src="props.options.src"
9
+ :loading="props.options.loadStrategy"
10
+ @load="addImageToCanvas"
11
+ >
12
+ </div>
13
+ </template>
14
+
15
+ <script setup>
16
+ import { ref, computed, watch, onMounted, nextTick, onBeforeUnmount } from "vue";
17
+ import { Canvas3 } from "#canvas3-nuxt/utils/canvas3/canvas3";
18
+ const props = defineProps({
19
+ options: {
20
+ type: Object,
21
+ default: () => ({
22
+ alt: "",
23
+ src: "",
24
+ loadStrategy: "lazy",
25
+ shaderName: void 0,
26
+ uniforms: {},
27
+ activateMeshUniforms: {}
28
+ })
29
+ }
30
+ });
31
+ const reducedMotion = computed(() => Canvas3.options?.disabled ?? null);
32
+ const image = ref(null);
33
+ const generatedMeshId = "image_" + crypto.randomUUID();
34
+ const imgAddedToCanvas = ref(false);
35
+ const addImageToCanvas = async () => {
36
+ await nextTick();
37
+ if (!image.value || Canvas3.canvasInitiated.value === false || Canvas3.options?.disabled || imgAddedToCanvas.value) return;
38
+ if (image.value.naturalWidth === 0) return;
39
+ image.value.dataset.meshId = generatedMeshId;
40
+ Canvas3.addImageAsMesh(
41
+ image.value,
42
+ props.options.shaderName,
43
+ generatedMeshId,
44
+ props.options.uniforms,
45
+ props.options.activateMeshUniforms
46
+ );
47
+ imgAddedToCanvas.value = true;
48
+ };
49
+ watch(() => Canvas3.canvasInitiated.value, (ready) => {
50
+ if (ready) addImageToCanvas();
51
+ });
52
+ watch(() => props.options.uniforms, (u) => {
53
+ Canvas3.meshUniformsUpdate(generatedMeshId, u);
54
+ }, { deep: true });
55
+ watch(() => props.options.src, () => {
56
+ imgAddedToCanvas.value = false;
57
+ nextTick(() => {
58
+ if (image.value?.complete) addImageToCanvas();
59
+ });
60
+ });
61
+ onMounted(() => {
62
+ if (image.value?.complete) addImageToCanvas();
63
+ });
64
+ onBeforeUnmount(() => {
65
+ Canvas3.removeMesh(generatedMeshId);
66
+ });
67
+ </script>
68
+
69
+ <style scoped>
70
+ .webgl-img{max-height:100%;max-width:100%;opacity:0}.webgl-img.reduced-motion{height:100%;-o-object-fit:cover;object-fit:cover;opacity:1;width:100%}
71
+ </style>
@@ -0,0 +1,5 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {
2
+ options: Record<string, any>;
3
+ $props: any;
4
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
5
+ export default _default;
@@ -0,0 +1,95 @@
1
+ <template>
2
+ <span
3
+ ref="htmlEl"
4
+ class="text-wrapper"
5
+ :class="{ 'reduced-motion': reducedMotion }"
6
+ >
7
+ <slot />
8
+ </span>
9
+ </template>
10
+
11
+ <script setup>
12
+ import { ref, watch, onMounted, onBeforeUnmount, defineProps, computed } from "vue";
13
+ import { Canvas3 } from "#canvas3-nuxt/utils/canvas3/canvas3";
14
+ const props = defineProps({
15
+ options: {
16
+ type: {
17
+ shaderName: {
18
+ type: String,
19
+ default: null
20
+ },
21
+ theme: {
22
+ type: String,
23
+ default: "dark"
24
+ },
25
+ uniforms: {
26
+ type: Object,
27
+ default: () => {
28
+ }
29
+ },
30
+ activateMeshUniforms: {
31
+ type: Object,
32
+ default: () => {
33
+ }
34
+ }
35
+ },
36
+ default: () => ({
37
+ uniforms: {},
38
+ activateMeshUniforms: {}
39
+ })
40
+ }
41
+ });
42
+ const reducedMotion = computed(() => {
43
+ return Canvas3.options?.disabled ?? null;
44
+ });
45
+ const htmlEl = ref("htmlEl");
46
+ const meshId = "text" + crypto.randomUUID();
47
+ const getTrimmedText = () => {
48
+ let innerHTML = htmlEl.value.innerHTML;
49
+ if (innerHTML.includes("<!--]-->")) {
50
+ const start = innerHTML.indexOf("<!--[-->") + 8;
51
+ const end = innerHTML.indexOf("<!--]-->");
52
+ innerHTML = innerHTML.slice(start, end);
53
+ }
54
+ return innerHTML;
55
+ };
56
+ watch(
57
+ () => props.options.uniforms,
58
+ (uniforms) => {
59
+ if (Canvas3.options?.disabled)
60
+ return;
61
+ setTimeout(() => {
62
+ Canvas3.meshUniformsUpdate(meshId, uniforms);
63
+ }, 0);
64
+ },
65
+ { deep: true }
66
+ );
67
+ onMounted(() => {
68
+ htmlEl.value.dataset.meshId = meshId;
69
+ });
70
+ onBeforeUnmount(() => {
71
+ Canvas3.removeMesh(meshId);
72
+ });
73
+ watch(
74
+ () => Canvas3.canvasInitiated.value,
75
+ (newVal) => {
76
+ if (Canvas3.options?.disabled || !newVal)
77
+ return;
78
+ setTimeout(() => {
79
+ Canvas3.addTextAsMSDF(
80
+ props.options.shaderName,
81
+ meshId,
82
+ htmlEl.value,
83
+ getTrimmedText(),
84
+ props.options.theme,
85
+ props.options.uniforms,
86
+ props.options.activateMeshUniforms
87
+ );
88
+ }, 0);
89
+ }
90
+ );
91
+ </script>
92
+
93
+ <style scoped>
94
+ .text-wrapper{display:inline-block;opacity:0}.text-wrapper.reduced-motion{opacity:1}
95
+ </style>
@@ -0,0 +1,11 @@
1
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
2
+ export default _default;
3
+ type __VLS_WithSlots<T, S> = T & (new () => {
4
+ $slots: S;
5
+ });
6
+ declare const __VLS_component: import("vue").DefineComponent<{}, {
7
+ $props: any;
8
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
9
+ type __VLS_Slots = {
10
+ default?: ((props: {}) => any) | undefined;
11
+ };
@@ -0,0 +1,40 @@
1
+ export declare const defaultCanvas3Options: {
2
+ font: {
3
+ fnt: string;
4
+ atlas: string;
5
+ };
6
+ shaders: {
7
+ scroll: {
8
+ fragmentShader: any;
9
+ vertexShader: any;
10
+ };
11
+ default: {
12
+ fragmentShader: any;
13
+ vertexShader: any;
14
+ textFragment: any;
15
+ textVertex: any;
16
+ };
17
+ };
18
+ activateMeshOptions: {
19
+ image: {
20
+ uAniInImage: {
21
+ value: number;
22
+ duration: number;
23
+ ease: string;
24
+ };
25
+ };
26
+ text: {
27
+ uAniInText: {
28
+ value: number;
29
+ duration: number;
30
+ ease: string;
31
+ };
32
+ };
33
+ };
34
+ canvasElement: {
35
+ zIndex: number;
36
+ };
37
+ prefersReducedMotion: boolean;
38
+ isMobile: boolean;
39
+ disabled: boolean;
40
+ };
@@ -0,0 +1,40 @@
1
+ import scrollFragment from "./shaders/scrollFragment.glsl";
2
+ import scrollVertex from "./shaders/scrollVertex.glsl";
3
+ import projectBlurFragment from "./shaders/projectBlurFragment.glsl";
4
+ import projectBlurVertex from "./shaders/projectBlurVertex.glsl";
5
+ import TextBlurFragment from "./shaders/TextBlurFragment.glsl";
6
+ import TextBlurVertex from "./shaders/TextBlurVertex.glsl";
7
+ export const defaultCanvas3Options = {
8
+ font: {
9
+ fnt: "./font/PPFormula-CondensedBlack.fnt",
10
+ atlas: "./font/PPFormula-CondensedBlack.png"
11
+ // fnt: '',
12
+ // atlas: '',
13
+ },
14
+ shaders: {
15
+ scroll: {
16
+ fragmentShader: scrollFragment,
17
+ vertexShader: scrollVertex
18
+ },
19
+ default: {
20
+ fragmentShader: projectBlurFragment,
21
+ vertexShader: projectBlurVertex,
22
+ textFragment: TextBlurFragment,
23
+ textVertex: TextBlurVertex
24
+ }
25
+ },
26
+ activateMeshOptions: {
27
+ image: {
28
+ uAniInImage: { value: 0, duration: 1, ease: "power1.inOut" }
29
+ },
30
+ text: {
31
+ uAniInText: { value: 0, duration: 1.5, ease: "power2.out" }
32
+ }
33
+ },
34
+ canvasElement: {
35
+ zIndex: -1
36
+ },
37
+ prefersReducedMotion: false,
38
+ isMobile: false,
39
+ disabled: false
40
+ };
@@ -0,0 +1,126 @@
1
+ // Varyings
2
+ varying vec2 vUv;
3
+
4
+ // Uniforms: Common
5
+ uniform float uThreshold;
6
+ uniform float uAlphaTest;
7
+ uniform vec3 uColor;
8
+ uniform sampler2D uMap;
9
+
10
+ varying float vNoise;
11
+
12
+ // Generic uniforms
13
+ uniform float uTime;
14
+ uniform float uAniInText;
15
+ uniform float uDevicePixelRatio;
16
+ uniform vec2 uViewport;
17
+ uniform vec2 uMouse;
18
+ uniform vec2 uMouseMovement;
19
+ uniform vec2 uFooterGameBall;
20
+ uniform vec2 uMeshSize;
21
+ uniform float devicePixelRatio;
22
+
23
+ uniform sampler2D gradientMap;
24
+
25
+ float DISTANCE_COEF = 0.5;
26
+ float uBlurStrength;
27
+
28
+ float median(float r, float g, float b) {
29
+ return max(min(r, g), min(max(r, g), b));
30
+ }
31
+
32
+ float createCircleTrail(float radius, vec2 mousePoint) {
33
+ vec2 viewportUv = gl_FragCoord.xy / uViewport / uDevicePixelRatio;
34
+ float viewportAspect = uViewport.x / uViewport.y;
35
+
36
+ vec2 shapeUvTrail = viewportUv - mousePoint;
37
+ shapeUvTrail /= vec2(1.0, viewportAspect);
38
+ shapeUvTrail += mousePoint;
39
+ float distTail = distance(shapeUvTrail, mousePoint);
40
+
41
+ float circleRadius = max(0.0, radius / uViewport.x);
42
+ float dist = smoothstep(circleRadius, circleRadius + 0.05, distTail);
43
+ return dist;
44
+ }
45
+
46
+ float createDraggedTrail(
47
+ vec2 mousePoint,
48
+ vec2 mousePointPrev,
49
+ float radiusStart,
50
+ float radiusEnd
51
+ ) {
52
+ vec2 viewportUv = gl_FragCoord.xy / uViewport / uDevicePixelRatio;
53
+ float viewportAspect = uViewport.x / uViewport.y;
54
+
55
+ // Adjust UV coordinates for aspect ratio
56
+ vec2 adjustedUv = viewportUv;
57
+ adjustedUv.y /= viewportAspect;
58
+ vec2 adjustedMousePoint = vec2(mousePoint.x, mousePoint.y / viewportAspect);
59
+ vec2 adjustedMousePointPrev = vec2(
60
+ mousePointPrev.x,
61
+ mousePointPrev.y / viewportAspect
62
+ );
63
+
64
+ // Compute distances to current and previous mouse points
65
+ float distToCurrent = distance(adjustedUv, adjustedMousePoint);
66
+ float distToPrev = distance(adjustedUv, adjustedMousePointPrev);
67
+
68
+ // Interpolate radius based on proximity to current or previous point
69
+ float interpFactor = distToCurrent / (distToCurrent + distToPrev + 0.0001);
70
+ float circleRadius = mix(radiusStart, radiusEnd, interpFactor) / uViewport.x;
71
+
72
+ // Compute minimum distance to the line segment between points
73
+ vec2 lineDir = adjustedMousePointPrev - adjustedMousePoint;
74
+ float lineLength = length(lineDir);
75
+ vec2 lineDirNorm = lineDir / (lineLength + 0.0001);
76
+ float proj = clamp(
77
+ dot(adjustedUv - adjustedMousePoint, lineDirNorm),
78
+ 0.0,
79
+ lineLength
80
+ );
81
+ vec2 closestPoint = adjustedMousePoint + lineDirNorm * proj;
82
+ float distToLine = distance(adjustedUv, closestPoint);
83
+
84
+ // Smoothly fade out the trail based on distance
85
+ float trail = smoothstep(circleRadius, circleRadius + 0.02, distToLine);
86
+ return trail;
87
+ }
88
+
89
+ float createOverlay(float activeOverlay) {
90
+ vec2 viewportUv =
91
+ gl_FragCoord.xy / uViewport * uDevicePixelRatio * (1.0 - activeOverlay);
92
+ float progress = smoothstep(
93
+ activeOverlay,
94
+ activeOverlay - 1.0,
95
+ viewportUv.x - vUv.x
96
+ );
97
+ return progress;
98
+ }
99
+
100
+ void main() {
101
+ vec2 mousePoint = vec2(uMouse.x, 1.0 - uMouse.y);
102
+ vec2 mousePointPrev = vec2(uMouseMovement.x, 1.0 - uMouseMovement.y);
103
+ vec2 ballPoint = vec2(uFooterGameBall.x, 1.0 - uFooterGameBall.y);
104
+
105
+ float circleTrail = createDraggedTrail(mousePoint, mousePointPrev, 35.0, 1.0);
106
+
107
+ float ballTrail = createCircleTrail(10.0, ballPoint);
108
+
109
+ float overlayOpacity = createOverlay(uAniInText);
110
+ vec2 newUv = vUv;
111
+
112
+ vec3 mySample = texture2D(uMap, newUv).rgb;
113
+ vec3 mySampleRGB = mySample.rgb;
114
+
115
+ float aniInDistance = mix(0.5, 1.0, uAniInText * overlayOpacity);
116
+
117
+ float sigDist =
118
+ median(mySampleRGB.r, mySampleRGB.g, mySampleRGB.b) -
119
+ DISTANCE_COEF / aniInDistance / ballTrail / circleTrail;
120
+ float fill = clamp(sigDist / fwidth(sigDist) + DISTANCE_COEF, 0.0, 1.0);
121
+
122
+ float finalAlpha = fill * overlayOpacity * ballTrail * circleTrail;
123
+
124
+ gl_FragColor = vec4(uColor, finalAlpha);
125
+ if (finalAlpha < uAlphaTest) discard;
126
+ }
@@ -0,0 +1,10 @@
1
+ // Varyings
2
+ varying vec2 vUv;
3
+ uniform vec2 hover;
4
+
5
+ //generic unifiorms
6
+
7
+ void main() {
8
+ vUv = uv;
9
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
10
+ }
@@ -0,0 +1,143 @@
1
+ precision highp float;
2
+
3
+ varying vec2 vUv;
4
+ uniform sampler2D uImage;
5
+
6
+ uniform float uHover;
7
+ uniform vec2 uMouse;
8
+ uniform float uAniInImage;
9
+
10
+ uniform vec2 uMeshSize; // The size of the mesh (width, height)
11
+ uniform vec2 uTextureSize; // The size of the texture (width, height)
12
+ uniform vec2 uViewport;
13
+ uniform float uDevicePixelRatio;
14
+
15
+ vec3 draw(sampler2D image, vec2 uv) {
16
+ return texture2D(image, vec2(uv.x, uv.y)).rgb;
17
+ }
18
+ float rand(vec2 co) {
19
+ return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
20
+ }
21
+
22
+ vec3 blur(vec2 uv, sampler2D image, float blurAmount, float blurStrength) {
23
+ vec3 blurredImage = vec3(0.0);
24
+ float gradient =
25
+ smoothstep(0.8, 0.0, 3.4 - gl_FragCoord.y / uViewport.y / uViewport.y) *
26
+ blurStrength +
27
+ smoothstep(0.8, 0.0, gl_FragCoord.y / uViewport.y / uViewport.y) *
28
+ blurStrength;
29
+ #define repeats (40.0)
30
+ for (float i = 0.0; i < repeats; i++) {
31
+ vec2 q =
32
+ vec2(
33
+ cos(degrees(i / repeats * 360.0)),
34
+ sin(degrees(i / repeats * 360.0))
35
+ ) *
36
+ (rand(vec2(i, uv.x + uv.y)) + blurAmount);
37
+ vec2 uv2 = uv + q * blurAmount * gradient;
38
+ blurredImage += draw(image, uv2) / 2.0;
39
+ q =
40
+ vec2(
41
+ cos(degrees(i / repeats * 360.0)),
42
+ sin(degrees(i / repeats * 360.0))
43
+ ) *
44
+ (rand(vec2(i + 2.0, uv.x + uv.y + 24.0)) + blurAmount);
45
+ uv2 = uv + q * blurAmount * gradient;
46
+ blurredImage += draw(image, uv2) / 2.0;
47
+ }
48
+ return blurredImage / repeats;
49
+ }
50
+
51
+ float DISTANCE_COEF = 0.5;
52
+
53
+ float createCircle(float radius) {
54
+ vec2 viewportUv = gl_FragCoord.xy / uViewport / uDevicePixelRatio;
55
+ float viewportAspect = uViewport.x / uViewport.y;
56
+
57
+ vec2 mousePoint = vec2(uMouse.x, 1.0 - uMouse.y);
58
+
59
+ vec2 shapeUv = viewportUv - mousePoint;
60
+ shapeUv /= vec2(1.0, viewportAspect);
61
+ shapeUv += mousePoint;
62
+ float dist = distance(shapeUv, mousePoint);
63
+
64
+ float circleRadius = max(0.0, radius / uViewport.x);
65
+
66
+ dist = smoothstep(circleRadius, circleRadius + 0.05, dist);
67
+ return dist;
68
+ }
69
+
70
+ float createOverlayBlur(float activeOverlay) {
71
+ vec2 viewportUv = gl_FragCoord.xy / uViewport / uDevicePixelRatio;
72
+ float progress = smoothstep(
73
+ activeOverlay - 1.0, // -1 0
74
+ activeOverlay, // 0 1
75
+ viewportUv.y - vUv.y
76
+ );
77
+ return progress;
78
+ }
79
+
80
+ float createOverlayOpacity(float activeOverlay) {
81
+ vec2 viewportUv =
82
+ uMeshSize.y / uViewport * uDevicePixelRatio * (1.0 - activeOverlay);
83
+ float progress = smoothstep(
84
+ activeOverlay,
85
+ activeOverlay - 1.0,
86
+ viewportUv.y - vUv.y
87
+ );
88
+ return progress;
89
+ }
90
+
91
+ // Function to apply a sepia tone to a given RGB color
92
+ vec3 applySepia(vec3 color) {
93
+ float r = color.r;
94
+ float g = color.g;
95
+ float b = color.b;
96
+
97
+ vec3 sepiaColor = vec3(
98
+ clamp(r * 0.358 + g * 0.704 + b * 0.138, 0.0, 1.0),
99
+ clamp(r * 0.357 + g * 0.705 + b * 0.141, 0.0, 1.0),
100
+ clamp(r * 0.3 + g * 0.497 + b * 0.203, 0.0, 1.0)
101
+ );
102
+ return mix(sepiaColor, vec3(0.5), 0.5);
103
+ }
104
+
105
+ void main() {
106
+ float overlayBlur = createOverlayBlur(uHover);
107
+ float circle = createCircle(105.0);
108
+
109
+ // Calculate the aspect ratios
110
+ float meshAspect = uMeshSize.x / uMeshSize.y;
111
+ float textureAspect = uTextureSize.x / uTextureSize.y;
112
+
113
+ // Adjust UV coordinates to maintain aspect ratio
114
+ vec2 uv = vUv;
115
+ if (meshAspect > textureAspect) {
116
+ // Mesh is wider than the texture
117
+ float scale = textureAspect / meshAspect;
118
+ uv.y = uv.y * scale + (1.0 - scale) / 2.0; // Center the texture vertically
119
+ } else {
120
+ // Mesh is taller than the texture
121
+ float scale = meshAspect / textureAspect;
122
+ uv.x = uv.x * scale + (1.0 - scale) / 2.0; // Center the texture horizontally
123
+ }
124
+
125
+
126
+ float overlayOpacity = createOverlayOpacity(uAniInImage);
127
+
128
+ // Apply sepia to the texture color
129
+ float blurStrength = 1.0 * circle * overlayBlur;
130
+ float blurAmount = 0.025;
131
+
132
+ vec3 originalColor = blur(uv, uImage, blurAmount, blurStrength);
133
+ vec3 sepiaColor = mix(
134
+ originalColor,
135
+ applySepia(originalColor),
136
+ circle
137
+ );
138
+
139
+ vec4 final = vec4(sepiaColor, overlayOpacity);
140
+
141
+ gl_FragColor = final;
142
+
143
+ }
@@ -0,0 +1,11 @@
1
+ uniform float uTime;
2
+ uniform float uHover;
3
+ varying float vNoise;
4
+ varying vec2 vUv;
5
+
6
+ void main() {
7
+ vec3 newposition = position;
8
+ vUv = uv;
9
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(newposition, 1.0);
10
+ }
11
+
@@ -0,0 +1,7 @@
1
+ uniform sampler2D tDiffuse;
2
+ varying vec2 vUv;
3
+ uniform float scrollSpeed;
4
+ void main() {
5
+ vec2 newUV = vUv;
6
+ gl_FragColor = texture2D(tDiffuse, newUV);
7
+ }
@@ -0,0 +1,8 @@
1
+ varying vec2 vUv;
2
+ uniform float scrollSpeed;
3
+
4
+ void main() {
5
+ vec3 newposition = position;
6
+ vUv = uv;
7
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(newposition, 1.0);
8
+ }