雪碧图并不陌生,将多张图片合在一起来减少请求数,从而提升网站的性能。在你的网站未支持 HTTP2 前,还是值得这么处理。
为了适应不同的设备分辨率,一般会做几套不同大小的图去适配,那如何用一套图来自适应缩放呢?
本文对等比缩放的雪碧图动画的原理进行分步讲解,并使用 gka 进行一键生成。
GitHub: https://github.com/gkajs/gka
原理剖析
当背景图片设置 background-size:100% 100% 时,百分比是以元素宽高为基准的,应用到雪碧图上会将整张雪碧图拉伸填充整个元素
虽然上面并不是我们希望的效果,但也可以发现设置了百分比后,背景图被拉伸填充整个元素且随着元素长宽而改变。所以只需再解决以下三个问题就能达到我们希望的自适应等比缩放。
- 元素只展示一张图片
- 能够指定展示某一张图
- 图片保持正常的长宽比 (不被拉伸)
元素只展示一张图片
雪碧图中,每张单图的宽高一致,设置 background-size: 100% 100% 后,可以看到上图元素展示区域中宽含 4 张图,高含有 5 张图,所以如果将雪碧图宽度 4 倍放大 (即每张图片宽度都 4 倍放大),此时元素在宽中将只能展示 1 张。同理,雪碧图的高放大 5 倍后,那么元素的展示就被一张图片填充满了。
1 2 |
background-size: 400% 500% |
所以,通过放大宽高对应的倍数设置 background-size,能让元素只展示一张图片。
能够指定展示某一张图
雪碧图可以通过调整 background-position 来展示不同区域。由于此时图片的具体大小未知,无法通过 px 直接定位出来。background-position 同样支持百分比,不同的是其百分比的值是根据元素宽高与背景图宽高计算得出的,公式如下
1 2 3 |
x百分比 = (x偏移量 / ((元素宽度 - 背景图片宽度) || 1)) * 100 + '%' y百分比 = (y偏移量 / ((元素高度 - 背景图片高度) || 1)) * 100 + '%' |
已知对 background-size 相应放大后,元素只展示一张图片,背景图片宽高为单图宽高倍数。所以,每张单图对应的位置百分比都可以通过对应 x、y 的偏移值和宽高来计算获得。
图片保持正常的长宽比
由于背景图片根据元素的宽高及进行填充展示,所以为了保持背景图片的正常宽高比,需要让元素的宽高比保持一致。元素 padding 设置的百分比是依据父容器的宽度计算的,padding-top/padding-bottom 也是如此,且 padding 能影响元素的展示区域。所以依据宽度来设置 padding-bottom 的百分比从而调整元素高度;另一方面,当元素的宽度为百分比时,同样是依据父容器的宽度计算的。
所以,保持元素的宽高比,只需要将 width 和 padding-bottom 按宽高比设置百分比即可。如单张图片的宽高比为 1: 2 时,只需要这样设置
1 2 3 4 5 6 |
.gka-base { width: 100%; height: 0; padding-bottom: 200%; } |
小结
通过以上一步步实践就可以做一个可自适应等比缩放的雪碧图帧动画了,大体有以下几个工作
- 将图片进行合图
- 计算 background-size 需要放大的倍数
- 计算单张图片的长宽比,设置元素的 width 和 padding-bottom
- 计算每一帧对应的 background-position
- 计算每个一帧对应的百分比
- 写代码 ( keyframes 等等)
gka 一键制作自适应等比缩放的雪碧图动画
使用 gka 仅一行命令,自动化完成以上所有工作。
1 2 |
gka imageDir -t percent |
gka 最终输出自适应的雪碧图帧动画套装:雪碧图、css 文件及预览文件。
欢迎试用 gka ,欢迎任何意见或建议,谢谢 :D
GitHub: https://github.com/gkajs/gka
mfkvfn 2017 年 8 月 21 日
“元素只展示一张图片” 中所有 background-position 应该改成 background-size
TAT.joeyguo 2017 年 8 月 21 日
已修正,多谢