visgl / deck.gl

WebGL2 powered visualization framework
https://deck.gl
MIT License
12.2k stars 2.09k forks source link

Ripple effect for selected point #4872

Closed UttamRahane closed 4 years ago

UttamRahane commented 4 years ago

Is there any way to add ripple effect for selected point in ScatterplotLayer/GeoJsonLayer/IconLayer? I'm trying to highlight selected object with some animation effects. like https://docs.mapbox.com/mapbox-gl-js/example/add-image-animated

UttamRahane commented 4 years ago

image

Pessimistress commented 4 years ago

You can create a separate layer for the highlighted node and use transitions:

https://codepen.io/Pessimistress/pen/jOqVKVB?editors=0010

UttamRahane commented 4 years ago

Great, Thanks. I resolved this issue by extending shaders & separate layer for highlighted node.

getShaders() {
        const shaders = super.getShaders();
        shaders.inject = {
            'vs:DECKGL_FILTER_SIZE': `
                size *= 3.0;`,
            'fs:#decl': `
                uniform float iTime;
           ` ,
            'fs:#main-end': `
                float wave = sin(iTime * 2.0);
                float circle = (geometry.uv.x * geometry.uv.x + geometry.uv.y * geometry.uv.y);
                vec4 color1 = vec4(0.0, 0.0, 0.6, 0.8);
                vec4 color2 = vec4(1.0, 1.0, 1.0, 0.6);
                gl_FragColor = mix(color1, color2, circle + wave);;
                gl_FragColor.a *= inCircle;
                DECKGL_FILTER_COLOR(gl_FragColor , geometry);
           `,
        };
        return shaders;
    }

but the approach suggested by you is nice. I have a question related to this. In the both approaches we are re-rendering that layer. I'm using multiple layers(with large data) with this. so if I try to re-render one layer it will re-render all. right? if yes, then can't we change the value of iTime(the uniform variable which i'm taking as input) in initializeState(params) or draw(opts ) function? so I can use setInterval & can keep changing value of iTime without re-rendering any layer.

Pessimistress commented 4 years ago

if I try to re-render one layer it will re-render all. right?

Yes

You can change the time uniform in draw():

draw(opts) {
  this.state.model.setUniforms({
    iTime: ... // calculate new time
  });
  super.draw(opts);

  // Mark this layer as dirty
  this.setNeedsRedraw();
}
UttamRahane commented 4 years ago

Perfect, Thank you so much @Pessimistress for the help.

Nitikaa commented 2 years ago

@UttamRahane I wanted to add ripple effect on lineLayer, the same thing I'm facing like its re-rendering all the layers (with large data). can you brief on iTime approach ?

Nitikaa commented 2 years ago

@Pessimistress I wanted to add ripple effect on lineLayer, the same thing I'm facing like its re-rendering all the layers (with large data). can you brief on iTime draw() approach ?