<!-- 新建立一个 animation.html (放在 dist 文件夹里面) --> <style> .box { width: 100px; height: 100px; background-color: aqua; } </style> <body> <div></div> <script src="https://www.jb51.net/article/main.js"></script> </body>
然后我们也不用 main.js 了,另外建立一个 animation-demo.js 来实现我们的动画调用。这样我们就不需要和我们的 carousel 混搅在一起了。
// 在根目录建立一个 `animation-demo.js` import { Timeline, Animation } from './animation.js'; let tl = new Timeline(); tl.start(); tl.add( new Animation( { set a(a) { console.log(a); }, }, 'property', 0, 100, 1000, null ) );
因为我们修改了我们页面使用的 js 入口文件。所以这里我们需要去 webpack.config.js 把 entry 改为 animation-demo.js。
module.exports = { entry: './animation-demo.js', mode: 'development', devServer: { contentBase: './dist', }, module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: [['@babel/plugin-transform-react-jsx', { pragma: 'createElement' }]], }, }, }, ], }, };
目前我们的 JavaScript 中是一个模拟的动画输出。接下来我们尝试给动画可以操纵一个元素的能力。
我们先给元素加一个 id="el",方便我们在脚本中获取到这个元素。
<div></div>
然后我们就可以对这个原形进行动画的操作了。首先我们需要回到 animation-demo.js,把 Animation 实例化的第一个参数改为 document.querySelector('#el').style。
然后第二个参数的属性就改为 "transform"。但是这里要注意,后面的开始时间和结束时间是无法用于 transform 这个属性的。
所以我们需要有一个转换的 template(模版),通过使用这个模版来转换时间成 transform 对应的值。
这里的 template 值就直接写成一个函数:
v => `translate(${$v}px)`;
最后我们的代码就是这样的:
tl.add( new Animation( document.querySelector('#el').style, 'transform', 0, 100, 1000, 0, null, v => `translate(${v}px)` ) );
这部分调整好之后,我们需要去到 animation.js 中去做对应的调整。
首先是给 Animation 类的 constructor 加入 template 参数的接收。与其他属性一样,在 constructor 中只是做一个存储的操作。
然后在 Animation 中的 run 方法,在 this.object[this.property] 这里面的值就应该调用 template 方法来生成属性值。而不是之前那样直接赋值给某一个属性了。
export class Animation { constructor( object, property, startValue, endValue, duration, delay, timingFunction, template ) { this.object = object; this.property = property; this.startValue = startValue; this.endValue = endValue; this.duration = duration; this.timingFunction = timingFunction; this.delay = delay; this.template = template; } run(time) { let range = this.endValue - this.startValue; this.object[this.property] = this.template( this.startValue + (range * time) / this.duration ); } }
最后效果如下:
我们发现,已经可以用我们的 Animation 库来控制元素的动画了。
首先我们来调整一下这些动画的参数,让开始到结束位置改为 0 到 500,然后动画的时间长改为 2000 毫秒。这样的设置,有利于我们调试后面的功能。
tl.add( new Animation( document.querySelector('#el').style, 'transform', 0, 500, 2000, 0, null, v => `translate(${v}px)` ) );
好,接下来我们一起去加一个 Pause 按钮。
<body> <div></div> <button>Pause</button> <script src="https://www.jb51.net/article/main.js"></script> </body>
然后我们回到 animation-demo.js 里面去绑定这个元素。并且让他执行我们 Timeline 中的 pause 方法。
document.querySelector('#pause-btn').addEventListener( 'click', () => tl.pause() );
我们可以看到,现在 pause 功能是可以的了,但是我们应该怎么去让这个动画继续播下去呢?也就是要实现一个 resume 的功能。
在实现这个 resume 功能的逻辑之前,我们先用同样的方式建立一个 resume 的按钮。并且让这个按钮调用我们 Timeline 里面的 resume() 方法。