Home > database >  Canvas list for loop is not appearing for oscillation image effect
Canvas list for loop is not appearing for oscillation image effect

Time:06-15

So the idea comes from here I just provided a an array to create a multiple waves effect in images but it doesn't work that way. Because what I wanna do is do it in an array but its not working and not creating the image load anyway here is the link. LINK

Here is the code

    const listImages = ["./img/Leo.jpg","./img/Einstein.jpg","./img/Newton.jpg"]

        var canvas = document.querySelectorAll("canvas")
        canvas.forEach((elem,i) => {
            var img = new Image();
            img.onload = waves;
            img.src = listImages[0]
            console.log(elem,listImages[0])
            function waves(image) {
                var ctx = elem.getContext("2d"),
                w = elem.width,
                h = elem.height;
                console.log(ctx,w,h)
                ctx.drawImage(this, 0, 0);
                var o1 = new Osc(0.05), o2 = new Osc(0.03), o3 = new Osc(0.06),  // osc. for vert
                    o4 = new Osc(0.08), o5 = new Osc(0.04), o6 = new Osc(0.067), // osc. for hori
                        
                        // source grid lines
                    x0 = 0, x1 = w * 0.25, x2 = w * 0.5, x3 = w * 0.75, x4 = w,
                    y0 = 0, y1 = h * 0.25, y2 = h * 0.5, y3 = h * 0.75, y4 = h,
                        
                        // cache source widths/heights
                    sw0 = x1, sw1 = x2 - x1, sw2 = x3 - x2, sw3 = x4 - x3,
                    sh0 = y1, sh1 = y2 - y1, sh2 = y3 - y2, sh3 = y4 - y3,
                        
                    vcanvas = document.createElement("canvas"),  // off-screen canvas for 2. pass
                    vctx = vcanvas.getContext("2d");
    
                vcanvas.width = w; vcanvas.height = h;           // set to same size as main canvas
        
                (function loop() {
                    ctx.clearRect(0, 0, w, h);
                    
                    for (var y = 0; y < h; y  ) {
        
                        // segment positions
                        var lx1 = x1   o1.current(y * 0.2) * 2.5,
                            lx2 = x2   o2.current(y * 0.2) * 2,
                            lx3 = x3   o3.current(y * 0.2) * 1.5,
        
                            // segment widths
                            w0 = lx1,
                            w1 = lx2 - lx1,
                            w2 = lx3 - lx2,
                            w3 =  x4 - lx3;
        
                        // draw image lines
                        ctx.drawImage(img, x0, y, sw0, 1, 0        , y, w0      , 1);
                        ctx.drawImage(img, x1, y, sw1, 1, lx1 - 0.5, y, w1   0.5, 1);
                        ctx.drawImage(img, x2, y, sw2, 1, lx2 - 0.5, y, w2   0.5, 1);
                        ctx.drawImage(img, x3, y, sw3, 1, lx3 - 0.5, y, w3   0.5, 1);
                        }
        
                        // pass 1 done, copy to off-screen canvas:
                        vctx.clearRect(0, 0, w, h);    // clear off-screen canvas (only if alpha)
                        vctx.drawImage(canvas, 0, 0);
                        ctx.clearRect(0, 0, w, h);     // clear main (onlyif alpha)
        
                        for (var x = 0; x < w; x  ) {
                        var ly1 = y1   o4.current(x * 0.32),
                            ly2 = y2   o5.current(x * 0.3) * 2,
                            ly3 = y3   o6.current(x * 0.4) * 1.5;
        
                        ctx.drawImage(vcanvas, x, y0, 1, sh0, x, 0        , 1, ly1);
                        ctx.drawImage(vcanvas, x, y1, 1, sh1, x, ly1 - 0.5, 1, ly2 - ly1   0.5);
                        ctx.drawImage(vcanvas, x, y2, 1, sh2, x, ly2 - 0.5, 1, ly3 - ly2   0.5);
                        ctx.drawImage(vcanvas, x, y3, 1, sh3, x, ly3 - 0.5, 1,  y4 - ly3   0.5);
                        }
                        requestAnimationFrame(loop);
                    })();
            }
            function Osc(speed) {
    
            var frame = 0;
    
            this.current = function(x) {
                frame  = 0.002 * speed;
                return Math.sin(frame   x * speed * 10);
            };
            }

        })

As you may see I did used a listImages and canvas because I want to call add three canvas in my screen. so that I could have three images in my screen but the thing is it doesn't appear in my screen or in console...What's am I wrong here? I created this in javascript since in reactjs will be much more complicated.

