我遇到了一个小问题,我无法解决问题。
我开发了一个跟随光标的元素,它需要运行的方式是光标周围的边框需要坚持光标的位置。但我现在遇到的问题是它在向下滚动时不会坚持。
您可以在下面的演示中查看我的意思。
问题似乎是没有正确检查页面的高度,这就是为什么它没有正确定位。我是对的吗?
const windowW = window.innerWidth;
const windowH = window.innerHeight;
const maxLength = Math.max(windowW, windowH);
const cursorWidth = 100;
const cursorR = cursorWidth >> 1;
const cursorDelay = 10;
const buttons = Array.from(document.querySelectorAll('.border-button'));
const cursor = {
el: document.querySelector('.border-cursor'),
x: windowW >> 1,
y: windowH >> 1,
scaleX: 1,
scaleY: 1,
};
const target = {
x: windowW >> 1,
y: windowH >> 1,
width: cursorWidth,
followMouse: true,
};
const norm = (val, max, min) => (val - min) / (max - min);
const toDegrees = r => r * (180 / Math.PI);
const distanceBetween = (v1, v2) => Math.sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y +- v2.y));
const loop = () => {
const destX = target.x - cursorR;
const destY = target.y - cursorR;
const newX = cursor.x + ((destX - cursor.x) / cursorDelay);
const newY = cursor.y + ((destY - cursor.y) / cursorDelay);
const angle = angleBetween(cursor.x, cursor.y, newX, newY);
if (target.followMouse) {
const distance = Math.abs(distanceBetween(target, cursor));
const scale = norm(distance, maxLength, cursorR);
cursor.scaleX = 1 + scale;
cursor.scaleY = 1 - scale;
} else {
const targetScale = target.width / cursorWidth;
cursor.scaleX += (targetScale - cursor.scaleX) / (cursorDelay / 2);
cursor.scaleY = cursor.scaleX;
}
cursor.x = newX;
cursor.y = newY;
cursor.el.style.transform = `translate(${cursor.x}px, ${cursor.y}px) rotate(${toDegrees(angle)}deg) scale(${cursor.scaleX}, ${cursor.scaleY})`;
requestAnimationFrame(loop);
};
const angleBetween = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1);
const onPointerMove = (e) => {
if (!target.followMouse) {
return;
}
const pointer = (e.touches && e.touches.length) ? e.touches[0] : e;
const { clientX: x, clientY: y } = pointer;
target.x = x;
target.y = y;
};
const onPointerOver = (e) => {
const btn = e.target;
const rect = btn.getBoundingClientRect();
target.followMouse = false;
target.x = rect.left + (rect.width >> 1);
target.y = rect.top + (rect.height >> 1);
target.width = Math.max(rect.width, rect.height) + 50;
};
const onPointerOut = () => {
target.followMouse = true;
target.width = cursorWidth;
};
document.body.addEventListener('mousemove', onPointerMove);
document.body.addEventListener('touchmove', onPointerMove);
buttons.forEach((btn) => {
btn.addEventListener('touchstart', onPointerOver);
btn.addEventListener('mouseover', onPointerOver);
btn.addEventListener('touchend', onPointerOut);
btn.addEventListener('mouseout', onPointerOut);
});
loop();
const windowW = window.innerWidth;
const windowH = window.innerHeight;
const maxLength = Math.max(windowW, windowH);
const cursorWidth = 100;
const cursorR = cursorWidth >> 1;
const cursorDelay = 10;
const buttons = Array.from(document.querySelectorAll('.border-button'));
const cursor = {
el: document.querySelector('.border-cursor'),
x: windowW >> 1,
y: windowH >> 1,
scaleX: 1,
scaleY: 1,
};
const target = {
x: windowW >> 1,
y: windowH >> 1,
width: cursorWidth,
followMouse: true,
};
const norm = (val, max, min) => (val - min) / (max - min);
const toDegrees = r => r * (180 / Math.PI);
const distanceBetween = (v1, v2) => Math.sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y +- v2.y));
const loop = () => {
const destX = target.x - cursorR;
const destY = target.y - cursorR;
const newX = cursor.x + ((destX - cursor.x) / cursorDelay);
const newY = cursor.y + ((destY - cursor.y) / cursorDelay);
const angle = angleBetween(cursor.x, cursor.y, newX, newY);
if (target.followMouse) {
const distance = Math.abs(distanceBetween(target, cursor));
const scale = norm(distance, maxLength, cursorR);
cursor.scaleX = 1 + scale;
cursor.scaleY = 1 - scale;
} else {
const targetScale = target.width / cursorWidth;
cursor.scaleX += (targetScale - cursor.scaleX) / (cursorDelay / 2);
cursor.scaleY = cursor.scaleX;
}
cursor.x = newX;
cursor.y = newY;
cursor.el.style.transform = `translate(${cursor.x}px, ${cursor.y}px) rotate(${toDegrees(angle)}deg) scale(${cursor.scaleX}, ${cursor.scaleY})`;
requestAnimationFrame(loop);
};
const angleBetween = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1);
const onPointerMove = (e) => {
if (!target.followMouse) {
return;
}
const pointer = (e.touches && e.touches.length) ? e.touches[0] : e;
const { clientX: x, clientY: y } = pointer;
target.x = x;
target.y = y;
};
const onPointerOver = (e) => {
const btn = e.target;
const rect = btn.getBoundingClientRect();
target.followMouse = false;
target.x = rect.left + (rect.width >> 1);
target.y = rect.top + (rect.height >> 1);
target.width = Math.max(rect.width, rect.height) + 50;
};
const onPointerOut = () => {
target.followMouse = true;
target.width = cursorWidth;
};
document.body.addEventListener('mousemove', onPointerMove);
document.body.addEventListener('touchmove', onPointerMove);
buttons.forEach((btn) => {
btn.addEventListener('touchstart', onPointerOver);
btn.addEventListener('mouseover', onPointerOver);
btn.addEventListener('touchend', onPointerOut);
btn.addEventListener('mouseout', onPointerOut);
});
loop();

