1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>无标题文档</title>
  6. </head>
  7.  
  8. <style>
  9.  
  10. #box{
  11. opacity:1;
  12. position: relative;
  13. top:100px;
  14. left: 0px;
  15. width:300px;
  16. height:300px;
  17. border:1px #ccc solid;
  18.  
  19. }
  20. #book{
  21. opacity:1;
  22. position:absolute;
  23. top:100px;
  24. left: 100px;
  25. width:100px;
  26. height:100px;
  27. background: red;
  28. }
  29.  
  30. #book1{
  31. opacity:1;
  32. position:absolute;
  33. top:220px;
  34. left: 0px;
  35. width:100px;
  36. height:100px;
  37. background: red;
  38. }
  39. .line{
  40.  
  41. position:absolute;
  42. top:0px;
  43. left: 200px;
  44. width:1px;
  45. height:500px;
  46. background:#000;
  47.  
  48. }
  49. </style>
  50. <!--<script src="../jquery-2.2.3.js"></script>-->
  51. <body>
  52. <button id="one">jQuery动画的模拟实现:放大</button>
  53. <button id="two">jQuery动画的模拟实现:缩小</button>
  54. <div id="box">
  55. <div id="book" ></div>
  56. </div>
  57. <!-- <div id="book1" ></div>-->
  58. <!-- <div class="line"></div>-->
  59. <script >
  60. /*在ie中 consloe.log 如果不在控制台的时候会报错, 调试的时候 按f12 控制台 即可*/
  61.  
  62. var book = document.getElementById('book');
  63. var book1 = document.getElementById('book1');
  64. var one = document.getElementById('one');
  65. var two = document.getElementById('two');
  66.  
  67. /*var $book = $('#book');
  68. var i = 10
  69. while(i){
  70. $book.append("<li>11</li>")
  71. i--;
  72. }*/
  73.  
  74. ////////////
  75. //创建动画缓动对象 //
  76. ////////////
  77. //生成属性对应的动画算法对象
  78. // tweens保存每一个属性对应的缓动控制对象
  79. //properties[k] 值
  80. // k 是建
  81. //animation 动画对象
  82. // 参数为:animation.tweens.push( new Tween(properties[k], k, animation) )
  83. //Tween 构造函数
  84. // this.elem 就是用户传进来的dom节点
  85. //this.prop = prop; 对象的属性
  86. //this.easing = "swing"; //动画缓动算法
  87. //this.end动画最终值
  88. //单位 this.unit = "px"
  89. //Tween 函数是初始化构造函数
  90.  
  91. function Tween(value, prop, animation) {
  92. //初始化
  93. this.elem = animation.elem;
  94. this.prop = prop;
  95. this.easing = "swing"; //动画缓动算法
  96. this.options = animation.options;
  97. //获取初始值,就是获取动画样式的值, this.get();
  98. this.start = this.now = this.get();
  99. //动画最终值,就是用户输入的值
  100. this.end = value;
  101. //单位
  102. this.unit = "px"
  103. }
  104. //获取动画样式
  105. function getStyles(elem, attr) {
  106. //return elem.ownerDocument.defaultView.getComputedStyle(elem, null);
  107.  
  108. if(elem.currentStyle) {
  109. // ie //这样兼容性强
  110. //console.log('attr='+attr+'||elem.currentStyle[attr]='+elem.currentStyle[attr])
  111. if(elem.currentStyle[attr]=='auto'){
  112. elem.style[attr] = '0px';
  113. }
  114. return elem.currentStyle[attr];
  115. } else {
  116. //ff w3c.
  117.  
  118. return getComputedStyle(elem,false)[attr];
  119. }
  120. };
  121.  
  122. //动画算法
  123. function swing(p) {
  124. //p 是动画时间比 0 ~ 1
  125. //Math.cos(x) x 的余弦值。返回的是 1.0 到 -1.0 之间的数;
  126. //(p * Math.PI) 是 0到3.14
  127. //(p * Math.PI)/2 是0到1.57
  128. //所以 Math.cos(p * Math.PI) / 2 值: 0.5 ~ -05
  129. //tmpe 值越大跑的越快
  130. var tmpe = 0.5 - Math.cos(p * Math.PI) / 2;
  131. // tmpe = Math.sin(p*Math.PI/2)
  132. // console.log('p * Math.PI='+Math.sin(p * Math.PI))
  133. //console.log('Math.sin(p * Math.PI)='+ Math.sin(p*Math.PI/2));
  134. // console.log('Math.cos(p * Math.PI) / 2='+ Math.cos(p * Math.PI) / 2)
  135. // console.log('tmpe='+tmpe)
  136. return tmpe
  137. }
  138.  
  139. Tween.prototype = {
  140. //获取元素的当前属性
  141. get: function() {
  142. var computed = getStyles(this.elem, this.prop);
  143. //var ret = computed.getPropertyValue(this.prop) || computed[this.prop];
  144. //var ret = computed[this.prop];
  145. //获取样式的值
  146. //return parseFloat(ret);
  147. return parseFloat(computed);
  148. },
  149. //运行动画
  150. run:function(percent){
  151. //percent 动画时间比 0-1
  152. var eased;
  153. //根据缓动算法改变percent
  154. this.pos = eased = swing(percent);
  155. //获取具体的改变坐标值 this.now缓冲值
  156.  
  157. //this.now (等于结束动画位置 - 开始动画的位置)* 时间戳比例,时间戳比例是从0 ~ 1 this.start 是起始的位置
  158. this.now = (this.end - this.start) * eased + this.start;
  159. //console.log('this.now='+this.now)
  160.  
  161. //console.log('this.prop='+this.prop+'||this.start='+this.start)
  162. //最终改变坐标
  163. //console.log('this.prop='+this.prop+'||this.now='+this.now)
  164.  
  165. this.elem.style[this.prop] = this.now + "px";
  166. return this;
  167. }
  168. }
  169.  
  170. ////////
  171. //动画类 //
  172. ////////
  173. //动画对象 elem
  174. //properties 动画属性
  175. //options 动画时间
  176. function Animation(elem, properties, options){
  177. //检查动画是否在执行
  178. if (Animation.timerId !=undefined && Animation.timerId) {
  179. return false;
  180. }
  181. //动画对象
  182. //animation.elem 动画对象
  183. //animation.props 动画属性
  184. //options.options 动画时间
  185. //Animation.fxNow || createFxNow() 开始动画的时间
  186. //tweens : [] //存放每个属性的缓动对象,用于动画
  187. var animation = {
  188. elem : elem,
  189. props : properties,
  190. originalOptions : options,
  191. options : options,
  192. startTime : null,//动画开始时间
  193. tweens : [] //存放每个属性的缓动对象,用于动画
  194. }
  195.  
  196. //生成属性对应的动画算法对象
  197. // tweens保存每一个属性对应的缓动控制对象
  198. //properties[k] 值
  199. // k 是建
  200. //animation 动画对象
  201. for (var k in properties) {
  202.  
  203. // tweens保存每一个属性对应的缓动控制对象
  204. animation.tweens.push( new Tween(properties[k], k, animation) )
  205. }
  206.  
  207. //动画状态
  208. //var stopped;
  209. //把 animation.startTime=Animation.fxNow || createFxNow(); 放在这里 为了避免 for (var k in properties) for循环的时候如果属性多的时候会出现时间误差,虽然不是很大,但是如果属性很多的话就显得很明显
  210. animation.startTime=Animation.fxNow || createFxNow();
  211. //动画的定时器调用包装器 动画循环函数 tick 每13毫秒执行一次
  212. var tick = function() {
  213. // console.log(1)
  214. //如果 stopped 为真则 停止函数
  215. //if (stopped) {
  216. // return false;
  217. //}
  218.  
  219. //动画时间算法 每次更新动画的时间戳
  220. var currentTime = Animation.fxNow || createFxNow();
  221. //运动时间递减
  222. remaining = Math.max(0, animation.startTime + animation.options.duration - currentTime),
  223. //时间比
  224. temp = remaining / animation.options.duration || 0,
  225. //取反时间比
  226. percent = 1 - temp;
  227.  
  228. var index = 0,
  229. length = animation.tweens.length;
  230.  
  231. //执行动画改变
  232. for (; index < length; index++) {
  233. //percent改变值
  234. //animation.tweens[index] 动画的对 象percent 动画时间比 0-1
  235. // run 就是一个动画执行多少个动画属性
  236. animation.tweens[index].run(percent);
  237. }
  238.  
  239. //是否继续,还是停止动画 percent <= 1 表示动画已经到达位置了
  240. if (percent <= 1 && length) {
  241.  
  242. return remaining;
  243.  
  244. } else {
  245. //停止 动画
  246.  
  247. return false;
  248. }
  249.  
  250. }
  251. tick.elem = elem;
  252. tick.anim = animation;
  253. //只是调用一次而已
  254. //console.log(3333)
  255. Animation.fx.timer(tick);
  256. }
  257.  
  258. //创建 获取时间戳 函数
  259. function createFxNow() {
  260. setTimeout(function() {
  261. //给 Animation.fxNow = undefined; 一个空的对象
  262. Animation.fxNow = undefined;
  263. });
  264. //Date.now() 时间戳
  265. return (Animation.fxNow = Date.now());
  266. }
  267.  
  268. Animation.fx = {
  269. //开始动画队列 这个函数也是执行一次而已
  270. timer: function(timer) {
  271.  
  272. //这里是把函数放到一个数组里面?有何用处
  273. Animation.timer=timer;
  274.  
  275. if (timer()) { //timer() 只是调用一个而已,就是说有这个动画时候就执行函数 返回一个false 或者是 remaining;
  276. //开始执行动画 走这里
  277. Animation.fx.start();
  278. }
  279. },
  280. //开始循环 这个函数也是执行一次而已
  281. start: function() {
  282. if (!Animation.timerId) {
  283.  
  284. Animation.timerId = setInterval(Animation.fx.tick, 13);
  285. }
  286. },
  287. //停止循环 停止定时器
  288. stop:function(){
  289. clearInterval(Animation.timerId);
  290. Animation.timerId = null;
  291.  
  292. },
  293. //循环的的检测 重点是这里
  294. tick: function() {
  295. var timer,
  296. i = 0;
  297. //每次更新时间戳
  298. Animation.fxNow = Date.now();
  299. //console.log(1)
  300. //如果所有的动画都执行完了就停止这个定时器
  301. if (!Animation.timer()) {
  302. //console.log('Animation.timer()')
  303. //console.log(!Animation.timer())
  304. Animation.fx.stop();
  305. }
  306. //问题出在这里,因为当执行完只有 Animation.fxNow 时间戳变量值还在,所以就产生了bug
  307. Animation.fxNow = undefined;
  308. }
  309. }
  310.  
  311. one.onclick=function(){
  312.  
  313. Animation(book, {
  314. 'width': '300',
  315. 'height':'300',
  316. 'marginLeft':'-100',
  317. 'marginTop':'-100'
  318. }, {
  319. duration: 1000
  320. })
  321.  
  322. }
  323.  
  324. two.onclick=function() {
  325.  
  326. Animation(book, {
  327. width: '100',
  328. height:'100',
  329. marginLeft:'0',
  330. marginTop:'0'
  331. }, {
  332. duration: 1000
  333. })
  334. }
  335.  
  336. </script>
  337. </body>
  338. </html>

