javascript - 悬停菜单效果和滚动

标签 javascript html css

我发现了一个 Codepen 的用户写的很棒的悬停菜单脚本,但是我遇到了我自己无法解决的问题。我希望这里的任何人都可以帮助我。我真的很感激。

问题是,如果我想添加使网站可滚动的内容,并且在我们将其向下滚动后固定的 Gooey 悬停效果应该坚持鼠标位置向下滚动,不再跟随鼠标指针。

代码

这里是 Codepen 的链接

HTML

<div id="menu">
    <div class="hamburger">
        <div class="line"></div>
        <div class="line"></div>
        <div class="line"></div>
    </div>
    <div class="menu-inner">

        <ul>
            <li>Menu Item</li>
            <li>Menu Item</li>
            <li>Menu Item</li>
            <li>Menu Item</li>
            <li>Menu Item</li>
            <li>Menu Item</li>
        </ul>
    </div>



    <svg version="1.1" id="blob"xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <path id="blob-path" d="M60,500H0V0h60c0,0,20,172,20,250S60,900,60,500z"/>
    </svg>
</div>

CSS

        body, html {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
        background-color:#26394E ;
    }

    #menu {
        height: 100%;
        position: fixed;
        background-color: #FED057;
        width: 300px;
        transition: 1000ms all cubic-bezier(0.19, 1, 0.22, 1);
        transform: translateX(-100%);
        left: 60px;
    }

    #menu.expanded {
        transform: translateX(0%);
        left: 0px;
    }

    .menu-inner {
        width: 100%;
        height: 100%;
        position: relative;
    }

    #blob {
        top: 0;
        z-index: -1;
        right: 60px;
        transform: translateX(100%);
        height: 100%;
        position: absolute;
    }

    #blob-path {
        height: 100%;
        fill:  #FED057;
    }

    .hamburger {
        right: 20px;
        position: absolute;
        width: 20px;
        height: 20px;
        margin-top: -10px;  
    }

    .hamburger .line {
        width: 100%;
        height: 4px;
        background-color: #fff;
        position: absolute;
    }

    .hamburger .line:nth-child(2) {
        top: 50%;
        margin-top: -2px;
    }

    .hamburger .line:nth-child(3) {
        bottom: 0;
    }

    h1 {
        position: fixed;
        right: 0;
        margin: 0;
    }

    ul {
        padding: 0;
        list-style: none;
        width: 80%;
        margin-left: 10%;
        position: absolute;
        top: 10px;
    }

    ul li {
        color: #fff;
        font-family: sans-serif;
        padding: 20px 0;
    }

    p {
        position: absolute;
       left: 10%;
  color: #fff;
        margin: 0;
  width: 500px;
  font-size: 16px;
  font-family: sans-serif;
  font-weight: 100;
    }

JS

$(window).load(function(){
var height = window.innerHeight,
x= 0, 
y= height/2,
curveX = 10,
curveY = 0,
targetX = 0,
xitteration = 0,
yitteration = 0,
menuExpanded = false;

blob = $('#blob'),
blobPath = $('#blob-path'),

hamburger = $('.hamburger');

$(this).on('mousemove', function(e){
    x = e.pageX;

    y = e.pageY;
});

$('.hamburger, .menu-inner').on('mouseenter', function(){
    $(this).parent().addClass('expanded');
    menuExpanded = true;
});

$('.menu-inner').on('mouseleave', function(){
    menuExpanded = false;
    $(this).parent().removeClass('expanded');
});

function easeOutExpo(currentIteration, startValue, changeInValue, totalIterations) {
    return changeInValue * (-Math.pow(2, -10 * currentIteration / totalIterations) + 1) + startValue;
}

var hoverZone = 150;
var expandAmount = 20;

function svgCurve() {
    if ((curveX > x-1) && (curveX < x+1)) {
        xitteration = 0;
    } else {
        if (menuExpanded) {
            targetX = 0;
        } else {
            xitteration = 0;
            if (x > hoverZone) {
                targetX = 0;
            } else {
                targetX = -(((60+expandAmount)/100)*(x-hoverZone));
            }           
        }
        xitteration++;
    }

    if ((curveY > y-1) && (curveY < y+1)) {
        yitteration = 0;
    } else {
        yitteration = 0;
        yitteration++;  
    }

    curveX = easeOutExpo(xitteration, curveX, targetX-curveX, 100);
    curveY = easeOutExpo(yitteration, curveY, y-curveY, 100);

    var anchorDistance = 200;
    var curviness = anchorDistance - 40;

    var newCurve2 = "M60,"+height+"H0V0h60v"+(curveY-anchorDistance)+"c0,"+curviness+","+curveX+","+curviness+","+curveX+","+anchorDistance+"S60,"+(curveY)+",60,"+(curveY+(anchorDistance*2))+"V"+height+"z";

    blobPath.attr('d', newCurve2);

    blob.width(curveX+60);

    hamburger.css('transform', 'translate('+curveX+'px, '+curveY+'px)');

$('h2').css('transform', 'translateY('+curveY+'px)');
    window.requestAnimationFrame(svgCurve);
}

window.requestAnimationFrame(svgCurve);
});