html,
body {
margin: 0;
padding: 0;
}
.wrapper {
width: 100vw;
min-height: 1500px;
display: flex;
flex-direction: row;
align-items: center;
}
.container {
width: 100%;
display: flex;
padding: 0 1rem;
}
.cursor {
position: absolute;
z-index: 10;
width: 100px;
height: 100px;
border: 2px solid #23bfa0;
border-radius: 50%;
pointer-events: none;
}
.button {
padding: 1rem;
background-color: #23bfa0;
border: none;
box-shadow: 0 0 7px 0px rgba(0, 0, 0, 0.2);
color: white;
font-size: 1.2rem;
cursor: pointer;
transition: box-shadow 0.1s ease-in, transform 0.1s ease-in;
&--small {
padding: 0.75rem;
font-size: 0.75rem;
}
&:hover {
transform: translate(0%, -2px);
box-shadow: 0px 4px 9px 2px rgba(0, 0, 0, 0.2)
}
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="cursor border-cursor"></div>
<div class="wrapper">
<div class="container">
<button class="button button--small border-button">small</button>
<button class="button border-button">hover me</button>
<button class="button border-button">hover me more</button>
</div>
</div>
</body>
&#13;
答案 0 :(得分:0)
在final List<Integer> integers = new List();
// Do whatever operations you want with the list
final List<Integer> integersInmutable = Collections.unmodifiableList(integers);
integers = null; // Better safe than sorry…
integersInmutable.add(1); // <- runtime exception
integersInmutable = new List(); // <- compiler error
中,尝试替换:
onPointerMove
使用:
const { clientX: x, clientY: y } = pointer;
这是一篇很好的帖子,解释了这些价值观之间的差异: https://stackoverflow.com/a/9335517/965834
另外,改变:
const { pageX: x, pageY: y } = pointer;
成:
target.x = rect.left + (rect.width >> 1);
target.y = rect.top + (rect.height >> 1);
这会在计算按钮位置时考虑滚动。
<强>演示强>:
target.x = window.scrollX + rect.left + (rect.width >> 1);
target.y = window.scrollY + rect.top + (rect.height >> 1);
&#13;
const windowW = window.innerWidth;
const windowH = window.innerHeight;
const maxLength = Math.max(windowW, windowH);
const cursorWidth = 100;
const cursorR = cursorWidth >> 1;
const cursorDelay = 10;
const buttons = Array.from(document.querySelectorAll('.border-button'));
const cursor = {
el: document.querySelector('.border-cursor'),
x: windowW >> 1,
y: windowH >> 1,
scaleX: 1,
scaleY: 1,
};
const target = {
x: windowW >> 1,
y: windowH >> 1,
width: cursorWidth,
followMouse: true,
};
const norm = (val, max, min) => (val - min) / (max - min);
const toDegrees = r => r * (180 / Math.PI);
const distanceBetween = (v1, v2) => Math.sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y +- v2.y));
const loop = () => {
const destX = target.x - cursorR;
const destY = target.y - cursorR;
const newX = cursor.x + ((destX - cursor.x) / cursorDelay);
const newY = cursor.y + ((destY - cursor.y) / cursorDelay);
const angle = angleBetween(cursor.x, cursor.y, newX, newY);
if (target.followMouse) {
const distance = Math.abs(distanceBetween(target, cursor));
const scale = norm(distance, maxLength, cursorR);
cursor.scaleX = 1 + scale;
cursor.scaleY = 1 - scale;
} else {
const targetScale = target.width / cursorWidth;
cursor.scaleX += (targetScale - cursor.scaleX) / (cursorDelay / 2);
cursor.scaleY = cursor.scaleX;
}
cursor.x = newX;
cursor.y = newY;
cursor.el.style.transform = `translate(${cursor.x}px, ${cursor.y}px) rotate(${toDegrees(angle)}deg) scale(${cursor.scaleX}, ${cursor.scaleY})`;
requestAnimationFrame(loop);
};
const angleBetween = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1);
const onPointerMove = (e) => {
if (!target.followMouse) {
return;
}
const pointer = (e.touches && e.touches.length) ? e.touches[0] : e;
const { pageX: x, pageY: y } = pointer;
target.x = x;
target.y = y;
};
const onPointerOver = (e) => {
const btn = e.target;
const rect = btn.getBoundingClientRect();
target.followMouse = false;
target.x = window.scrollX + rect.left + (rect.width >> 1);
target.y = window.scrollY + rect.top + (rect.height >> 1);
target.width = Math.max(rect.width, rect.height) + 50;
};
const onPointerOut = () => {
target.followMouse = true;
target.width = cursorWidth;
};
document.body.addEventListener('mousemove', onPointerMove);
document.body.addEventListener('touchmove', onPointerMove);
buttons.forEach((btn) => {
btn.addEventListener('touchstart', onPointerOver);
btn.addEventListener('mouseover', onPointerOver);
btn.addEventListener('touchend', onPointerOut);
btn.addEventListener('mouseout', onPointerOut);
});
loop();
&#13;
html,
body {
margin: 0;
padding: 0;
}
.wrapper {
width: 100vw;
min-height: 1500px;
display: flex;
flex-direction: row;
align-items: center;
}
.container {
width: 100%;
display: flex;
padding: 0 1rem;
}
.cursor {
position: absolute;
z-index: 10;
width: 100px;
height: 100px;
border: 2px solid #23bfa0;
border-radius: 50%;
pointer-events: none;
}
.button {
padding: 1rem;
background-color: #23bfa0;
border: none;
box-shadow: 0 0 7px 0px rgba(0, 0, 0, 0.2);
color: white;
font-size: 1.2rem;
cursor: pointer;
transition: box-shadow 0.1s ease-in, transform 0.1s ease-in;
&--small {
padding: 0.75rem;
font-size: 0.75rem;
}
&:hover {
transform: translate(0%, -2px);
box-shadow: 0px 4px 9px 2px rgba(0, 0, 0, 0.2)
}
}
&#13;