标题中说的苹果动效指的是https://www.apple.com.cn/ipad-pro/中雷达摄像头的进入效果

当然苹果的网站上存在着大量的视差动效,这里为了实现这个摄像头的效果

于是根据以往的思路,首先看一下网页的代码是怎么样写的,进而应该能分析出来了。。这样想着,我打开了F12开发者工具。。

结果您猜怎么着,页面上动效全部消失了。。。

不知道是不是苹果做了限制,防止自家技术太快别别人模仿?

不过这难不倒我,既然Elements部分看不了,那我可以看Source部分吧。。

其实看到这个效果,我想的是通过滚动条控制视频前后播放

结果看到网站资源部分我发现了苹果的秘密,原来这个摄像头的效果,是73张图片切换构成的。。

对,你没有看错,他就是那么多张图片切换以达到的效果。。。

那就好办了(虽然我还什么都不会,但是又可以询问google老师啊

于是先弄素材,最快的方式就是写个爬虫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# %% 清除控制台输出的内容
import sys
import os
def clear_output():
"""
clear output for both jupyter notebook and the console
"""
os.system('cls' if os.name == 'nt' else 'clear')
if 'ipykernel' in sys.modules:
from IPython.display import clear_output as clear
clear()

# %% 下载所有头像到本地计算机
import requests
# %%
url = "https://www.apple.com.cn/105/media/us/ipad-pro/2020/7be9ce7b-fa4e-4f54-968b-4a7687066ed8/anim/depth-sensor/large/large_00"
# %%
for i in range(1, 74):
with open('./img/large_00{0}.jpg'.format(str(i) if i > 10 else "0" + str(i)), 'wb') as file:
file.write(requests.get(url+'{0}.jpg'.format(str(i) if i > 10 else "0"+str(i))).content)
clear_output()
print("pic:"+str(i)+"\t图片下载完成")
print("全部完成")

图片到手之后,开始构思。。

接着看苹果的代码,发现是直接展示了73张图片,然后通过js切换图片的display属性,这个简单。

然后还需要做到当切换图片的时候,图片位置不能改变,因此需要用到position:sticky;这个属性(也是我现学现卖的)

那么就可以开始写了。

之前的版本

先把js写了

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
var nowPic = 1;
var flag = 0;
var childElementCount;

function MouseWheel(e) {
if (document.getElementById("picBox")) {
childElementCount = document.getElementById("picBox").childElementCount;
// document.getElementById("picBox").style.height= document.getElementById("picBox").children[0].style.height*childElementCount;
} else if (document.getElementById("picBox-FixUp")) {
childElementCount = document.getElementById("picBox-FixUp").childElementCount;
// document.getElementById("picBox-FixUp").style.height= document.getElementById("picBox-FixUp").children[0].style.height*childElementCount;

}
// else if(document.getElementById("picBox-FixDown"))childElementCount = document.getElementById("picBox-FixDown").childElementCount;
e = e || window.event;
for (i = 1; i < childElementCount + 1; i++) {
// console.log(i);
if (i == nowPic) {
if (e.wheelDelta || e.detail) { //IE
document.getElementById("pic" + i).style.display = "block";
}
} else {
document.getElementById("pic" + i).style.display = "none";
}
}
flag = (flag + 1) % 2; // 我的电脑鼠标滚轮一次滚动两行,因此做一个限制
if (flag == 0) {
if (e.wheelDelta < 0 || e.detail < 0) { // 正向播放
if (nowPic == childElementCount) {
if (document.getElementById("picBox-FixUp")) document.getElementById("picBox-FixUp").id = 'picBox';
} else {
nowPic++;
if (document.getElementById("picBox")) document.getElementById("picBox").id = 'picBox-FixUp';
// else if(document.getElementById("picBox-FixDown")) document.getElementById("picBox-FixDown").id = 'picBox-FixUp';
}
}
// else if(e.wheelDelta > 0 || e.detail > 0){ // 反向播放
// if (nowPic == 1){
// if(document.getElementById("picBox-FixDown")) document.getElementById("picBox-FixDown").id = 'picBox';
// }
// else {
// nowPic--;
// if(document.getElementById("picBox")) document.getElementById("picBox").id = 'picBox-FixDown';
// else if(document.getElementById("picBox-FixUp")) document.getElementById("picBox-FixUp").id = 'picBox-FixDown';
// }
// }
}
// nowPic = (nowPic + 1) % childElementCount + 1;
console.log(nowPic);
}
/*Firefox注册事件*/
if (document.addEventListener) {
document.addEventListener("DOMMouseScroll", MouseWheel, false);
}
window.onmousewheel = document.onmousewheel = MouseWheel; //IE/Opera/Chrome

然后是CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#picBox {
width: 100%;
margin: 70px auto;
}
#picBox-FixUp{
position: -webkit-sticky;
position: sticky;
height: 60px;
top: 0px;
}
#picBox-FixDown{
position: -webkit-sticky;
position: sticky;
top: 0px;
}

