参考文档:Swiper中文网-轮播图幻灯片js插件,H5页面前端开发
标准地图来源:自然资源部地图技术审查中心承办的标准地图服务
想要了解和下载更多关于 标准地图 的内容,欢迎访问中国地图出版集团官网和中国地图出版集团官方微博
效果演示
滑动时,地图元素的位移和文字元素的位移偏差导致的视差效果
横屏时显示蒙版,锁定显示(文字其实应该是,“请竖屏观看”😓,懒得再录屏了)
代码分释
主要用的是 swiper.js
基本属性中的 parallax
项
官网说明如下
parallax
设置为true开启Swiper的视差效果,内容在切换时更有层次感。
效果可以应用于container或slide的子元素。当应用于container的子元素(常用于视差背景图),每次切换时视差效果仅有设定值的slide个数-1分之1
视差位移变化
在所需要的元素上增加data-swiper-parallax属性(与Swiper切换方向相同)或data-swiper-parallax-x (x方向) data-swiper-parallax-y(y方向)
data-swiper-parallax接受两种类型的参数。
- number(单位:px),如-300,从右边300px进入左边出去。
- percentage(百分比),移动距离=该元素宽度 * percentage。
配图解释下 data-swiper-parallax
参数设定的 视差位移变化
-
当视差设定在
slide
子元素上时
data-swiper-parallax
代表切换时,元素的起始定位(或者终止定位)
其中正数代表 从左往右(从上往下),负数代表从右往左(从下往上)
-
当视差设定在
container
子元素上时,常作为视差的背景图
data-swiper-parallax
设定的值代表 所有的slide
滑动后,背景图需要移动多少位移
-
当
data-swiper-parallax
为百分比的时候,其实是移动的像素距离,与当前元素宽度(高度)的比值
DOM 结构
<!-- 提示请竖屏观看 蒙版 -->
<div class="mask">
请竖屏观看
</div>
<div class="swiper-container">
<div class="swiper-title">
SWIPER PARALLAX SHOW PAGE
</div>
<div class="parallax-bg" data-swiper-parallax="-100%">
<img class="bg" src="assets/bg.jpg" width="100%" />
</div>
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="title" data-swiper-parallax="-1000">
<h3>长江经济带区域</h3>
<p>审图号:GS(2016)605号</p>
</div>
<div class="map" data-swiper-parallax="-100">
<img src="assets/map1.jpg" alt="长江经济带区域">
</div>
</div>
<div class="swiper-slide">
<div class="title" data-swiper-parallax="-1000">
<h3>京津冀都市圈</h3>
<p>审图号:GS(2016)1610号</p>
</div>
<div class="map" data-swiper-parallax="-100">
<img src="assets/map2.jpg" alt="京津冀都市圈">
</div>
</div>
<div class="swiper-slide">
<div class="title" data-swiper-parallax="-1000">
<h3>粤港澳大湾区</h3>
<p>审图号:GS(2019)4342号</p>
</div>
<div class="map" data-swiper-parallax="-100">
<img src="assets/map3.jpg" alt="粤港澳大湾区">
</div>
</div>
</div>
<div class="swiper-pagination"></div>
<div class="swiper-author">
Develop By Nora7aki
</div>
</div>
脚本代码
const parallaxBg = document.querySelector('.bg')
// animate动画执行方法
const animateCSS = (element, animation, prefix = '') =>
new Promise((resolve, reject) => {
const animationName = `${prefix}${animation}`;
const node = element.nodeType == 1 ? element : document.querySelector(element);
node.classList.add(`${prefix}animated`, animationName);
function handleAnimationEnd(event) {
event.stopPropagation();
node.classList.remove(`${prefix}animated`, animationName);
resolve('Animation ended');
}
node.addEventListener('animationend', handleAnimationEnd, { once: true });
});
// 图片点击事件
document.querySelectorAll('img').forEach(el => {
el.addEventListener('click', function () { animateCSS(this, 'heartBeat') })
})
// 检测竖屏状态
const isVertical = () => {
return window.orientation % 180 === 0
}
// 计算移动的位移
const setParallax = () => {
const mask = document.querySelector('.mask')
// 如果是横屏则蒙版
if (!isVertical()) {
mask.style.display = 'flex'
return
}
// 计算滚动百分比
mask.style.display = 'none'
let pt = (parallaxBg.height - window.innerHeight) / window.innerHeight * 100
document.querySelector('.parallax-bg').setAttribute('data-swiper-parallax', `-${pt}%`)
}
// 图片加载后 & resize事件
parallaxBg.onload = setParallax
window.addEventListener('resize', setParallax)
// 初始化swiper
var swiper = new Swiper('.swiper-container', {
speed: 600,
parallax: true,
direction: 'vertical',
pagination: {
el: '.swiper-pagination',
type: 'progressbar',
},
});
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="screen-orientation" content="portrait">
<title>Parallax demo</title>
<link href="https://cdn.bootcdn.net/ajax/libs/Swiper/6.4.14/swiper-bundle.min.css" rel="stylesheet">
<link href="https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/style.css">
</head>
<body>
<!-- 提示请竖屏观看 蒙版 -->
<div class="mask">
请竖屏观看
</div>
<div class="swiper-container">
<div class="swiper-title">
SWIPER PARALLAX SHOW PAGE
</div>
<div class="parallax-bg" data-swiper-parallax="-100%">
<img class="bg" src="assets/bg.jpg" width="100%" />
</div>
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="title" data-swiper-parallax="-1000">
<h3>长江经济带区域</h3>
<p>审图号:GS(2016)605号</p>
</div>
<div class="map" data-swiper-parallax="-100">
<img src="assets/map1.jpg" alt="长江经济带区域">
</div>
</div>
<div class="swiper-slide">
<div class="title" data-swiper-parallax="-1000">
<h3>京津冀都市圈</h3>
<p>审图号:GS(2016)1610号</p>
</div>
<div class="map" data-swiper-parallax="-100">
<img src="assets/map2.jpg" alt="京津冀都市圈">
</div>
</div>
<div class="swiper-slide">
<div class="title" data-swiper-parallax="-1000">
<h3>粤港澳大湾区</h3>
<p>审图号:GS(2019)4342号</p>
</div>
<div class="map" data-swiper-parallax="-100">
<img src="assets/map3.jpg" alt="粤港澳大湾区">
</div>
</div>
</div>
<div class="swiper-pagination"></div>
<div class="swiper-author">
Develop By Nora7aki
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/Swiper/6.4.14/swiper-bundle.min.js"></script>
<script>
const parallaxBg = document.querySelector('.bg')
// animate动画执行方法
const animateCSS = (element, animation, prefix = '') =>
new Promise((resolve, reject) => {
const animationName = `${prefix}${animation}`;
const node = element.nodeType == 1 ? element : document.querySelector(element);
node.classList.add(`${prefix}animated`, animationName);
function handleAnimationEnd(event) {
event.stopPropagation();
node.classList.remove(`${prefix}animated`, animationName);
resolve('Animation ended');
}
node.addEventListener('animationend', handleAnimationEnd, { once: true });
});
// 图片点击事件
document.querySelectorAll('img').forEach(el => {
el.addEventListener('click', function () { animateCSS(this, 'heartBeat') })
})
// 检测竖屏状态
const isVertical = () => {
return window.orientation % 180 === 0
}
// 计算移动的位移
const setParallax = () => {
const mask = document.querySelector('.mask')
// 如果是横屏则蒙版
if (!isVertical()) {
mask.style.display = 'flex'
return
}
// 计算滚动百分比
mask.style.display = 'none'
let pt = (parallaxBg.height - window.innerHeight) / window.innerHeight * 100
document.querySelector('.parallax-bg').setAttribute('data-swiper-parallax', `-${pt}%`)
}
// 图片加载后 & resize事件
parallaxBg.onload = setParallax
window.addEventListener('resize', setParallax)
// 初始化swiper
var swiper = new Swiper('.swiper-container', {
speed: 600,
parallax: true,
direction: 'vertical',
pagination: {
el: '.swiper-pagination',
type: 'progressbar',
},
});
</script>
</body>
</html>
/**
* 全屏通用 RESET 部分
*/
html, body {
position: relative;
height: 100%;
}
body {
background: #eee;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-size: 14px;
color: #000;
margin: 0;
padding: 0;
}
.swiper-container {
width: 100%;
height: 100%;
}
.swiper-slide {
text-align: center;
font-size: 18px;
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
/**
* 本例独用
*/
.parallax-bg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
-webkit-background-size: cover;
background-size: cover;
background-position: center;
}
.mask {
position: absolute;
height: 100%;
width: 100%;
z-index: 100;
/* text-align: center; */
align-items: center;
justify-content: center;
display: none;
background: #f2f2f2;
color: #333;
font-size: 32px;
}
.swiper-title {
top: 20px;
left: 0;
width: 100%;
position: absolute;
text-align: center;
-webkit-transition: .3s opacity;
-o-transition: .3s opacity;
transition: .3s opacity;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
z-index: 10;
}
.swiper-author{
bottom: 20px;
left: 0;
width: 100%;
position: absolute;
text-align: center;
-webkit-transition: .3s opacity;
-o-transition: .3s opacity;
transition: .3s opacity;
z-index: 10;
}
.title {
text-shadow: 0px 5px 5px #999;
position: absolute;
text-align: center;
left: 0;
top: 25%;
width: 100%;
}
.title h3 {
font-size: 30px;
font-weight: bold;
color: #f4645f;
}
.map {
position: absolute;
left: 0;
top: 50%
}
.map img {
box-shadow: 0px 5px 5px #999;
width: 50%;
border-radius: 50%;
border: 5px double #ccc;
}
码字不易,如果喜欢,不用三连,点个赞👍便是最大的鼓励
欢迎关注微信公众号 "书咖里的曼基康"