H5C3小功能案例分享

3D切割轮播图案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
body {
margin: 0;
}

.container {
width: 560px;
height: 300px;
/* background: green; */
margin: 100px auto;
/* 视距,体现近大远小的效果 */
/* 测试代码,不用时可注释
perspective: 800px;*/
position: relative;
}

.container ul {
width: 560px;
height: 300px;
margin: 0;
padding: 0;
list-style: none;
transform-style: preserve-3d;
/* 调节眼睛看到物体的位置 */
/* 如不需要旋转注释即可
transform: rotateX(-45deg); */
}

.container li {
/* 560/5=112 */
width: 112px;
height: 300px;
position: relative;
/* li是2D元素,要变成3D元素 */
transform-style: preserve-3d;
float: left;
transition: all 1s;
}

.container li span {
width: 112px;
height: 300px;
position: absolute;
left: 0;
top: 0;
}

.container .front {
background: skyblue;
transform: translateZ(150px);
background: url(images/q1.jpg) no-repeat;
/* 图片需要位移,否则一屏中只出现第一个li,每个宽度都是112
一张图片有五个面,每个面112px */
}

.container .back {
/* background: green; */
/* 一定要向后移动150度后,要顺时针旋转180度,才能在盒子外 */
transform: translateZ(-150px) rotateX(180deg);
background: url(images/q3.jpg) no-repeat;
}

.container .top {
/* background: blue; */
/* 只有往前走,显示内容的面,才能显示到盒子外面 */
transform: translateY(-150px) rotateX(90deg);
background: url(images/q2.jpg) no-repeat;
}

.container .bottom {
/* background: yellow; */
transform: translateY(150px) rotateX(-90deg);
background: url(images/q4.jpg) no-repeat;
}
/* 第一张立方体的4个面都是0所以不用调 */
/* 每一个立方体的四个面背景图片的位置信息都是一样的,所以就可统一设置 */
/* 从第二个立方体开始就要开始调位置 */
/* 要选择第二个li里的span */
/* 5个立方体的背景位置都是一样的 */

.container li:nth-child(2) span {
background-position: -112px;
}

.container li:nth-child(3) span {
background-position: -224px;
}

.container li:nth-child(4) span {
background-position: -336px;
}

.container li:nth-child(5) span {
background-position: -448px;
}

.btn {
width: 50px;
height: 50px;
position: absolute;
top: 50%;
transform: translateY(-50%);
background: rgba(25, 25, 25, 0.5);
color: #fff;
font-size: 40px;
line-height: 50px;
text-align: center;
/* 去除文本的下划线 */
text-decoration: none;
}

.prev {
left: 0;
}

.next {
right: 0;
}
</style>

<body>
<!-- container用来做布局的 -->
<div class="container">
<!-- ul是5个小立方体组成的大立方体 -->
<ul>
<!-- li是大立方体中小立方体 -->
<li>
<!-- span是行级元素,每个面默认情况下重叠,设置成定位了,就有了个块级元素的特性 -->
<span class="front"></span>
<span class="back"></span>
<span class="top"></span>
<span class="bottom"></span>
</li>

<li>
<span class="front"></span>
<span class="back"></span>
<span class="top"></span>
<span class="bottom"></span>
</li>

<li>
<span class="front"></span>
<span class="back"></span>
<span class="top"></span>
<span class="bottom"></span>
</li>

<li>
<span class="front"></span>
<span class="back"></span>
<span class="top"></span>
<span class="bottom"></span>
</li>

<li>
<span class="front"></span>
<span class="back"></span>
<span class="top"></span>
<span class="bottom"></span>
</li>
</ul>
<!-- javascript:;阻止a标签跳转 -->
<a href="javascript:;" class="btn prev" id="prev">&lt;</a>
<a href="javascript:;" class="btn next" id="next">&gt;</a>
</div>
<script>
var next = document.getElementById('next');
var prev = document.getElementById('prev');
var smallBox = document.querySelectorAll('li');
// 图片索引
var index = 0;
// 默认没有处于运动状态
var flag = false;
// 当点击下一个按钮的时候

