#define VTIME 0.3

float yPoint(float y0, float y1, float x) {
    float a = 2. * (y0 - y1);
    float b = 3. * (y1 - y0);
    //float c. = 0.;
    float d = y0;
    return a * x * x * x + b * x * x + d;
}

float remap2(float uv, float inputLow, float inputHigh, float outputLow, float outputHigh){
    float t = (uv - inputLow)/(inputHigh - inputLow);
    float final = mix(outputLow,outputHigh,t);
    return final;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;
    float t = ${myTime} ;    
    // float t = abs(sin(iTime));
    //v animation
    if (t < VTIME) {
        float vAnimP = (t) / VTIME;
        float top = mix(1.0, ${RANGE_1}, vAnimP);
        float bottom = mix(0.0, ${RANGE_2}, vAnimP);
        float yTop = yPoint(top, 1., uv.x);
        float yBottom = yPoint(bottom, 0., uv.x);
        float newUvY = remap2(uv.y, yBottom, yTop, 0.0, 1.0);
        if (newUvY > 1. || newUvY < 0.) {
            fragColor = vec4(0.);
        } else {
            fragColor = jsvTexture2D(iChannel0, vec2(uv.x, newUvY));
        }
    } else {
        //h animation
        float yTop = yPoint(${RANGE_1}, 1., uv.x);
        float yBottom = yPoint(${RANGE_2}, 0., uv.x);
        float newUvY = remap2(uv.y, yBottom, yTop, 0.0, 1.0);
        float hAnimP = (t - VTIME) / (1. - VTIME);
        float xStart = mix(0., 1., hAnimP);
        float newUvX = uv.x + xStart;
        if (newUvY > 1. || newUvY < 0. || newUvX > 1. || newUvY < 0.) {
            fragColor = vec4(0.);
        } else {
            fragColor = jsvTexture2D(iChannel0, vec2(newUvX, newUvY));
        }
    }
}