如何在光标到来时将按钮移近光标,并在光标离开时移动得更远
How to move a button near to cursor when cursor is coming and move a little more far when cursor is leaving
我正在尝试创建一个鼠标移动的小动画。当光标靠近按钮时,我称之为borderline - 距离按钮一定距离,按钮向光标方向移动。
这里我用 borderline 和 css 虚线显示了两个步骤,只是为了清楚和理解。
我通过计算按钮的中心点并减少和增加 x 轴和 y 轴的按钮宽度和高度,从代码中创建了最近的 borderline。
我想在我正在工作的同一过程中解决这个问题,而不是通过向按钮的 parent-elements
添加其他 event-listener
。
这是我试过的..
const button = document.querySelector(".button");
let { width, height, x: buttonX, y: buttonY } = button.getBoundingClientRect(); // gives you width, height, left-X,top-y of the button
buttonX = buttonX + width / 2; // center point of button on x-axis
buttonY = buttonY + height / 2; // center point of button on y-axis
/*************** Functions ***************/
let distance = width;
let mouseHasEntered = true;
let mouseIsInButtonTerritory;
function mouseMove(e) {
const x = e.x; // current x of cursor
const y = e.y; // current y of cursor
const leftBorderLine = buttonX - distance;
const rightBorderLine = buttonX + distance;
const topBorderLine = buttonY - distance;
const bottomBorderline = buttonY + distance;
const xWalk = (x - buttonX) / 2; // the distance to move the button when mouse moves on X axis
const yWalk = (y - buttonY) / 2; // the distance to move the button when mouse moves on Y axis
mouseIsInButtonTerritory =
x > leftBorderLine &&
x < rightBorderLine &&
y > topBorderLine &&
y < bottomBorderline; // becomes true if mouse is inside all of these border-line
if (mouseIsInButtonTerritory) {
if (mouseHasEntered) {
// this must happen only once to create outside borderline
//creating another level borderline by incresing distance;
// while cursor is returing the button comes out of nearest border-line and return from this borderline
distance = distance + distance;
mouseHasEntered = false;
}
catchCursor(xWalk, yWalk); // call the function when mouse in in the button's territory
} else {
resetPositon();
}
}
function catchCursor(xWalk, yWalk) {
// translates the button in the direction where cursor is.
button.style.transform = `translate(${xWalk}px, ${yWalk}px)`;
}
function resetPositon() {
// resets the postion of the button as it was initial.
button.style.transform = `translate([=10=]px, [=10=]px)`;
mouseHasEntered = true;
// when button is return to it's position (mouseHasEntered = true) lets to increase the initial borderline of button for the next time
}
/*************** Event-handler ***************/
window.addEventListener("mousemove", mouseMove);
window.addEventListener("mouseout", resetPositon);
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--gutter-lg: 4rem;
--gutter-md: 3rem;
--gutter-sm: 1rem;
--gutter-xm: 1rem;
--color-white: #fff;
--color-black: #000;
}
body {
background: var(--color-black);
font: 16px verdana;
color: var(--color-white);
}
.banner {
display: flex;
height: 100vh;
}
.button {
margin: auto;
cursor: pointer;
transition: all 0.2s ease-out;
}
.button-wrap-wrapper {
width: 192px;
height: 192px;
border: 1px dashed #fff;
margin: auto;
display: flex;
}
.button-wrap {
width: 128px;
height: 128px;
margin: auto;
/* background: orange; */
display: flex;
justify-content: center;
align-items: center;
border: 1px dashed #fff;
}
.button__like-text {
display: block;
color: var(--color-black);
background: var(--color-white);
width: var(--gutter-lg);
height: var(--gutter-lg);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
<section class="banner">
<div class="button-wrap-wrapper">
<div class="button-wrap">
<div class="button">
<span class="button__like-text">
Like
</span>
</div>
</div>
</div>
</section>
没有按预期工作的是:mouseIsInButtonTerritory
变为 true,我正在尝试增加 borderline
此处
if (mouseHasEntered) {
// this must happen only once to create outside borderline
//creating another level borderline by incresing distance;
// while cursor is returing the button comes out of nearest border-line and return from this borderline
distance = distance + distance;
}
按钮一直跟随光标。
我要解决的是,如果光标从两个 边界线 出来,按钮必须越过第一个 边界线 和接近最后一个 边界线 并返回初始阶段的位置。
我没有找到我做错的地方。有什么遗漏的吗?
如果我正确理解了您的意图,我认为您需要:
- 添加
buttonWrapWrapper
选择器
const button = document.querySelector(".button");
const buttonWrapWrapper = document.querySelector(".button-wrap-wrapper");
- 附加 事件侦听器到
buttonWrapWrapper
而不是 window
:
buttonWrapWrapper.addEventListener("mousemove", mouseMove);
buttonWrapWrapper.addEventListener("mouseout", resetPositon);
- 你应该在鼠标离开时重新设置距离。 (我不确定,只是猜测这就是你想要的,因为你在重置时写
mouseHasEntered = true
)
- 因为你自己处理鼠标离开(
else mouseIsInButtonTerritory
部分)不要听window。
const button = document.querySelector(".button");
let { width, height, x: buttonX, y: buttonY } = button.getBoundingClientRect(); // gives you width, height, left-X,top-y of the button
buttonX = buttonX + width / 2; // center point of button on x-axis
buttonY = buttonY + height / 2; // center point of button on y-axis
/*************** Functions ***************/
let distance = width;
let mouseHasEntered = true;
let mouseIsInButtonTerritory;
function mouseMove(e) {
const x = e.x; // current x of cursor
const y = e.y; // current y of cursor
const leftBorderLine = buttonX - distance;
const rightBorderLine = buttonX + distance;
const topBorderLine = buttonY - distance;
const bottomBorderline = buttonY + distance;
const xWalk = (x - buttonX) / 2; // the distance to move the button when mouse moves on X axis
const yWalk = (y - buttonY) / 2; // the distance to move the button when mouse moves on Y axis
mouseIsInButtonTerritory =
x > leftBorderLine &&
x < rightBorderLine &&
y > topBorderLine &&
y < bottomBorderline; // becomes true if mouse is inside all of these border-line
if (mouseIsInButtonTerritory) {
if (mouseHasEntered) {
// this must happen only once to create outside borderline
//creating another level borderline by incresing distance;
// while cursor is returing the button comes out of nearest border-line and return from this borderline
distance = distance + distance;
mouseHasEntered = false;
}
catchCursor(xWalk, yWalk); // call the function when mouse in in the button's territory
} else {
resetPositon();
}
}
function catchCursor(xWalk, yWalk) {
// translates the button in the direction where cursor is.
button.style.transform = `translate(${xWalk}px, ${yWalk}px)`;
}
function resetPositon() {
// resets the postion of the button as it was initial.
button.style.transform = `translate([=10=]px, [=10=]px)`;
if(!mouseHasEntered)distance/=2;
mouseHasEntered = true;
// when button is return to it's position (mouseHasEntered = true) lets to increase the initial borderline of button for the next time
}
/*************** Event-handler ***************/
window.addEventListener("mousemove", mouseMove);
//window.addEventListener("mouseout", resetPositon);
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--gutter-lg: 4rem;
--gutter-md: 3rem;
--gutter-sm: 1rem;
--gutter-xm: 1rem;
--color-white: #fff;
--color-black: #000;
}
body {
background: var(--color-black);
font: 16px verdana;
color: var(--color-white);
}
.banner {
display: flex;
height: 100vh;
}
.button {
margin: auto;
cursor: pointer;
transition: all 0.2s ease-out;
}
.button-wrap-wrapper {
width: 192px;
height: 192px;
border: 1px dashed #fff;
margin: auto;
display: flex;
}
.button-wrap {
width: 128px;
height: 128px;
margin: auto;
/* background: orange; */
display: flex;
justify-content: center;
align-items: center;
border: 1px dashed #fff;
}
.button__like-text {
display: block;
color: var(--color-black);
background: var(--color-white);
width: var(--gutter-lg);
height: var(--gutter-lg);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
<section class="banner">
<div class="button-wrap-wrapper">
<div class="button-wrap">
<div class="button">
<span class="button__like-text">
Like
</span>
</div>
</div>
</div>
</section>
我正在尝试创建一个鼠标移动的小动画。当光标靠近按钮时,我称之为borderline - 距离按钮一定距离,按钮向光标方向移动。
这里我用 borderline 和 css 虚线显示了两个步骤,只是为了清楚和理解。 我通过计算按钮的中心点并减少和增加 x 轴和 y 轴的按钮宽度和高度,从代码中创建了最近的 borderline。
我想在我正在工作的同一过程中解决这个问题,而不是通过向按钮的 parent-elements
添加其他 event-listener
。
这是我试过的..
const button = document.querySelector(".button");
let { width, height, x: buttonX, y: buttonY } = button.getBoundingClientRect(); // gives you width, height, left-X,top-y of the button
buttonX = buttonX + width / 2; // center point of button on x-axis
buttonY = buttonY + height / 2; // center point of button on y-axis
/*************** Functions ***************/
let distance = width;
let mouseHasEntered = true;
let mouseIsInButtonTerritory;
function mouseMove(e) {
const x = e.x; // current x of cursor
const y = e.y; // current y of cursor
const leftBorderLine = buttonX - distance;
const rightBorderLine = buttonX + distance;
const topBorderLine = buttonY - distance;
const bottomBorderline = buttonY + distance;
const xWalk = (x - buttonX) / 2; // the distance to move the button when mouse moves on X axis
const yWalk = (y - buttonY) / 2; // the distance to move the button when mouse moves on Y axis
mouseIsInButtonTerritory =
x > leftBorderLine &&
x < rightBorderLine &&
y > topBorderLine &&
y < bottomBorderline; // becomes true if mouse is inside all of these border-line
if (mouseIsInButtonTerritory) {
if (mouseHasEntered) {
// this must happen only once to create outside borderline
//creating another level borderline by incresing distance;
// while cursor is returing the button comes out of nearest border-line and return from this borderline
distance = distance + distance;
mouseHasEntered = false;
}
catchCursor(xWalk, yWalk); // call the function when mouse in in the button's territory
} else {
resetPositon();
}
}
function catchCursor(xWalk, yWalk) {
// translates the button in the direction where cursor is.
button.style.transform = `translate(${xWalk}px, ${yWalk}px)`;
}
function resetPositon() {
// resets the postion of the button as it was initial.
button.style.transform = `translate([=10=]px, [=10=]px)`;
mouseHasEntered = true;
// when button is return to it's position (mouseHasEntered = true) lets to increase the initial borderline of button for the next time
}
/*************** Event-handler ***************/
window.addEventListener("mousemove", mouseMove);
window.addEventListener("mouseout", resetPositon);
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--gutter-lg: 4rem;
--gutter-md: 3rem;
--gutter-sm: 1rem;
--gutter-xm: 1rem;
--color-white: #fff;
--color-black: #000;
}
body {
background: var(--color-black);
font: 16px verdana;
color: var(--color-white);
}
.banner {
display: flex;
height: 100vh;
}
.button {
margin: auto;
cursor: pointer;
transition: all 0.2s ease-out;
}
.button-wrap-wrapper {
width: 192px;
height: 192px;
border: 1px dashed #fff;
margin: auto;
display: flex;
}
.button-wrap {
width: 128px;
height: 128px;
margin: auto;
/* background: orange; */
display: flex;
justify-content: center;
align-items: center;
border: 1px dashed #fff;
}
.button__like-text {
display: block;
color: var(--color-black);
background: var(--color-white);
width: var(--gutter-lg);
height: var(--gutter-lg);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
<section class="banner">
<div class="button-wrap-wrapper">
<div class="button-wrap">
<div class="button">
<span class="button__like-text">
Like
</span>
</div>
</div>
</div>
</section>
没有按预期工作的是:mouseIsInButtonTerritory
变为 true,我正在尝试增加 borderline
此处
if (mouseHasEntered) {
// this must happen only once to create outside borderline
//creating another level borderline by incresing distance;
// while cursor is returing the button comes out of nearest border-line and return from this borderline
distance = distance + distance;
}
按钮一直跟随光标。
我要解决的是,如果光标从两个 边界线 出来,按钮必须越过第一个 边界线 和接近最后一个 边界线 并返回初始阶段的位置。
我没有找到我做错的地方。有什么遗漏的吗?
如果我正确理解了您的意图,我认为您需要:
- 添加
buttonWrapWrapper
选择器
const button = document.querySelector(".button");
const buttonWrapWrapper = document.querySelector(".button-wrap-wrapper");
- 附加 事件侦听器到
buttonWrapWrapper
而不是window
:
buttonWrapWrapper.addEventListener("mousemove", mouseMove);
buttonWrapWrapper.addEventListener("mouseout", resetPositon);
- 你应该在鼠标离开时重新设置距离。 (我不确定,只是猜测这就是你想要的,因为你在重置时写
mouseHasEntered = true
) - 因为你自己处理鼠标离开(
else mouseIsInButtonTerritory
部分)不要听window。
const button = document.querySelector(".button");
let { width, height, x: buttonX, y: buttonY } = button.getBoundingClientRect(); // gives you width, height, left-X,top-y of the button
buttonX = buttonX + width / 2; // center point of button on x-axis
buttonY = buttonY + height / 2; // center point of button on y-axis
/*************** Functions ***************/
let distance = width;
let mouseHasEntered = true;
let mouseIsInButtonTerritory;
function mouseMove(e) {
const x = e.x; // current x of cursor
const y = e.y; // current y of cursor
const leftBorderLine = buttonX - distance;
const rightBorderLine = buttonX + distance;
const topBorderLine = buttonY - distance;
const bottomBorderline = buttonY + distance;
const xWalk = (x - buttonX) / 2; // the distance to move the button when mouse moves on X axis
const yWalk = (y - buttonY) / 2; // the distance to move the button when mouse moves on Y axis
mouseIsInButtonTerritory =
x > leftBorderLine &&
x < rightBorderLine &&
y > topBorderLine &&
y < bottomBorderline; // becomes true if mouse is inside all of these border-line
if (mouseIsInButtonTerritory) {
if (mouseHasEntered) {
// this must happen only once to create outside borderline
//creating another level borderline by incresing distance;
// while cursor is returing the button comes out of nearest border-line and return from this borderline
distance = distance + distance;
mouseHasEntered = false;
}
catchCursor(xWalk, yWalk); // call the function when mouse in in the button's territory
} else {
resetPositon();
}
}
function catchCursor(xWalk, yWalk) {
// translates the button in the direction where cursor is.
button.style.transform = `translate(${xWalk}px, ${yWalk}px)`;
}
function resetPositon() {
// resets the postion of the button as it was initial.
button.style.transform = `translate([=10=]px, [=10=]px)`;
if(!mouseHasEntered)distance/=2;
mouseHasEntered = true;
// when button is return to it's position (mouseHasEntered = true) lets to increase the initial borderline of button for the next time
}
/*************** Event-handler ***************/
window.addEventListener("mousemove", mouseMove);
//window.addEventListener("mouseout", resetPositon);
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--gutter-lg: 4rem;
--gutter-md: 3rem;
--gutter-sm: 1rem;
--gutter-xm: 1rem;
--color-white: #fff;
--color-black: #000;
}
body {
background: var(--color-black);
font: 16px verdana;
color: var(--color-white);
}
.banner {
display: flex;
height: 100vh;
}
.button {
margin: auto;
cursor: pointer;
transition: all 0.2s ease-out;
}
.button-wrap-wrapper {
width: 192px;
height: 192px;
border: 1px dashed #fff;
margin: auto;
display: flex;
}
.button-wrap {
width: 128px;
height: 128px;
margin: auto;
/* background: orange; */
display: flex;
justify-content: center;
align-items: center;
border: 1px dashed #fff;
}
.button__like-text {
display: block;
color: var(--color-black);
background: var(--color-white);
width: var(--gutter-lg);
height: var(--gutter-lg);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
<section class="banner">
<div class="button-wrap-wrapper">
<div class="button-wrap">
<div class="button">
<span class="button__like-text">
Like
</span>
</div>
</div>
</div>
</section>