最佳答案

这里的问题是 pageY 是相对于 body 而不是相对于 window 的。

代替 countY 我在几个地方使用了 (y - window.scrollY) 并且它起作用了。

Javascript 代码在这里

$(window).load(function(){
    var height = window.innerHeight,
  x= 0, y= height/2,
    curveX = 10,
    curveY = 0,
    targetX = 0,
    xitteration = 0,
    yitteration = 0,
    menuExpanded = false;

    blob = $('#blob'),
    blobPath = $('#blob-path'),

    hamburger = $('.hamburger');

    $(this).on('mousemove', function(e){
        x = e.pageX - window.scrollX;

        y = e.pageY - window.scrollX;
    });

    $('.hamburger, .menu-inner').on('mouseenter', function(){
        $(this).parent().addClass('expanded');
        menuExpanded = true;
    });

    $('.menu-inner').on('mouseleave', function(){
        menuExpanded = false;
        $(this).parent().removeClass('expanded');
    });

    function easeOutExpo(currentIteration, startValue, changeInValue, totalIterations) {
        return changeInValue * (-Math.pow(2, -10 * currentIteration / totalIterations) + 1) + startValue;
    }

    var hoverZone = 150;
    var expandAmount = 20;

    function svgCurve() {
        if ((curveX > x-1) && (curveX < x+1)) {
            xitteration = 0;
        } else {
            if (menuExpanded) {
                targetX = 0;
            } else {
                xitteration = 0;
                if (x > hoverZone) {
                    targetX = 0;
                } else {
                    targetX = -(((60+expandAmount)/100)*(x-hoverZone));
                }           
            }
            xitteration++;
        }

        if ((curveY > y-1) && (curveY < y+1)) {
            yitteration = 0;
        } else {
            yitteration = 0;
            yitteration++;  
        }

        curveX = easeOutExpo(xitteration, curveX, targetX-curveX, 100);
        curveY = easeOutExpo(yitteration, curveY, y-curveY, 100);

        var anchorDistance = 200;
        var curviness = anchorDistance - 40;

        var newCurve2 = "M60,"+height+"H0V0h60v"+((y -  window.scrollY)-anchorDistance)+"c0,"+curviness+","+curveX+","+curviness+","+curveX+","+anchorDistance+"S60,"+(curveY)+",60,"+((y -  window.scrollY)+(anchorDistance*2))+"V"+height+"z";

        blobPath.attr('d', newCurve2);

        blob.width(curveX+60);
        hamburger.css('transform', 'translate('+curveX+'px, '+(y -  window.scrollY)+'px)');

    $('h2').css('transform', 'translateY('+curveY+'px)');
        window.requestAnimationFrame(svgCurve);
    }

    window.requestAnimationFrame(svgCurve);

});

关于javascript - 悬停菜单效果和滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41089030/

相关文章:

PHP 代码如果 url 的一部分包含 *this* 则执行 *this*

php - 如何使用ajax加载php文件。一些兼容性问题

Javascript 新函数对象与函数实例化

javascript - jquery circle-progress 中的动态颜色

javascript - 在浏览器调整大小之前,CanvasJs 图表不适合其容器

javascript - 将 2 个数组合并并交替为单个数组

html - 元素在不同屏幕上失去比例

javascript - 没有值的 VueJs 单选按钮会打开所有单选输入元素

html - 带有图像背景的无序列表,如果 1 或 2 行,则使其高度相同

javascript - 在容器中单击的位置创建 div