cheryglsljs 1.1.7 → 1.1.9
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/README.md +90 -0
- package/dist/cherry.js +1 -1
- package/package.json +1 -1
- package/src/cherry.js +2 -2
- package/src/effects/TransitionEffect/Effect.js +0 -182
- package/src/effects/TransitionEffect1/Effect.js +182 -0
- /package/src/effects/{TransitionEffect → TransitionEffect1}/FragementShader.glsl.js +0 -0
- /package/src/effects/{TransitionEffect → TransitionEffect1}/VertexShader.glsl.js +0 -0
package/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# cheryglsljs
|
2
|
+
|
3
|
+
A lightweight JavaScript library for beautiful, interactive image effects using Three.js, GLSL shaders, and GSAP. Easily add animated wave and transition effects to images in your web projects, with support for both CDN and bundler workflows.
|
4
|
+
|
5
|
+
---
|
6
|
+
|
7
|
+
## ✨ Features
|
8
|
+
|
9
|
+
- GPU-accelerated wave and transition effects for images
|
10
|
+
- Highly customizable via parameters (speed, strength, hover, etc.)
|
11
|
+
- Works with both CDN and npm/bundler setups
|
12
|
+
- Built on top of [Three.js](https://threejs.org/) and [GSAP](https://greensock.com/gsap/)
|
13
|
+
|
14
|
+
---
|
15
|
+
|
16
|
+
## 🚀 Installation
|
17
|
+
|
18
|
+
### Using CDN
|
19
|
+
|
20
|
+
1. Add Three.js and GSAP via CDN in your HTML:
|
21
|
+
```html
|
22
|
+
<script src="https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.min.js"></script>
|
23
|
+
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
|
24
|
+
<script src="https://unpkg.com/cheryglsljs/dist/cherry.js"></script>
|
25
|
+
```
|
26
|
+
|
27
|
+
2. The library will be available as a global variable: `Cherryglsl`.
|
28
|
+
|
29
|
+
---
|
30
|
+
|
31
|
+
### Using npm (Bundler: Webpack, Vite, etc.)
|
32
|
+
|
33
|
+
1. Install via npm:
|
34
|
+
```sh
|
35
|
+
npm install cheryglsljs three gsap
|
36
|
+
```
|
37
|
+
|
38
|
+
2. Import in your JavaScript:
|
39
|
+
```js
|
40
|
+
import Cherryglsl from 'cheryglsljs';
|
41
|
+
// or import { CherryWave, ImageTransition1 } from 'cheryglsljs';
|
42
|
+
```
|
43
|
+
|
44
|
+
---
|
45
|
+
|
46
|
+
## 🛠️ Usage
|
47
|
+
|
48
|
+
### 1. Wave Effect on an Image
|
49
|
+
|
50
|
+
**HTML:**
|
51
|
+
```html
|
52
|
+
<div class="container" style="width: 400px; height: 400px;">
|
53
|
+
<img class="cherry" src="your-image.jpg" style="width: 100%; height: 100%;" />
|
54
|
+
</div>
|
55
|
+
|
56
|
+
|
57
|
+
**HTML:**
|
58
|
+
```html
|
59
|
+
import Cherryglsl from 'cheryglsljs';
|
60
|
+
|
61
|
+
const img = document.querySelector('.cherry');
|
62
|
+
const container = document.querySelector('.container');
|
63
|
+
|
64
|
+
Cherryglsl.default.CherryWave({
|
65
|
+
image: img,
|
66
|
+
container: container,
|
67
|
+
speed: 0.04, // (optional) wave animation speed
|
68
|
+
strength: 8, // (optional) wave strength
|
69
|
+
hover: true, // (optional) enable wave on hover
|
70
|
+
light: false // (optional) enable light effect
|
71
|
+
});
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
### 2. Image Transition Effect
|
80
|
+
|
81
|
+
import Cherryglsl from 'cheryglsljs';
|
82
|
+
|
83
|
+
const container = document.querySelector('.container');
|
84
|
+
Cherryglsl.default.ImageTransition(Container,{
|
85
|
+
|
86
|
+
radius:0.05,
|
87
|
+
speed:0.04,
|
88
|
+
strength:0.2,hover:true,
|
89
|
+
noise:6
|
90
|
+
});
|
package/dist/cherry.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("Cherryglsl",[],n):"object"==typeof exports?exports.Cherryglsl=n():e.Cherryglsl=n()}(this,(()=>(()=>{"use strict";var e={d:(n,t)=>{for(var o in t)e.o(t,o)&&!e.o(n,o)&&Object.defineProperty(n,o,{enumerable:!0,get:t[o]})},o:(e,n)=>Object.prototype.hasOwnProperty.call(e,n),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},n={};e.r(n),e.d(n,{default:()=>o});function t(e=400,n=400){const t=new THREE.Scene,o=new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,.1,1e3),r=new THREE.WebGLRenderer({alpha:!1});return r.setSize(e,n),{Scene:t,camera:o,renderer:r}}const o={CherryWave:({container:e,image:n,speed:o=.05,strength:r=.02,hover:i=!1,light:a})=>{if(!n)return void console.log("No image provided");(new THREE.TextureLoader).load(n.src,(n=>{const u={uImage:{value:n},uTime:{value:0},uStrength:{value:i?0:r},uLight:{value:a}},l=t(e.clientWidth,e.clientHeight);let s;function v(){s&&(l.Scene.remove(s),s.geometry.dispose(),s.material.dispose()),s=function(){const n=e.clientWidth/e.clientHeight*2.3,t=new THREE.PlaneGeometry(n,2.3,100,100),o=new THREE.ShaderMaterial({vertexShader:"\nprecision highp float;\n varying vec2 vUv;\n varying vec3 pos;\n uniform float uTime;\n uniform float uStrength;\n\n void main() {\n \n vUv = uv;\n \n vec3 newPosition = position;\n\n \n float waveX = uStrength * sin(10.0 * uv.y + uTime * 2.0);\n float waveY = uStrength * cos(12.0 * uv.x + uTime * 1.5);\n \n float waveZ = uStrength * sin(10.0 * uv.x + uTime * 2.5);\n\n newPosition.x += waveX;\n newPosition.y += waveY;\n newPosition.z += waveZ;\n\n pos = (modelViewMatrix * vec4(newPosition, 1.0)).xyz;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);\n }",fragmentShader:"\nprecision highp float;\n\nvarying vec2 vUv;\nuniform sampler2D uImage;\nuniform float uTime;\n\nuniform float uStrength;\nuniform bool uLight;\n\n\nvoid main() {\n vec2 uv = vUv;\n \n\n \n \n\n // Apply wave distortion\n float waveX = sin(10.0 * uv.y + uTime * 2.0);\n float waveY = cos(10.0 * uv.x + uTime * 2.0);\n uv.x += (uStrength * 0.05) * waveX;\n uv.y += (uStrength * 0.05) * waveY;\n\n \n\n vec4 color = texture2D(uImage, uv);\n if(uLight){\n color.x+=smoothstep(0.001,0.6,sin(2.0*uTime));\n color.y+=smoothstep(0.2,0.6,sin(0.2*uTime));\n }\n \n gl_FragColor = color;\n}\n",uniforms:u,transparent:!0});return new THREE.Mesh(t,o)}(),l.mesh=s,l.Scene.add(s)}function d(){const n=e.clientWidth,t=e.clientHeight;l.renderer.setSize(n,t),l.renderer.setPixelRatio(window.devicePixelRatio),l.camera.aspect=n/t,l.camera.updateProjectionMatrix(),v()}return l.camera.fov=2*Math.atan(e.clientHeight/2/600)*(180/Math.PI),l.camera.position.z=2.8,i&&(e.addEventListener("mouseenter",(()=>{gsap.to(u.uStrength,{value:r,duration:.5,ease:"power2.out"})})),e.addEventListener("mouseleave",(()=>{gsap.to(u.uStrength,{value:0,duration:.5,ease:"power2.out"})}))),e.innerHTML="",e.appendChild(l.renderer.domElement),window.addEventListener("resize",d),d(),function e(){u.uTime.value+=o,l.renderer.render(l.Scene,l.camera),requestAnimationFrame(e)}(),{mesh:l.mesh,geometry:l.geometry,renderer:l.renderer,Scene:l.Scene}}))},
|
1
|
+
!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("Cherryglsl",[],n):"object"==typeof exports?exports.Cherryglsl=n():e.Cherryglsl=n()}(this,(()=>(()=>{"use strict";var e={d:(n,t)=>{for(var o in t)e.o(t,o)&&!e.o(n,o)&&Object.defineProperty(n,o,{enumerable:!0,get:t[o]})},o:(e,n)=>Object.prototype.hasOwnProperty.call(e,n),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},n={};e.r(n),e.d(n,{default:()=>o});function t(e=400,n=400){const t=new THREE.Scene,o=new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,.1,1e3),r=new THREE.WebGLRenderer({alpha:!1});return r.setSize(e,n),{Scene:t,camera:o,renderer:r}}const o={CherryWave:({container:e,image:n,speed:o=.05,strength:r=.02,hover:i=!1,light:a})=>{if(!n)return void console.log("No image provided");(new THREE.TextureLoader).load(n.src,(n=>{const u={uImage:{value:n},uTime:{value:0},uStrength:{value:i?0:r},uLight:{value:a}},l=t(e.clientWidth,e.clientHeight);let s;function v(){s&&(l.Scene.remove(s),s.geometry.dispose(),s.material.dispose()),s=function(){const n=e.clientWidth/e.clientHeight*2.3,t=new THREE.PlaneGeometry(n,2.3,100,100),o=new THREE.ShaderMaterial({vertexShader:"\nprecision highp float;\n varying vec2 vUv;\n varying vec3 pos;\n uniform float uTime;\n uniform float uStrength;\n\n void main() {\n \n vUv = uv;\n \n vec3 newPosition = position;\n\n \n float waveX = uStrength * sin(10.0 * uv.y + uTime * 2.0);\n float waveY = uStrength * cos(12.0 * uv.x + uTime * 1.5);\n \n float waveZ = uStrength * sin(10.0 * uv.x + uTime * 2.5);\n\n newPosition.x += waveX;\n newPosition.y += waveY;\n newPosition.z += waveZ;\n\n pos = (modelViewMatrix * vec4(newPosition, 1.0)).xyz;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);\n }",fragmentShader:"\nprecision highp float;\n\nvarying vec2 vUv;\nuniform sampler2D uImage;\nuniform float uTime;\n\nuniform float uStrength;\nuniform bool uLight;\n\n\nvoid main() {\n vec2 uv = vUv;\n \n\n \n \n\n // Apply wave distortion\n float waveX = sin(10.0 * uv.y + uTime * 2.0);\n float waveY = cos(10.0 * uv.x + uTime * 2.0);\n uv.x += (uStrength * 0.05) * waveX;\n uv.y += (uStrength * 0.05) * waveY;\n\n \n\n vec4 color = texture2D(uImage, uv);\n if(uLight){\n color.x+=smoothstep(0.001,0.6,sin(2.0*uTime));\n color.y+=smoothstep(0.2,0.6,sin(0.2*uTime));\n }\n \n gl_FragColor = color;\n}\n",uniforms:u,transparent:!0});return new THREE.Mesh(t,o)}(),l.mesh=s,l.Scene.add(s)}function d(){const n=e.clientWidth,t=e.clientHeight;l.renderer.setSize(n,t),l.renderer.setPixelRatio(window.devicePixelRatio),l.camera.aspect=n/t,l.camera.updateProjectionMatrix(),v()}return l.camera.fov=2*Math.atan(e.clientHeight/2/600)*(180/Math.PI),l.camera.position.z=2.8,i&&(e.addEventListener("mouseenter",(()=>{gsap.to(u.uStrength,{value:r,duration:.5,ease:"power2.out"})})),e.addEventListener("mouseleave",(()=>{gsap.to(u.uStrength,{value:0,duration:.5,ease:"power2.out"})}))),e.innerHTML="",e.appendChild(l.renderer.domElement),window.addEventListener("resize",d),d(),function e(){u.uTime.value+=o,l.renderer.render(l.Scene,l.camera),requestAnimationFrame(e)}(),{mesh:l.mesh,geometry:l.geometry,renderer:l.renderer,Scene:l.Scene}}))},ImageTransition1:function(e,{speed:n=.02,strength:o=.02,radius:r=.02,hover:i=!1,noise:a=.4}={}){let u=Array.from(e.querySelectorAll("img"));if(!u.length)return void console.log("No image provided");const l={uImage:{value:null},uImage2:{value:null},uTime:{value:0},uStrength:{value:i?0:o},uNoise:{value:a},uMouse:{value:new THREE.Vector2(-10,-10)},uRadius:{value:r}},s=new THREE.TextureLoader;let v,d=[];u.map(((e,n)=>{s.load(e.src,(e=>{v=0,1==n&&(l.uImage2.value=e),0==n&&(l.uImage.value=e),d.push(e)}))}));const c=t(e.clientWidth,e.clientHeight);let m;function g(){m&&(c.Scene.remove(m),m.geometry.dispose(),m.material.dispose()),m=function(){const n=e.clientWidth/e.clientHeight*2.3,t=new THREE.PlaneGeometry(n,2.3,100,100),o=new THREE.ShaderMaterial({vertexShader:"\nprecision highp float;\nvarying vec2 vUv; \n\n void main() { \n vUv = uv; \n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }",fragmentShader:"\nprecision highp float;\nuniform vec2 uMouse;\nvarying vec2 vUv;\nuniform sampler2D uImage;\nuniform float uTime;\nuniform float uRadius;\nuniform float uStrength;\nuniform float uNoise;\nuniform bool uLight;\nuniform sampler2D uImage2;\nfloat rand(float n){return fract(sin(n) * 43758.5453123);}\nfloat rand(vec2 n){return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453123);}\n\nfloat noise(float p){\n float fl = floor(p);\n float fc = fract(p);\n return mix(rand(fl), rand(fl + 1.0), fc);\n}\n \nfloat noise(vec2 n) {\n const vec2 d = vec2(0.0, 1.0);\n vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));\n return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);\n}\n\nvoid main() {\n vec2 uv = vUv;\n vec2 guv = vUv;\n guv.x -= 0.5;\n guv.y -= 0.5;\n\n // Calculate distance from mouse\n float dist = length(guv - uMouse);\n\n \n float edgeNoise = noise(guv * 10.0 + uTime * 2.0 ) * uNoise;\n\n // Create mask for area following mouse, with wobbly edge\n float inside = step(dist, uRadius *edgeNoise);\n\n // Apply noise only inside the circle\n float n = noise(guv * 0.2);\n\n vec3 circle = mix(vec3(1.0), vec3(n), inside);\n\n // Apply wave distortion\n float waveX = sin(10.0 * uv.y + uTime * 2.0);\n float waveY = cos(10.0 * uv.x + uTime * 2.0);\n uv.x += (uStrength * 0.05) * waveX;\n uv.y += (uStrength * 0.05) * waveY;\n\n \n\n vec4 color = texture2D(uImage, uv);\n \n vec4 color2 = texture2D(uImage2,uv);\n gl_FragColor = mix(color,(vec4(n)+color2),inside);\n}\n",uniforms:l,transparent:!0});return new THREE.Mesh(t,o)}(),c.mesh=m,c.Scene.add(m)}function f(){const n=e.clientWidth,t=e.clientHeight;c.renderer.setSize(n,t),c.renderer.setPixelRatio(window.devicePixelRatio),c.camera.aspect=n/t,c.camera.updateProjectionMatrix(),g()}return c.camera.fov=2*Math.atan(e.clientHeight/2/600)*(180/Math.PI),c.camera.position.z=2.8,e.addEventListener("mousemove",(function(n){const t=e.getBoundingClientRect(),o=(n.clientX-t.left)/t.width-.5,r=-(n.clientY-t.top)/t.height+.5;gsap.to(l.uMouse.value,{x:o,y:r,duration:.2})})),i&&(e.addEventListener("mouseenter",(()=>{gsap.to(l.uStrength,{value:o,duration:.5,ease:"power2.out"}),gsap.to(l.uRadius,{value:r,duration:.2})})),e.addEventListener("mouseleave",(()=>{gsap.to(l.uStrength,{value:0,duration:.5,ease:"power2.out"}),gsap.to(l.uRadius,{value:-100,duration:.6})}))),e.innerHTML="",e.appendChild(c.renderer.domElement),window.addEventListener("resize",f),f(),function e(){l.uTime.value+=n,c.renderer.render(c.Scene,c.camera),requestAnimationFrame(e)}(),e.addEventListener("click",(()=>{const e=(v+1)%d.length,n=(v+2)%d.length;gsap.to(l.uRadius,{value:2,duration:2,ease:"power2.inOut",onComplete:()=>{l.uImage.value=d[e],l.uImage2.value=d[n],gsap.fromTo(l.uRadius,{value:0},{value:r,duration:2,ease:"power2.inOut"}),v=e}})})),{mesh:c.mesh,geometry:c.geometry,renderer:c.renderer,Scene:c.Scene,currntimageIndex:v}}};return n})()));
|
package/package.json
CHANGED
package/src/cherry.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
import CherryWave from "./effects/waveEffect/Effect";
|
3
|
-
import {
|
3
|
+
import { ImageTransition1 } from "./effects/TransitionEffect1/Effect";
|
4
4
|
export default {
|
5
5
|
CherryWave,
|
6
|
-
|
6
|
+
ImageTransition1
|
7
7
|
};
|
@@ -1,182 +0,0 @@
|
|
1
|
-
import createWaveAssets from "../../utils/init.js";
|
2
|
-
import fragmentShader from "./FragementShader.glsl.js";
|
3
|
-
import vertexShader from "./VertexShader.glsl.js";
|
4
|
-
// Make sure the file 'FragmentShader.glsl.js' exists in the same directory as this file.
|
5
|
-
// If the file is named differently or located elsewhere, update the import path accordingly.
|
6
|
-
// Example: import fragmentShader from '../../shaders/FragmentShader.glsl.js';
|
7
|
-
|
8
|
-
export function ImageTransition(
|
9
|
-
container,
|
10
|
-
{ speed = 0.02, strength = 0.02, radius = 0.02, hover = false,noise=0.4 } = {}
|
11
|
-
) {
|
12
|
-
let image = Array.from(container.querySelectorAll("img"));
|
13
|
-
if (!image.length) {
|
14
|
-
console.log("No image provided");
|
15
|
-
return;
|
16
|
-
}
|
17
|
-
const uniforms = {
|
18
|
-
uImage: { value: null },
|
19
|
-
uImage2: { value: null },
|
20
|
-
uTime: { value: 0.0 },
|
21
|
-
uStrength: { value: hover ? 0 : strength },
|
22
|
-
uNoise:{value:noise},
|
23
|
-
uMouse: { value: new THREE.Vector2(-10, -10) },
|
24
|
-
uRadius: { value: radius },
|
25
|
-
};
|
26
|
-
const textureLoader = new THREE.TextureLoader();
|
27
|
-
|
28
|
-
let textures = [];
|
29
|
-
let index;
|
30
|
-
image.map((img, i) => {
|
31
|
-
textureLoader.load(img.src, (texture) => {
|
32
|
-
index = 0;
|
33
|
-
if (i == 1) uniforms.uImage2.value = texture;
|
34
|
-
if (i == 0) uniforms.uImage.value = texture;
|
35
|
-
textures.push(texture);
|
36
|
-
});
|
37
|
-
});
|
38
|
-
|
39
|
-
const waveassets = createWaveAssets(
|
40
|
-
container.clientWidth,
|
41
|
-
container.clientHeight
|
42
|
-
);
|
43
|
-
|
44
|
-
// Set camera to frame a 2x2 unit square
|
45
|
-
waveassets.camera.fov =
|
46
|
-
2 * Math.atan(container.clientHeight / 2 / 600) * (180 / Math.PI);
|
47
|
-
waveassets.camera.position.z = 2.8;
|
48
|
-
|
49
|
-
let mesh;
|
50
|
-
|
51
|
-
function createMesh() {
|
52
|
-
const width = container.clientWidth;
|
53
|
-
const height = container.clientHeight;
|
54
|
-
|
55
|
-
const aspect = width / height;
|
56
|
-
const worldHeight = 2.3;
|
57
|
-
const worldWidth = worldHeight * aspect;
|
58
|
-
|
59
|
-
const geometry = new THREE.PlaneGeometry(worldWidth, worldHeight, 100, 100);
|
60
|
-
const material = new THREE.ShaderMaterial({
|
61
|
-
vertexShader,
|
62
|
-
fragmentShader,
|
63
|
-
uniforms,
|
64
|
-
transparent: true,
|
65
|
-
});
|
66
|
-
|
67
|
-
return new THREE.Mesh(geometry, material);
|
68
|
-
}
|
69
|
-
|
70
|
-
function addMesh() {
|
71
|
-
if (mesh) {
|
72
|
-
waveassets.Scene.remove(mesh);
|
73
|
-
mesh.geometry.dispose();
|
74
|
-
mesh.material.dispose();
|
75
|
-
}
|
76
|
-
|
77
|
-
mesh = createMesh();
|
78
|
-
waveassets.mesh = mesh;
|
79
|
-
waveassets.Scene.add(mesh);
|
80
|
-
}
|
81
|
-
|
82
|
-
function onResize() {
|
83
|
-
const width = container.clientWidth;
|
84
|
-
const height = container.clientHeight;
|
85
|
-
|
86
|
-
waveassets.renderer.setSize(width, height);
|
87
|
-
waveassets.renderer.setPixelRatio(window.devicePixelRatio);
|
88
|
-
|
89
|
-
waveassets.camera.aspect = width / height;
|
90
|
-
waveassets.camera.updateProjectionMatrix();
|
91
|
-
|
92
|
-
addMesh();
|
93
|
-
}
|
94
|
-
|
95
|
-
function onMouseMove(event) {
|
96
|
-
const bounds = container.getBoundingClientRect();
|
97
|
-
const x = (event.clientX - bounds.left) / bounds.width - 0.5;
|
98
|
-
const y = -((event.clientY - bounds.top) / bounds.height) + 0.5;
|
99
|
-
|
100
|
-
gsap.to(uniforms.uMouse.value, {
|
101
|
-
x: x,
|
102
|
-
y: y,
|
103
|
-
duration: 0.2,
|
104
|
-
});
|
105
|
-
}
|
106
|
-
|
107
|
-
container.addEventListener("mousemove", onMouseMove);
|
108
|
-
if (hover) {
|
109
|
-
container.addEventListener("mouseenter", () => {
|
110
|
-
gsap.to(uniforms.uStrength, {
|
111
|
-
value: strength,
|
112
|
-
duration: 0.5,
|
113
|
-
ease: "power2.out",
|
114
|
-
});
|
115
|
-
gsap.to(uniforms.uRadius, {
|
116
|
-
value: radius,
|
117
|
-
duration: 0.2,
|
118
|
-
});
|
119
|
-
});
|
120
|
-
|
121
|
-
container.addEventListener("mouseleave", () => {
|
122
|
-
gsap.to(uniforms.uStrength, {
|
123
|
-
value: 0,
|
124
|
-
duration: 0.5,
|
125
|
-
ease: "power2.out",
|
126
|
-
});
|
127
|
-
gsap.to(uniforms.uRadius, {
|
128
|
-
value: -100,
|
129
|
-
duration: 0.6,
|
130
|
-
});
|
131
|
-
});
|
132
|
-
}
|
133
|
-
|
134
|
-
container.innerHTML = "";
|
135
|
-
container.appendChild(waveassets.renderer.domElement);
|
136
|
-
|
137
|
-
window.addEventListener("resize", onResize);
|
138
|
-
onResize();
|
139
|
-
|
140
|
-
function animate() {
|
141
|
-
uniforms.uTime.value += speed;
|
142
|
-
waveassets.renderer.render(waveassets.Scene, waveassets.camera);
|
143
|
-
requestAnimationFrame(animate);
|
144
|
-
}
|
145
|
-
|
146
|
-
animate();
|
147
|
-
// let isTransitioning = false; // Removed unused variable
|
148
|
-
|
149
|
-
container.addEventListener("click", () => {
|
150
|
-
const nextIndex = (index + 1) % textures.length;
|
151
|
-
const nextNextIndex = (index + 2) % textures.length;
|
152
|
-
|
153
|
-
gsap.to(uniforms.uRadius, {
|
154
|
-
value: 2,
|
155
|
-
duration: 2,
|
156
|
-
ease: "power2.inOut",
|
157
|
-
|
158
|
-
onComplete: () => {
|
159
|
-
uniforms.uImage.value = textures[nextIndex];
|
160
|
-
uniforms.uImage2.value = textures[nextNextIndex];
|
161
|
-
gsap.fromTo(
|
162
|
-
uniforms.uRadius,
|
163
|
-
{ value: 0.0 },
|
164
|
-
{
|
165
|
-
value: radius,
|
166
|
-
duration: 2,
|
167
|
-
ease: "power2.inOut",
|
168
|
-
}
|
169
|
-
);
|
170
|
-
index = nextIndex;
|
171
|
-
},
|
172
|
-
});
|
173
|
-
});
|
174
|
-
|
175
|
-
return {
|
176
|
-
mesh: waveassets.mesh,
|
177
|
-
geometry: waveassets.geometry,
|
178
|
-
renderer: waveassets.renderer,
|
179
|
-
Scene: waveassets.Scene,
|
180
|
-
currntimageIndex: index,
|
181
|
-
};
|
182
|
-
}
|
@@ -0,0 +1,182 @@
|
|
1
|
+
import createWaveAssets from "../../utils/init.js";
|
2
|
+
import fragmentShader from "./FragementShader.glsl.js";
|
3
|
+
import vertexShader from "./VertexShader.glsl.js";
|
4
|
+
// Make sure the file 'FragmentShader.glsl.js' exists in the same directory as this file.
|
5
|
+
// If the file is named differently or located elsewhere, update the import path accordingly.
|
6
|
+
// Example: import fragmentShader from '../../shaders/FragmentShader.glsl.js';
|
7
|
+
|
8
|
+
export function ImageTransition1(
|
9
|
+
container,
|
10
|
+
{ speed = 0.02, strength = 0.02, radius = 0.02, hover = false,noise=0.4 } = {}
|
11
|
+
) {
|
12
|
+
let image = Array.from(container.querySelectorAll("img"));
|
13
|
+
if (!image.length) {
|
14
|
+
console.log("No image provided");
|
15
|
+
return;
|
16
|
+
}
|
17
|
+
const uniforms = {
|
18
|
+
uImage: { value: null },
|
19
|
+
uImage2: { value: null },
|
20
|
+
uTime: { value: 0.0 },
|
21
|
+
uStrength: { value: hover ? 0 : strength },
|
22
|
+
uNoise:{value:noise},
|
23
|
+
uMouse: { value: new THREE.Vector2(-10, -10) },
|
24
|
+
uRadius: { value: radius },
|
25
|
+
};
|
26
|
+
const textureLoader = new THREE.TextureLoader();
|
27
|
+
|
28
|
+
let textures = [];
|
29
|
+
let index;
|
30
|
+
image.map((img, i) => {
|
31
|
+
textureLoader.load(img.src, (texture) => {
|
32
|
+
index = 0;
|
33
|
+
if (i == 1) uniforms.uImage2.value = texture;
|
34
|
+
if (i == 0) uniforms.uImage.value = texture;
|
35
|
+
textures.push(texture);
|
36
|
+
});
|
37
|
+
});
|
38
|
+
|
39
|
+
const waveassets = createWaveAssets(
|
40
|
+
container.clientWidth,
|
41
|
+
container.clientHeight
|
42
|
+
);
|
43
|
+
|
44
|
+
// Set camera to frame a 2x2 unit square
|
45
|
+
waveassets.camera.fov =
|
46
|
+
2 * Math.atan(container.clientHeight / 2 / 600) * (180 / Math.PI);
|
47
|
+
waveassets.camera.position.z = 2.8;
|
48
|
+
|
49
|
+
let mesh;
|
50
|
+
|
51
|
+
function createMesh() {
|
52
|
+
const width = container.clientWidth;
|
53
|
+
const height = container.clientHeight;
|
54
|
+
|
55
|
+
const aspect = width / height;
|
56
|
+
const worldHeight = 2.3;
|
57
|
+
const worldWidth = worldHeight * aspect;
|
58
|
+
|
59
|
+
const geometry = new THREE.PlaneGeometry(worldWidth, worldHeight, 100, 100);
|
60
|
+
const material = new THREE.ShaderMaterial({
|
61
|
+
vertexShader,
|
62
|
+
fragmentShader,
|
63
|
+
uniforms,
|
64
|
+
transparent: true,
|
65
|
+
});
|
66
|
+
|
67
|
+
return new THREE.Mesh(geometry, material);
|
68
|
+
}
|
69
|
+
|
70
|
+
function addMesh() {
|
71
|
+
if (mesh) {
|
72
|
+
waveassets.Scene.remove(mesh);
|
73
|
+
mesh.geometry.dispose();
|
74
|
+
mesh.material.dispose();
|
75
|
+
}
|
76
|
+
|
77
|
+
mesh = createMesh();
|
78
|
+
waveassets.mesh = mesh;
|
79
|
+
waveassets.Scene.add(mesh);
|
80
|
+
}
|
81
|
+
|
82
|
+
function onResize() {
|
83
|
+
const width = container.clientWidth;
|
84
|
+
const height = container.clientHeight;
|
85
|
+
|
86
|
+
waveassets.renderer.setSize(width, height);
|
87
|
+
waveassets.renderer.setPixelRatio(window.devicePixelRatio);
|
88
|
+
|
89
|
+
waveassets.camera.aspect = width / height;
|
90
|
+
waveassets.camera.updateProjectionMatrix();
|
91
|
+
|
92
|
+
addMesh();
|
93
|
+
}
|
94
|
+
|
95
|
+
function onMouseMove(event) {
|
96
|
+
const bounds = container.getBoundingClientRect();
|
97
|
+
const x = (event.clientX - bounds.left) / bounds.width - 0.5;
|
98
|
+
const y = -((event.clientY - bounds.top) / bounds.height) + 0.5;
|
99
|
+
|
100
|
+
gsap.to(uniforms.uMouse.value, {
|
101
|
+
x: x,
|
102
|
+
y: y,
|
103
|
+
duration: 0.2,
|
104
|
+
});
|
105
|
+
}
|
106
|
+
|
107
|
+
container.addEventListener("mousemove", onMouseMove);
|
108
|
+
if (hover) {
|
109
|
+
container.addEventListener("mouseenter", () => {
|
110
|
+
gsap.to(uniforms.uStrength, {
|
111
|
+
value: strength,
|
112
|
+
duration: 0.5,
|
113
|
+
ease: "power2.out",
|
114
|
+
});
|
115
|
+
gsap.to(uniforms.uRadius, {
|
116
|
+
value: radius,
|
117
|
+
duration: 0.2,
|
118
|
+
});
|
119
|
+
});
|
120
|
+
|
121
|
+
container.addEventListener("mouseleave", () => {
|
122
|
+
gsap.to(uniforms.uStrength, {
|
123
|
+
value: 0,
|
124
|
+
duration: 0.5,
|
125
|
+
ease: "power2.out",
|
126
|
+
});
|
127
|
+
gsap.to(uniforms.uRadius, {
|
128
|
+
value: -100,
|
129
|
+
duration: 0.6,
|
130
|
+
});
|
131
|
+
});
|
132
|
+
}
|
133
|
+
|
134
|
+
container.innerHTML = "";
|
135
|
+
container.appendChild(waveassets.renderer.domElement);
|
136
|
+
|
137
|
+
window.addEventListener("resize", onResize);
|
138
|
+
onResize();
|
139
|
+
|
140
|
+
function animate() {
|
141
|
+
uniforms.uTime.value += speed;
|
142
|
+
waveassets.renderer.render(waveassets.Scene, waveassets.camera);
|
143
|
+
requestAnimationFrame(animate);
|
144
|
+
}
|
145
|
+
|
146
|
+
animate();
|
147
|
+
// let isTransitioning = false; // Removed unused variable
|
148
|
+
|
149
|
+
container.addEventListener("click", () => {
|
150
|
+
const nextIndex = (index + 1) % textures.length;
|
151
|
+
const nextNextIndex = (index + 2) % textures.length;
|
152
|
+
|
153
|
+
gsap.to(uniforms.uRadius, {
|
154
|
+
value: 2,
|
155
|
+
duration: 2,
|
156
|
+
ease: "power2.inOut",
|
157
|
+
|
158
|
+
onComplete: () => {
|
159
|
+
uniforms.uImage.value = textures[nextIndex];
|
160
|
+
uniforms.uImage2.value = textures[nextNextIndex];
|
161
|
+
gsap.fromTo(
|
162
|
+
uniforms.uRadius,
|
163
|
+
{ value: 0.0 },
|
164
|
+
{
|
165
|
+
value: radius,
|
166
|
+
duration: 2,
|
167
|
+
ease: "power2.inOut",
|
168
|
+
}
|
169
|
+
);
|
170
|
+
index = nextIndex;
|
171
|
+
},
|
172
|
+
});
|
173
|
+
});
|
174
|
+
|
175
|
+
return {
|
176
|
+
mesh: waveassets.mesh,
|
177
|
+
geometry: waveassets.geometry,
|
178
|
+
renderer: waveassets.renderer,
|
179
|
+
Scene: waveassets.Scene,
|
180
|
+
currntimageIndex: index,
|
181
|
+
};
|
182
|
+
}
|
File without changes
|
File without changes
|