最后是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
102
103
104
105
106
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>iPad Pro 动效模拟</title>
<script src="./js/main.js"></script>
<link rel="stylesheet" type="text/css" href="./css/main.css">
<link rel="shortcut icon" href="./favicon.ico" />
</head>

<body style="border: 0px; border: 0px;margin:0px;width:100%;height:100%;">
<h3 align="center">鼠标通过滚动滚轮切换图片</h3>
<div id="picBox">
<img src="img/roll/large_0001.jpg" width="100%" id="pic1">
<img src="img/roll/large_0002.jpg" width="100%" id="pic2" style="display:none;">
<img src="img/roll/large_0003.jpg" width="100%" id="pic3" style="display:none;">
<img src="img/roll/large_0004.jpg" width="100%" id="pic4" style="display:none;">
<img src="img/roll/large_0005.jpg" width="100%" id="pic5" style="display:none;">
<img src="img/roll/large_0006.jpg" width="100%" id="pic6" style="display:none;">
<img src="img/roll/large_0007.jpg" width="100%" id="pic7" style="display:none;">
<img src="img/roll/large_0008.jpg" width="100%" id="pic8" style="display:none;">
<img src="img/roll/large_0009.jpg" width="100%" id="pic9" style="display:none;">
<img src="img/roll/large_0010.jpg" width="100%" id="pic10" style="display:none;">
<img src="img/roll/large_0011.jpg" width="100%" id="pic11" style="display:none;">
<img src="img/roll/large_0012.jpg" width="100%" id="pic12" style="display:none;">
<img src="img/roll/large_0013.jpg" width="100%" id="pic13" style="display:none;">
<img src="img/roll/large_0014.jpg" width="100%" id="pic14" style="display:none;">
<img src="img/roll/large_0015.jpg" width="100%" id="pic15" style="display:none;">
<img src="img/roll/large_0016.jpg" width="100%" id="pic16" style="display:none;">
<img src="img/roll/large_0017.jpg" width="100%" id="pic17" style="display:none;">
<img src="img/roll/large_0018.jpg" width="100%" id="pic18" style="display:none;">
<img src="img/roll/large_0019.jpg" width="100%" id="pic19" style="display:none;">
<img src="img/roll/large_0020.jpg" width="100%" id="pic20" style="display:none;">
<img src="img/roll/large_0021.jpg" width="100%" id="pic21" style="display:none;">
<img src="img/roll/large_0022.jpg" width="100%" id="pic22" style="display:none;">
<img src="img/roll/large_0023.jpg" width="100%" id="pic23" style="display:none;">
<img src="img/roll/large_0024.jpg" width="100%" id="pic24" style="display:none;">
<img src="img/roll/large_0025.jpg" width="100%" id="pic25" style="display:none;">
<img src="img/roll/large_0026.jpg" width="100%" id="pic26" style="display:none;">
<img src="img/roll/large_0027.jpg" width="100%" id="pic27" style="display:none;">
<img src="img/roll/large_0028.jpg" width="100%" id="pic28" style="display:none;">
<img src="img/roll/large_0029.jpg" width="100%" id="pic29" style="display:none;">
<img src="img/roll/large_0030.jpg" width="100%" id="pic30" style="display:none;">
<img src="img/roll/large_0031.jpg" width="100%" id="pic31" style="display:none;">
<img src="img/roll/large_0032.jpg" width="100%" id="pic32" style="display:none;">
<img src="img/roll/large_0033.jpg" width="100%" id="pic33" style="display:none;">
<img src="img/roll/large_0034.jpg" width="100%" id="pic34" style="display:none;">
<img src="img/roll/large_0035.jpg" width="100%" id="pic35" style="display:none;">
<img src="img/roll/large_0036.jpg" width="100%" id="pic36" style="display:none;">
<img src="img/roll/large_0037.jpg" width="100%" id="pic37" style="display:none;">
<img src="img/roll/large_0038.jpg" width="100%" id="pic38" style="display:none;">
<img src="img/roll/large_0039.jpg" width="100%" id="pic39" style="display:none;">
<img src="img/roll/large_0040.jpg" width="100%" id="pic40" style="display:none;">
<img src="img/roll/large_0041.jpg" width="100%" id="pic41" style="display:none;">
<img src="img/roll/large_0042.jpg" width="100%" id="pic42" style="display:none;">
<img src="img/roll/large_0043.jpg" width="100%" id="pic43" style="display:none;">
<img src="img/roll/large_0044.jpg" width="100%" id="pic44" style="display:none;">
<img src="img/roll/large_0045.jpg" width="100%" id="pic45" style="display:none;">
<img src="img/roll/large_0046.jpg" width="100%" id="pic46" style="display:none;">
<img src="img/roll/large_0047.jpg" width="100%" id="pic47" style="display:none;">
<img src="img/roll/large_0048.jpg" width="100%" id="pic48" style="display:none;">
<img src="img/roll/large_0049.jpg" width="100%" id="pic49" style="display:none;">
<img src="img/roll/large_0050.jpg" width="100%" id="pic50" style="display:none;">
<img src="img/roll/large_0051.jpg" width="100%" id="pic51" style="display:none;">
<img src="img/roll/large_0052.jpg" width="100%" id="pic52" style="display:none;">
<img src="img/roll/large_0053.jpg" width="100%" id="pic53" style="display:none;">
<img src="img/roll/large_0054.jpg" width="100%" id="pic54" style="display:none;">
<img src="img/roll/large_0055.jpg" width="100%" id="pic55" style="display:none;">
<img src="img/roll/large_0056.jpg" width="100%" id="pic56" style="display:none;">
<img src="img/roll/large_0057.jpg" width="100%" id="pic57" style="display:none;">
<img src="img/roll/large_0058.jpg" width="100%" id="pic58" style="display:none;">
<img src="img/roll/large_0059.jpg" width="100%" id="pic59" style="display:none;">
<img src="img/roll/large_0060.jpg" width="100%" id="pic60" style="display:none;">
<img src="img/roll/large_0061.jpg" width="100%" id="pic61" style="display:none;">
<img src="img/roll/large_0062.jpg" width="100%" id="pic62" style="display:none;">
<img src="img/roll/large_0063.jpg" width="100%" id="pic63" style="display:none;">
<img src="img/roll/large_0064.jpg" width="100%" id="pic64" style="display:none;">
<img src="img/roll/large_0065.jpg" width="100%" id="pic65" style="display:none;">
<img src="img/roll/large_0066.jpg" width="100%" id="pic66" style="display:none;">
<img src="img/roll/large_0067.jpg" width="100%" id="pic67" style="display:none;">
<img src="img/roll/large_0068.jpg" width="100%" id="pic68" style="display:none;">
<img src="img/roll/large_0069.jpg" width="100%" id="pic69" style="display:none;">
<img src="img/roll/large_0070.jpg" width="100%" id="pic70" style="display:none;">
<img src="img/roll/large_0071.jpg" width="100%" id="pic71" style="display:none;">
<img src="img/roll/large_0072.jpg" width="100%" id="pic72" style="display:none;">
<img src="img/roll/large_0073.jpg" width="100%" id="pic73" style="display:none;">
</div>

