你用的那些CSS转场动画可以换一换了

这篇文章发布于 2019年05月27日,星期一,00:04,归类于 CSS相关。 阅读 52540 次, 今日 4 次 24 条评论

 

现代浏览器转场动画占位图

一、传统的转场动画

传统转场动画就是滑来滑去,淡入淡出这些。

时代在召唤,技术在发展,可以试一试使用一些新的转场动画了。

二、规则的单个图形扩展动效

这里先介绍使用clip-path轻松实现转场动效。

只要不要兼容IE浏览器,clip-path的兼容性可以非常放心的使用。然后目前clip-path在实际项目中应用的时候,还需要加上-webkit-私有前缀,本文所有相关的演示代码主要是为了示意历,因此并没有加上,需要注意下。

1. 圆形效果

实时如下,可以看到每一个图片每4秒就圆形剪裁呈现,click或者hover小圆点可以快速体验切换效果:

呈现相关CSS代码如下:

.in {
    animation: clipCircleIn .6s;
}
@keyframes clipCircleIn {
    0%   {
        clip-path: circle(0 at 50% 50%);
    }
    100% {
        clip-path: circle(200px at 50% 50%);
    }    
}

使用的是clip-path中的circle方法,语法是:

circle(半径 at 圆心坐标)

圆心默认是50% 50%也就是元素的中心,因此,这里的css代码也可以简化成:

.in {
    animation: clipCircleIn .6s;
}
@keyframes clipCircleIn {
    0%   { clip-path: circle(0); }
    100% { clip-path: circle(200px); }    
}

原理很简单:动画0%开始时候圆的剪裁半径是0,于是整个图像元素都不可见;动画100%结束的时候,圆的剪裁半径是200像素,于是整个图像元素就可见了。clip-path属性是支持CSS animation动画的,因此可以看到一个图片元素从0到有,圆形呈现的效果。

使用也很简单,在需要呈现的元素上添加类名.in就可以了,不仅可以写在图片元素上,任意的<div>, 甚至整个<body>页面都可以。

完整代码,包括HTML和JavaScript可以狠狠地点击这里获取:CSS clip-path圆形转场动画demo

2. 三角效果

除了圆形,实现多边形的转场效果,例如三角形,实时效果如下:

相关CSS代码如下:

.in {
    animation: clipTriangleIn .6s;
}
@keyframes clipTriangleIn {
    0%   {
        clip-path: polygon(50% 50%, 49% 51%, 51% 51%);
    }
    100% {
        clip-path: polygon(50% -100%, -100% 150%, 200% 150%);
    }    
}

polygon方法可以用来剪裁多边形,其函数值就是一个一个的点坐标,最终呈现的图形就是这些点连起来的图形。更详细的内容可以参考我之前的文章:“CSS3 clip-path polygon图形构建与动画”,这里不展开。

这里使用的是百分比值,只要你的元素的高宽比例不是很悬殊,上面的CSS参数足矣应付,否则需要你自己调整一下三角形三个点的坐标位置,但有一点是肯定的,那就是这三个点一定需要在元素区域的外面,这样才能将整个图形元素剪裁在里面。

所使用的HTML和JavaScript代码和上面的圆形效果是一模一样的,下面的所有clip-path案例这部分代码也都是一样的啊,不一样的就是CSS。

可以狠狠地点击这里获取完整代码:CSS clip-path三角转场动画demo

3. 带圆角的矩形效果

效果如下:

这里的效果是借助clip-path中的inset方法。在clip-path的这个方法函数中,inset是最难理解的,因为和clip属性的rect()参数含义容易弄混淆,语法如下:

inset(距离元素上边缘距离 距离元素右边缘距离 距离元素下边缘距离 距离元素左边缘距离 round 圆角大小)

这里使用的CSS动画代码是:

.in {
    animation: clipRectIn .6s;
}
@keyframes clipRectIn {
    0%   {
        clip-path: inset(50% round 10% 50%);
    }
    100% {
        clip-path: inset(0% round 0);
    }    
}

inset()里面的距离参数可以是1~4个,圆角也是1~4个,且都支持百分比,非常强大。以上CSS代码适用于任何元素类似的转场效果,无需任何坐标参数调整。

可以狠狠地点击这里获取完整代码:CSS clip-path带圆角的矩形转场动画demo

