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>