I got some trouble with a canvas. I’ve created a bunch of words moving inside the element and I want to change the style of a single word on click. Th click function works great but: if I try to stop and scale the word the script works fine; if I try to change the color of the text it apply the transformation to another word (but stop from moving the correct one);
Here live example with codepen
This is the code to detect and style elements:
floatingWords.forEach((element) => {
if (
y > element.pos.y &&
y <= element.pos.y + element.size &&
x > element.pos.x &&
x <= element.pos.x + element.width
) {
speed = element.speed;
size = element.size;
element.opacity = 1;
element.speed -= speed;
//element.size = 120;
}
Advertisement
Answer
In the function floating.prototype.update() you need to set the fillStyle before calling fillText().
I added a color property to the elements.
$(document).ready(function() {
$(window)
.resize(function(event) {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
canvas.width = $(window).width();
canvas.height = $(window).height();
})
.trigger("resize");
createWords(36);
});
var elemLeft = canvas.offsetLeft + canvas.clientLeft,
elemTop = canvas.offsetTop + canvas.clientTop;
var words = [
"Lorem",
"ipsum",
"dolor",
"sit",
"amet",
"consectetur",
"adipiscing",
"elit",
"sed",
"do",
"eiusmod",
"tempor",
"incididunt",
"ut",
"labore",
"et",
"dolore",
"magna",
"aliqua",
"Lorem",
"ipsum",
"dolor",
"sit",
"amet",
"consectetur",
"adipiscing",
"elit",
"sed",
"do",
"eiusmod",
"tempor",
"incididunt",
"ut",
"labore",
"et",
"dolore",
"magna",
"aliqua",
];
var floatingWords = [];
function floating(word) {
this.pos = {
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
};
this.speed = Math.random() * 2 + 1;
this.size = Math.round(Math.random() * 40 + 14);
this.font = this.size + "px serif";
this.color = {r:255,g:255,b:255};
this.text = word;
this.opacity = Math.random() * (1 - 0.1) + 0.1;
ctx.font = this.font;
this.width = ctx.measureText(this.text).width;
}
floating.prototype.update = function() {
this.pos.x += this.speed;
this.font = this.size + "px serif";
if (this.pos.x >= canvas.width) {
this.pos.x = -this.width;
this.pos.y = Math.random() * canvas.height;
}
ctx.font = this.font;
ctx.fillStyle = `rgba(${this.color.r},${this.color.g},${this.color.b},${this.opacity})`;
ctx.fillText(this.text, this.pos.x, this.pos.y);
};
function createWords(n) {
for (var i = 0; i < n; i++) {
floatingWords.push(new floating(words[i]));
}
animateWords();
}
function animateWords() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < floatingWords.length; i++) {
floatingWords[i].update();
}
requestAnimationFrame(animateWords);
}
canvas.addEventListener("click", (event) => {
var x = event.pageX - elemLeft;
var y = event.pageY - elemTop;
//console.log(x, y);
floatingWords.forEach((element) => {
if (
y > element.pos.y &&
y <= element.pos.y + element.size &&
x > element.pos.x &&
x <= element.pos.x + element.width
) {
const word = element
speed = element.speed;
size = element.size;
element.opacity = 1;
element.speed -= speed;
element.color = {r:255,g:0,b:0};
}
if (element.speed === 0) {
setTimeout(() => {
element.speed += speed;
element.size = size;
element.color = {r:255,g:255,b:255};
}, 1000);
}
});
});html,
body {
font-family: 'Open Sans', sans-serif;
overflow: hidden;
background-color: #2b2b2b;
min-height: 100%;
color: #fff;
}
#canvas {
z-index: -1;
background-image: #ffff;
}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <canvas id="canvas"></canvas>