But let me destructure the codes into something like this so you guys would understand better.

     This will be my loop for calling the oscillation animation image effect.    
    //const listImages = ["./img/Leo.jpg","./img/Einstein.jpg","./img/Newton.jpg"]
    //var canvas = document.querySelectorAll("canvas")


        var img = new Image();
        img.onload = waves;
        img.src = "./img/Newton.jpg";

        function waves() {
            var canvas = document.querySelector("canvas"),
                ctx = canvas.getContext("2d"),
                w = canvas.width,
                h = canvas.height;


            ctx.drawImage(this, 0, 0);

            var o1 = new Osc(0.05), o2 = new Osc(0.03), o3 = new Osc(0.06),  // osc. for vert
                o4 = new Osc(0.08), o5 = new Osc(0.04), o6 = new Osc(0.067), // osc. for hori
                
                // source grid lines
                x0 = 0, x1 = w * 0.25, x2 = w * 0.5, x3 = w * 0.75, x4 = w,
                y0 = 0, y1 = h * 0.25, y2 = h * 0.5, y3 = h * 0.75, y4 = h,
                
                // cache source widths/heights
                sw0 = x1, sw1 = x2 - x1, sw2 = x3 - x2, sw3 = x4 - x3,
                sh0 = y1, sh1 = y2 - y1, sh2 = y3 - y2, sh3 = y4 - y3,
                
                vcanvas = document.createElement("canvas"),  // off-screen canvas for 2. pass
                vctx = vcanvas.getContext("2d");

            vcanvas.width = w; vcanvas.height = h;           // set to same size as main canvas

            (function loop() {
                ctx.clearRect(0, 0, w, h);
                
                for (var y = 0; y < h; y  ) {

                // segment positions
                var lx1 = x1   o1.current(y * 0.2) * 2.5,
                    lx2 = x2   o2.current(y * 0.2) * 2,
                    lx3 = x3   o3.current(y * 0.2) * 1.5,

                    // segment widths
                    w0 = lx1,
                    w1 = lx2 - lx1,
                    w2 = lx3 - lx2,
                    w3 =  x4 - lx3;

                // draw image lines
                ctx.drawImage(img, x0, y, sw0, 1, 0        , y, w0      , 1);
                ctx.drawImage(img, x1, y, sw1, 1, lx1 - 0.5, y, w1   0.5, 1);
                ctx.drawImage(img, x2, y, sw2, 1, lx2 - 0.5, y, w2   0.5, 1);
                ctx.drawImage(img, x3, y, sw3, 1, lx3 - 0.5, y, w3   0.5, 1);
                }

                // pass 1 done, copy to off-screen canvas:
                vctx.clearRect(0, 0, w, h);    // clear off-screen canvas (only if alpha)
                vctx.drawImage(canvas, 0, 0);
                ctx.clearRect(0, 0, w, h);     // clear main (onlyif alpha)

                for (var x = 0; x < w; x  ) {
                var ly1 = y1   o4.current(x * 0.32),
                    ly2 = y2   o5.current(x * 0.3) * 2,
                    ly3 = y3   o6.current(x * 0.4) * 1.5;

                ctx.drawImage(vcanvas, x, y0, 1, sh0, x, 0        , 1, ly1);
                ctx.drawImage(vcanvas, x, y1, 1, sh1, x, ly1 - 0.5, 1, ly2 - ly1   0.5);
                ctx.drawImage(vcanvas, x, y2, 1, sh2, x, ly2 - 0.5, 1, ly3 - ly2   0.5);
                ctx.drawImage(vcanvas, x, y3, 1, sh3, x, ly3 - 0.5, 1,  y4 - ly3   0.5);
                }
                requestAnimationFrame(loop);
            })();
        }

        function Osc(speed) {

        var frame = 0;

        this.current = function(x) {
            frame  = 0.002 * speed;
            return Math.sin(frame   x * speed * 10);
        };
        }

CodePudding user response:

Your waves function queries the DOM for the first canvas element it has.

If you want to run the effect multiple times in the same document, you will have to link your images to a specific canvas element. There are many ways to do that; here's one:

  • Add 3 canvas elements to the document
  • Loop over each image source
  • Use document.querySelectorAll("canvas")[i] to select the canvas corresponding to the index of the image source

