Jump to content
Search Community

OSUblake last won the day on September 16 2023

OSUblake had the most liked content!

OSUblake

Moderators
  • Posts

    9,196
  • Joined

  • Last visited

  • Days Won

    708

Posts posted by OSUblake

  1. 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.

     

     

    • Like 3
  2. 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. 

     

    • Like 4
    • Thanks 1
  3. 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 with await. Using .then() is basically an alternate way to do async/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 same useRef 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 of testE. A ref needs to be unique. Just like you can't have the same id 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

     

    • Like 2
  4. 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();
      }, []);
    };

     

     

     

    • Like 2
  5. 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.

     

     

    • Like 2
  6. 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.

    • Like 4
  7. 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

     

     

    • Like 3
    • Thanks 1
  8. 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.

     

     

  9. 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.

     

    • Like 2
    • Haha 1
  10. 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
        });
      }
    }

     

     

    • Like 2
  11. 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? 

     

  12. 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".

     

  13. 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

     

     

    • Thanks 1
×
×
  • Create New...