[英]Mouse move with hover using JavaScript
我试图实现这一点(使用 webflow 构建)animation 和悬停在元素上时的交互,但我无法这样做。 我在这里找到了这个答案,但是当我尝试在 hover function 上重构它时,我仍然无法让它工作。
这是我尝试过的。
// Maximum offset for image
var maxDeltaX = 50,
maxDeltaY = 50,
viewportWidth = 0,
viewportHeight = 0,
mouseX = 0,
mouseY = 0,
translateX = 0,
translateY = 0;
// Bind mousemove event to document
jQuery('.image-content-right').on('mousemove', function(e) {
// Get viewport dimensions
viewportWidth = document.documentElement.clientWidth,
viewportHeight = document.documentElement.clientHeight;
// Get relative mouse positions to viewport
// Original range: [0, 1]
// Should be in the range of -1 to 1, since we want to move left/right
// Transform by multipling by 2 and minus 1
// Output range: [-1, 1]
mouseX = e.pageX / viewportWidth * 2 - 1,
mouseY = e.pageY / viewportHeight * 2 - 1;
// Calculate how much to transform the image
translateX = mouseX * maxDeltaX,
translateY = mouseY * maxDeltaY;
jQuery('.cyan').css('transform', 'translate(' + translateX + 'px, ' + translateY + 'px)');
jQuery('.small-cyan').css('transform', 'translate(' + translateX + 'px, ' + translateY + 'px)');
jQuery('.small-darktangirine').css('transform', 'translate(' + translateX + 'px, ' + translateY + 'px)');
}).hover(function() {
jQuery('.cyan').css('transform', 'translate(' + translateX + 'px, ' + translateY + 'px)');
jQuery('.small-cyan').css('transform', 'translate(' + translateX + 'px, ' + translateY + 'px)');
jQuery('.small-darktangirine').css('transform', 'translate(' + translateX + 'px, ' + translateY + 'px)');
})
它有点笨拙,不像我想要实现的那样平滑,而且我希望它在不悬停时将 go 恢复到原来的 position。
我向您介绍...有史以来最混乱(但有效)的代码!
我想我可以通过向要移动的元素添加几个类来让它工作,并跟踪鼠标是否悬停在图像上。
首先,当鼠标悬停在图像上时,跟踪 state,并删除一些表示元素被翻译的类。
let hover = false;
$(".image-content-right").hover(
() => {
hover = true;
$(".cyan").removeClass("translated");
$(".small-cyan").removeClass("translated");
$(".small-darktangirine").removeClass("translated");
},
() => (hover = false)
);
现在您知道鼠标何时悬停在 img 上,您可以使用该信息来决定何时翻译图像。
$(document).on("mousemove", function(e) {
// If the mouse if currently hovering the image
if (hover) {
(viewportWidth = document.documentElement.clientWidth),
(viewportHeight = document.documentElement.clientHeight);
(mouseX = (e.pageX / viewportWidth) * 2 - 1),
(mouseY = (e.pageY / viewportHeight) * 2 - 1);
(translateX = mouseX * maxDeltaX),
(translateY = mouseY * maxDeltaY);
// Translate the elements
jQuery(".cyan").css(
"transform",
"translate(" + translateX + "px, " + translateY + "px)"
);
jQuery(".small-cyan").css(
"transform",
"translate(" + translateX + "px, " + translateY + "px)"
);
jQuery(".small-darktangirine").css(
"transform",
"translate(" + translateX + "px, " + translateY + "px)"
);
} else {
// If the mouse is no longer hovering the image, add a class that
// adds a smooth transition to the elements, and translate them back
$(".cyan")
.addClass("translated")
.css("transform", "translate(" + 0 + "px, " + 0 + "px)");
$(".small-cyan")
.addClass("translated")
.css("transform", "translate(" + 0 + "px, " + 0 + "px)");
$(".small-darktangirine")
.addClass("translated")
.css("transform", "translate(" + 0 + "px, " + 0 + "px)");
}
});
为了平滑过渡回原来的 position(而不是立即恢复),我为transform
class 添加了一些过渡样式。
.translated {
/* This will make the transition back to the original spot smooth */
transition-duration: 0.2s;
transition-timing-function: linear;
}
我希望这对你有用,我很抱歉它太乱了。
我不太确定你真的会做更多的事情来使 function 更平滑一点,因为它真的取决于 jQuery 本身执行其事件的频率。 现在,也许我会考虑将 jQuery 事件声明中的所有代码拆分为各自的函数。 你的工作会更容易和更干净:)
function animateElementOnMouseMove() {
// your translate code
}
function animateElementOnMouseHover() {
// your initial hover animation code
}
$('.image-content-right').on('mousemove', animateElementOnMouseMove)
.on('hover', animateElementOnMouseHover);
让它返回到您拥有的 position 之前,您可以保存每个元素的原始未翻译 position 或者,您可以将每个翻译保存到一个计数变量中,然后在元素具有变得注意力不集中。
喜欢:
var elementTranslateCountX = 0;
var elementTranslateCountY = 0;
// ON TRANSLATE
elementTranslateCountX += translateX;
elementTranslateCountY += translateY;
通过 webflow 的外观和感觉(如果我正确理解您的目标),您希望能够在 hover 区域内将 object 移动完整的 maxDeltaX/Y。 如果是这种情况,您的数学需要进行一些调整:您需要定义一个原点(最有可能是移动 object 的中心)并将原点周围的 hover 区域标准化为 [-1, 1]。 将 object 放置在 hover 框的死点可简化计算。 我将代码发布在一个片段中,但它应该在整页上运行,因为坐标计算不正确。 有趣的是,如果我在codepen上运行它,它可以在 Chrome 上按预期工作,但在 Safari 上却不行。 为避免此问题,您应该将所有内容包装在父 div 中并计算相对于它的坐标
const page = document.getElementById("page-id"); const area = document.getElementById("area-id"); const box = document.getElementById("box-id"); // we want to move the object by 50px at most const maxDeltaX = 50; const maxDeltaY = 50; let pageBox = page.getBoundingClientRect(); let pageTopLeft = { x: pageBox.x, y: pageBox.y }; let areaBox = area.getBoundingClientRect(); let areaRange = { w: areaBox.width / 2.0, h: areaBox.height / 2.0 }; let boxBox = box.getBoundingClientRect(); let transformOrigin = { x: boxBox.x + (boxBox.width / 2.0), y: boxBox.y + (boxBox.height / 2.0) }; // multipliers allow the full delta displacement within the hover area range let multX = maxDeltaX / areaRange.w; let multY = maxDeltaY / areaRange.h; area.addEventListener("mousemove", onMove); area.addEventListener("mouseleave", onLeave); window.addEventListener("resize", onResize); // mouse coords are computed wrt the wrapper top left corner and their distance from the object center is normalized function onMove(e) { let dx = (((e.clientX - pageTopLeft.x) - transformOrigin.x)); let dy = (((e.clientY - pageTopLeft.y) - transformOrigin.y)); box.style.transform = "translate3d(" + (dx * multX) + "px, " + (dy * multY) + "px, 0)"; /* // or you can add some fancy rotation as well lol let rotationDeg = Math.atan2(dy,dx) * (180/Math.PI); let rotationString = "rotate(" + rotationDeg + "deg)"; box.style.transform = "translate3d(" + (dx * multX) + "px, " + (dy * multY) + "px, 0) " + rotationString; */ } function onLeave(e) { box.style.transform = "translate3d(0, 0, 0)"; } function onResize(e) { // redefine all the "let" variables }
* { margin: 0; padding: 0; }.page { position: relative; width: 100%; height: 100vh; background-color: #ddd; display: grid; place-items: center; }.hover-area { position: relative; width: 50%; height: 100%; background-color: #888; }.box { position: absolute; left: calc(50% - 25px); top: calc(50% - 25px); width: 50px; height: 50px; border-radius: 25px; background-image: linear-gradient(45deg, #000, #aaa); transform: translate3d(0, 0, 0); transition: all 0.2s; will-change: transform; }
<div id="page-id" class="page"> <div id="area-id" class="hover-area"> <div id="box-id" class="box" /> </div> </div>
请注意,它在 Chrome 上比在 Safari 上运行更流畅。 我不确定 div 和 css 是 go 的最佳方式。 如果我误解了最终结果,请解释更多,我会尽力提供帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.