const listImages = [
  // Leo
  "https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Leonardo_da_Vinci_-_presumed_self-portrait_-_WGA12798.jpg/170px-Leonardo_da_Vinci_-_presumed_self-portrait_-_WGA12798.jpg",

  // Einstein
  "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Einstein_1921_by_F_Schmutzer_-_restoration.jpg/220px-Einstein_1921_by_F_Schmutzer_-_restoration.jpg",

  // Newton
  "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Portrait_of_Sir_Isaac_Newton,_1689.jpg/220px-Portrait_of_Sir_Isaac_Newton,_1689.jpg"
  
]


listImages.forEach((src, i) => {
  var canvas = document.querySelectorAll("canvas")[i];
  var img = new Image();
  img.onload = waves;
  img.src = src;
  
  var running = true;
  canvas.addEventListener("mouseover", function() { running = false; });
  canvas.addEventListener("mouseout", function() { running = true; });

  function waves() {
    var ctx = canvas.getContext("2d"),
      w = canvas.width,
      h = canvas.height;


    ctx.drawImage(this, 0, 0);

    var o1 = new Osc(0.05),
      o2 = new Osc(0.03),
      o3 = new Osc(0.06), // osc. for vert
      o4 = new Osc(0.08),
      o5 = new Osc(0.04),
      o6 = new Osc(0.067), // osc. for hori

      // source grid lines
      x0 = 0,
      x1 = w * 0.25,
      x2 = w * 0.5,
      x3 = w * 0.75,
      x4 = w,
      y0 = 0,
      y1 = h * 0.25,
      y2 = h * 0.5,
      y3 = h * 0.75,
      y4 = h,

      // cache source widths/heights
      sw0 = x1,
      sw1 = x2 - x1,
      sw2 = x3 - x2,
      sw3 = x4 - x3,
      sh0 = y1,
      sh1 = y2 - y1,
      sh2 = y3 - y2,
      sh3 = y4 - y3,

      vcanvas = document.createElement("canvas"), // off-screen canvas for 2. pass
      vctx = vcanvas.getContext("2d");

    vcanvas.width = w;
    vcanvas.height = h; // set to same size as main canvas

    (function loop() {
      ctx.clearRect(0, 0, w, h);

      for (var y = 0; y < h; y  ) {

        // segment positions
        var lx1 = x1   o1.current(y * 0.2) * 2.5,
          lx2 = x2   o2.current(y * 0.2) * 2,
          lx3 = x3   o3.current(y * 0.2) * 1.5,

          // segment widths
          w0 = lx1,
          w1 = lx2 - lx1,
          w2 = lx3 - lx2,
          w3 = x4 - lx3;

        // draw image lines
        ctx.drawImage(img, x0, y, sw0, 1, 0, y, w0, 1);
        ctx.drawImage(img, x1, y, sw1, 1, lx1 - 0.5, y, w1   0.5, 1);
        ctx.drawImage(img, x2, y, sw2, 1, lx2 - 0.5, y, w2   0.5, 1);
        ctx.drawImage(img, x3, y, sw3, 1, lx3 - 0.5, y, w3   0.5, 1);
      }

      // pass 1 done, copy to off-screen canvas:
      vctx.clearRect(0, 0, w, h); // clear off-screen canvas (only if alpha)
      vctx.drawImage(canvas, 0, 0);
      ctx.clearRect(0, 0, w, h); // clear main (onlyif alpha)

      for (var x = 0; x < w; x  ) {
        var ly1 = y1   o4.current(x * 0.32),
          ly2 = y2   o5.current(x * 0.3) * 2,
          ly3 = y3   o6.current(x * 0.4) * 1.5;

        ctx.drawImage(vcanvas, x, y0, 1, sh0, x, 0, 1, ly1);
        ctx.drawImage(vcanvas, x, y1, 1, sh1, x, ly1 - 0.5, 1, ly2 - ly1   0.5);
        ctx.drawImage(vcanvas, x, y2, 1, sh2, x, ly2 - 0.5, 1, ly3 - ly2   0.5);
        ctx.drawImage(vcanvas, x, y3, 1, sh3, x, ly3 - 0.5, 1, y4 - ly3   0.5);
      }
      requestAnimationFrame(loop);
    })();
  }

  function Osc(speed) {

    var frame = 0;

    this.current = function(x) {
      if (running) {
        frame  = 0.002 * speed;
      }
      return Math.sin(frame   x * speed * 10);
    };
  }
});
<canvas width="170" height="265"></canvas>
<canvas width="220" height="265"></canvas>
<canvas width="220" height="289"></canvas>

  • Related