4-2 小男孩部分代码的封装
本节编程练习不计算学习进度,请电脑登录imooc.com操作

小男孩部分代码的封装

前端充斥着大量的异步操作,动画就是异步的逻辑,七夕主题的整个设计都是以小男孩走路为主线。在走到不同的路段就会有不同的操作,走路是通过CSS3的transition与animation结合完成的,所以针对这类异步的处理我采用了jQuery的Deferred封装起来。

除此之外,在整个结构中都是采用面向接口编程,简单的说就是将行为分布在各个对象中,并让这些对象自己各自负责自己的行为。那么小孩男的整个行为逻辑我都将会封装成一个独立的对象,通过接口调用

说了半天,我们看右边的代码最直接,我单独用了个BoyWalk.js把小男孩的动作给封装了起来,暴露了walkTo、stopWalk、setColoer三个接口,提供给外部调用。 接口的命名与数量是需要根据具体的业务逻辑的需要,随着人物的动作变化的增加,接口也会增加

以小男孩走路为变化,不同的路段有不同的速率与距离,所以会提供一个走路的walkTo接口给外部。在第三章的时候我把走路动作的一些细节与实现都分解了一遍,这里主要看下怎么融入Deferred的处理

index.html中的代码调用,可以这样理解:

通过加入Deferred的处理,让我们的流程就跟同步一样,这件事完成了就开始下一件事,非常合适人类的线性编程的逻辑,之后的整个流程都会基于then的方式书写

任务

打开index.html文件,在代码的68行填入相应代码,可以观察到之后的更多动作

