• 妙用 scale 与 transfrom-origin,精准控制动画方向


    上次发完 不可思议的纯 CSS 导航栏下划线跟随效果 这篇文章之后,很多朋友找我讨论,感叹 CSS 的奇妙。

    然后昨天,群里一位朋友问到了一个和这个效果比较类似的效果,问如何

    将下面这个动画的下划线效果,从左进入,右边离开修改为从上方进入,下方离开。

    描述很难理解,看看原本的效果:

    tsorigin

    难点所在

    第一眼看到这个效果,我的内心毫无波澜。以为只是简单的一个下划线 hover 效果,经过友人提醒,才发现,这个动画效果中,下划线是从一端进入,从另外一端离开的。而且,这个 hover 动画是纯 CSS 实现的。

    youqu

    先不考虑上面说的修改需求,先想一想,如果就是还原上述效果,仅仅使用 CSS,该如何做呢?

     

    还原效果

    嗯,正常而言,我们一个 hover 效果,可能就是从哪里来,回哪里去,大部分的应该是这样的:

    xxx

    现在,难点就在于如何在 hover 离开的时候,改变动画行进的方向。

    下面我们将一个 hover 动画分解为 3 个部分:

    1. hover 进入状态
    2. hover 停留状态
    3. hover 离开状态

    但是,对于一个 hover 效果而言,正常来说,只有初始状态,和hover状态两种。可能我们的代码是这样:

    div {
        xxxx...
    }
    
    div:hover {
        xxxx...
    }

    对于一个 hover transition 动画,它应该是从:

    • 正常状态 -> hover状态 -> 正常状态 (三个步骤,两种状态)

    所以,必须要有一种方法,能够使得 hover 动画的进入与离开产生两种不一样的效果,实现:

    • 状态1 -> hover状态 -> 状态2 (三个步骤,三种状态)

     

    实现控制动画方向的关键点

    所以,这里的关键点就在于(划重点):

    使得 hover 动画的进入与离开产生两种不一样的效果 。

    接下来,也就是本文的关键所在,使用 transform: scale() 以及 transform-origin 实现这个效果。

     

    transform: scale() 实现线条运动

    transform: scale 大家应该都很熟悉了,通俗来说是用于缩放,用官方的话说,就是:

    CSS 函数 scale() 用于修改元素的大小。可以通过向量形式定义的缩放值来放大或缩小元素,同时可以在不同的方向设置不同的缩放值。

    这里我们使用 transform: scaleX(0) 与 transform: scaleX(1) 来改变线条的显示与隐藏,它的 CSS 代码简单来看,可能是这样:

    div {
        position: absolute;
         200px;
        height: 60px;
    }
    
    div::before {
        content: "";
        position: absolute;
        left: 0;
        bottom: 0;
         200px;
        height: 2px;
        background: deeppink;
        transition: transform .5s;
        transform: scaleX(0);
    }
    
    div:hover::before {
        transform: scaleX(1);
    }

    scale

    嗯?为什么是要用 transform: scale() 来实现线条的动画?因为它可以配合 transform-origin 实现动画的不同运动方向:

     

    transform-origin 实现线条运动方向

    transform-origin 让我们可以更改一个元素变形(transform)的原点,transform-origin 属性可以使用一个,两个或三个值来指定,其中每个值都表示一个偏移量。 没有明确定义的偏移将重置为其对应的初始值。

    本效果最最最重要的地方就在于这里,我们使用 transform-origin 去改变 transform: scale() 的原点实现线条运动的方向。

    1. 我们给线条设置一个默认的 transform-origin 记为状态1
    2. hover 的时候,设置另外一个不同的 transform-origin, 记为状态2

    所以,当然我们 hover 的时候,会读取状态2的transform-origin,从该原点开始放大至 scaleX(1),hover 离开的时候,会读取状态1的transform-origin,从scaleX(1)状态缩小至该原点。

    嗯,CSS代码大概是这样:

    div {
        position: absolute;
         200px;
        height: 60px;
    }
    
    div::before {
        content: "";
        position: absolute;
        left: 0;
        bottom: 0;
         200px;
        height: 2px;
        background: deeppink;
        transition: transform .5s;
        transform: scaleX(0);
        transform-origin: 100% 0;
    }
    
    div:hover::before {
        transform: scaleX(1);
        transform-origin: 0 0;
    }

    这里,我们巧妙的通过 hover 状态施加了一层新的 transform-origin ,让动画的进入与离开产生了两种不同的效果,两个不同的方向。

    如此一来,也就顺利实现了我们想要的效果,撒花:

    torigin

    注意,这里使用了 transform-origin 去改变 transform: scale() 的原点实现线条运动的方向,而没有借助诸如 position 位移,transform: translate(),或者 margin 等位置属性去改变线条所在的位置。

    所以,有趣的是,线条其实没有产生过任何位移,这里其实也是障眼法,让它看上去,它好像在移动。 

     

    拓展延伸

    嗯,有了上述方法,也就是 transform: scale() 配合 transform-origin ,我们可以开始随意改变动画的初始与结束状态了。把他们运用到其他效果之上,简单的几个示意效果:

    othertraorigin

     

    值得注意的点

    还有几个点是比较有意思的,大家可以尝试尝试,思考思考:

    • 尝试改变两种状态的 transition-timing-function 缓动函数,可以让动画更加流畅具有美感;
    • 注意一下,线条的 transition 设置的是 transition: transform .5s 而不是 transition: all .5s,体验一下两种写法所产生的不同效果。

     

    最后

    本方法我个人最早见于 Css菜单悬停效果。如果你有更好的方法欢迎提出共同探讨。

    更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

    好了,本文到此结束,希望对你有帮助 :)

    如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

    我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3ly2fi88twowo

  • 相关阅读:
    901Air724UG模块(4G全网通GPRS开发)Air724UG(4G)使用SPI控制CH395Q(以太网模块)实现TCP/IP通信
    02STM32+MN316(NBIOT)基本控制篇(自建MQTT服务器)硬件使用说明
    Docker 清理none镜像 Prune命令
    Leetcode 252. 会议室 253. 会议室II 贪心算法扫描线技巧
    Leetcode 77. 组合(中等)回溯算法
    Leetcode 787. K 站中转内最便宜的航班(中等) 动态规划
    Leetcode 174. 地下城游戏(困难) 动态规划
    Linux arm环境下pip3安装av失败
    Leetcode 134. 加油站(中等) 贪心算法
    Leetcode 698. 划分为k个相等的子集(中等) 回溯算法=集合划分
  • 原文地址:https://www.cnblogs.com/coco1s/p/8882542.html
Copyright © 2020-2023  润新知