稍微混淆了我应该在我的网站中使用addEventListener的功能



我正在尝试用JavaScript在HTML的空白画布上制作移动星星的背景。

背景会根据用户是否移动鼠标来移动星星。它确实像预期的那样工作,但后来我决定通过添加一个类似鼠标垫的框来改变它的功能,这个框将允许背景只有在鼠标垫处于焦点时才移动。我试着用addEventListener做这个,但它不起作用。我想我可能调用了错误的函数。

我尝试在.js文件的开头做以下操作:

const mousepad = document.querySelector('.mousepad');
mousepad.addEventListener('focus', render);

任何帮助将不胜感激!!

代码:

const STAR_COLOR = '#fff';
const STAR_SIZE = 3;
const STAR_MIN_SCALE = 0.2;
const OVERFLOW_THRESHOLD = 50;
const STAR_COUNT = (window.innerWidth + window.innerHeight) / 20;
const canvas = document.querySelector('canvas'),
context = canvas.getContext('2d');
let scale = 1, // device pixel ratio
width,
height;
let stars = [];
let pointerX,
pointerY;
let velocity = {
x: 0,
y: 0,
tx: 0,
ty: 0,
z: 0.0005
};
let touchInput = false;
generate();
resize();
step();
window.onresize = resize;
canvas.onmousemove = onMouseMove;
canvas.ontouchmove = onTouchMove;
canvas.ontouchend = onMouseLeave;
document.onmouseleave = onMouseLeave;
function generate() {
for (let i = 0; i < STAR_COUNT; i++) {
stars.push({
x: 0,
y: 0,
z: STAR_MIN_SCALE + Math.random() * (1 - STAR_MIN_SCALE)
});
}
}
function placeStar(star) {
star.x = Math.random() * width;
star.y = Math.random() * height;
}
function recycleStar(star) {
let direction = 'z';
let vx = Math.abs(velocity.x),
vy = Math.abs(velocity.y);
if (vx > 1 || vy > 1) {
let axis;
if (vx > vy) {
axis = Math.random() < vx / (vx + vy) ? 'h' : 'v';
} else {
axis = Math.random() < vy / (vx + vy) ? 'v' : 'h';
}
if (axis === 'h') {
direction = velocity.x > 0 ? 'l' : 'r';
} else {
direction = velocity.y > 0 ? 't' : 'b';
}
}
star.z = STAR_MIN_SCALE + Math.random() * (1 - STAR_MIN_SCALE);
if (direction === 'z') {
star.z = 0.1;
star.x = Math.random() * width;
star.y = Math.random() * height;
} else if (direction === 'l') {
star.x = -OVERFLOW_THRESHOLD;
star.y = height * Math.random();
} else if (direction === 'r') {
star.x = width + OVERFLOW_THRESHOLD;
star.y = height * Math.random();
} else if (direction === 't') {
star.x = width * Math.random();
star.y = -OVERFLOW_THRESHOLD;
} else if (direction === 'b') {
star.x = width * Math.random();
star.y = height + OVERFLOW_THRESHOLD;
}
}
function resize() {
scale = window.devicePixelRatio || 1;
width = window.innerWidth * scale;
height = window.innerHeight * scale;
canvas.width = width;
canvas.height = height;
stars.forEach(placeStar);
}
function step() {
context.clearRect(0, 0, width, height);
update();
render();
requestAnimationFrame(step);
}
function update() {
velocity.tx *= 0.96;
velocity.ty *= 0.96;
velocity.x += (velocity.tx - velocity.x) * 0.8;
velocity.y += (velocity.ty - velocity.y) * 0.8;
stars.forEach((star) => {
star.x += velocity.x * star.z;
star.y += velocity.y * star.z;
star.x += (star.x - width / 2) * velocity.z * star.z;
star.y += (star.y - height / 2) * velocity.z * star.z;
star.z += velocity.z;
// recycle when out of bounds
if (star.x < -OVERFLOW_THRESHOLD || star.x > width + OVERFLOW_THRESHOLD || star.y < -OVERFLOW_THRESHOLD || star.y > height + OVERFLOW_THRESHOLD) {
recycleStar(star);
}
});
}
function render() {
stars.forEach((star) => {
context.beginPath();
context.lineCap = 'round';
context.lineWidth = STAR_SIZE * star.z * scale;
context.globalAlpha = 0.5 + 0.5 * Math.random();
context.strokeStyle = STAR_COLOR;
context.beginPath();
context.moveTo(star.x, star.y);
var tailX = velocity.x * 2,
tailY = velocity.y * 2;
// stroke() wont work on an invisible line
if (Math.abs(tailX) < 0.1) tailX = 0.5;
if (Math.abs(tailY) < 0.1) tailY = 0.5;
context.lineTo(star.x + tailX, star.y + tailY);
context.stroke();
});
}
function movePointer(x, y) {
if (typeof pointerX === 'number' && typeof pointerY === 'number') {
let ox = x - pointerX,
oy = y - pointerY;
velocity.tx = velocity.tx + (ox / 8 * scale) * (touchInput ? 1 : -1);
velocity.ty = velocity.ty + (oy / 8 * scale) * (touchInput ? 1 : -1);
}
pointerX = x;
pointerY = y;
}