next.onclick = function() {
// flag,阻止连续点击轮播按钮时,单击一次右键时来回切换的诡异事件,
if (flag == false) {
flag = true;
// 在旋转的过程中,每一个li的旋转角度一定要一样
index++;
// 在for循环执行第一次时已经获取到, 所以在下一次执行的时候则会节省性能
// 循环所有的立方体,
for (var i = 0, len = smallBox.length; i < len; i++) {
// 让立方体旋转,所以rotateX不能写死,否则只旋转一次
// 所以需要加上index++
// 此处 -index指的是就是-90度,
smallBox[i].style.transform = 'rotateX(' + index * -90 + 'deg)';
// 让每一个立方体依次延迟旋转
smallBox[i].style.transitionDelay = i * 0.2 + 's';
}
setTimeout(function() {
flag = false;
// 最后一次延迟的时间是1.2s,最后一次的运动时间1s
// 则1.2+1s=2.2(2200)加上这次的运动时间
}, 2200)
}
};
prev.onclick = function() {
if (flag == false) {
flag = true;
index--;
for (var i = 0, len = smallBox.length; i < len; i++) {
smallBox[i].style.transform = 'rotateX(' + index * -90 + 'deg)';
smallBox[i].style.transitionDelay = i * 0.2 + 's';
}
setTimeout(function() {
flag = false;

}, 2200)
}
};
</script>
</body>

</html>

立方体案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
body {
margin: 0;
}

.hello {
width: 400px;
height: 200px;
border: 1px solid red;
margin: 100px auto;
perspective: 800px;
}

.container {
width: 200px;
height: 200px;
margin: 100px auto;
background: red;
position: relative;
/* 使其子元素保留3D空间位置 ,让某一个盒子变成3D的,不再是一个平面*/
transform-style: preserve-3d;
/* 旋转45度 */
transform: rotateY(-45deg) rotateX(-20deg);
/* 如果不设置perspective,则看不到这个近大远小效果 */
/* perspective: 800px; */
}

.box {
width: 200px;
height: 200px;
background: green;
position: absolute;
left: 0;
top: 0;
}
/* 默认情况下,所有的面在3D空间的中间位置, */

.front {
background: red;
/* 前面的盒子往前走了100px; */
transform: translateZ(100px);
}

.back {
background: green;
/* 后面的盒子往后走了-100px,但是面在立方体里,
要沿着X轴顺时针旋转180度,在盒子外面 */
transform: translateZ(-100px) rotateX(180deg);
}

.top {
background: blue;
transform: translateY(-100px) rotateX(90deg);
}

.bottom {
background: yellow;
/* 逆时针旋转,面冲着外面旋转-90度 */
transform: translateY(100px) rotateX(-90deg);
}

.left {
background: pink;
transform: translateX(-100px) rotateY(-90deg);
}

.right {
background: purple;
transform: translateX(100px) rotateY(90deg);
}
</style>

<body>
<div class="hello">
<!-- 虽然元素处在模拟的3维空间,这是他的一个环境,
container这个盒子本身是一个平面,如果想让盒子为三维
则需要在container盒子设置transform-style:preserve-3d
(使其子元素保留3D空间位置) -->
<div class="container">
<div class="box front">front</div>
<div class="box back">back</div>
<div class="box top">top</div>
<div class="box bottom">bottom</div>
<div class="box left">left</div>
<div class="box right">right</div>
</div>
</div>


</body>

</html>

滚屏页面制作原理

布局

1
2
3
4
5
6
7
8
9
1. 当滑动鼠标滚轮的时候,需要每一屏最外层的盒子滚动 
2. 每一屏的高度需要是浏览器的可视区高度,高度是100%,而100%是相对单位,相对于父级的高度

.page=>#container=>body=>html{height:100%}

3.当滚动鼠标滚轮时,实际上需要使#container这个元素进行唯一translateY

位置计算:-index*一屏的高度

原生滚轮事件

兼容

1
2
在谷歌浏览器中,滚轮事件是 onmousewheel
在火狐浏览器中,滚轮 事件是 onDOMMouseScroll

jQuery提供的滚轮事件

1
2
3
4
5
6
7
8
9
10
11
12
需要引用jquery.mousewheel.min.js文件 
1.1为页面绑定滚轮事件 当鼠标滚动时,不出现滚动条进行滚动 document不加引号,是因为把他转为了jquery对象
$(Document).on('mousewheel',function(event,delta){ event 事件对象 delta 区分滚动方向的参数
console.log() })
2.区分方向 向上滚动delta=>1
向下滚动 delta=>-1
$(document).on('mousewheel',function(event,delta){ if(delta==1){
<!-- 向上滚动 -->
}else if(delta==-1){
<!-- 向下滚动 -->
} }) 注意: jQuery中animate中不支持transform,
自身没有高度和宽度的时候不能使用margin值,被其他子元素撑开也不可以,需要使用transform

