Issue
I took this JS snippet from codepen and apply it to my site. I want the watercolor effect to be both inside the div but it seems like it only works on the first one.
I tried using const canvas = document.querySelectorAll('.see-more');
but this makes it worse and doesn't work.
//watercolor effect on see more//
const canvas = document.querySelector('.see-more');
console.log(canvas);
//canvas.width = 300;
//canvas.height = 150;
const cx = canvas.getContext('2d');
cx.globalCompositeOperation = 'source-over';
cx.imageSmoothingEnabled = true;
cx.imageSmoothingQuality = 'low';
const palette = [
//[255, 255, 255],
//[83, 159, 162], //turqoise//
//[114, 177, 164], //green
[171, 204, 177],
//mint
//[196, 219, 180], //light green//
[221, 160, 221],
//plum//
[255, 192, 203],
//pink//
[0, 255, 255],
//neon blue//
[255, 255, 0] //yellow//
//[212, 226, 182] //bright green
];
const gradients = palette.map(([r, g, b]) => {
const gradient = cx.createRadialGradient(0, 0, 1, 0, 0, 50);
gradient.addColorStop(0, `rgba(${r},${g},${b},1)`);
gradient.addColorStop(1, `rgba(${r},${g},${b},0)`);
return gradient;
});
const watercolors = [];
class Watercolor {
constructor(time) {
const colorIndex = Math.floor(Math.random() * palette.length);
this.color = gradients[colorIndex];
this.radius = 50;
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.dx = Math.random() * 2 - 1;
this.dy = Math.random() * 2 - 1;
this.startTime = time;
this.currentTime = time;
this.duration = Math.ceil(Math.random() * 5000);
}
update(time) {
this.currentTime = time;
if (this.currentTime - this.startTime >= this.duration) {
return false;
}
this.x += this.dx;
this.y += this.dy;
return true;
}
render(cx) {
cx.save();
cx.globalAlpha = (this.currentTime - this.startTime) / this.duration;
cx.translate(this.x, this.y);
cx.beginPath();
cx.arc(0, 0, this.radius, 0, Math.PI * 2);
cx.fillStyle = this.color;
cx.fill();
cx.restore();
}
}
let frameId;
function frame(time) {
const multiplier = 0.25;
const expectedWidth = Math.floor(canvas.clientWidth * multiplier);
if (canvas.width !== expectedWidth) {
canvas.width = expectedWidth;
}
const expectedHeight = Math.floor(canvas.clientHeight * multiplier);
if (canvas.height !== expectedHeight) {
canvas.height = expectedHeight;
}
if (watercolors.length < 2) {
watercolors.push(new Watercolor(time));
}
for (let index = watercolors.length - 1; index >= 0; index--) {
const watercolor = watercolors[index];
if (!watercolor.update(time)) {
console.log(watercolors.splice(index, 1));
}
}
for (const watercolor of watercolors) {
watercolor.render(cx);
}
frameId = window.requestAnimationFrame(frame);
}
function start() {
frameId = window.requestAnimationFrame(frame);
}
function stop() {
window.cancelAnimationFrame(frameId);
}
start();
.sec {
padding-top: 200px;
padding-bottom: 200px;
}
.cont {
max-width: 1440px;
padding-right: 30px;
padding-left: 30px;
}
.see-more-wrap {
position: relative;
overflow: hidden;
width: 40%;
margin-left: 10px;
//border-style: solid;
//border-width: 1px;
background-color: @swatch_76b6399f;
text-decoration: none;
}
<section class="sec"><div class="w-layout-blockcontainer cont w-container"><div><a href="#" class="see-more-wrap w-inline-block"><div><h3 class="h3-copy">More work?</h3><div class="mar-btm-10px">Discover the collection of our previous projects.</div></div><div class="pos-abs w-embed"><canvas class="see-more" width="137" height="18"></canvas>
<style>
.see-more {
width: 100%;
height: 100%;
display: flex;
}
.see-more {
filter: blur(20px) contrast(2);
}
</style></div></a><a href="#" class="see-more-wrap w-inline-block"><div><h3 class="h3-copy">More work?</h3><div class="mar-btm-10px">Discover the collection of our previous projects.</div></div><div class="pos-abs w-embed"><canvas class="see-more"></canvas>
<style>
.see-more {
width: 100%;
height: 100%;
display: flex;
}
.see-more {
filter: blur(20px) contrast(2);
}
</style></div></a></div></div></section>
Solution
I got it working but it was a lot of work, basically, we change the querySelector
to querySelectorAll
then run a for loop for all the canvases. As for the changes, basically, I scoped the canvases to exist through passing params, so that each canvas function runs on its respective canvas!
//watercolor effect on see more//
let frameId;
const watercolors = [];
const palette = [
//[255, 255, 255],
//[83, 159, 162], //turqoise//
//[114, 177, 164], //green
[171, 204, 177],
//mint
//[196, 219, 180], //light green//
[221, 160, 221],
//plum//
[255, 192, 203],
//pink//
[0, 255, 255],
//neon blue//
[255, 255, 0] //yellow//
//[212, 226, 182] //bright green
];
const getGradients = (canvas) => palette.map(([r, g, b]) => {
const cx = canvas.getContext('2d');
const gradient = cx.createRadialGradient(0, 0, 1, 0, 0, 50);
gradient.addColorStop(0, `rgba(${r},${g},${b},1)`);
gradient.addColorStop(1, `rgba(${r},${g},${b},0)`);
return gradient;
});
class Watercolor {
constructor(time, canvas) {
const colorIndex = Math.floor(Math.random() * palette.length);
const gradientsArr = getGradients(canvas);
this.color = gradientsArr[colorIndex];
this.radius = 50;
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.dx = Math.random() * 2 - 1;
this.dy = Math.random() * 2 - 1;
this.startTime = time;
this.currentTime = time;
this.duration = Math.ceil(Math.random() * 5000);
}
update(time) {
this.currentTime = time;
if (this.currentTime - this.startTime >= this.duration) {
return false;
}
this.x += this.dx;
this.y += this.dy;
return true;
}
render(cx) {
cx.save();
cx.globalAlpha = (this.currentTime - this.startTime) / this.duration;
cx.translate(this.x, this.y);
cx.beginPath();
cx.arc(0, 0, this.radius, 0, Math.PI * 2);
cx.fillStyle = this.color;
cx.fill();
cx.restore();
}
}
const canvases = document.querySelectorAll('.see-more');
if (canvases && canvases.length) {
canvases.forEach((canvas) => {
//canvas.width = 300;
//canvas.height = 150;
const cx = canvas.getContext('2d');
cx.globalCompositeOperation = 'source-over';
cx.imageSmoothingEnabled = true;
cx.imageSmoothingQuality = 'low';
start(canvas);
});
}
function start(canvas) {
frameId = window.requestAnimationFrame(frame.bind(this, canvas));
}
function stop() {
window.cancelAnimationFrame(frameId);
}
function frame(canvas, time) {
const cx = canvas.getContext('2d');
const multiplier = 0.25;
const expectedWidth = Math.floor(canvas.clientWidth * multiplier);
if (canvas.width !== expectedWidth) {
canvas.width = expectedWidth;
}
const expectedHeight = Math.floor(canvas.clientHeight * multiplier);
if (canvas.height !== expectedHeight) {
canvas.height = expectedHeight;
}
if (watercolors.length < 2) {
watercolors.push(new Watercolor(time, canvas));
}
for (let index = watercolors.length - 1; index >= 0; index--) {
const watercolor = watercolors[index];
if (!watercolor.update(time)) {
watercolors.splice(index, 1);
}
}
for (const watercolor of watercolors) {
watercolor.render(cx);
}
frameId = window.requestAnimationFrame(frame.bind(this, canvas));
}
.sec {
padding-top: 200px;
padding-bottom: 200px;
}
.cont {
max-width: 1440px;
padding-right: 30px;
padding-left: 30px;
}
.see-more-wrap {
position: relative;
overflow: hidden;
width: 40%;
margin-left: 10px;
//border-style: solid;
//border-width: 1px;
background-color: @swatch_76b6399f;
text-decoration: none;
}
<section class="sec">
<div class="w-layout-blockcontainer cont w-container">
<div>
<a href="#" class="see-more-wrap w-inline-block">
<div>
<h3 class="h3-copy">More work?</h3>
<div class="mar-btm-10px">Discover the collection of our previous projects.</div>
</div>
<div class="pos-abs w-embed"><canvas class="see-more" width="137" height="18"></canvas>
<style>
.see-more {
width: 100%;
height: 100%;
display: flex;
}
.see-more {
filter: blur(20px) contrast(2);
}
</style>
</div>
</a>
<a href="#" class="see-more-wrap w-inline-block">
<div>
<h3 class="h3-copy">More work?</h3>
<div class="mar-btm-10px">Discover the collection of our previous projects.</div>
</div>
<div class="pos-abs w-embed"><canvas class="see-more"></canvas>
<style>
.see-more {
width: 100%;
height: 100%;
display: flex;
}
.see-more {
filter: blur(20px) contrast(2);
}
</style>
</div>
</a>
</div>
</div>
</section>
Answered By - Naren Murali
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.