<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<div>
<font style="color:red;">Test Environment: Chrome+Win10</font>
</div>
</body>

</html>

在写这个的时候我发现一个问题,图片那一块太多了,就算复制粘贴改起来也很麻烦,所以干脆直接用程序生成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#%% 

import os
filePath = './img/'
fileList = []
for i,j,k in os.walk(filePath):
fileList.append(k)
#%%
len(fileList[0])
#%%
for i in range(10,len(fileList[0])):
print('<img src="img/{0}.jpg" width="800px" height="600px" id="pic{1}" style="display:none;">'.format(fileList[0][i],str(i+1)))
# %%

for i in range(5,10):
print('<img src="img/{0}.jpg" width="800px" height="600px" id="pic{1}" style="display:none;">'.format(fileList[0][i],str(i+1)))

生成代码之后直接粘贴到html文件即可。。

运行后发现实现了鼠标滚轮上下滚动实现图片变换。。以为写完了满心欢喜的我

却发现了两个问题

我没有做sticky时候的div高度限制,导致元素虽然停在那里,但是滚动条会一直下移,因此当图片切换到最后一张时,其css会取消pin,这样就会直接跳到页面末尾(因为滚动的太多了)

另外一点就是,如果我拖动进度条,或者是模拟触屏的时候,图片是不会切换的,因为我只检测了滚轮的方式,实现这个效果应该实现图片切换与滚动条绑定。