function onMouseMove(event) {
touchInput = false;
movePointer(event.clientX, event.clientY);
}
function onTouchMove(event) {
touchInput = true;
movePointer(event.touches[0].clientX, event.touches[0].clientY, true);
event.preventDefault();
}

function onMouseLeave() {
pointerX = null;
pointerY = null;
}
body {
width: 100%;
height: 100vh;
background-color: #000;
background-image: radial-gradient(circle at top right, rgba(84, 187, 115, 0.13), transparent), radial-gradient(circle at 20% 80%, rgba(41, 196, 255, 0.13), transparent)
}
canvas {
position: fixed;
width: 100%;
height: 100%;
}
.mousepad {
width: 700px;
height: 100px;
background-color: rgba(41, 196, 255, 0.13);
border-radius: 10px;
margin: auto;
}

/* Hide Scrollbar for aesthetic looks*/
::-webkit-scrollbar {
overflow: auto;
display: none;
}
<canvas></canvas>
<div class="mousepad"></div>

我认为您正在搜索这个mousemove事件侦听器。您可以看到下面的示例:

document.getElementById("background").addEventListener("mousemove",function(e){
let element = document.getElementById("background");
element.innerHTML = parseInt(element.innerHTML) + 1
})
#background {
width: 100px;
height: 100px;
color: white;
background-color: black;
display:flex;
justify-content:center;
align-items:center;
font-size: 40px;
}
<div id="background">1</div>

如果我理解你的问题,你只对div元素的焦点事件有问题?

为了接收div的焦点,您需要为该div指定tabindex

像这样:<div class="mousepad" tabindex="0"></div>。请记住,聚焦会冒泡,而聚焦不会。

window.addEventListener("load",onLoadHandler);
function onLoadHandler(e){
const mousepad = document.querySelector('.mousepad');
mousepad.addEventListener('focus', startRender);
mousepad.addEventListener('blur', stopRender);
}
function startRender(e){
e.target.innerHTML="focus in";
}
function stopRender(e){
e.target.innerHTML="focus out";
}
.mousepad{
width: 700px;
height: 100px;
background-color: rgba(41, 196, 255, 0.13);
border-radius: 10px;
margin: auto;
}
<div class="mousepad" tabindex="0">
Click in and out the div to focus in our out
</div>

你也可以使用:

mousepad.addEventListener('focusin', startRender);
mousepad.addEventListener('focusout', stopRender);

我希望这对你有帮助。

祝你过得愉快。

尼古拉斯。

最新更新