CSS cubic-bezier 不能将动画返回到原始位置

3

我有一个相对简单的动画。当鼠标悬停在目标元素上时,它可以正常进行动画,但是当鼠标悬停在目标元素外部时,它不会过渡回原始位置,而是突然且不美观地回到原来的位置。

<article class="anim">
    <a href="#foo">
        <img src="https://dummyimage.com/240x200/ff9900/fff.png&text=TADA" alt="foo">
        <span class="left">
            <img src="https://dummyimage.com/240x200/121212/fff&text=hey+you" alt="left">
        </span>
        <span class="right">
            <img src="https://dummyimage.com/240x200/000/fff&text=hey+you" alt="right">
        </span>
    </a>
</article>

以下是 scss 代码:

.anim {
    $w: 240px;
    $h: 200px;
    width: $w;
    height: $h;
    overflow: hidden;
    a {
        display: block;
        position: relative;
        width: 100%;
        height: 100%;
    }
    img {
        z-index: 1;
        position: absolute;
        width: $w;
        top: 0;
        left: 0;
    }
    span {
        display: block;
        height: 100%;
        width: 50%;
        position: absolute;
        z-index: 2;
        overflow: hidden;

        // This animation snaps back uglily.
        transition: all cubic-bezier(.29, 1.01, 1, -0.68) 0.5s;

        // This animation transitions back just fine...
        //transition: all 0.5s ease-in 0s;
    }

    .left {
        left: 0px;
    }
    .right {
        right: 0px;
        img {
            margin-left: -100%;
        }
    }

    a:hover > .left {
        left: -100%;
    }
    a:hover > .right {
        right: -100%;
    }
}

我不理解的是被注释掉的动画(使用easy-in)可以平滑地进行过渡,但是使用cubic-bezier的动画无法实现平滑过渡。我不知道这里缺少了什么。这是一个例子: https://codepen.io/FernandoBasso/pen/XqrOpV?editors=1100
2个回答

3
原因在于以下代码中:
a:hover > .left {
    left: -100%;
}
a:hover > .right {
    right: -100%;
}
数值-100%会将div推得太远而看不到反转效果。使用-50%可以达到你想要的效果! :)

我明白了。不过我自己从来没有得出那样的结论,因为如果它在“进入”的时候有效,我就认为它在“离开”的时候也必须有效。谢谢。 - Fernando Basso

1
你可以反转 cubic-bezier 来实现这个效果:
(不用在意 JavaScript 函数,它只是为了展示如何反转 cubic-bezier

function reverseCssCubicBezier(cubicBezier) {
    var maxX = Math.max(cubicBezier[0].x, cubicBezier[1].x, cubicBezier[2].x, cubicBezier[3].x);
    var maxY = Math.max(cubicBezier[0].y, cubicBezier[1].y, cubicBezier[2].y, cubicBezier[3].y);
    var halfUnitTurn = function(v) {
        var tx = maxX/2, ty = maxY/2;
        return { x: tx - (v.x-tx), y: ty - (v.y-ty) };
    };
    var revd = cubicBezier.map(halfUnitTurn);
    return revd.reverse();
}

var ease = [{x:0,y:0}, {x:0.29,y:1.01}, {x:1,y:-0.68}, {x:1,y:1}]; 
var ease_reversed = reverseCssCubicBezier(ease);
var ease_css_string = 'cubic_bezier(' + [ease[1].x, ease[1].y, ease[2].x, ease[2].y].join(', ') + ')';
var ease_reversed_css_string = 'cubic_bezier(' + [ease_reversed[1].x, ease_reversed[1].y, ease_reversed[2].x, ease_reversed[2].y].join(', ') + ')';

console.log('ease_css_string : ', ease_css_string)
console.log('ease_reversed_css_string : ', ease_reversed_css_string)
.anim {
  width: 240px;
  height: 200px;
  overflow: hidden;
}
.anim a {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
}
.anim img {
  z-index: 1;
  position: absolute;
  width: 240px;
  top: 0;
  left: 0;
}
.anim span {
  display: block;
  height: 100%;
  width: 50%;
  position: absolute;
  z-index: 2;
  overflow: hidden;
  transition: all cubic-bezier(0, 1.69, 0.71, 0) 0.5s; /* added */
}
.anim .left {
  left: 0px;
}
.anim .right {
  right: 0px;
}
.anim .right img {
  margin-left: -100%;
}
.anim a:hover > span {
  transition: all cubic-bezier(0.29, 1.01, 1, -0.68) 0.5s; /* added */
}
.anim a:hover > .left {
  left: -100%;
}
.anim a:hover > .right {
  right: -100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<article class="anim">
    <a href="#foo">
        <img src="https://dummyimage.com/240x200/ff9900/fff.png&text=TADA" alt="foo">
        <span class="left">
            <img src="https://dummyimage.com/240x200/121212/fff&text=hey+you" alt="left">
        </span>
        <span class="right">
            <img src="https://dummyimage.com/240x200/000/fff&text=hey+you" alt="right">
        </span>
    </a>
</article>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接