于是只能另寻他法。。。

虽然大体思路有了,但是还是不确定具体怎样实现细节。

于是我就从头开始想,应该怎样用js去实现。。

突然想起来古人的一句话

非专业使用其他类似的推送代码可能会导致危险的副作用,包括但不限于:安全缺陷症、冗余代码症、重新发明轮子症、啃文档症、怀疑人生、抑郁、头疼,甚至死亡、魂飞魄散、湮灭。

hhhhhh

差一点就又忍不住开始Re:0 从零开始的造轮子生活

于是去找了大名鼎鼎的Google老师,顺利找到了答案

有一个叫做scrollorama的js,可以实现好多中炫酷的视差动效,其中就有一项叫做pin,就是我要解决的那个切换图片时滚动条移动的问题。

所以就决定用这个内容。。

然后又找到一篇专门讲如何实现苹果交互动画的文章,根据里边的启发,结合上面的js代码,重新写了一个新的js代码,改成可以通过拖动滚动条切换图片的效果。

新的js文件
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
var totalPicNum = 73;
var movePX = 9300;
var startOpen;


function scrollEvent(e) {

if (document.getElementById('examples-pin').style.position == "fixed") {
if (document.getElementById("picBox")) {
startOpen = document.getElementById("picBox").offsetTop - (window.innerHeight / 2 - document.getElementById("picBox").style.height / 2);
// alert(startOpen)
childElementCount = document.getElementById("picBox").childElementCount;
}
const scrollTop = $('html').scrollTop();
// alert(scrollTop);
// alert(scrollTop < startOpen + movePX)
if (scrollTop > startOpen && scrollTop < startOpen + movePX) {

let offset = Math.floor((scrollTop - startOpen) / movePX * totalPicNum);
// alert(offset);
if (offset < 1) {
offset = 1;
} else if (offset > totalPicNum) {
offset = totalPicNum;
}
for (i = 1; i < childElementCount + 1; i++) {
if (i == offset) {
document.getElementById("pic" + i).style.display = "block";
} else {
document.getElementById("pic" + i).style.display = "none";
}
}
}
}
}
if (document.getElementById('examples-pin')) {
document.addEventListener('scroll', scrollEvent, false);
}

又重新写了html文件

新的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
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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>滚动动效</title>

<link href='http://fonts.googleapis.com/css?family=Bowlby+One+SC' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/normalize.css" type="text/css">
<link rel="stylesheet" href="css/style.css" type="text/css">

<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/jquery.lettering-0.6.1.min.js"></script>
<script src="js/jquery.scrollorama.js"></script>
<!-- <script src="./js/main.js"></script> -->
<link rel="stylesheet" type="text/css" href="./css/main.css">
<link rel="shortcut icon" href="./favicon.ico" />
</head>

<body>

<div class="scrollblock" id="intro">
<h1 id="title">滚动动效</h1>
<p id="author">
<script>
! function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (!d.getElementById(id)) {
js = d.createElement(s);
js.id = id;
js.src = "//platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
}
}(document, "script", "twitter-wjs");
</script>
</p>

</div>


