Fernando Basso
Fernando Basso

Reputation: 708

CSS cubic-bezier doesn't animate back to the original position

I have this somewhat simple animation. It does the animation just fine when hover over the target elements, but it doesn't transition back to the original position when the cursor hovers outside the target element. Rather, it just snaps back in one fell and ugly swoop. :)

<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>

And this is the 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%;
    }
}

What I don't understand is that the commented out animation (with easy-in) transitions back smootly, but the cubic-bezier one does not.

I don't know what is missing here. Here's a pen:

https://codepen.io/FernandoBasso/pen/XqrOpV?editors=1100

Upvotes: 3

Views: 409

Answers (2)

Taki
Taki

Reputation: 17654

you can reverse the cubic-bezier to achieve that :

( don't mind the javascript function it's there just to show how to reverse the 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>

Upvotes: 1

Sotiris
Sotiris

Reputation: 81

The reason is that in the following code

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

the values -100% send the divs too far away to see the reverse effect. Using -50% instead does what you want! :)

Check this out: https://codepen.io/sotmihos/pen/yjLqJK

Upvotes: 3

Related Questions