OSUblake
Content Type
Profiles
Forums
Store
Blog
Product
Showcase
FAQ
Downloads
Posts posted by OSUblake
-
-
@Cassie just posted a demo.
See the Pen a565a64ed971eadafd29a4c932ae9d05 by cassie-codes (@cassie-codes) on CodePen
The other thread she linked also shows different ways to animate gradients.
- 2
-
- 4
-
Here's the trick to making anything responsive. Keep track of everything as ratio i.e. a percentage. Some might call that a normalized value.
So if x is at 200 and the image width is 1000, then the ratio is 0.2. Now if the image resizes to 500, you can set the draggable to 0.2 of 500 which would be 100.
- 3
-
55 minutes ago, uarreghini said:
I could do that in gsap 2 using ["{self}"]
For the record, that was kind of pointless as
this
is the instance inside the callback, so it was removed.function fillLetter() { this.targets()[0].style.fill = "#0d47a1"; console.log("INSTANCE", this); // tween instance }
But I would just follow @Carl's advice.
- 4
- 1
-
What did you try?
1 hour ago, Dcoo said:So you can't use gradients with ScrollTrigger / data-scrollcolor ?
Get a tween working first. Add in the more complicated stuff later.
- 1
-
I would just reset everything on media query changes.
See the Pen 152ea0d171ea5883d79f2623f7096338 by osublake (@osublake) on CodePen
- 5
-
9 hours ago, GreenSock said:
I noticed, for example, that you're passing in pageWidth to the useEffect() and you're also adding a "resize" listener EVERY time that function gets called AND when cleanup is supposed to happen.
Yeah, it definitely should not be like that. I would search around for how to handle resizes, like here.
https://blog.logrocket.com/developing-responsive-layouts-with-react-hooks/
- 2
-
Hey @tunji.akanbi
Can I ask why you are using React? I'm trying to understand our React users better and how to improve the experience.
So let's break down some issues with your code...
Not a big one, but
async
is meant to be used withawait
. Using.then()
is basically an alternate way to doasync/await
. It really doesn't matter which method you use as the end result will be the same.useEffect(() => { (async () => { const response = await fetch("data.json", { headers: { "Content-Type": "application/json", Accept: "application/json" } }); const data = await response.json(); setMusic(data); })(); }, []);
9 hours ago, tunji.akanbi said:From everything I was able to find online, it seems I need to use useRef() with GSAP
Yes, GSAP needs a reference to your element(s), and in React Hooks
useRef()
is usually the best way. However, one problem with your refs is that you are using the sameuseRef
for each element.ref={(el) => { testE = el; }}
<div key={m.id} className="m_Artist"> ... <div className="artists"> <h4 ref={(el) => { testE = el; }} className="artists" > Artist Bio: </h4> {m.bio} </div> </div>
The very last artist
<h4>
element is going to be the value oftestE
. A ref needs to be unique. Just like you can't have the sameid
in html. The HTML below "might" work, but can lead to problems because the IDs are the same.<div id="artist">Foo</div> <div id="artist">Bar</div> <div id="artist">Baz</div>
This is essentially what your code is doing....
var testE = null testE = element1; testE = element2; testE = element3; testE = element4; console.log(testE); // element4
So even if you had a unique ref for each element, you have another problem, those elements aren't going to be in the DOM until the music data has loaded.
{music.map((m) => (...))}
So you need another useEffect to wait for the data to come in.
useEffect(() => { // the artists are in the DOM // let's get animating!!! }, [music]);
We are having a discussion over here about how to simplify the ref process...
But until then, this is what I would do...
https://codesandbox.io/s/musicapp-with-react-and-gsap-forked-csqtx?file=/src/Test.js
cc @GreenSock ref problems
- 2
-
No worries. That's how is goes with programming.
-
28 minutes ago, javierGnz said:
I don't want to create a parent element that wrap
You already have a parent element i.e. your AnimatedBox, and the best option is do animations inside there. You can also pass down the index and create your delay. Or even pass down a timeline.
BTW, it's not a good idea to create a timeline inside the function like that.
// bad const Item = ({ item }) => { const tl = gsap.timeline(); useEffect(() => { tl.from([boxRef.current], 1, { y: 100, opacity: 0, stagger: 1, delay: 1 }); }, []); }; // ok const Item = ({ item }) => { const tl = useRef(); useEffect(() => { tl.current = gsap.timeline() .from([boxRef.current], 1, { y: 100, opacity: 0, stagger: 1, delay: 1 }); return () => tl.current.kill(); }, []); }; // ok const Item = ({ item }) => { useEffect(() => { const tl = gsap.timeline() .from([boxRef.current], 1, { y: 100, opacity: 0, stagger: 1, delay: 1 }); return () => tl.kill(); }, []); };
- 2
-
This is more of a three.js question. Try searching for how to rotate on axis. Once you figure that out, it should be relatively easy to animate with gsap.
- 1
-
7 minutes ago, MichaelGaddis said:
My question is this. Since this is a new Chrome thing, is there a known cross browser compatibility issue here? If not--never mind..
No. If you think it's an issue with gsap, remove/comment out your gsap code and see if you still get the warning.
Are you using WebGL? That's probably the most common use for shared array buffers. GSAP has compatibility with Typed Arrays, but that's the only thing in gsap that could possibility be related to shared array buffers.
- 2
-
On 4/30/2021 at 10:01 PM, Shrug ¯\_(ツ)_/¯ said:
I wonder what the % of GSAP related websites are made from something from Blake's pens. 😉
10% of my likes, so about 1,432 sites.
- 1
- 2
-
8 minutes ago, OSUblake said:
I think images are always faster.
There might be exceptions, like when drawing rectangles using fillRect or strokeRect as it doesn't have to compute a path. It's always best to test and compare first. There really are no hard rules when it comes to coding.
- 4
-
On 11/10/2020 at 11:18 AM, ZachSaucier said:
Note: Images in canvas perform well but basic shapes perform even better. If you are just using basic shapes or need better performance, consider dropping the need for images.
I think images are always faster. This demo really shows the performance difference. When you check "Use bitmap", it will use images instead of drawing shapes, giving a massive performance boost.
See the Pen EOeBdm by osublake (@osublake) on CodePen
- 3
- 1
-
12 minutes ago, Cassie said:
Woooah. That paint on heat effect is amazing
Another one I can't take credit for. This is the original. I made that version to show how to use SVG filters inside canvas. Unfortunately, Safari still doesn't support canvas filters.
See the Pen zzENQQ by mattpopovich (@mattpopovich) on CodePen
-
5 minutes ago, mikaL said:
I'm using a library, uhtml, that uses template literals, like lit-html.
Ah, nice! I used to use his hyperHTML library before lit-html came out. Didn't know he came out with another one.
-
2 hours ago, elegantseagulls said:
I'd follow the tympanus tutorial
More like copy and paste the source code. That is a definitely an expert level tutorial if I've ever seen one. I doubt 0.01% of web developers can even write a shader.
- 2
- 1
-
-
4 hours ago, GreenSock said:
I'm still not sure I'm loving this concept. Do ya'll think it'll really get used and provide enough value to expand the API surface area?
I'm pretty sure people will start using it once it starts showing up in demos. It will probably also be a good learning experience for some as I don't think a lot of people know you can do element.querySelectorAll.
But I think the biggest usage will be with React and Angular. I've shown some React examples, but Angular is probably worse.
Ex HTML:
<div #heading class="heading">Lorem Ipsum</div> <div> <div #img class="img"></div> <div #img class="img"></div> <div #img class="img"></div> </div>
Ex TS:
@component() class MyComponent implements AfterViewInit { @ViewChild("heading") heading: ElementRef; @ViewChildren("img") images: QueryList<ElementRef>; ngAfterViewInit(): void { const imageElements = this.images.map(img => img.nativeElement); gsap.to(this.heading.nativeElement, { y: 100 }); gsap.to(imageElements, { autoAlpha: 1, stagger: 0.1 }); } }
With context...
@component() class MyComponent implements AfterViewInit { constructor(el: ElementRef) { this.el = el.nativeElement; } ngAfterViewInit(): void { const $ = gsap.context(this.el); gsap.to($(".heading"), { y: 100 }); gsap.to($(".img"), { autoAlpha: 1, stagger: 0.1 }); } }
- 2
-
1 hour ago, mikaL said:
That's where it's often used, but it doesn't have to be. ShadowRoot inherits from DocumentFragment --> Node , so it's got append() , appendChild() etc. methods.
Right, I get all that. I was just trying to understand your workflow. Like are you cloning a template, creating elements dynamically and then appending them, appending already existing elements, using innerHTML, etc?
-
Any reason against in the vars?
2 hours ago, GreenSock said:Or it could be used like:
cont q = gsap.context(svgRef.current); gsap.to(q("circle"), {...}); gsap.to(q("rect"), {...});
But that's probably the most versatile. For the people who miss jQuery...
const $ = gsap.context(); // document
2 hours ago, GreenSock said:In fact, we could add some logic so that you could pass in the ref, and it'll automatically get the ".current" in that case.
And for Angular, it might be ".nativeElement".
-
Maybe like this?
const interp = interpolate([q1, q2, q3], (start, end, progress) => { // custom interpolation return ...; });
-
2 hours ago, SammyC123 said:
When the rect comes in, it's seemingly a different stroke color than the lines... closer to light gray than white.
Probably antialiasing. The stroke might not lie perfectly in the pixel grid. Kind of like here. The top box looks lighter with a thicker stroke. That's just nature of how graphics are displayed on a monitor.
See the Pen 03a55f0e37f66d5c9c85ef7a91e28705 by osublake (@osublake) on CodePen
If you click the translate 1/2 pixel checkbox here, you should see the line go from gray to black.
See the Pen 08be2488622766dc922010a69c5b40c8 by osublake (@osublake) on CodePen
The only way to really fix that is to move anything that has an odd stroke width 1, 3, 5, etc over 1/2 a pixel. It's probably not worth it if you're animating it as it won't look smooth.
So I'm not exactly sure what the end result is supposed to be, but I think a good first step would be to reorganize your code. Everything should be controlled by a single render/update function, and that function could draw stuff based on a simple scene graph like so...
See the Pen f5b7c30693a9555cbc598e56388b4b3c by osublake (@osublake) on CodePen
And with canvas, you can draw other canvases onto a canvas. This is useful if you want to combine different rendering techniques.
const canvas = document.querySelector("#canvas"); const ctx = canvas.getContext("2d"); const canvas2 = document.createElement("canvas"); const ctx2 = canvas2.getContext("2d"); ... // draw canvas2 on canvas ctx.drawImage(canvas2);
That's how I do the filter effects in this.
See the Pen RLOzxo by osublake (@osublake) on CodePen
- 1
Use functions to detect variables in tweens based on getBoundingClientRect()
in GSAP
Posted
getBoundingClientRect
always includes transforms. You can remove the transforms, measure, and then reapply the transforms.Or use something like
element.clientWidth/clientHeight
orelement.offsetWidth/offsetHeight
depending on your needs.