.then(function() {
    //第二次走
    return boy.walkTo(2000, 0.4)
}).then(function() {
    //第二次走路完成
    boy.setColoer('yellow')
}).then(function() {
    //第三次走路
    return boy.walkTo(2000, 0.6)
}).then(function() {
    //第三次走路完成
    boy.setColoer('blue')
});
  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
  6. <title>慕课七夕主题</title>
  7. <link rel='stylesheet' href='style.css' />
  8. <link rel='stylesheet' href='pageA.css' />
  9. <style type="text/css">
  10. button {
  11. width: 80px;
  12. height: 50px;
  13. }
  14.  
  15. .button {
  16. position: absolute;
  17. bottom: 0;
  18. }
  19. </style>
  20. <script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script>
  21. <script type="text/javascript" src="http://img1.sycdn.imooc.com//down/55ac9ea30001ace700000000.js"></script>
  22. <script type="text/javascript" src="Swipe.js"></script>
  23. <script type="text/javascript" src="BoyWalk.js"></script>
  24. </head>
  25.  
  26. <body>
  27. <div id='content'>
  28. <ul class='content-wrap'>
  29. <li>
  30. <div class="a_background">
  31. <div class="a_background_top"></div>
  32. <div class="a_background_middle"></div>
  33. <div class="a_background_botton"></div>
  34. </div>
  35. </li>
  36. <li> 页面2 </li>
  37. <li> 页面3 </li>
  38. </ul>
  39. <div id="boy" class="charector"></div>
  40. <div class="button">
  41. <button>开始</button>
  42. </div>
  43. </div>
  44. </body>
  45. <script type="text/javascript">
  46. $(function() {
  47.  
  48. var container = $("#content");
  49. var swipe = Swipe(container);
  50.  
  51. ////////////////////////////////////////////////////////
  52. //=================== 动画处理 ====================== //
  53. ////////////////////////////////////////////////////////
  54.  
  55. //////////
  56. // 小孩走路 //
  57. //////////
  58. var boy = BoyWalk();
  59.  
  60. // 开始
  61. $("button:first").click(function() {
  62.  
  63. // 开始第一次走路
  64. boy.walkTo(2000, 0.2)
  65. .then(function() {
  66. //第一次走路完成
  67. boy.setColoer('red')
  68. })
  69.  
  70. });
  71.  
  72. })
  73. </script>
  74.  
  75. </html>
  1. /////////
  2. //页面滑动 //
  3. /////////
  4.  
  5.  
  6. /**
  7.  * [Swipe description]
  8.  * @param {[type]} container [页面容器节点]
  9.  * @param {[type]} options [参数]
  10.  */
  11. function Swipe(container) {
  12. // 获取第一个子节点
  13. var element = container.find(":first");
  14. var swipe = {};
  15.  
  16. // li页面数量
  17. var slides = element.find("li");
  18.  
  19. // 获取容器尺寸
  20. var width = container.width();
  21. var height = container.height();
  22.  
  23. // 设置li页面总宽度
  24. element.css({
  25. width: (slides.length * width) + 'px',
  26. height: height + 'px'
  27. });
  28.  
  29. // 设置每一个页面li的宽度
  30. $.each(slides, function(index) {
  31. var slide = slides.eq(index); // 获取到每一个li元素
  32. slide.css({
  33. width: width + 'px',
  34. height: height + 'px'
  35. });
  36. });
  37.  
  38. //监控完成与移动
  39. swipe.scrollTo = function(x, speed) {
  40. //执行动画移动
  41. element.css({
  42. 'transition-timing-function' : 'linear',
  43. 'transition-duration' : speed + 'ms',
  44. 'transform' : 'translate3d(-' + x + 'px,0px,0px)'
  45. });
  46. return this;
  47. };
  48.  
  49. return swipe;
  50. }
  1. /**
  2.  * 小孩走路
  3.  * @param {[type]} container [description]
  4.  */
  5. function BoyWalk() {
  6.  
  7. var container = $("#content");
  8. // 页面可视区域
  9. var visualWidth = container.width();
  10. var visualHeight = container.height();
  11.  
  12. // 获取数据
  13. var getValue = function(className) {
  14. var $elem = $('' + className + '');
  15. // 走路的路线坐标
  16. return {
  17. height: $elem.height(),
  18. top: $elem.position().top
  19. };
  20. };
  21. // 路的Y轴
  22. var pathY = function() {
  23. var data = getValue('.a_background_middle');
  24. return data.top + data.height / 2;
  25. }();
  26. var $boy = $("#boy");
  27. var boyWidth = $boy.width();
  28. var boyHeight = $boy.height();
  29. // 修正小男孩的正确位置
  30. $boy.css({
  31. top: pathY - boyHeight + 25
  32. });
  33.  
  34. // 暂停走路
  35. function pauseWalk() {
  36. $boy.addClass('pauseWalk');
  37. }
  38.  
  39. // 恢复走路
  40. function restoreWalk() {
  41. $boy.removeClass('pauseWalk');
  42. }
  43.  
  44. // css3的动作变化
  45. function slowWalk() {
  46. $boy.addClass('slowWalk');
  47. }
  48.  
  49. // 用transition做运动
  50. function stratRun(options, runTime) {
  51. var dfdPlay = $.Deferred();
  52. // 恢复走路
  53. restoreWalk();
  54. // 运动的属性
  55. $boy.transition(
  56. options,
  57. runTime,
  58. 'linear',
  59. function() {
  60. dfdPlay.resolve(); // 动画完成
  61. });
  62. return dfdPlay;
  63. }
  64.  
  65. // 开始走路
  66. function walkRun(time, dist, disY) {
  67. time = time || 3000;
  68. // 脚动作
  69. slowWalk();
  70. // 开始走路
  71. var d1 = stratRun({
  72. 'left': dist + 'px',
  73. 'top': disY ? disY : undefined
  74. }, time);
  75. return d1;
  76. }
  77.  
  78. // 计算移动距离
  79. function calculateDist(direction, proportion) {
  80. return (direction == "x" ?
  81. visualWidth : visualHeight) * proportion;
  82. }
  83.  
  84. return {
  85. // 开始走路
  86. walkTo: function(time, proportionX, proportionY) {
  87. var distX = calculateDist('x', proportionX)
  88. var distY = calculateDist('y', proportionY)
  89. return walkRun(time, distX, distY);
  90. },
  91. // 停止走路
  92. stopWalk: function() {
  93. pauseWalk();
  94. },
  95. setColoer:function(value){
  96. $boy.css('background-color',value)
  97. }
  98. }
  99. }
  1. /*背景图*/
  2.  
  3. .a_background {
  4. width: 100%;
  5. height: 100%;
  6. position: absolute;
  7. }
  8.  
  9. .a_background_top{
  10. width: 100%;
  11. height: 71.6%;
  12. background-image: url("http://img1.sycdn.imooc.com//55addf6900019d8f14410645.png");
  13. background-size: 100% 100%;
  14. }
  15.  
  16.  
  17. .a_background_middle{
  18. width: 100%;
  19. height: 13.1%;
  20. background-image: url("http://img1.sycdn.imooc.com//55addf800001ff2e14410118.png");
  21. background-size: 100% 100%;
  22. }
  23.  
  24. .a_background_botton{
  25. width: 100%;
  26. height: 15.3%;
  27. background-image: url("http://img1.sycdn.imooc.com//55addfcb000189b314410138.png");
  28. background-size: 100% 100%;
  29. }
  1. * {
  2. padding: 0;
  3. margin: 0;
  4. }
  5.  
  6. ol,
  7. ul,
  8. li {
  9. list-style-type: none;
  10. }
  11. /*主体部分*/
  12.  
  13. #content {
  14. width: 100%;
  15. height: 100%;
  16. /* top: 20%; */
  17. overflow: hidden;
  18. position: absolute;
  19. }
  20.  
  21. .content-wrap {
  22. position: relative;
  23. }
  24.  
  25. .content-wrap > li {
  26. background: #CAE1FF;
  27. color: red;
  28. float: left;
  29. overflow: hidden;
  30. position: relative;
  31. }
  32.  
  33. li:nth-child(2) {
  34. background: #9BCD9B;
  35. }
  36.  
  37. li:nth-child(3) {
  38. background: yellow;
  39. }
  40.  
  41. a {
  42. position: absolute;
  43. top: 50%;
  44. left: 40%;
  45. }
  46.  
  47. .charector {
  48. left: 0%;
  49. top: 55%;
  50. position: absolute;
  51. width: 100%;
  52. height: 100%;
  53. width: 151px;
  54. height: 291px;
  55. background: url(http://img.mukewang.com/55ade248000198ae10550582.png) -0px -291px no-repeat;
  56. }
  57.  
  58. .slowWalk {
  59. -webkit-animation-name: person-slow;
  60. -webkit-animation-duration: 950ms;
  61. -webkit-animation-iteration-count: infinite;
  62. -webkit-animation-timing-function: steps(1, start);
  63. -moz-animation-name: person-slow;
  64. -moz-animation-duration: 950ms;
  65. -moz-animation-iteration-count: infinite;
  66. -moz-animation-timing-function: steps(1, start)
  67. }
  68. /*普通慢走*/
  69.  
  70. @-webkit-keyframes person-slow {
  71. 0% {
  72. background-position: -0px -291px;
  73. }
  74. 25% {
  75. background-position: -602px -0px;
  76. }
  77. 50% {
  78. background-position: -302px -291px;
  79. }
  80. 75% {
  81. background-position: -151px -291px;
  82. }
  83. 100% {
  84. background-position: -0px -291px;
  85. }
  86. }
  87.  
  88. @-moz-keyframes person-slow {
  89. 0% {
  90. background-position: -0px -291px;
  91. }
  92. 25% {
  93. background-position: -602px -0px;
  94. }
  95. 50% {
  96. background-position: -302px -291px;
  97. }
  98. 75% {
  99. background-position: -151px -291px;
  100. }
  101. 100% {
  102. background-position: -0px -291px;
  103. }
  104. }
下一节