4. 菱形效果

效果如下:

使用的是polygon方法绘制的四边形,相关CSS如下:

.in {
    animation: clipDiamondIn .6s;
}
@keyframes clipDiamondIn {
    0%   {
        clip-path: polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%);
    }
    100% {
        clip-path: polygon(50% -50%, 150% 50%, 50% 150%, -50% 50%);
    }    
}

和三角一样,最终的剪裁坐标需要在元素的外面。

可以狠狠地点击这里获取完整代码:CSS clip-path菱形钻石形转场动画demo

5. 十字星到矩形效果

我们还可以polygon()方法绘制更为复杂的图形,例如下面要展示的十字星扩展转场效果:

相关CSS如下:

.in {
    animation: clipRectSpIn .6s;
}
@keyframes clipRectSpIn {
    0%   {
        clip-path: polygon(50% 20%, 50% 50%, 20% 50%, 50% 50%, 50% 80%, 50% 50%, 80% 50%, 50% 50%);
    }
    100% {
        clip-path: polygon(50% 0%, 0% 0%, 0% 50%, 0% 100%, 50% 100%, 100% 100%, 100% 50%, 100% 0%);
    }
}

如果你想把这个demo效果用在自己的项目中,可以狠狠地点击这里复制完整代码:CSS clip-path十字星转场动画demo

6. 扇形展开效果

我们还可以给动画增加更多的关键点,而实现更丰富的动画效果,例如下面的扇形展开:

相关CSS如下:

.in {
    animation: clipSectorIn .6s linear;
}
@keyframes clipSectorIn {
    0%   {
        clip-path: polygon(50% 100%, 50% 0%, 0% 0%, 100% 0%, 50% 0%);
    }
    50% {
        clip-path: polygon(50% 100%, 0% 0%, 0% 0%, 100% 0%, 100% 0%);
    }
    100% {
        clip-path: polygon(50% 100%, 0% 100%, 0% 0%, 100% 0%, 100% 100%);
    }
}

您可以狠狠地点击这里:CSS clip-path扇形展开转场完整demo

三、不规则的单个图形扩展动效

不是所有的图形都能够使用clip-path绘制出来的,如果我们希望我们的这种过场动画里面所中展开这种图形更具有个性些,也是有方法可以实现的,就是借助CSS mask遮罩。

关于CSS遮罩,强烈推荐我之前爆肝写的这篇文章:“CSS遮罩CSS3 mask/masks详细介绍”。

这里我们直接进入效果。

1. 带圆角的五角星扩展

实时效果如下:

实现方法

准备一个五角星图像作为遮罩背景图,推荐使用SVG格式图像,例如下面这个:

五角星SVG图像

然后CSS动画代码这样(这里省略了mask-webkit私有前缀):

.in {
    mask: url(./star.svg) no-repeat center;
    mask-size: 300% 300%;    /* Safari没有这个类似“初始化”的东西居然无效 */
    animation: maskStarIn 1s both;
}
@keyframes maskStarIn {
    from { mask-size: 0 0; }
    to   { mask-size: 300% 300%; }
}

实现原理

很好理解,一开始通过设置mask-size属性让用来遮罩图像的尺寸是0,因此图像完全不可见;动画结束的时候,设置的遮罩尺寸足够大,图像完全显示,扩展动画效果即实现。

完整代码

您可以狠狠地点击这里获取完整代码:CSS mask星星转场动画demo

2. 爱心放大过场动画

既然使用图像作为扩展的形状,那我们可以实现的图形动画效果可以说是无限的,例如整一个爱心放大效果:

和五角星放大代码几乎一模一样,就使用的遮罩图形不同,这里使用的是这个:

爱心SVG图像

CSS代码:

.in {
    mask: url(./heart.svg) no-repeat center;
    mask-size: 200% 300%;    /* Safari没有这个类似“初始化”的东西居然无效 */
    animation: maskHeartIn 1s both;
}
@keyframes maskHeartIn {
    from { mask-size: 0 0; }
    to   { mask-size: 200% 300%; }
}

您可以狠狠地点击这里获取完整代码:CSS mask爱心转场动画demo

四、平铺图形的展示动效

上面介绍的都是单个图形的呈现效果,如果我想实现多个图形同时出现的效果,类似于百叶窗效果又该如何实现呢?

