中秋国庆双节长假余额不足,不知大家这个假期过得怎么样?赶着假期的尾巴,抽空献上之前陈诺的教程,先来回顾下案例。

对于之前看过我SVG基础教程的同学,相信已经对固定宽度的SVG伸长动画结构和用法了然于胸,在这种结构中我们先将图文的宽度固定,然后通过等比例计算出图文的最终高度。

在固定宽度的图文动画中,为了适配不同设备屏幕,我们不得不将图文动画宽度设置为最小设备宽度,结果就会导致在一些宽屏手机设备上,图文左右两边会留有多余的空白区域,影响用户体验。

这次我们来学习一种自适应SVG图文动画排版方法,我会继续发扬授人以渔精神,剖析这种自适应方法的实现原理,让大家知其所以然,力求做到抛砖引玉。

自适应图文动画原理

要明白这种自适应图文动画的原理,我们先要引入一个叫做”替换元素”的概念。什么是替换元素呢?我们平时在图文排版中用到的<img>标签就是一种替换元素。

<img>标签这种替换元素的一个重要特性是:当我们只设置图片的宽度,浏览器会根据图片原始宽高比自动计算出图片的高度来显示;同样,当我们只设置图片的高度,图片的宽度会等比例缩放显示。

我们来做一个实验,将一张1000×1080的图片的宽度设置为200%,看看他的高度会发生什么变化。

<section style="overflow:hidden;">
  <img src="img/1000x1080.jpg" style="width:200%;">
</section>

通过chrome的移动端模拟器发现,当手机宽度是375像素宽度时,图片的高度变成了810像素,等比例缩放的计算方法是:375/(1000/1080)*200% = 810,由于我们没有设置父容器的高度,父容器的高度也被图片撑开变成810像素,因此我们只需要改变图片的宽度就能实现间接改变父容器高度的目的,这种图文伸长动画的原理就是如此简单。

图片的高度会随着宽度等比例缩放

用SVG标签实现自适应图文动画

与<img>标签类似,<svg>标签也有相似的替换元素特性。我们先通过viewBox属性设置svg标签的宽高来确定原始宽高比,然后通过style属性改变视口的宽度或者高度时,就能得到和<img>标签一样的效果,而这个<svg>标签我们可以将其视作伸长图文的触发器。

我们再来做个试验,通过<animate>标签动态改变触发器svg的宽度值,以达到伸长图文的目的。

下面的代码是简化后的版本,完整代码可以通过”阅读原文”获得。

<section style="overflow:hidden;">
  <section style="height:0;">
    <!-- 蓝色矩形 -->
    <svg viewBox="0 0 750 800"></svg>
    <!-- 绿色矩形 -->
    <svg viewBox="0 0 750 800"></svg>
  </section>
  <!-- 红色触发器矩形 -->
  <svg viewBox="0 0 750 500">
    <animate attributeName="width" 
      begin="click" 
      from="100%" 
      to="320%">
    </animate>
    <animate 
      attributeName="visibility" 
      begin="click" 
      from="visible" 
      to="hidden">
    </animate>
  </svg>
</section>

当触发器的宽度改变时,触发器的高度会根据原始比例等比例缩放,达到间接改变父容器高度的效果。

基于svg的自适应伸长动画

自适应伸长动画的高度计算

有些同学也许会问,原理我是懂了,但是触发器标签的宽度值是怎么确定的呢?其实很简单,我们只需要根据标签的原始比例来计算就可以。

以上面的代码为例,触发器svg的viewBox尺寸是750×500,伸长图文的总高度为1600(800+800),所以我们只要将宽度设置为1600/500=320%即可。

总结

聪明的你也许已经发现,这种自适应伸长动画的缺点,由于要改变触发器svg的尺寸,所以不适合在其中放置任何可视元素,否则会因为缩放变形,通常我们会选择在动画触发后立刻隐藏触发器。

对于基础薄弱的同学,后面我会专门录制一个视频教程,收录在我的SVG基础教程的实战部分,视频中会对案例中的代码进行更加详细的讲解。

有任何问题欢迎给我留言,或者在我们的微信交流群中和大家一起讨论。

关注