MooTools 1.4 源码分析 - Fx
Mootools1.4 - Fx源码分析,如果理解有误欢迎指正:
![](/assets/blank.gif)
![](/assets/blank.gif)
1 /* 2 --- 3 4 name: Fx 5 6 description: Contains the basic animation logic to be extended by all other Fx Classes. 7 8 license: MIT-style license. 9 10 requires: [Chain, Events, Options] 11 12 provides: Fx 13 14 源码分析: 苦苦的苦瓜(http://www.cnblogs.com/hmking) 15 ... 16 */ 17 18 (function () { 19 20 /** 21 * @Fx: 本类一般不独立使用,它用来提供作为Fx系的类的基础功能类.所有其他的Fx系列的类都继承本类. 22 **/ 23 var Fx = this.Fx = new Class({ 24 25 Implements: [Chain, Events, Options], 26 27 // #region - constructor - 28 29 /** 30 * @Events: 31 * @event start - (function) 特效开始执行时触发 32 * @event cancel - (function) 手动停止特效执行时触发 33 * @event complete - (function) 特效执行完成后触发 34 * @event chainComplete - (function) 当使用link可选项为'chain'时, 该事件在特效链执行完后触发 35 * @event stop - (function) 特效执行完成前,执行stop方法时触发 36 **/ 37 38 /** 39 * @Optoins: 40 * @option fps - (number: 默认为 60) 动画特效的秒帧数 41 * @option unit - (string: 默认为 false) 计量单位(如: 'px', 'em', 或 '%'). 42 * @option duration - (number: 默认为 500) 可以让你定义这个动画的持续时间。持续时间和速度是不一样的,因此如果你想让一个对象在一秒内移动100个像素, 43 * 那么它将比一个每秒移动1000个像素的对象要慢。你可以输入一个数字(以毫秒为单位). 也可使用以下预定义字符串: 44 * 'short' - 250ms 45 * 'normal' - 500ms 46 * 'long' - 1000ms 47 * @option frames - (number) 设定动画特效执行的总帧数,默认为null自动匹配 48 * @option frameSkip - (boolean: 默认为true) 设定动画特效当一帧执行的时间大于每帧之间的时间间隔,是否跳过这段时间所要执行的帧 49 * @option link - (string: 默认为 ignore) 可为: 'ignore', 'cancel' 或 'chain' 50 * 'ignore' - 当特效正在执行之中时,再次调用特效开始的方法将被忽略(和可选项'wait'为true时同义) 51 * 'cancel' - 当特效正在执行之中时,再次调用特效开始的方法将立即取消当前执行的特效,开始执行新的特效 52 * 'chain' - 当特效正在执行之中时,再次调用特效开始的方法将会把新的特效链接在当前执行的特效之后,依次执行各个特效 53 * @option transition - (function: 默认为 Fx.Transitions.Sine.easeInOut) 特效的变换方程, 详见Fx.Transitions. 也可以使用如下格式的字符串: 54 * transition[:in][:out] - 例如: 'linear', 'quad:in', 'back:in', 'bounce:out', 'elastic:out', 'sine:in:out' 55 **/ 56 options: { 57 /* 58 onStart: nil, 59 onCancel: nil, 60 onComplete: nil, 61 */ 62 fps: 60, 63 unit: false, 64 duration: 500, 65 frames: null, 66 frameSkip: true, 67 link: 'ignore' 68 }, 69 70 initialize: function (options) { 71 this.subject = this.subject || this; 72 this.setOptions(options); 73 }, 74 75 // #endregion 76 77 /** 78 * @method: getTransition 79 * @returns: (function) - 特效的变换方程 80 * @description: 取得动画特效所要执行的特效方程 81 **/ 82 getTransition: function () { 83 return function (p) { 84 return -(Math.cos(Math.PI * p) - 1) / 2; 85 }; 86 }, 87 88 /** 89 * @method: step 90 * @param now - (mixed) 特效值 91 * @returns: (function) - 特效的变换方程 92 * @description: 动画特效每一步执行的操作 93 **/ 94 step: function (now) { 95 if (this.options.frameSkip) { 96 // 先取得当前时间减去上一帧执行时的时间,得到两帧之间的时间间隔,计算这段时间内按正常的帧间隔时间能执行的帧的数量 97 var diff = (this.time != null) ? (now - this.time) : 0, 98 frames = diff / this.frameInterval; 99 // 存储当前帧执行时的时间100 this.time = now;101 // 执行的帧数累加102 this.frame += frames;103 } else {104 this.frame++;105 }106 107 // 判断当前帧是否为动画特效的最后一帧108 if (this.frame < this.frames) {109 // 通过特效方程计算动画特效运行当前帧所要变化的比例因子110 var delta = this.transition(this.frame / this.frames);111 this.set(this.compute(this.from, this.to, delta));112 } else {113 // 动画特效执行完毕114 this.frame = this.frames;115 this.set(this.compute(this.from, this.to, 1));116 this.stop();117 }118 },119 120 /**121 * @method: set122 * @param value - (mixed) 特效值123 * @description: 用于设置特效值.该方法在特效变换过程中每个'步进'都会调用; 也可以手工调用,留作派生类实现124 **/125 set: function (now) {126 return now;127 },128 129 /**130 * @method: compute131 * @param from - (mixed) 特效的起始值132 * @param to - (mixed) 特效的结束值133 * @param delta - (mixed) 特效变化所需要的比例因子134 * @description: 根据初始值,结束值和比例因子求目标值135 **/136 compute: function (from, to, delta) {137 return Fx.compute(from, to, delta);138 },139 140 /**141 * @method: check142 * @parameters - 与start方法参数一致143 * @returns: (boolean) - 如果start方法可以继续执行, 则返回 true ; 否则返回 false144 * @description: 判断当特效正在执行之中时,再次调用特效开始的方法(start)是否继续可以执行start方法145 **/146 check: function () {147 // 如果特效没有运行,返回true148 if (!this.isRunning()) { return true; }149 switch (this.options.link) {150 case 'cancel': // 不等待正在运行的特效,直接取消并重新开始151 this.cancel();152 return true;153 154 case 'chain': // 等待当前特效运行结束后再继续运行新特效155 this.chain(this.caller.pass(arguments, this));156 return false;157 }158 return false;159 },160 161 /**162 * @method: start163 * @param from - (mixed) 特效的起始值. 如果只给出一个参数,则本值将作为结束值164 * @param to - (mixed, 可选) 特效的结束值165 * @returns: (object) - 当前的Fx实例166 * @description: 开始执行特效变换(并触发'start'事件)167 **/168 start: function (from, to) {169 // 检测start方法是否可以继续执行170 if (!this.check(from, to)) { return this; }171 172 /**173 # 苦苦的苦瓜174 # 2011-09-25175 # 将用局部变量_options代替this.options176 **/177 var _options = this.options;178 179 this.from = from;180 this.to = to;181 this.frame = (_options.frameSkip) ? 0 : -1;182 this.time = null;183 // 取得特效执行的变换方程184 this.transition = this.getTransition();185 var frames = _options.frames,186 fps = _options.fps,187 duration = _options.duration;188 // 可选参数duration既可以数字类型,也可以为字符串类型189 this.duration = Fx.Durations[duration] || duration.toInt();190 // 取得动画特效每帧之间的时间间隔,毫秒为单位191 this.frameInterval = 1000 / fps;192 // 计算动画特效执行的总帧数193 this.frames = frames || Math.round(this.duration / this.frameInterval);194 // 触发'start'事件195 this.fireEvent('start', this.subject);196 pushInstance.call(this, fps);197 return this;198 },199 200 /**201 * @method: stop202 * @returns: (object) - 当前的Fx实例203 * @description: 停止一个特效的执行204 **/205 stop: function () {206 if (this.isRunning()) {207 this.time = null;208 pullInstance.call(this, this.options.fps);209 if (this.frames == this.frame) {210 this.fireEvent('complete', this.subject);211 if (!this.callChain()) {212 this.fireEvent('chainComplete', this.subject);213 }214 } else {215 this.fireEvent('stop', this.subject);216 }217 }218 return this;219 },220 221 /**222 * @method: cancel223 * @returns: (object) - 当前的Fx实例224 * @description: 取消一个特效的执行(并触发'cancel'事件)225 **/226 cancel: function () {227 if (this.isRunning()) {228 this.time = null;229 pullInstance.call(this, this.options.fps);230 this.frame = this.frames;231 this.fireEvent('cancel', this.subject).clearChain();232 }233 return this;234 },235 236 /**237 * @method: pause238 * @returns: (object) - 当前的Fx实例239 * @description: 暂停当前执行的特效240 **/241 pause: function () {242 if (this.isRunning()) {243 this.time = null;244 pullInstance.call(this, this.options.fps);245 }246 return this;247 },248 249 /**250 * @method: pause251 * @return: (object) - 当前的Fx实例252 * @description: 恢复执行暂停中的特效253 * @remark: 只有对暂停中的特效执行本方法才有效果, 否则将忽略.254 **/255 resume: function () {256 if ((this.frame < this.frames) && !this.isRunning()) {257 pushInstance.call(this, this.options.fps);258 }259 return this;260 },261 262 /**263 * @method: isRunning264 * @return: (boolean) 特效运行状态265 * @description: 检测特效是否正在运行266 **/267 isRunning: function () {268 var list = instances[this.options.fps];269 return list && list.contains(this);270 }271 272 });273 274 Fx.compute = function (from, to, delta) {275 return (to - from) * delta + from;276 };277 278 // 预置特效间隔毫秒数,当可选参数duration为字符串时调用Fx.Durations对象得到特效间隔毫秒数279 Fx.Durations = { 'short': 250, 'normal': 500, 'long': 1000 };280 281 // global timers282 // instances对象字面量缓存所有的fx实例对象,它的所有键值对中的键就是对应一个fps值,值为一个包含设置了相同fps的动画特效实例的数组283 // timers对象缓存setInterval()方法返回的ID值284 var instances = {},285 timers = {};286 287 /**288 * @method: loop289 * @description: 遍历动画特效实例数组,执行动画特效290 **/291 var loop = function () {292 var now = Date.now();293 for (var i = this.length; i--; ) {294 var instance = this[i];295 if (instance) { instance.step(now); }296 }297 };298 299 /**300 * @method: pushInstance301 * @description: 遍历动画特效实例数组,执行动画特效302 **/303 var pushInstance = function (fps) {304 // 取得缓存的与参数fps对应的动画特效数组,如果没有则instances对象新建一个键值存储这个数组305 var list = instances[fps] || (instances[fps] = []);306 // 缓存fx实例对象307 list.push(this);308 if (!timers[fps]) {309 // 设置定时器310 timers[fps] = loop.periodical(Math.round(1000 / fps), list);311 }312 };313 314 /**315 * @method: pullInstance316 * @param from - (number) 要停止的动画特效实例的秒帧数317 * @description: 停止运行一个动画特效实例318 **/319 var pullInstance = function (fps) {320 // 取得缓存的与参数fps对应的动画特效数组321 var list = instances[fps];322 if (list) {323 // 从数组中删除运行pullInstance函数的fx实例对象324 list.erase(this);325 if (!list.length && timers[fps]) {326 // 如果数组为空,则删除instances对象中的这个数组327 delete instances[fps];328 // 清除定时器329 timers[fps] = clearInterval(timers[fps]);330 }331 }332 };333 334 })();
转载于:https://www.cnblogs.com/hmking/archive/2011/09/30/2196604.html
MooTools 1.4 源码分析 - Fx相关推荐
- MooTools 1.4 源码分析 - (关于Core、Type等模块分析)
MooTools由1.3升级到1.4的过程中,这几个核心模块只有String模块和Event模块(现在已修改为DOMEvent)做了比较大的修改,这几个模块源码的分析参考 棍子上的萝卜 所写的 ...
- [前沿技术] AMD FSR 1.0源码分析(二)
FSR技术分析 前文:[前沿技术] AMD FSR 1.0源码分析(一) 2. EASU源码分析 2.3 FsrEasuF分析 1️⃣首先,就参数而言,主要是: void FsrEasuF(out A ...
- 【图像】【OpenCV鱼眼矫正】二、fisheye::initUndistortRectifyMap()源码分析
目录 一.fisheye::initUndistortRectifyMap() 之 功能介绍 二.fisheye::initUndistortRectifyMap() 之 源码分析 1. 源码分析 2 ...
- 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析
目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...
- SpringBoot-web开发(四): SpringMVC的拓展、接管(源码分析)
[SpringBoot-web系列]前文: SpringBoot-web开发(一): 静态资源的导入(源码分析) SpringBoot-web开发(二): 页面和图标定制(源码分析) SpringBo ...
- SpringBoot-web开发(二): 页面和图标定制(源码分析)
[SpringBoot-web系列]前文: SpringBoot-web开发(一): 静态资源的导入(源码分析) 目录 一.首页 1. 源码分析 2. 访问首页测试 二.动态页面 1. 动态资源目录t ...
- SpringBoot-web开发(一): 静态资源的导入(源码分析)
目录 方式一:通过WebJars 1. 什么是webjars? 2. webjars的使用 3. webjars结构 4. 解析源码 5. 测试访问 方式二:放入静态资源目录 1. 源码分析 2. 测 ...
- Yolov3Yolov4网络结构与源码分析
Yolov3&Yolov4网络结构与源码分析 从2018年Yolov3年提出的两年后,在原作者声名放弃更新Yolo算法后,俄罗斯的Alexey大神扛起了Yolov4的大旗. 文章目录 论文汇总 ...
- ViewGroup的Touch事件分发(源码分析)
Android中Touch事件的分发又分为View和ViewGroup的事件分发,View的touch事件分发相对比较简单,可参考 View的Touch事件分发(一.初步了解) View的Touch事 ...
- View的Touch事件分发(二.源码分析)
Android中Touch事件的分发又分为View和ViewGroup的事件分发,先来看简单的View的touch事件分发. 主要分析View的dispatchTouchEvent()方法和onTou ...
最新文章
- HttpClient 中文官方教程----第一章基础知识-只收录,未测试
- RTSP再学习 -- 利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中
- Android开发(三十二)——延时
- One Order CLOSING date修改后的执行原理
- c语言115写成16进制,西安电子科技大学计算机导论与C语言程序设计 计算机文化概论.pdf...
- 5G多输入多输出技术,到底是个啥东东?
- Spark学习笔记:使用RDD
- 赞一个 kindle电子书有最新的计算机图书可买了【Docker技术入门与实战】
- nginx config的多个config配置
- python定位网页元素_python爬虫技术:如何定位网页上的内容?xpath定位元素
- mysql角色管理权限管理_mysql权限角色管理
- MATLAB点云重采样,PCL点云曲面重采样三种方法:上采样,下采样,均匀采样
- 【Java系列】八大排序算法
- linux-arm下如何开启tftp传输,linux-arm间tftp命令的安装、使用
- mysql代码创建表博客园_数据库——用代码创建表
- 观影计划:漫威电影宇宙「无限战争」系列
- Beaglebone Black– 智能家居控制系统 LAS - 网页服务器 Node.js 、Web Service、页面 和 TCP 请求转 UDP 发送...
- 移动端H5页面编辑器开发实战--原理结构篇
- 2022年终总结——工作第五年
- 7-2 列出连通集 (25 分)
热门文章
- u8显示云服务器已离线_u8登录不知道这样的主机
- 信用评分卡 (part 2of 7)
- 孝感高考成绩2021分数查询,孝感教育局官网2021年大悟中考分数查询成绩查分
- 超轻薄笔记本电脑软件测试,一口气测了三款轻薄本 这三个核心问题有答案了...
- 教育部计算机应用基础统考试题,月教育部统考计算机应用基础试卷十附答案.doc...
- 守望先锋 获取cdn配置_英特尔酷睿i5 9400F万金油配置推荐 适合吃鸡 守望先锋
- C/C++[codeup 1941]新版A+B
- const数据成员的初始化
- 凸优化第四章凸优化问题 4.6广义不等式约束
- 白话machine learning之Loss Function