效果链接
示例雪碧图如下,雪碧图图片资源来源于力扣官网中头像悬浮Dark Side功能。
雪碧图分析:该雪碧图横向为12等分,高度32px
1. JavaScript方式使用雪碧图(猜测力扣使用的方式就是这个)
(步骤一)html格式为div嵌套img,div设置宽高overflow设置为hidden隐藏超出宽度,img设置高度宽度自适应图片完全展示。(html代码如下)
<div class="mode javascript-mode">
<button>javascript测试</button>
<div style="width: 18px;height: 18px;overflow: hidden;">
<img style="height: 18px;" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-bf64a103-2eee-41c9-b4a7-57511d30e28e/a27b3cbc-432f-4200-9f77-5f2c3b22d0fb.png" />
</div>
</div>
(步骤二)Js代码编写,因设置宽高为18px,针对img使用translateX进行X轴平移即可实现效果,因12等分,为0时即展示的雪碧图第一张,所以循环11次就可以移动到雪碧图最后一张。(Js代码如下)
// javascript方式
let x = 0;
document.querySelector('.javascript-mode button').addEventListener('click', function() {
let mode = x == 0; // 变换模式
document.querySelector('.javascript-mode img').style.transform = `translateX(-${x}px)`;
let timer = setInterval(()=>{
x += mode ? 18 : -18;
document.querySelector('.javascript-mode img').style.transform = `translateX(-${x}px)`;
// 为0即展示的是第一块
// 雪碧图中存在12块 展示像素为18px 所以 18 * 11
if(x == 0 || x >= 18 * 11){
clearInterval(timer);
}
},50);
})
2. css方式使用雪碧图
(步骤一)css主要使用background方式实现,html部分设置一个div承载图片即可(html代码如下)
<div class="mode css-mode">
<button>css测试</button>
<div />
</div>
(步骤二)background 设置为雪碧图url,background-size:参数一为宽度因为雪碧图宽度无法固定设置为auto,高度设置为100%即为18px,background-position:参数一为x轴 参数二为y轴。(css代码如下)
.css-mode div{
width: 18px;
height: 18px;
background: url(https://vkceyugu.cdn.bspapp.com/VKCEYUGU-bf64a103-2eee-41c9-b4a7-57511d30e28e/a27b3cbc-432f-4200-9f77-5f2c3b22d0fb.png);
background-size: auto 100%;
background-position: 0% 0;
}
(步骤三)定义从做到右的动画,background-position从0%-100%,steps为播放分为几步完成动画,因雪碧图为12等分且为0时即为展示的第一张图所以这边设置为11,forwards动画播放完毕时保持动画的最后一帧。
@keyframes css-forward-move{
0%{ background-position: 0% 0; }
100%{ background-position: 100% 0; }
}
.css-mode div.forward-move{
background-position: 0% 0;
animation: css-forward-move 0.55s steps(11) forwards;
}
(步骤四)定义从右向左的反向动画,解释参照步骤三
.css-mode div.back-move{
background-position: 100% 0;
animation: css-back-move 0.55s steps(11) forwards;
}
@keyframes css-back-move{
0%{ background-position: 100% 0; }
100%{ background-position: 0% 0; }
}
(步骤五)定义js代码动态赋值类名来展示动画
document.querySelector('.css-mode button').addEventListener('click', function() {
let div = document.querySelector('.css-mode div')
div.className = div.className != 'forward-move' ? 'forward-move' : 'back-move';
})
完整Html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<style>
.mode{
padding: 30px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.mode button{
margin-bottom: 10px;
}
.css-mode div{
width: 18px;
height: 18px;
background: url(https://vkceyugu.cdn.bspapp.com/VKCEYUGU-bf64a103-2eee-41c9-b4a7-57511d30e28e/a27b3cbc-432f-4200-9f77-5f2c3b22d0fb.png);
background-size: auto 100%;
background-position: 0% 0;
}
.css-mode div.forward-move{
background-position: 0% 0;
/* forwards 动画保持最后一帧 */
animation: css-forward-move 0.55s steps(11) forwards;
}
.css-mode div.back-move{
background-position: 100% 0;
/* forwards 动画保持最后一帧 */
animation: css-back-move 0.55s steps(11) forwards;
}
@keyframes css-forward-move{
0%{ background-position: 0% 0; }
100%{ background-position: 100% 0; }
}
@keyframes css-back-move{
0%{ background-position: 100% 0; }
100%{ background-position: 0% 0; }
}
</style>
<body>
<div class="mode javascript-mode">
<button>javascript测试</button>
<div style="width: 18px;height: 18px;overflow: hidden;">
<img style="height: 18px;" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-bf64a103-2eee-41c9-b4a7-57511d30e28e/a27b3cbc-432f-4200-9f77-5f2c3b22d0fb.png" />
</div>
</div>
<div class="mode css-mode">
<button>css测试</button>
<div />
</div>
<script>
// javascript方式
let x = 0;
document.querySelector('.javascript-mode button').addEventListener('click', function() {
let mode = x == 0; // 变换模式
document.querySelector('.javascript-mode img').style.transform = `translateX(-${x}px)`;
let timer = setInterval(()=>{
x += mode ? 18 : -18;
document.querySelector('.javascript-mode img').style.transform = `translateX(-${x}px)`;
// 为0即展示的是第一块
// 雪碧图中存在12块 展示像素为18px 所以 18 * 11
if(x == 0 || x >= 18 * 11){
clearInterval(timer);
}
},50);
})
// css 方式
document.querySelector('.css-mode button').addEventListener('click', function() {
let div = document.querySelector('.css-mode div')
div.className = div.className != 'forward-move' ? 'forward-move' : 'back-move';
})
</script>
</body>
</html>