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>