繁体   English   中英

使用 JavaScript 使用 hover 移动鼠标

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM