ScrollMagic 是一个专门用于实现滚动效果的插件,不仅可以把某些元素固定在一个特定的滚动位置,还可以使动画同步滚动条的动作,从而实现滚动视差效果,特点如下:
<script src="./js/ScrollMagic.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
header {
width: 100%;
height: 100px;
background-color: black;
}
.section {
width: 100%;
height: 200px;
background-color: red;
}
.section:nth-of-type(2) {
background-color: orange;
}
.section:nth-of-type(3) {
background-color: green;
}
.section:nth-of-type(4) {
background-color: blue;
}
footer {
width: 100%;
height: 500px;
background-color: black;
}
</style>
<header></header>
<div class="section"></div>
<div class="section"></div>
<div class="section"></div>
<div class="section"></div>
<footer></footer>
let controller = new ScrollMagic.Controller();
let scene = new ScrollMagic.Scene({
offset: 100,
duration: 200
});
scene.setPin(".section:nth-of-type(1)");
controller.addScene(scene);
如果通过 setPin 方法固定某个元素,默认情况下,场景元素下方将出现空白,且随着网页的滚动而被向下推压的场景元素覆盖,在添加场景元素时可以关闭此功能,此时场景元素下方不存在空白,示例如下:
let controller = new ScrollMagic.Controller();
let scene = new ScrollMagic.Scene({
offset: 100,
duration: 200
});
scene.setPin(".section:nth-of-type(1)", {
pushFollowers: false
});
controller.addScene(scene);
综上所述,ScrollMagic 库的使用步骤如下:
创建 Scene 实例,实际上就是创建一个在某个特殊位置/时间开始的场景,不一定必须固定某个元素(调用 setPin 实例)
ScrollMagic 中创建 Scene 实例时的选项内容如下:
属性 | 类型 | 描述 |
---|---|---|
offset | Number | 网页滚动到哪一个位置时开始场景 |
duration | Number | 场景的有效范围 |
reverse | Boolean | 网页回滚时场景是否有效 |
triggerElement | String | 指定一个用于开始场景的参考元素 |
triggerHook | String | triggerElement 在视口的哪一个位置时开始场景(onEnter 、onCenter 和 onLeave 等) |
示例如下:
let controller = new ScrollMagic.Controller();
let scene = new ScrollMagic.Scene({
duration: 200,
triggerElement: "footer",
triggerHook: "onEnter",
reverse: false
});
scene.setPin(".section:nth-of-type(1)");
controller.addScene(scene);
上述示例中的含义是当 footer 元素在视口中显示时开始场景
若想在页面滚动视差时添加动画,可以将 ScrollMagic 与 GSAP 或者 Velocity 联合,在使用时必须导入 ScrollMagic 提供的与各个库的联合文件,区别在于,GSAP 动画将随着网页的滚动而执行,Velocity 将在场景开始时立即执行,此外,不论是 GSAP 还是 Velocity,各个库的特性都被保留,最典型的例子是各个插件为若干元素同时添加动画的方式
<script src="./js/ScrollMagic.js"></script>
<script src="./js/gsap.js"></script>
<script src="./js/animation.gsap.js"></script>
<style>
.anim {
width: 100px;
height: 100px;
background-color: white;
margin: 0 auto;
}
</style>
<header></header>
<div class="section">
<div class="anim"></div>
</div>
<div class="section"></div>
<div class="section"></div>
<div class="section"></div>
<footer></footer>
let controller = new ScrollMagic.Controller();
let scene = new ScrollMagic.Scene({
offset: 100,
duration: 200,
});
scene.setPin(".section:nth-of-type(1)");
let myTween = gsap.to(".anim", {
width: 200,
height: 200
});
scene.setTween(myTween);
controller.addScene(scene);
实际上,在为场景添加动画时,可以传入动画相关的参数,示例如下:
let controller = new ScrollMagic.Controller();
let scene = new ScrollMagic.Scene({
offset: 100,
duration: 200,
});
scene.setPin(".section:nth-of-type(1)");
scene.setTween(".anim", {
width: 200,
height: 200
});
controller.addScene(scene);
<script src="./js/ScrollMagic.js"></script>
<script src="./js/velocity.js"></script>
<script src="./js/animation.velocity.js"></script>
必须注意 Velocity 库的版本必须在 1.2 版本以上、2.0 版本以下
<style>
.anim {
width: 100px;
height: 100px;
background-color: white;
margin: 0 auto;
}
</style>
<header></header>
<div class="section">
<div class="anim"></div>
</div>
<div class="section"></div>
<div class="section"></div>
<div class="section"></div>
<footer></footer>
let controller = new ScrollMagic.Controller();
let scene = new ScrollMagic.Scene({
offset: 100
});
scene.setPin(".section:nth-of-type(1)");
scene.setVelocity(".anim", {
width: "200px",
height: "200px"
}, {
duration: 3000
});
controller.addScene(scene);
ScrollMagic 可以在场景中监听事件,内容如下:
事件 | 描述 |
---|---|
start | 开始 |
end | 结束 |
progress | 执行 |
示例如下:
let controller = new ScrollMagic.Controller();
let scene = new ScrollMagic.Scene({
offset: 100,
duration: 200
});
scene.setPin(".section:nth-of-type(1)");
scene.on("start", function (event) {
console.log("Start");
});
scene.on("end", function (event) {
console.log("End");
});
scene.on("progress", function (event) {
console.log("Progress", event.progress);
});
controller.addScene(scene);