Jump to content

Sam Tremblay

  • Posts

  • Joined

  • Last visited

Everything posted by Sam Tremblay

  1. Hehe, np @mvaneijgen @Rodrigo, Thank you 💪 I pushed a few updates though from while you were watching until now, hope there was no bug 😅 Btw guys, sorry if my english is not accurate! I'm a frenchie boy ^^ Happy Tweening too!
  2. Hello @chandrashekhar! What result you want to obtain? Snap to top of next section when you stop scrolling and this next section is in viewport? Other? Best Regards! Sam
  3. Sup again @mvaneijgen! I have a question for you please : Do you use some "Smart Invert" option with your phone? Or an option in this sense? Dark mode maybe? I'm trying to understand why the white color is displayed black and black color is displayed white ^^ The correct display is supposed to be like this : https://www.awesomescreenshot.com/video/19556226 EDIT: I just tested the "colors inversed mode" on my Android and I obtain the same result that you. I almost got screwed 😂 Thanks again! Sam
  4. Thank you @mvaneijgen 💪 I'm sorry to use the forum for this purpose! The scroll seems to work good, but I have definitively a bug with the mix-blend-mode and my background! Happy tweening too and thanks again for your help! You are awesome! Sam
  5. Sup people of GSAP! I am currently developping my new Web Agency Website and I need you for a test on Mobile Apple Devices. Could you help me with that please? Unfortunately, I have only a windows PC and an Android Phone and since I use the "normalizeScroll" with ScrollTrigger, I am not sure if on Safari (and maybe chrome, etc.), only on mobile/touch devices of Apple, the scroll works good. Can I ask you a feedback about that please? Here is the website: https://dev.champgauche.studio/ A really big thank you 🙏
  6. Hello @Superloop! Put a look just there:
  7. Hi @BruceST! On your gsap.to that control your .one-one height, add this parameter: onComplete: () => { ScrollTrigger.refresh(); } https://codepen.io/sam-tremblay/pen/OJwzwmz Happy Tweening!
  8. Hello @amapic! Put a look on this example: import gsap from './gsap/index.js'; import gsapCore from './gsap/gsap-core.js'; class App{ constructor(){ this.moveLight(); } moveLight(){ const x = gsap.quickTo('#id_element_to_move', 'x', {duration: .5, ease: 'power2'}); const y = gsap.quickTo('#id_element_to_move', 'y', {duration: .5, ease: 'power2'}); window.addEventListener('mousemove', (e) => { x(e.clientX); y(e.clientY); }); } } new App(); Happy Tweening!
  9. Hello @aok! Try this: https://codepen.io/sam-tremblay/pen/wvxqEgW EDIT: Hey @GreenSock, does kill the tween on each complete is a good mind to adopt or not?
  10. Hillo @AlexanderGS! I'm not sure to understand. What do you want exactly ? Is it to start each item after the other? If yes, use "stagger" for that. Does help you :)? Best regards!
  11. Hillo! When you import, if you don't take the all.js, you need import index.js and gsap-core.js. You'll need the CSSPlugins.js file and others maybe and some utils too.. but you don't need to import them, just have it.
  12. Hello @kresogalic! This cursor is render on <canvas>. You'll need a tool like THREE.js for do that. Put a look on this URL... it's not exacly what you want, but it's close... One thing is sure, it's a good start: https://codesandbox.io/s/water-like-effect-demo-4-iermg?from-embed You can find this CodeSandbox on this tutorial: https://tympanus.net/codrops/2019/10/08/creating-a-water-like-distortion-effect-with-three-js/ Does help you?
  13. Hello @R007 ! The image isn't animated. The image is fixe and each pixels are animated (distortioned) with THREE.js. For do that, you need to mesh a custom Shader that uniform your image (called texture) and some data for your texture (called DataTexture) on a Plane Geometry Face. You can use the SharderMaterial of THREE.js for that. Put a look into this code (result: https://www.awesomescreenshot.com/video/13995579?key=ff81768b65c3645d42370c8b649b2197 (just know, the result video is done on a computer with bad framerate... it's more smooth in real)) : 'use strict'; import * as THREE from './three/three.module.js'; export default class WaterEffect{ constructor(options){ this.options = options; this.scene = new THREE.Scene(); this.container = this.options.dom; this.width = this.container.offsetWidth; this.height = this.container.offsetHeight; this.renderer = new THREE.WebGLRenderer(); this.renderer.domElement.id = 'bg-water'; this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); this.renderer.setSize(this.width, this.height); //this.renderer.setClearColor(0xeeeeee, 1); this.renderer.physicallyCorrectLights = true; this.renderer.outputEncoding = THREE.sRGBEncoding; this.container.appendChild(this.renderer.domElement); const frustumSize = 1; const aspect = window.innerWidth / window.innerHeight; this.camera = new THREE.OrthographicCamera(frustumSize / - 2, frustumSize / 2, frustumSize / 2, frustumSize / -2, -1000, 1000); this.camera.position.set(0, 0, 2); this.time = 0; this.mouse = { x: 0, y: 0, prevX: 0, prevY: 0, vX: 0, vY: 0 } } addObjects(){ this.size = 32; const width = this.size; const height = this.size; const size = width * height; const data = new Float32Array( 4 * size ); for (let i = 0; i < size; i++) { let r = Math.random() * 10; const stride = i * 4; data[ stride ] = r; data[ stride + 1 ] = r; data[ stride + 2 ] = r; data[ stride + 3 ] = 255; } // used the buffer to create a DataTexture this.texture = new THREE.DataTexture( data, width, height, THREE.RGBAFormat, THREE.FloatType); this.texture.magFilter = this.texture.minFilter = THREE.LinearFilter; //THREE.NearestFilter; this.material = new THREE.ShaderMaterial({ extensions: { derivatives: true }, side: THREE.DoubleSide, uniforms: { time: { value: 0 }, resolution: { value: new THREE.Vector4() }, uTexture: { value: this.textures[0] }, uDataTexture: { value: this.texture } }, vertexShader: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); } `, fragmentShader: ` uniform float time; uniform float progress; uniform sampler2D uDataTexture; uniform sampler2D uTexture; uniform vec4 resolution; varying vec2 vUv; varying vec3 vPosition; float PI = 3.141592653589793238; void main(){ vec2 newUV = (vUv - vec2(0.5))*resolution.zw + vec2(0.5); vec4 color = texture2D(uTexture, vUv); vec4 offset = texture2D(uDataTexture, vUv); gl_FragColor = vec4(vUv,0.0,1.); gl_FragColor = vec4(offset.r,0.,0.,1.); gl_FragColor = color; gl_FragColor = texture2D(uTexture, newUV - 0.05*offset.rg); } ` }); this.geometry = new THREE.PlaneGeometry(1, 1, 1, 1); this.plane = new THREE.Mesh(this.geometry, this.material); this.scene.add(this.plane); } mouseEvents(){ window.addEventListener('mousemove', (e) => { this.mouse.x = e.clientX/this.width; this.mouse.y = e.clientY/this.height; this.mouse.vX = this.mouse.x - this.mouse.prevX; this.mouse.vY = this.mouse.y - this.mouse.prevY; this.mouse.prevX = this.mouse.x; this.mouse.prevY = this.mouse.y; }); } updateDataTexture(){ let data = this.texture.image.data; for (var i = 0; i < data.length; i+=4) { data[i] *= 0.91; data[i+1] *= 0.91; } let gridMouseX = this.size*this.mouse.x; let gridMouseY = this.size*(1-this.mouse.y); let maxDist = this.size/4; for (var i = 0; i < this.size; i++) { for (var j = 0; j < this.size; j++) { let distance = (gridMouseX - i)**2 + (gridMouseY - j)**2; let maxDistSq = maxDist**2; if(distance<maxDistSq){ let index = 4*(i + this.size*j); let power = maxDist/Math.sqrt(distance); //if(distance < 1) power = 1; data[index] += this.mouse.vX * power; data[index+1] -= this.mouse.vY * power; } } } this.mouse.vX *= 0.91; this.mouse.vY *= 0.91; this.texture.needsUpdate = true; } render(){ this.time += 0.05; this.updateDataTexture(); this.material.uniforms.time.value = this.time; requestAnimationFrame(this.render.bind(this)); this.renderer.render(this.scene, this.camera); } setupResize(){ window.addEventListener('resize', this.resize.bind(this)); } resize(){ this.width = this.container.offsetWidth; this.height = this.container.offsetHeight; this.renderer.setSize(this.width, this.height); this.camera.aspect = this.width / this.height; /* * Cover Image */ let a1, a2; this.imageAspect = 1./1.5; if(this.height/this.width > this.imageAspect){ a1 = (this.width/this.height) * this.imageAspect; a2 = 1; } else { a1 = 1; a2 = (this.height/this.width) / this.imageAspect; } this.material.uniforms.resolution.value.x = this.width; this.material.uniforms.resolution.value.y = this.height; this.material.uniforms.resolution.value.z = a1; this.material.uniforms.resolution.value.w = a2; this.camera.updateProjectionMatrix(); } } Run it: import * as THREE from './three/three.module.js'; import WaterEffect from './water.js'; class App{ constructor(){ this.gwater = new WaterEffect({ dom: your_container_here }); this.loader(); } loader(){ this.gwater.loadingManager = new THREE.LoadingManager(); this.gwater.textureLoader = new THREE.TextureLoader(this.gwater.loadingManager); this.gwater.textures = []; this.gwater.textures.push(this.gwater.textureLoader.load('/wp-content/themes/gate-child/assets/images/mono.png')); this.gwater.loadingManager.onLoad = () => { /* * Alright, THREE.js is ready, run IT */ this.gwater.addObjects(); this.gwater.resize(); this.gwater.render(); this.gwater.setupResize(); this.gwater.mouseEvents(); } } } new App(); You can reach THREE.js Loading Progression before onLoad... Put a look here: https://threejs.org/docs/index.html?q=loading#api/en/loaders/managers/LoadingManager
  14. Hi @Delarge! Is that possible to provide a demo from codepen please? I'm not sure without testing, but your example seems to be something like the URL you propose... I have tested some part of your code by copy/paste him in the codepen of the DEMO, but is working good for me. ScrollTrigger is register too? gsap.registerPlugin(ScrollTrigger); Best regards! Sam
  15. Hi momo! I'm not sure I understand good, sorry for my bad english, but try position fixed on your .middle-mask element. Does help you? Best Regards! Sam
  16. Thanks @Rodrigo! I'll test some things this week and come back to push a feedback Have a nice day!
  17. Hi @stvn! Put a look on that: https://codepen.io/sam-tremblay/pen/JjvRGJw Just play with the ease, stagger and CSS transform of .word elements if you want more style in your reveal. Ease Docs: https://greensock.com/docs/v3/Eases Stagger Docs: https://greensock.com/docs/v3/Staggers SplitText Docs: https://greensock.com/docs/v3/Plugins/SplitText Happy Tweening! Sam
  18. I want Just add to my idea and make sure you can understand me: In case, when you scroll and you hover an element (In fact, you don't need to scroll... so only if you hover an element) and you plan to come back to the original height, the height don't need to change because the part hidding on the end screen/body in overflow it's ok and will be not hidden any more on "mouseleave".
  19. Yes it's clear for me, at least, I think, I'm not super good in English ^^ (Sorry by the way) But I'm not sure you understand me haha! When I hover an element and the height change, I don't want ScrollSmoother/Trigger act on the body height before I call a ScrollTrigger.refresh(). In fact, as a dev, when I scroll and I hover an element that the height change, I don't want change the body height because on "mouseleave" I want come back to the default height.... If I want that (body height changing on hover) I'ld want use ScrollTrigger.refresh() manually. Now that I explain it this way do we understand each other differently or always the same haha? Best regards and really thank you to you too! Sam
  20. Awesome! I have think to force the height of JOBS section with JS/CSS so it'll don't change the height of the page... Thanks for your help, you grow up my personal discuss hehe (Sorry for my bad english) For answer to your misunderstanding, I have a mind based on Locomotive Scroll where the scroll is not based on the real Body Scroll... So when we hover a element with Loco Scroll we don't get a bug because the body can change without affect the default height given for the scroll wrapper/content. I'm thinking when am saying this, can I suggest a parameter? I don't know if it makes sense, but a parameter where the height would not be affected when hovering an element while scrolling with the ScrollSmoother plugin.. Do we have a space for some suggestions? A really big thank you again for your help! Sam
  21. Hi momo! Here is an example if you want animate your lines when they are on screen... I have not tested, but I think it's good! let gsplit; $(window).on('load', function(){ /* * Register GSAP Plugins */ gsap.registerPlugin(ScrollTrigger, SplitText); /* * Init SplitText Gsap Plugin */ gsplit = new SplitText('.splitText', { type: 'chars,words,lines', charsClass: 'char', linesClass: 'line', wordsClass: 'word' }); // Prevent Bug, add opacity 0 to your CSS and turn it to opacity 1 when ready. $('.splitText').css({opacity: 1}); /* * With ScrollTrigger, on Scroll, reveal each line of a pragraph when is coming in viewport */ const paragraphs_lines = gsap.utils.toArray('.to-reveal .line'); // Add translateY -10 and opacity 0 for the test to your CSS on elements ".to-reveal .line" paragraphs_lines.forEach((line, i, v) => { gsap.to(line, { y: 0, opacity: 1, stagger: .03, scrollTrigger: { trigger: line, start: 'top ' + (window.innerHeight - 100), // Bottom position - 100px end: 'bottom ' + (window.innerHeight - 100), // Bottom position - 100px scrub: true, markers: true } }); }); }); You can turn scrub parameter to false or just not add it if you when a reveal based on the viewport only and not on scroll + viewport. EDIT: Maybe you don't want anim your paragraph based on scroll/viewport position, but directly, with delay or not... Just remove scrollTrigger and add a delay or not.... I push a repair in my code too. Change splitText variable to gsplit. Best Regards! Sam
  22. Woow Thanks for your fast come back! Yes I updated to 3.11.1, but it's not resolve the problem. For the extra space, i'm not sure to understand. Do I need to add some padding-bottom to body? But in fact, I'll have a space that I don't have in the graphic model right? Here is my Codepen: <iframe height="300" style="width: 100%;" scrolling="no" title="Untitled" src="https://codepen.io/sam-tremblay/embed/preview/QWrEqRX?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen <a href="https://codepen.io/sam-tremblay/pen/QWrEqRX"> Untitled</a> by Sam T (<a href="https://codepen.io/sam-tremblay">@sam-tremblay</a>) on <a href="https://codepen.io">CodePen</a>. </iframe> (Sorry, I just copy Source Code from Chrome instead of my PHP Code, it's not clean) A really big thank you for your help! Sam
  23. Hi GSAP Helper! Thanks for your help, but in fact, I don't understand how do you want I push to you an example if it's for the global Website? My example is in the video, wee see the problem... Could you just help me by said to me if Gsap do that normaly or if it's me the problem please? And if it's Gsap, can I disabled it? Thank you! Sam
  24. Hi Martin! You have multiples ways to do that. First, you can simply add an "onComplete" function to trigger when your SVG is completely draw. .from(".path-1", {drawSVG: 0, onComplete: () => { console.log('Completed'); }}, 0) In an other hand, you can done your scrolltrigger inner a timeline and call your border-color change after like you do now, but like that: main.from(".path-1", {drawSVG: 0}, 0) main.to(".path-1", {stroke: '#ff0000'}); (For the example I change the stroke color of your SVG, but feel free to change it for do your stuff with the .box) Or, in your actual scrolltrigger code, you can use onLeave, onEnterBack function. Best regards! Sam