<!-- 图片pin -->
<div class="scrollblock" id="examples-pin">
<div id="picBox">
<img src="img/roll/large_0001.jpg" width="100%" id="pic1">
<img src="img/roll/large_0002.jpg" width="100%" id="pic2" style="display:none;">
<img src="img/roll/large_0003.jpg" width="100%" id="pic3" style="display:none;">
<img src="img/roll/large_0004.jpg" width="100%" id="pic4" style="display:none;">
<img src="img/roll/large_0005.jpg" width="100%" id="pic5" style="display:none;">
<img src="img/roll/large_0006.jpg" width="100%" id="pic6" style="display:none;">
<img src="img/roll/large_0007.jpg" width="100%" id="pic7" style="display:none;">
<img src="img/roll/large_0008.jpg" width="100%" id="pic8" style="display:none;">
<img src="img/roll/large_0009.jpg" width="100%" id="pic9" style="display:none;">
<img src="img/roll/large_0010.jpg" width="100%" id="pic10" style="display:none;">
<img src="img/roll/large_0011.jpg" width="100%" id="pic11" style="display:none;">
<img src="img/roll/large_0012.jpg" width="100%" id="pic12" style="display:none;">
<img src="img/roll/large_0013.jpg" width="100%" id="pic13" style="display:none;">
<img src="img/roll/large_0014.jpg" width="100%" id="pic14" style="display:none;">
<img src="img/roll/large_0015.jpg" width="100%" id="pic15" style="display:none;">
<img src="img/roll/large_0016.jpg" width="100%" id="pic16" style="display:none;">
<img src="img/roll/large_0017.jpg" width="100%" id="pic17" style="display:none;">
<img src="img/roll/large_0018.jpg" width="100%" id="pic18" style="display:none;">
<img src="img/roll/large_0019.jpg" width="100%" id="pic19" style="display:none;">
<img src="img/roll/large_0020.jpg" width="100%" id="pic20" style="display:none;">
<img src="img/roll/large_0021.jpg" width="100%" id="pic21" style="display:none;">
<img src="img/roll/large_0022.jpg" width="100%" id="pic22" style="display:none;">
<img src="img/roll/large_0023.jpg" width="100%" id="pic23" style="display:none;">
<img src="img/roll/large_0024.jpg" width="100%" id="pic24" style="display:none;">
<img src="img/roll/large_0025.jpg" width="100%" id="pic25" style="display:none;">
<img src="img/roll/large_0026.jpg" width="100%" id="pic26" style="display:none;">
<img src="img/roll/large_0027.jpg" width="100%" id="pic27" style="display:none;">
<img src="img/roll/large_0028.jpg" width="100%" id="pic28" style="display:none;">
<img src="img/roll/large_0029.jpg" width="100%" id="pic29" style="display:none;">
<img src="img/roll/large_0030.jpg" width="100%" id="pic30" style="display:none;">
<img src="img/roll/large_0031.jpg" width="100%" id="pic31" style="display:none;">
<img src="img/roll/large_0032.jpg" width="100%" id="pic32" style="display:none;">
<img src="img/roll/large_0033.jpg" width="100%" id="pic33" style="display:none;">
<img src="img/roll/large_0034.jpg" width="100%" id="pic34" style="display:none;">
<img src="img/roll/large_0035.jpg" width="100%" id="pic35" style="display:none;">
<img src="img/roll/large_0036.jpg" width="100%" id="pic36" style="display:none;">
<img src="img/roll/large_0037.jpg" width="100%" id="pic37" style="display:none;">
<img src="img/roll/large_0038.jpg" width="100%" id="pic38" style="display:none;">
<img src="img/roll/large_0039.jpg" width="100%" id="pic39" style="display:none;">
<img src="img/roll/large_0040.jpg" width="100%" id="pic40" style="display:none;">
<img src="img/roll/large_0041.jpg" width="100%" id="pic41" style="display:none;">
<img src="img/roll/large_0042.jpg" width="100%" id="pic42" style="display:none;">
<img src="img/roll/large_0043.jpg" width="100%" id="pic43" style="display:none;">
<img src="img/roll/large_0044.jpg" width="100%" id="pic44" style="display:none;">
<img src="img/roll/large_0045.jpg" width="100%" id="pic45" style="display:none;">
<img src="img/roll/large_0046.jpg" width="100%" id="pic46" style="display:none;">
<img src="img/roll/large_0047.jpg" width="100%" id="pic47" style="display:none;">
<img src="img/roll/large_0048.jpg" width="100%" id="pic48" style="display:none;">
<img src="img/roll/large_0049.jpg" width="100%" id="pic49" style="display:none;">
<img src="img/roll/large_0050.jpg" width="100%" id="pic50" style="display:none;">
<img src="img/roll/large_0051.jpg" width="100%" id="pic51" style="display:none;">
<img src="img/roll/large_0052.jpg" width="100%" id="pic52" style="display:none;">
<img src="img/roll/large_0053.jpg" width="100%" id="pic53" style="display:none;">
<img src="img/roll/large_0054.jpg" width="100%" id="pic54" style="display:none;">
<img src="img/roll/large_0055.jpg" width="100%" id="pic55" style="display:none;">
<img src="img/roll/large_0056.jpg" width="100%" id="pic56" style="display:none;">
<img src="img/roll/large_0057.jpg" width="100%" id="pic57" style="display:none;">
<img src="img/roll/large_0058.jpg" width="100%" id="pic58" style="display:none;">
<img src="img/roll/large_0059.jpg" width="100%" id="pic59" style="display:none;">
<img src="img/roll/large_0060.jpg" width="100%" id="pic60" style="display:none;">
<img src="img/roll/large_0061.jpg" width="100%" id="pic61" style="display:none;">
<img src="img/roll/large_0062.jpg" width="100%" id="pic62" style="display:none;">
<img src="img/roll/large_0063.jpg" width="100%" id="pic63" style="display:none;">
<img src="img/roll/large_0064.jpg" width="100%" id="pic64" style="display:none;">
<img src="img/roll/large_0065.jpg" width="100%" id="pic65" style="display:none;">
<img src="img/roll/large_0066.jpg" width="100%" id="pic66" style="display:none;">
<img src="img/roll/large_0067.jpg" width="100%" id="pic67" style="display:none;">
<img src="img/roll/large_0068.jpg" width="100%" id="pic68" style="display:none;">
<img src="img/roll/large_0069.jpg" width="100%" id="pic69" style="display:none;">
<img src="img/roll/large_0070.jpg" width="100%" id="pic70" style="display:none;">
<img src="img/roll/large_0071.jpg" width="100%" id="pic71" style="display:none;">
<img src="img/roll/large_0072.jpg" width="100%" id="pic72" style="display:none;">
<img src="img/roll/large_0073.jpg" width="100%" id="pic73" style="display:none;">
</div>

