Skip to content

图片放大预览

html
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
		<style>
			img:hover {
				cursor: zoom-in;
			}
			* {
				margin: 0;
				padding: 0;
			}
			.asd {
				margin: 100px;
			}
		</style>
	</head>
	<body>
		<img src="https://xarzhi.gitee.io/nodeImgs/1.png" alt="" class="asd" />
		<img src="https://xarzhi.gitee.io/nodeImgs/1.png" alt="" class="asd" />
		<img src="https://xarzhi.gitee.io/nodeImgs/1.png" alt="" class="asd" />
		<img src="https://xarzhi.gitee.io/nodeImgs/1.png" alt="" class="asd" />
		<img src="https://xarzhi.gitee.io/nodeImgs/1.png" alt="" class="asd" />
		<script>
			const img = document.querySelectorAll('img')
            // 创建一个新img元素,并隐藏
			const copyImg = document.createElement('img')
			copyImg.style.display = 'none'
			img.forEach(item => {
				item.addEventListener('click', () => {
                    // 原来的img隐藏
					item.style.opacity = '0'
                    // 生成背景遮罩
					const cover = document.createElement('div')
					let scale = 1.5
					cover.style.position = 'fixed'
					cover.style.width = '100vw'
					cover.style.height = '100vh'
					cover.style.top = '0'
					cover.style.left = '0'
					cover.style.background = 'rgba(0,0,0,0.5)'
					document.body.appendChild(cover)
                    // 获取原img的位置,给新img设置一样的位置
					const rect = item.getBoundingClientRect()
					copyImg.src = item.src
					copyImg.style.display = 'block'
					copyImg.style.position = 'absolute'
					copyImg.style.top = `${rect.top}px`
					copyImg.style.left = `${rect.left}px`
					copyImg.style.transform = `translate(0,0) scale(${1})`
					// 设置新img从原位置到屏幕中间的动画
					const keyframs = new KeyframeEffect(
						copyImg,
						[
							{
								top: `${rect.top}px`,
								left: `${rect.left}px`,
								transform: `translate(0,0) scale(${1})`,
							},
							{
								top: `50%`,
								left: `50%`,
								transform: `translate(-50%,-50%) scale(${scale})`,
							},
						],
						{
							duration: 200,
						}
					)
					const ani = new Animation(keyframs)
					ani.play()
                    // 动画结束设置新img最后的位置
					ani.onfinish = () => {
						copyImg.style.top = '50%'
						copyImg.style.left = '50%'
						copyImg.style.transform = `translate(-50%,-50%) scale(${1.5})`
					}
                    // 取消滚动条默认行为
					cover.addEventListener('wheel', e => {
						e.preventDefault()
					})
                    // 鼠标滚动放大图片
					copyImg.addEventListener('wheel', e => {
						e.preventDefault()
						const ev = e || window.event
						let down = true // 定义一个标志,当滚轮向下滚时,执行一些操作
						down = ev.wheelDelta ? ev.wheelDelta < 0 : ev.detail > 0
						copyImg.style.transition = `all .3s`

						if (down) {
							if (scale < 1) return
							scale -= 0.1
							copyImg.style.transform = `translate(-50%,-50%) scale(${scale})`
						} else {
							if (scale > 3) return
							scale += 0.1
							copyImg.style.transform = `translate(-50%,-50%) scale(${scale})`
						}
					})
					// 点击关掉图片预览
					copyImg.addEventListener('click', () => {
						cover.remove()
						item.style.opacity = '1'
						copyImg.style.display = 'none'
						copyImg.style.transition = `none`
					})
					cover.appendChild(copyImg)
				})
			})
		</script>
	</body>
</html>

MIT Licensed