【问题标题】:Mouse move with hover using JavaScript使用 JavaScript 悬停鼠标移动
【发布时间】:2019-10-27 11:21:12
【问题描述】:

我试图在悬停在元素上时实现 this(使用 webflow 构建)动画和交互,但我无法做到。我在这里找到了this answer,但是当我尝试使用悬停功能对其进行重构时,我仍然无法使其工作。

这是我尝试过的。

// 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)');
        })

它有点笨拙,不像我想要实现的那样平滑,而且我希望它在不悬停时回到原来的位置。

【问题讨论】:

    标签: javascript jquery css


    【解决方案1】:

    我不太确定你真的会做更多的事情来使这个函数更流畅一点,因为它真的取决于 jQuery 本身执行其事件的频率。现在,也许我会考虑将 jQuery 事件声明中的所有代码拆分为它们各自的函数。对你来说工作会更容易、更干净:)

    function animateElementOnMouseMove() {
       // your translate code
    }
    function animateElementOnMouseHover() {
       // your initial hover animation code
    }
    $('.image-content-right').on('mousemove', animateElementOnMouseMove)
                             .on('hover', animateElementOnMouseHover);
    
    

    在您保存每个元素的原始未翻译位置之前,它可以返回到您的位置,或者,您可以将每个翻译保存到一个计数变量中,然后在之后“撤消”翻译元素变得没有焦点。

    喜欢:

    var elementTranslateCountX = 0;
    var elementTranslateCountY = 0;
    
    // ON TRANSLATE
    elementTranslateCountX += translateX;
    elementTranslateCountY += translateY;
    
    

    【讨论】:

      【解决方案2】:

      通过 webflow 事物的外观和感觉(如果我正确理解您的目标),您希望能够在悬停区域内将对象移动完整的 maxDeltaX/Y。如果是这种情况,您的数学需要进行一些调整:您需要定义一个原点(最有可能是移动对象的中心)并将原点周围的悬停区域标准化为 [-1, 1]。将对象放置在悬停框的死点可简化计算。我在 sn-p 中发布代码,但它应该在整页上运行,因为坐标计算不正确。有趣的是,如果我在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 上更流畅。我不确定 divs 和 css 是否是获得性能的最佳方式。 如果我对最终结果有误解,请多解释,我会尽力提供帮助。

      【讨论】:

      • 我们删除初始动画怎么样?当我将鼠标悬停在元素上时,它会下降很多。我只是想让它在悬停时移动一点
      • 我将所有内容都包装在一个 div 中,并在 onMove 函数中添加了相对坐标。现在它在 codepen 和 sn-p 中似乎可以正常工作,但据我所知,Safari 上的性能很糟糕
      猜你喜欢
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 2011-05-26
      • 2017-10-02
      • 2017-10-14
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多