<h3 id="unpin">&#9733; Then unpin it &#9733;</h3>
</div>

<div class="scrollblock" id="examples-parallax">
<h2 id="parallax1">Parallax</h2>
<h3 id="parallax2">Parallax</h3>
<h3 id="parallax3">Parallax</h3>
</div>

<div class="scrollblock">


<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<img src="img/framework/bottom.png" width="100%">
<div>
<font style="color:red;">Test Environment: Chrome+Win10</font>
参考链接:https://juejin.im/post/6844904168281358349
</div>
</div>



<script>
$(document).ready(function() {

// initialize the plugin, pass in the class selector for the sections of content (blocks)
var scrollorama = $.scrollorama({
blocks: '.scrollblock'
});

// animate some examples
scrollorama
.animate('#unpin', {
duration: 9300,
property: 'padding-top',
start: 900,
pin: true
});

});
</script>
<script src="./js/scroll.js"></script>
</body>

</html>

这样就解决了这个问题


更新:2020年9月28日

昨天,我准备正式将这个部分用在公司的项目中,却发现了这样那样的问题。

因此,接下来的部分是我完整造了一个轮子(准确说是根据下方参考链接中内容改写的)

之前的版本2

文件scrollpic.html

1
2
3
4
5
6
7
8
9
10
11
12
<style type="text/css">
@import "/source/css/scrollpic.css";
</style>
<div class="stickyContainer">
<div class="stickyWrapper">
<div id="imgWrapper" class="imgWrapper">
<img src="/source/img/roll/large_0001.jpg" id="pic1">
</div>
</div>
</div>

<script src="/source/js/scroll.js"></script>

文件scrollpic.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.stickyContainer {
height: 150vh;
}

.stickyWrapper {
height: 100vh;
position: sticky;
top: 0;
}

.imgWrapper {
width: 100%;
/* height: 521px; */
margin: 0 auto;
}

.imgWrapper img {
width: 100%;
}

文件scroll.js

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
var totalPicNum = 64;
var movePX = 600;
function scrollEvent(e) {
const scrollTop = $('html').scrollTop()+$('body').scrollTop(); // Chrome读取html, safari读取body 两者另一个都是0,所以直接相加
let newAsset = '';
if (scrollTop > startOpen && scrollTop < startOpen + movePX) {
console.log("scrollTop: " + scrollTop);
console.log("startOpen: " + startOpen);
console.log(scrollTop > startOpen && scrollTop < startOpen + movePX);
let offset = Math.floor((scrollTop - startOpen) / movePX * totalPicNum);
console.log("offset: " + offset);
if (offset < 1) {
offset = 1;
} else if (offset > totalPicNum) {
offset = totalPicNum;
}
if (offset < 10) {
newAsset = `large_000${offset}`;
} else if (offset < 100) {
newAsset = `large_00${offset}`;
} else {
newAsset = `large_0${offset}`;
}
$('#pic1').attr('src', '/source/img/roll/' + newAsset + '.jpg');
}
}
startOpen = $('#imgWrapper').offset().top + (window.innerHeight / 2 + $('#picBox').height() / 2);
document.addEventListener('scroll', scrollEvent, true);