可以试试使用“变量种子计数器”实现。

1. 圆点百花齐放效果

实时效果如下,Chrome和Android下可见:

如果Safari等浏览器访问,可以点击这里在下方显示GIF录屏效果。

实现的原理其实并不难,关键是活用CSS变量,CSS代码如下(-webkit私有前缀省略):

.in {
    mask: radial-gradient(#000 calc(1% * var(--seed)), transparent calc(1% * var(--seed)));
    mask-size: 40px 40px;
    animation: seed 1s;
}
@keyframes seed {
    0%{--seed:0}1%{--seed:1}2%{--seed:2}3%{--seed:3}...98%{--seed:98}99%{--seed:99}100%{--seed:100}
}

也就是我们直接用CSS3 radial-graident绘制一个径向渐变,然后这个径向渐变的实色半径和变量--seed关联,而变量--seed通过animation关键帧的设置从0~100变化,于是,配合mask-size尺寸控制,最终形成了很小小圆圈一起绽放的转场效果。

如果对上面所说的原理还不是很理解,可以看看我之前一篇文章:“使用变量种子计数器扩展CSS动画更多可能性”。

您也可以狠狠地点击这里学习完整代码:CSS圆点绽放转场动画demo

2. 三角斜切效果

上面使用的是径向渐变,换成使用线性渐变可以有其他的效果,例如这个案例就是使用右上角45度的斜向渐变实现:

如果上面的图片slide效果没有酷酷的动效,可以点击这里在下方显示GIF录屏效果。

CSS代码如下(-webkit私有前缀省略):

.in {
    mask: linear-gradient(135deg, #000 calc(1% * var(--seed)), transparent calc(1% * var(--seed)));
    mask-size: 40px 40px;
    animation: seed .6s;
}
@keyframes seed {
    0%{--seed:0}1%{--seed:1}2%{--seed:2}...99%{--seed:99}100%{--seed:100}
}

原理和上面的圆点绽放效果是一样的,区别在于渐变的类型不同。

您可以狠狠地点击这里学习完整代码:CSS三角齐刷刷转场动画demo

3. 百叶窗效果

如果我们的线性渐变是水平方向的,则可以有百叶窗效果:

如果没有动效可以点击这里在下方显示录屏GIF。

CSS代码如下(-webkit私有前缀省略):

.in {
    mask: linear-gradient(to right, #000 calc(1% * var(--seed)), transparent calc(1% * var(--seed)));
    mask-size: 20px;
    animation: seed .6s;
}
@keyframes seed {
    0%{--seed:0}1%{--seed:1}2%{--seed:2}...99%{--seed:99}100%{--seed:100}
}

您可以狠狠地点击这里:CSS百叶窗效果转场动画demo

4. 车轮转动效果

这个是使用锥形渐变实现的效果。

如果没有动效可以点击这里在下方显示录屏GIF。

CSS代码如下(-webkit私有前缀省略):

.in {
    mask: conic-gradient(#000 calc(1% * var(--seed)), transparent calc(1% * var(--seed)));
    mask-size: 40px 40px;
    animation: seed .6s;
}
@keyframes seed {
    0%{--seed:0}1%{--seed:1}2%{--seed:2}...99%{--seed:99}100%{--seed:100}
}

您可以狠狠地点击这里:CSS车轮转场动画demo


由于mask的渐变背景也是支持无限累加的,因此,如果我们把背景图形进行多背景组合,不难想象还会有更多精彩的切换效果出现,这里就不一一展示。

五、其它尝试:滤镜与转场动效

除了clip-path剪裁和mask遮罩,我们还可以尝试使用filter实现一些转场切换效果,比如亮度、灰度、模糊等。

我专门做了demo页面给大家体验下,您可以狠狠的点击这里:CSS滤镜与图片切换动画demo

这个demo 3个滤镜效果三合一,您可以点击上方单选体验不同滤镜的切换效果:

图像亮度变化中

不过,对于这种幻灯片场景,使用滤镜实现的过场效果的舒适度还不如上面的图形切换。不过滤镜过场效果在有些场合还是挺有用的。例如在“CSS scroll-snap滚动事件停止及元素位置检测”这篇文章中的这个demo页面的灰度变化效果就很酷很合适,因为可以实时看到前后两个元素的状态变化。而这里的元素都是上下层叠,于是滤镜当开始动画的时候,原本的元素是看不见的,因此,视觉上的动画就不连贯,从而显得不舒服。

使用实现实现转场也很简单,拿亮度举例,CSS代码如下:

.in {
    animation: brightnessIn .6s;
}
@keyframes brightnessIn {
    0%   { filter: brightness(5); }
    100% { filter: brightness(1); }    
}

也就是从很亮变成正常亮度。

六、不仅仅是转场,显隐交互亦可

实际上本文介绍所有这些动画效果,不仅仅可以适用于转场,元素显示隐藏也是可以的使用这些动画效果的。

举个例子,弹框的出现,平时弹框出现,我们要么是淡入,要么是scale放大。现在,不妨试试“比心”呈现效果。

您可以狠狠地点击这里:dialog弹框爱心放大出现demo

点击页面的绿色按钮,就可以看到类似下图的弹框出现效果了:

爱心与弹框的出现

其他很多交互效果例如下拉框的出现,侧边栏的展开与收起,以及那种整页翻屏效果,都非常使用本文介绍的这些全新的转场动画,大胆使用吧。

七、关于密集型转场动效及结语

类似百叶窗,圆点绽放这样的密集型的平铺效果是最酷的,因为其他地方很少看到。但有个致命的问题那就是Safari浏览器目前并不支持“动画种子变量”,也就意味着苹果手机上没有动画效果。

但是这并不表示我们就无法使用,两种可行策略:

  • 一种是渐进增强,如果大家在Safari下访问过类似百叶窗这样的demo页面,会发现slide图片一个一个切换效果完全是正常的,就是没有动画而已,也就是功能完全正常,因此,我们是可以Chrome和Android设备酷酷的动画过场效果,Safari普通变化效果。
  • 一种是优雅降级。例如圆点绽放效果,Safari浏览器就借助mask-size动画实现一个圆点扩散效果,至于Chrome浏览器则可以很多个点点一起绽放,我们做一点浏览器的区别处理即可。

当然,我也会继续研究如何让Safari下也能实现平铺风格的转场动画效果的。

另外,本文所有的广告滚动相关代码都是原生语法,大家可以直接Copy去使用。本来想借助Shadow DOM把各个动画效果以Web Components形式集成,一看这时间点,算了算了,扛不住了,以后吧,总有机会的。

好,就说这么多,本文花费的时间出乎意料的长,因为整demo比较花时间,写了好几天。

总之,希望本文的内容能够对您的学习有所帮助,如果你觉得内容不错,也欢迎分享到各个群里面。

(本篇完)

分享到:


发表评论(目前24 条评论)

  1. 罗杰说道:

    SVG也有clip-path,请问这些效果是不是也可以用SVG来实现呢?

  2. renmu说道:

    为什么百叶窗效果上下就不行呢?

  3. Ray说道:

    PPT既视感 捂脸.jpg

  4. NidhoggDJoking说道:

    大人时代变了

  5. asdfq说道:

    当年IE不知道人们对jQuery UI的转场会怎么想。现在丢掉了一堆框架,效果更花()

  6. 芬达说道:

    本节的图片都报错,不显示了

  7. 小白说道:

    在第一个动画中
    eleZxxSlides.forEach(function(container) {
    也可以实现功能,为什么还要用
    [].slice.call(eleZxxSlides).forEach(function(container) {

  8. 路过的说道:

    是我操作问题吗?怎么把三个东西复制到对应的代码框,然后改了一下图片。进入点击没效果的?

  9. CC说道:

    重点还是IE…

  10. 129138说道:

    不得不说好像不怎么好看。

  11. 路人甲说道:

    每次来绝不会空手而归,抱拳.jpg

  12. wingmeng说道:

    壮哉我大CSS!把 Power Point 上的转场效果都实现了个遍

  13. DeathGhost说道:

    高手,高手,高高手!
    — 菜鸟路过!

  14. mengkun说道:

    看到这些切换效果,仿佛又回到了 flash 时代。哈哈

  15. updown说道:

    最后一个弹框的示例链接放错了

  16. zwing说道:

    dialog弹框爱心放大出现demo
    地址错了

  17. 0x11说道:

    这几个都是ie6时代梦寐以求的效果

  18. simplified说道:

    dialog弹框爱心放大出现demo 链接是不是有误