雪碧图 css 使用方式与 Js使用方式

584 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

示例雪碧图如下,雪碧图图片资源来源于力扣官网中头像悬浮Dark Side功能。

img.png

雪碧图分析:该雪碧图横向为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>