更新:2020-10-21 11:32:54

在上述代码成功在服务器上运行起来之后,我又发现了一个问题,那就是图片加载的问题

使用上述的方法是完全单张图片加载

并且每次更换图片之后,图片都需要从服务器重新加载,而且没有写入本地缓存,这就会导致服务器压力超级大

并且由于服务器出口网络限制,根本承载不了如此快速的加载

给用户的体验就是滑动卡顿(图片会卡住)

解决方法就是在加载主页的同时直接加载这些图片,通过js去监听滚动来切换不同图片的显示语隐藏。

然后浏览器会自动将图片写入缓存,这样一段时间内下一次加载就会快很多

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
<style type="text/css">
@import "/source/css/scrollpic.css";
</style>
<div class="stickyContainer">
<div class="stickyWrapper">
<div id="imgWrapper" class="imgWrapper">
<!-- <img src="/source/img/roll/large_0001.jpg" id="pic1"> -->

<img src="/source/img/roll/large_0001.jpg" id="pic1">
<img src="/source/img/roll/large_0002.jpg" id="pic2" style="display:none;">
<img src="/source/img/roll/large_0003.jpg" id="pic3" style="display:none;">
<img src="/source/img/roll/large_0004.jpg" id="pic4" style="display:none;">
<img src="/source/img/roll/large_0005.jpg" id="pic5" style="display:none;">
<img src="/source/img/roll/large_0006.jpg" id="pic6" style="display:none;">
<img src="/source/img/roll/large_0007.jpg" id="pic7" style="display:none;">
<img src="/source/img/roll/large_0008.jpg" id="pic8" style="display:none;">
<img src="/source/img/roll/large_0009.jpg" id="pic9" style="display:none;">
<img src="/source/img/roll/large_0010.jpg" id="pic10" style="display:none;">
<img src="/source/img/roll/large_0011.jpg" id="pic11" style="display:none;">
<img src="/source/img/roll/large_0012.jpg" id="pic12" style="display:none;">
<img src="/source/img/roll/large_0013.jpg" id="pic13" style="display:none;">
<img src="/source/img/roll/large_0014.jpg" id="pic14" style="display:none;">
<img src="/source/img/roll/large_0015.jpg" id="pic15" style="display:none;">
<img src="/source/img/roll/large_0016.jpg" id="pic16" style="display:none;">
<img src="/source/img/roll/large_0017.jpg" id="pic17" style="display:none;">
<img src="/source/img/roll/large_0018.jpg" id="pic18" style="display:none;">
<img src="/source/img/roll/large_0019.jpg" id="pic19" style="display:none;">
<img src="/source/img/roll/large_0020.jpg" id="pic20" style="display:none;">
<img src="/source/img/roll/large_0021.jpg" id="pic21" style="display:none;">
<img src="/source/img/roll/large_0022.jpg" id="pic22" style="display:none;">
<img src="/source/img/roll/large_0023.jpg" id="pic23" style="display:none;">
<img src="/source/img/roll/large_0024.jpg" id="pic24" style="display:none;">
<img src="/source/img/roll/large_0025.jpg" id="pic25" style="display:none;">
<img src="/source/img/roll/large_0026.jpg" id="pic26" style="display:none;">
<img src="/source/img/roll/large_0027.jpg" id="pic27" style="display:none;">
<img src="/source/img/roll/large_0028.jpg" id="pic28" style="display:none;">
<img src="/source/img/roll/large_0029.jpg" id="pic29" style="display:none;">
<img src="/source/img/roll/large_0030.jpg" id="pic30" style="display:none;">
<img src="/source/img/roll/large_0031.jpg" id="pic31" style="display:none;">
<img src="/source/img/roll/large_0032.jpg" id="pic32" style="display:none;">
<img src="/source/img/roll/large_0033.jpg" id="pic33" style="display:none;">
<img src="/source/img/roll/large_0034.jpg" id="pic34" style="display:none;">
<img src="/source/img/roll/large_0035.jpg" id="pic35" style="display:none;">
<img src="/source/img/roll/large_0036.jpg" id="pic36" style="display:none;">
<img src="/source/img/roll/large_0037.jpg" id="pic37" style="display:none;">
<img src="/source/img/roll/large_0038.jpg" id="pic38" style="display:none;">
<img src="/source/img/roll/large_0039.jpg" id="pic39" style="display:none;">
<img src="/source/img/roll/large_0040.jpg" id="pic40" style="display:none;">
<img src="/source/img/roll/large_0041.jpg" id="pic41" style="display:none;">
<img src="/source/img/roll/large_0042.jpg" id="pic42" style="display:none;">
<img src="/source/img/roll/large_0043.jpg" id="pic43" style="display:none;">
<img src="/source/img/roll/large_0044.jpg" id="pic44" style="display:none;">
<img src="/source/img/roll/large_0045.jpg" id="pic45" style="display:none;">
<img src="/source/img/roll/large_0046.jpg" id="pic46" style="display:none;">
<img src="/source/img/roll/large_0047.jpg" id="pic47" style="display:none;">
<img src="/source/img/roll/large_0048.jpg" id="pic48" style="display:none;">
<img src="/source/img/roll/large_0049.jpg" id="pic49" style="display:none;">
<img src="/source/img/roll/large_0050.jpg" id="pic50" style="display:none;">
<img src="/source/img/roll/large_0051.jpg" id="pic51" style="display:none;">
<img src="/source/img/roll/large_0052.jpg" id="pic52" style="display:none;">
<img src="/source/img/roll/large_0053.jpg" id="pic53" style="display:none;">
<img src="/source/img/roll/large_0054.jpg" id="pic54" style="display:none;">
<img src="/source/img/roll/large_0055.jpg" id="pic55" style="display:none;">
<img src="/source/img/roll/large_0056.jpg" id="pic56" style="display:none;">
<img src="/source/img/roll/large_0057.jpg" id="pic57" style="display:none;">
<img src="/source/img/roll/large_0058.jpg" id="pic58" style="display:none;">
<img src="/source/img/roll/large_0059.jpg" id="pic59" style="display:none;">
<img src="/source/img/roll/large_0060.jpg" id="pic60" style="display:none;">
<img src="/source/img/roll/large_0061.jpg" id="pic61" style="display:none;">
<img src="/source/img/roll/large_0062.jpg" id="pic62" style="display:none;">
<img src="/source/img/roll/large_0063.jpg" id="pic63" style="display:none;">
<img src="/source/img/roll/large_0064.jpg" id="pic64" style="display:none;">
</div>
</div>
</div>

