检测 <canvas> 内的元素并设置样式
Detecting element inside a <canvas> and styling
canvas 我遇到了一些麻烦。我创建了一堆在元素内移动的单词,我想在单击时更改单个单词的样式。点击功能效果很好,但是:
如果我尝试停止并缩放脚本的单词,则脚本可以正常工作;
如果我尝试更改文本的颜色,它会将转换应用于另一个词(但停止移动正确的词);
Here 使用 codepen 的实例
这是检测和设置元素样式的代码:
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;
}
在函数 floating.prototype.update()
中,您需要在调用 fillText()
之前设置 fillStyle
。
我为元素添加了颜色属性。
$(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>
canvas 我遇到了一些麻烦。我创建了一堆在元素内移动的单词,我想在单击时更改单个单词的样式。点击功能效果很好,但是: 如果我尝试停止并缩放脚本的单词,则脚本可以正常工作; 如果我尝试更改文本的颜色,它会将转换应用于另一个词(但停止移动正确的词);
Here 使用 codepen 的实例
这是检测和设置元素样式的代码:
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;
}
在函数 floating.prototype.update()
中,您需要在调用 fillText()
之前设置 fillStyle
。
我为元素添加了颜色属性。
$(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>