jq动画分析的更多相关文章

  1. jq动画分析1

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. iOS 手机淘宝加入购物车动画分析

    1.最终效果 仿淘宝动画 2.核心代码 _cartAnimView=[[UIImageView alloc] initWithFrame:CGRectMake(_propView.frame.size ...

  3. iOS手机淘宝加入购物车动画分析

    本文转载至 http://www.jianshu.com/p/e77e3ce8ee24 1.最终效果 仿淘宝动画 2.核心代码 _cartAnimView=[[UIImageView alloc] i ...

  4. (21)jq动画

    jq动画的优点 优点: 1.可以知道动画结束的表示(结束的回调函数) 2.可以利用jq动画插件完成复杂的动画 动画有三个参数:动画的样式是字典.动画持续的事件,动画结束回调函数 <!DOCTYP ...

  5. css动画和jq动画的简单区分

    有很多不怎么用css3写动画的同学经常会对其中css3的transform,transition,translate,animation,@keyframes等等动画属性混淆错乱,经常使用了发现没有效 ...

  6. 拆轮子之Fish动画分析

    概述 最近发现一个很好玩的动画库,纯代码实现的而不是通过图片叠加唬人的,觉得很有意思看了下源码https://github.com/dinuscxj/LoadingDrawable, 这个动画效果使用 ...

  7. jq动画设置图片抽奖(修改效果版)

    效果:点击开始,图片转动,按钮显示"停止",点击停止,选出中奖号码,,最后一个数字停止时,按钮变为"again",点击"again"开始转动 ...

  8. ANDROID开机动画分析

    开机动画文件:bootanimation.zip在system\media文件夹下动画是由系列图片连续刷屏实现的..bootanimation.zip文件是zip压缩文件,压缩方式要求是存储压缩,包含 ...

  9. Android——Fragment过度动画分析一(转)

    Sliding Fragment 作者:小文字 出处:http://www.cnblogs.com/avenwu/   介绍:该案例为传统的Fragment增加了个性化的补间动画,其效果是原有frag ...

随机推荐

  1. 微信小程序调用微信登陆获取openid及用户信息 java做为服务端

    转载的文章,很不错 https://blog.csdn.net/weilai_zhilu/article/details/77932630

  2. 自定义锁屏图片 win7

    win + R打开运行对话框 输入Regedit 点确定 进入注册表,找到以下项次 HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersi ...

  3. jQuery对象的获取与操作方法总结

    一.文章概述: 众所周知,jQuery 是一个 JavaScript 库,包含多个可重用的函数,用来辅助我们简化javascript开发,它极大地简化了 JavaScript 编程.但是需要注意的一点 ...

  4. [UE4]控件模板

    控件模板:一个UI可以作为另外一个UI的子控件,这个子控件就是控件模板. 控件模板一般使用“Size Box”组件作为根节点,给“Size Box”组件设置合适的尺寸,显示模式选择“Desired”, ...

  5. Windows平台下使用CodeBlocks+GCC编译器生成动态dll,C#调用报错

    报无法加载dll错误,解决方法: 1) 编译选择设置成x86,即-m322) 必须在c#程序目录下加上libgcc_s_dw2-1.dll

  6. 在Docker中安装配置Oracle11g并实现数据持久化

    1.拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g 镜像详情:https://dev.aliyun.com/ ...

  7. Hive调优

    Hive存储格式选择 和Hive 相关优化: 压缩参考 Hive支持的存储数的格式主要有:TEXTFILE .SEQUENCEFILE.ORC.PARQUET. 文件存储格式 列式存储和行式存储 行存 ...

  8. tkinter简单使用

    第一个运行程序 # -*- coding: utf-8 -*- import tkinter as tk //引入 root = tk.Tk() // 实例化root T大写k小写 root.titl ...

  9. union与union all的用法给区别

    用法: 当我们需要把两个或多个sql联合起来查询就用到了union或者union all 区别: 这两者的区别就在于union会自动的把多个sql查出来重复的排除掉,而union all这是会全部显示 ...

  10. 如何用两块硬盘做磁盘阵列的教程Raid 1

    如今,市面上的大部分服务器都自带有阵列卡.只要有两块以上硬盘,我们就可以利用服务器自带的阵列卡做磁盘阵列.Raid 1 为例.Raid 1 是磁盘阵列的其中一个系列,将两块硬盘构成磁盘阵列,可以保证数 ...