OSUblake
Content Type
Profiles
Forums
Store
Blog
Product
Showcase
FAQ
Downloads
Posts posted by OSUblake
-
-
1 minute ago, 321dev said:
So this would first interpolate between items 0 and 1, then 1 and 2, and so on.
Yep.
2 minutes ago, 321dev said:BTW: Maybe gsap.utils.interpolate() could be expanded so that you could pass a custom function that interpolates between two elements?
That's not a bad idea. Any thoughts on this @GreenSock?
-
So using three.js's slerp is fine, you just need to interpolate an array of them?
Would something like this work?
const interp = interpolate([q1, q2, q3]); let qx = interp(0.3); function interpolate(targets) { const interpolators = []; let len = targets.length; const iLen = len - 2; const q = new THREE.Quaternion(); for (let i = 1; i < len; i++) { interpolators.push(slerp(targets[i - 1], targets[i], q)); } len--; return p => { p *= len; let i = Math.min(iLen, ~~p); return interpolators[i](p - i); } } function slerp(a, b, q) { return p => { // three.js slerp return q.slerpQuaternions(a, b, p); } }
- 1
-
18 hours ago, marosko said:
I thought it would be easier 😕
Definitely not easy. Something like this is definitely a good use case for some gsap utils like interpolate and mapRange.
An example of how the points could be setup and then modified in the update function.
See the Pen 2ed6786c0e21107ed101211053db81df by osublake (@osublake) on CodePen
-
What properties are you trying to animate? Do you have some psuedo code?
- 1
-
I know, that's why I tagged someone else 😉
-
2 hours ago, 321dev said:
E.g. when you wanted to interpolate a rotation in degrees from 350 to 10, the code should go from 350...359..0...10, instead of going backwards from 350 to 10.
@GreenSock do you have some code for this? I can't find my demos that show this.
- 1
-
8 hours ago, 321dev said:
There are quite a few posts about this, but they're many years old, and many of them mention a plugin that can handle quaternions. What's the state today? Can GSAP tween quaternions, or do we still need a plugin?
That's from the flash days.
You should be able to just use onUpdate kind of like what shown here... although they are using Tween.js
https://discourse.threejs.org/t/animating-quaternion-rotation/8015/12
- 1
-
12 hours ago, mikaL said:
No, it's not. All you have to do is
const element = document.createElement('div'); element.attachShadow({mode: 'open'});
Well, I would still consider that part of the web components API. So if you do that way, then how to do you add elements to the shadow root?
-
Using lineTo definitely requires a lot more work.
See the Pen 9ecbcd3e4f22a6187f53de90474083e2 by osublake (@osublake) on CodePen
- 1
-
With lineTo, you would need to draw each line of the square. But it's easier to just to use strokeRect or fillRect for a square.
See the Pen b9683e34dff19d85dba7ae6f8015820f by osublake (@osublake) on CodePen
- 2
-
You're right about it being no better/different.
Would that API work if you like create an animation after calling context?
gsap.context(svgRef.current, () => { gsap.to("circle", { x: 100, onComplete() { gsap.to("rect", { ... }); } }); });
-
I'll check your demo out in a bit, but this is what I meant scaling. It can be used to change the position of something.
-
51 minutes ago, GreenSock said:
and one of the reasons for using refs
The reason for using refs is to get the correct element. You really don't need refs if you are 100% sure that the
document.querySelectorAll
will get the correct element, but that's unlikely if a component is used more than once, which is basically the whole point of using components. -
59 minutes ago, GreenSock said:
Next question: how does this impact the whole re-rendering thing?
I think there's been a lot of confusion over the years, especially with people throwing out terms like virtual DOM. Elements just don't get trashed or recreated. Once it's in the DOM, it's stays in there until you tell React to remove it.
Re-rendering basically just means applying changes made within React, or whatever component framework you're using, to the DOM. In this demo, React is re-rendering the
cx
attribute, which is being changed within React. GSAP is animating thecy
attribute. There would only be an issue if gsap tries to change what React is trying to change.See the Pen bd15dbff73a59bd52de033864b2559d8 by osublake (@osublake) on CodePen
- 2
-
And this doesn't apply to just React. Vue and Angular behave the same way with refs.
-
Now if a component has a bunch children elements that you want to animate, you're going to have to get a reference to them somehow.
Most common is probably with the useRef.
function MySvg() { const svg = useRef(); const circle1 = useRef(); const circle2 = useRef(); const circle3 = useRef(); const rect1 = useRef(); const rect2 = useRef(); const rect3 = useRef(); useEffect(() => { gsap.to([circle1.current, circle2.current, circle3.current], { x: 100 }); gsap.to([rect1.current, rect2.current, rect3.current], { y: 200 }); }, []); return ( <svg ref={svg}> <circle ref={circle1}></circle> <circle ref={circle2}></circle> <circle ref={circle3}></circle> <rect ref={rect1}></rect> <rect ref={rect2}></rect> <rect ref={rect3}></rect> </svg> ); }
If we had an option to pass in the context, we could eliminate all those useRefs except for the parent one, and just use query strings, greatly reducing the amount of code.
function MySvg() { const svg = useRef(); useEffect(() => { gsap.to("circle", { context: svg.current, x: 100 }); gsap.to("rect", { context: svg.current, y: 200 }); }, []); return ( <svg ref={svg}> <circ></circle> <circ></circle> <circ></circle> <rect></rect> <rect></rect> <rect></rect> </svg> ); }
- 1
- 1
-
Well, let's first go over the biggest problem I see with React users, they don't use refs. They assume the selector string is just going to target that component, but if you use that component more than once, it's not going to animate correctly.
This is supposed to animate the first box to 100 with a color of red, the second box to 200 with a color of green, and the third box to 300 with a color of yellow, but it doesn't happen.
See the Pen 581c7a732f60e8322b5b543f4691a77b by osublake (@osublake) on CodePen
Correct behavior using refs.
See the Pen b8f05fd1700a1ef0c41ef1c41c9ca0fd by osublake (@osublake) on CodePen
- 2
-
11 hours ago, mikaL said:
As far as I know web components tend to use shadow DOM too. But as I said, it's not a deal breaker for me.
How are you using shadow DOM without web components? AFAIK that's the only way.
-
16 hours ago, mikaL said:
Yes, I think this is exactly what I'm looking for. I could even set it sort of globally beforehand, with something like this
gsap.defaults({context: shadowRoot})
I don't even know how that could work as a default. How would it get a reference to
this.shadowRoot
?Where I see this being the most helpful is with component frameworks like React. People wouldn't have to contemplate the best way to stagger elements.
-
7 hours ago, marosko said:
if I call createBlob with different setup on scrollChange it rerenders whole "blob" and it's not smooth...
Yeah, that's probably the worst thing you could do.Why don't you convert that demo over to gsap 3, research how to scale a vector, and then I can provide more guidance.
For reference, this is the vector that we want to scale.
var point = { x: options.centerX + Math.cos(angle) * options.minRadius, y: options.centerY + Math.sin(angle) * options.minRadius };
- 1
-
That's what I'm thinking.
So like in React, the user could just pass in the parent element of component.
function App() { const container = useRef(null); useEffect(() => { gsap.to(".box", { context: container.current, x: 100 }); }, []); return ( <div className="container" ref={container}> <div className="box"></div> <div className="box"></div> <div className="box"></div> <div className="box"></div> </div> ); }
- 1
-
17 minutes ago, Robert Wildling said:
Could it be that you just want to tell me "don't define
menuTween
on the data object, instead just declare it inmethods
"?Yep. The main point is that you can define your animations anywhere. It doesn't have to be inside a method per se. The only bad place might be inside
created
as you won't be able to access any refs at that point in the lifecycle.- 2
- 1
-
Did you try it? 100% guaranteed it will be reachable.
this
does not point to the data object. The data properties are copied tothis
.- 2
-
1 hour ago, Robert Wildling said:
Hmmm... I still do not see the place where I add a gsap instance to the object returned by the data object...
He's saying you don't need to put anything related to GSAP on the data object. The data object is for reactive properties. GSAP animations are not reactive, and therefore you are putting additional overhead into your components by adding your animations to the data object.
You can set your animations in any method, mounted, or from the vm passed in. It all points to the same instance.
// this isn't needed data() { return {}; }, beforeRouteEnter(to, from, next) { next((vm) => { vm.foo(); console.log(vm.bar); // Hello }); }, // Or using mounted mounted() { this.foo(): console.log(this.bar); // Hello }, methods: { foo() { this.bar = "Hello"; } }
- 1
Tweening three.js quaternions
in GSAP
Posted
If it's not smooth, maybe make a simple demo so we can mess around and tweak it.