OSUblake last won the day on April 16

OSUblake had the most liked content!

OSUblake

Moderators
  • Content count

    3,479
  • Joined

  • Last visited

  • Days Won

    339

Posts posted by OSUblake


  1. 22 minutes ago, Shaun Gorneau said:

    Chrome 66 - Buttery smooth until it's not :/ It's perfect, then hangs for .5 seconds, then perfect again .. on pretty much each slide transition. No idea why.

    Opera 52 - Nearly identical to Chrome (to be expected)

     

    Has anyone else noticed performance issues with these browsers? Scrolling and changing tabs has been really slow for me, and I've been going insane the past couple of weeks trying to figure out the problem.  

    • Like 2

  2. If you need help, post a demo instead of code. It's hard to understand what's going on without one.

     

    That's why I'm going to have to take a guess on this one. If something goes crazy when you change tabs and come back, it's probably because you're using setTimeout or setInterval.

     

    And I don't know if you should really be using xOrigin and yOrigin like that. Those are used for internal calculations done by GSAP, so they might not be what you expect.

     

    For SVG positioning, look at this thread.

     

     

     

     

    • Like 4

  3. Hi @ScottJenson

     

     

    There's really no spec for this. The filters in Pixi are shaders, little programs that run on the GPU. The displacement filter is a fragment shader, which runs every pixel through a function to get it's color. That's what gl_FragColor returns. To learn more about shaders, The Book of Shaders is a good place to start.

     

     

    varying vec2 vFilterCoord;
    varying vec2 vTextureCoord;
    
    uniform vec2 scale;
    
    uniform sampler2D uSampler;
    uniform sampler2D mapSampler;
    
    uniform vec4 filterArea;
    uniform vec4 filterClamp;
    
    void main(void)
    {
      vec4 map =  texture2D(mapSampler, vFilterCoord);
    
      map -= 0.5;
      map.xy *= scale / filterArea.xy;
    
      gl_FragColor = texture2D(uSampler, clamp(vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y), filterClamp.xy, filterClamp.zw));
    }

     

     

    The colors used in the displacement map aren't too important. What matters are the channels in the color. In an image, each pixel is an rgba value. In the displacement map, each pixel represents an xy value. A 2D vector.

     

    // color channels from 0-255
    var color = {
      r: 100,
      g: 200,
      b: 0,
      a: 255
    };
    
    // convert to values from -0.5 to 0.5
    var map = {
      x: (color.r / 255) - 0.5,
      y: (color.g / 255) - 0.5
    };

     

     

    So the red and green channel are what matters. The red channel is the x displacement, and the green channel is the y displacement. The displacement values will be from -0.5 to 0.5. If the channel is 0, the displacement value will be -0.5. If the channel is 128, the displacement will be 0. If the channel is 255, the displacement value will be 0.5.

     

    The filter uses the coordinates of the texture pixel being processed and offsets it by the corresponding displacement and scale value in the map, and returns the color of the texture at those coordinates. So if the red and green channel are both 128, it's going to return the same pixel. It's neutral. If the red channel is less than 128, it's going to return a pixel to the left of it. If the green channel is less than 128, it's going to return a pixel above it.

     

    This displacement map will work almost like the one you posted.

     

    gPx8aix.jpg

     

    The gray background has an rgb value of 128, 128, 128. The brownish background in the image you posted has an rgb value of 128, 128, 0. The red and green channels are what matters, so no displacement happens in those areas.

     

    Here are some terms worth knowing as they are kind of related.

    Displacement mapping - https://en.wikipedia.org/wiki/Displacement_mapping

    Heightmap - https://en.wikipedia.org/wiki/Heightmap

    Normal mapping - https://en.wikipedia.org/wiki/Normal_mapping

     

    A normal map is used for lighting, but it's similar to a displacement map.

    http://www.falloutsoftware.com/tutorials/gl/normal-map.html

    https://cpetry.github.io/NormalMap-Online/

     

    This tutorial shows the relationship between a normal map and a displacement map.

    http://zarria.net/nrmphoto/nrmphoto.html

     

    And here's a demo I made for some fabric. You can drag the letter. The displacement map is black and white.

     

     

     

     

    • Like 5

  4. I've read a lot of articles on why ES6 classes are bad, and I can summarize every single one of them.

     

    Classes are bad, blah blah blah, classical inheritance is bad, blah blah blah, functional programming is good. 

     

    It's all opinions. I'm not saying there's no merit to their claims, but there are no technical reasons for why classes are bad.

     

    But here's the thing about classes, what they do isn't new. It's mostly just syntactic sugar for constructor functions.

    https://hacks.mozilla.org/2015/07/es6-in-depth-classes/

     

    I personally use classes all the time. The biggest argument against using classes is one of the reasons why I like using them, classical inheritance, creating a class from another class. The people that wrote those articles would consider my CustomSprite bad, but they would be OK with my CustomElement. They both do the same thing.

     

    See how to create a custom element. You need to use a class.

    https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements

     

    // Inherits from PIXI.Sprite
    class CustomSprite extends PIXI.Sprite {  
      constructor() {
        super();
      }  
      
      customMethod() {
        
      }
    }
    
    // Inherits from HTMLElement
    class CustomElement extends HTMLElement {
      constructor() {
        super();
      }
      
      customMethod() {
        
      }
    }

     

     

    • Like 2

  5. 8 hours ago, maxxheth said:

    Yeah, fair enough! I guess I just wanted to be able to switch back and forth between being able to target single elements and multiple elements on a whim, but your event emitter / data attribute solution works perfectly for that as well.

     

     

    Gotcha. I wasn't sure if you wanted to target single and multiple elements, so that's why I brought up the event emitter. It's a great way to keep things decoupled. That's actually how reactive libraries like React, Vue, Angular and RxJS work, although they call it a observer/observable.

     

    A silly event emitter demo I made for another thread. 45 different input ranges are being driven by animating a simple object.

     

     

    • Like 1

  6. @gogo125

     

    There's plenty of examples. I know because I made them. Webpackbin merged with CodeSandbox, so all those demos are gone, but if somebody asks, I can make another version. 

     

    Another thing that might make searching harder, don't use a version number. It's Angular. 

     

    Also, you can add scripts to the .angular.cli.json file instead of importing.

    https://github.com/angular/angular-cli/wiki/stories-global-scripts

     

    "scripts": [
      "assets/gsap/TweenMax.js",
      "assets/gsap/plugins/DrawSVGPlugin.js"
    ]

     

    • Like 2

  7. How wide are your clouds? How wide is the stage? Why is 0 such an awesome number?

     

    If a cloud is 200, the stage is 1000, and that cloud is positioned at 0.

    var tl = new TimelineMax({ repeat: -1 })
      .set(cloud, { x: -200 })
      .to(cloud, 10, { x: 1000 })
      .progress(Math.random())

     

     

    Here's a hint. Your SVG is 2645.22 wide.

     

    <svg viewBox="0 0 2645.22 1529.55"></svg>

     

     

    Now move your clouds to 0, and head on over to this thread.

     

     

    • Like 5

  8. The only thing I would have done differently is to handle the click inside the createAnimation function.

     

    const createAnimation = (element) => {
      let tween = TweenLite.to(element, 1, {
        width: 400,
        backgroundColor: "#673AB7",
        borderRadius: 0,
        ease: Elastic.easeOut
      }).reverse();
    
      element.addEventListener("click", () => tween.reversed(!tween.reversed()));
    }

     

    • Like 3
    • Thanks 1

  9. 10 hours ago, maxxheth said:

    @OSUblake Is there a way to toggle items individually without reversing other elements that have already been triggered?

     

    I'd just let each element handle the click individually instead of looping through the entire set.

     

     

    And who needs loops when you can when you can emit events. I do that a lot in games.

     

     

    • Like 3
    • Thanks 1

  10. 3 hours ago, benoit said:

    my hack is not really ok on Chrome mobile device due to auto-hidden address bar :( 

     

    Yes, that's a problem because the element is fixed.

    https://developers.google.com/web/updates/2016/12/url-bar-resizing

     

    But the gap is at the top because the scroller moves in the opposite direction. Not sure how to fix at the moment. There might be a solution somewhere in here.

    https://stackoverflow.com/questions/24944925/background-image-jumps-when-address-bar-hides-ios-android-mobile-chrome

     

     

    • Like 1

  11. 1 hour ago, Pete Barr said:

    Yeah using a retina display, does that have a bearing even though the issue is only present in Chrome? 

     

    It depends. Every browser handles rendering a little different, but a retina display can put a lot of strain on the browser during an animation, especially if you're using high DPI images or SVG. Setting display to none probably freed up a lot resources. 

    • Like 3

  12. The problem is simple. 

     

    // Called repeatedly by for loop
    function displayTribute( tribute, j ) { 
      
      // Executed immediately 
      console.log( tribute[j], tribute[j+1], tribute[j+2]);
      $line1.text( tribute[j] );
      $line2.text( tribute[j+1] );
      $line3.text( tribute[j+2] );
      
      // Happens some time in the future
      tl.staggerTo( [$line1, $line2, $line3], 3, { opacity: 1 }, 0.5 )
        .delay(2).to( [$line1, $line2, $line3], 1, { opacity: 0 } );
    }

     

     

    What's happening in the console is the same thing that's happening with your line elements. You need to change the text in the future, not now. You could do that with a callback using .call() or with the TextPlugin.

     

     

     

    • Like 3

  13. 24 minutes ago, Visual-Q said:

    Pretty hard to tell from the description whether it's a problem with the code or you're overloading Chrome momentarily as Jack suggested.

     

    Sounds reasonable. Are you using a retina display?

     

    You might be running out GPU memory. Turn on the FPS meter in the Rendering tab in Chrome/Opera dev tools, and see if you notice a huge spike in the GPU Memory during that part.

     

    Psy1FlR.jpg 

    • Like 5

  14. x and y are properties on a container, so you really don't have to use position.

    TweenMax.to(container, 1, { x:400 } );

     

    Another Pixi tip, you can chain graphics commands.

    var graphics = new PIXI.Graphics()
      .lineStyle(0)
      .beginFill(0xffffff, 1)
      .drawRect(0, 95, 800, 10)
      .beginFill(0x7FFF00)
      .drawCircle(400, 100,50)

     

    • Like 3

  15. Regarding groups, it's not a problem. See this Stackoverflow question for different ways to get rid of transforms.

    https://stackoverflow.com/questions/13329125/removing-transforms-in-svg-files

     

    I thought Illustrator had an option to automatically apply transforms to paths, but I can't find it. Maybe @PointC can offer some tips. I know SVGO is popular, but you have to be careful about some of the settings as it might change too much stuff in your svg file.

    https://jakearchibald.github.io/svgomg/

     

     

    • Like 1