<script src="/source/js/scroll.js"></script>
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
var totalPicNum = 64;
var movePX = 400;
// var startOpen; // 开始动画的滚动距离


function scrollEvent(e) {
topHeight = $('#slides').children("li").children("img").height();

const scrollTop = $('body').scrollTop() + $('html').scrollTop();
if (scrollTop > (startOpen + topHeight) && scrollTop < (startOpen + topHeight) + movePX) {
let offset = Math.floor((scrollTop - (startOpen + topHeight)) / movePX * totalPicNum);
if (offset < 1) {
offset = 1;
} else if (offset > totalPicNum) {
offset = totalPicNum;
}
for (var i = 1; i <= totalPicNum; i++) {
$('#pic' + i).css('display', 'none');
}
$('#pic' + offset).css('display', '');
}
}
var topHeight = $('#slides').children("li").children("img").css('height');
startOpen = $('#imgWrapper').offset().top;

document.addEventListener('scroll', scrollEvent, true);

这样修改完之后,确实会有一些提升,但是图片加载还是很慢

于是我在网上又发现了另一个概念渐进式jpg(jpeg)

所谓渐进式的图片,指的是图片的保存方式有别于传统jpg文件

传统jpg文件是从左上角到右下角逐个像素顺序存储的

于是在加载慢的情况下,你可以看到图片像是被“打印”了出来

而jpeg图片的保存方式是多次采样,每次采样会保存整张图片的一部分内容(有点像是图片的降低分辨路的感觉),直到保存完所有的像素。

这样做的好处是,图片在加载的时候,用户看到的是图片由模糊逐渐变清晰,这一行为是由于图片加载自动才产生的,并不用单独设计服务器端的代码来实现这一效果

即使用户滑动图片,图片也已经加载好了低分辨率的部分,这样就能及时响应用户的交互部分了。

关于新的概念

  • vue
  • 视差动效
  • jsx文件

参考

scrollorama:https://github.com/johnpolacek/scrollorama

苹果自家:https://www.apple.com.cn/ipad-pro/

聊聊苹果营销页中几个有趣的交互动画:https://juejin.im/post/6844904168281358349