小案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.mousewheel.min.js"></script>
<style type="text/css">
body, html {
margin: 0;
height: 100%;
overflow: hidden;
}

#container {
height: 100%;
transition: transform .7s;
}

.page {
height: 100%;
}

.page-1 {
background: skyblue;
}

.page-2 {
background: pink;
}

.page-3 {
background: green;
}

#point {
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
}

#point span {
width: 15px;
height: 15px;
display: block;
background: #FFF;
margin: 10px 0;
border-radius: 50%;
cursor: pointer;
}

#point .active {
background: red;
}
</style>
</head>
<body>

<div id="container">
<div class="page page-1"></div>
<div class="page page-2"></div>
<div class="page page-3"></div>
</div>

<div id="point"></div>

<script type="text/javascript">
/*
1.布局

1.当滑动鼠标滚轮的时候 需要每一屏最外层的盒子滚动

2.每一屏的高度需要是浏览器可视区的高度 高度是100%

而100%是相对单位 相对于父级的高度

.page => #container => body => html {height: 100%}

3.当滚动鼠标滚轮的时候 实际上需要使#container这个元素进行位移 translateY

位置计算 -index * 一屏的告诉

2.滚轮事件

在谷歌浏览器中 滚轮事件是 onmousewheel
在火狐浏览器中 滚轮事件是 onDOMMouseScroll

基于滚轮事件有非常大的兼容问题 所以此处我们不使用原生事件

我们需要使用jQuery提供的滚轮事件 需要引用 jquery.mousewheel.min.js文件

1.为页面绑定滚轮事件

$(document).on('mousewheel', function (event, delta) {
// event 事件对象
// delta 区分滚动方向的参数
});

2.区分方向

向上滚动 delta => 1
向下滚动 delta => -1

3.滚轮事件是怎么触发的?

当我们使用手指去滚动滚轮的时候 滚动是一下一下滚动的 每滚动一下 触发一次 滚动轮的事件处理函数


注意:jQuery中animate方法中不支持2d转换


*/

// 屏幕索引
var index = 0;

// 滚动元素
var container = $('#container');

// 导航点容器
var point = $('#point');

// 一屏的高度
var iHeight = $(window).height();

// 屏幕的个数
var size = container.children().length;

// 导航点的变量
var str = '';

// 循环屏幕个数
for (var i = 0; i < size; i++) {
// 根据屏幕个数创建导航点
str += '<span></span>'
}

// 将创建好的导航点span放置在页面的容器中
point.html(str);

// 滚动开关 false 没有处理滚动的状态
var flag = false;

$(document).on('mousewheel', function (event, delta) {

// 如果当前没有处于滚动状态
if (flag == false) {

flag = true;

if (delta == 1) {
// 向上滚动
index--;

// 限制滚动的范围
if (index < 0) {
index = 0;
}

// 让盒子滚动
container.css('transform', 'translateY('+-index * iHeight+'px)');

}else if (delta == -1) {
// 向下滚动
index++;

// 限制滚动的范围
if (index > size - 1) {
index = size - 1;
}

// 让盒子滚动
container.css('transform', 'translateY('+-index * iHeight+'px)');
}

// 更改导航点的选中状态
spans.eq(index).addClass('active').siblings().removeClass('active');

// 延迟的目的是需要等待 动画执行完成 再将状态变量恢复成false
setTimeout(function () {
flag = false;
}, 1000);

}

});

// 获取所有的导航点
var spans = point.children();
// 让第一个导航点处于选中状态
spans.eq(0).addClass('active');

// 当点击导航点的时候
spans.on('click', function () {

// 导航点的个数和屏幕的个数是一样的 所以他们的索引是对应的
index = $(this).index();

// 让盒子滚动
container.css('transform', 'translateY('+-index * iHeight+'px)');

// $(this).addClass('active').siblings().removeClass('active');

// 更改导航点的选中状态
spans.eq(index).addClass('active').siblings().removeClass('active');

});
</script>
</body>
</html>

H5C3小功能案例分享
http://www.dwyblog.cn/2021/02/11/H5C3小功能案例分享/
作者
幸福来敲门
发布于
2021年2月11日
许可协议