5-4 3D开窗效果
本节编程练习不计算学习进度,请电脑登录imooc.com操作

3D开窗效果

当圣诞雪橇飞到窗户前时,在设计上窗户会开打了。在圣诞中采用了"开门式","开门式"可以营造一个3d的感觉

"开门式"的效果:

左右2片窗户需要慢慢的向内打开,门在变化的过程中是需要有个3d的视角变化的,门内需要有一个背景图

简单的说下原理:

在"开门式"中需要用到rotateY与scale,通过对rotateY角度的变化,从而产生开门的视角,这里需要引入一些3d属性设置,具体在之前就已经学习过了,如果不记得了请看3D变换的梳理那一节

整个效果是JS+CSS结合处理的,分别定义在pageA.js中的openWindow方法,在pageA.css中,窗户的底边与阴影是采用的before与after伪元素增加的,减少了html结构

在openWindow方法中,动态的通过JS对"门"增加对应的样式,从而执行动画

this.$leftWin.addClass("window-transition").addClass("hover")
this.$rightWin.addClass("window-transition").addClass("hover")

window-transition:定义的一个transition过渡动画,

hover:定义了一个transform过渡动画执行的变换 scale(0.95) rotateY(60deg)

通过增加2个CSS样式后,“门”自然就会开了。

还要注意:为了衔接后续的动作,所以需要针对这个动画做监听,这样才能能确保动画之后执行之后的动作,这里监听transitionend事件

element.one("transitionend webkitTransitionEnd", function(event) {
     complete()
})

注意必须要等2个动画都结束后才能执行后续的动作,是需要监听2个开门动作的动画完成了

 var complete = function() {
        ++count
        if (count === 2) {
            callback && callback();
        }
 }

任务

请在pageA.css代码143,147行处填入css样式,执行3d开窗的样式效果

左边:

缩放0.95倍,rotateY角度是60,top=0.1rem left= - 0.25rem

右边:

缩放0.95倍,rotateY角度是-60,top=0.1rem left= -0.25rem

  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='common.css' />
  8. <script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script>
  9. <script type="text/javascript" src="http://img1.sycdn.imooc.com//down/55ac9ea30001ace700000000.js"></script>
  10. <link rel="stylesheet" type="text/css" href="pageA.css">
  11. <script src="pageA.js"></script>
  12. <script src="christmas.js"></script>
  13. </head>
  14.  
  15. <body>
  16. <section class="container">
  17. <!-- 第一幅画面 -->
  18. <section class="page-a bg-adaptive">
  19. <!-- 男孩 -->
  20. <div class="chs-boy chs-boy-deer"></div>
  21. <!-- 窗户 -->
  22. <div class="window wood">
  23. <div class="window-bg"></div>
  24. <div class="window-content">
  25. <div class="window-left"></div>
  26. <div class="window-right"></div>
  27. </div>
  28. </div>
  29. </section>
  30. <!-- 第二幅画面 -->
  31. <section class="page-b bg-adaptive">
  32. </section>
  33. <!-- 第三幅画面 -->
  34. <section class="page-c bg-adaptive">
  35. </section>
  36. </section>
  37. <button>点击开窗户</button>
  38. <script type="text/javascript">
  39. //rem设置
  40. (function(doc, win) {
  41. var docEl = doc.documentElement,
  42. resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
  43. recalc = function() {
  44. var clientWidth = docEl.clientWidth;
  45. if (!clientWidth) return;
  46. docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';
  47. //宽与高度
  48. document.body.style.height = clientWidth * (900 / 1440) + "px"
  49. };
  50. win.addEventListener(resizeEvt, recalc, false);
  51. doc.addEventListener('DOMContentLoaded', recalc, false);
  52. })(document, window);
  53.  
  54. </script>
  55. </body>
  56.  
  57. </html>
  58.  
  1. /**
  2.  * 慕课网特制
  3.  * 圣诞主题效果
  4.  * @type {Object}
  5.  */
  6.  
  7. /**
  8.  * 中间调用
  9.  */
  10. var Christmas = function() {
  11. //页面容器元素
  12. var $pageA = $(".page-a");
  13.  
  14. //构建第一个场景页面对象
  15. new pageA($pageA);
  16. };
  17.  
  18. $(function() {
  19. //圣诞主题效果,开始
  20. $("button").on("click",function(){Christmas()})
  21. })
  1. /**
  2.  * 第一副场景页面
  3.  * @param {[type]} argument [description]
  4.  * @return {[type]} [description]
  5.  */
  6. function pageA(element) {
  7. //根元素
  8. this.$root = element;
  9. //小男孩
  10. this.$boy = element.find(".chs-boy");
  11. //窗户
  12. this.$window = element.find(".window");
  13. this.$leftWin = this.$window.find(".window-left")
  14. this.$rightWin = this.$window.find(".window-right")
  15. //运行动画
  16. this.run();
  17. }
  18.  
  19. /**
  20.  * 开窗
  21.  * @return {[type]} [description]
  22.  */
  23. pageA.prototype.openWindow = function(callback) {
  24. var count = 1;
  25. var complete = function() {
  26. ++count
  27. if (count === 2) {
  28. callback && callback();
  29. }
  30. }
  31. var bind = function(data) {
  32. data.one("transitionend webkitTransitionEnd", function(event) {
  33. data.removeClass("window-transition")
  34. complete()
  35. })
  36. }
  37. bind(this.$leftWin.addClass("window-transition").addClass("hover"))
  38. bind(this.$rightWin.addClass("window-transition").addClass("hover"))
  39. }
  40.  
  41.  
  42. /**
  43.  * 运行下一个动画
  44.  * @return {Function} [description]
  45.  */
  46. pageA.prototype.next = function(options) {
  47. var dfd = $.Deferred();
  48. this.$boy.transition(options.style, options.time, "linear", function() {
  49. dfd.resolve()
  50. });
  51. return dfd;
  52. }
  53.  
  54.  
  55. /**
  56.  * 停止走路
  57.  * @return {[type]} [description]
  58.  */
  59. pageA.prototype.stopWalk = function() {
  60. this.$boy.removeClass("chs-boy-deer")
  61. }
  62.  
  63. /**
  64.  * 路径
  65.  * @return {[type]} [description]
  66.  */
  67. pageA.prototype.run = function(callback) {
  68. var that = this;
  69. var next = function() {
  70. return this.next.apply(this, arguments)
  71. }.bind(this)
  72.  
  73. next({})
  74. .then(function() {
  75. // that.stopWalk();
  76. that.openWindow(function() {
  77. alert("窗户已打开")
  78. });
  79. })
  80. }
  81.  
  1. *{
  2. margin: 0;
  3. padding: 0;
  4. }
  5.  
  6.  
  7. .container {
  8. width: 100%;
  9. height: 100%;
  10. position: relative;
  11. overflow: hidden;
  12. }
  13.  
  14. .bg-adaptive {
  15. background-size: 100% 100%;
  16. }
  17.  
  18.  
  19.  
  20.  
  1. /**
  2.  * 背景布置
  3.  */
  4. .container .page-a {
  5. width : 100%;
  6. height : 100%;
  7. background-image: url("http://img1.sycdn.imooc.com//565d07770001790814410901.png");
  8. position: absolute;
  9. z-index: 5;
  10. }
  11.  
  12. /**
  13.  * 窗户
  14.  */
  15.  
  16. .window {
  17. width: 2.6rem;
  18. height: 1.5rem;
  19. position: absolute;
  20. left: 9.7rem;
  21. top: 6.2rem;
  22. cursor: pointer;
  23. -webkit-perspective: 500px;
  24. -moz-perspective: 500px;
  25. }
  26.  
  27. .window-content {
  28. -webkit-transform-style: preserve-3d;
  29. -moz-transform-style: preserve-3d;
  30. width: 91%;
  31. margin: 0 auto;
  32. height: 100%;
  33. overflow: hidden;
  34. }
  35.  
  36.  
  37. /**
  38.  * 窗户背景
  39.  */
  40.  
  41. .window-bg {
  42. width: 86%;
  43. height: 92%;
  44. position: absolute;
  45. left: 50%;
  46. margin-left: -43%;
  47. bottom: 0;
  48. background: url(http://img.mukewang.com/565d07770001790814410901.png);
  49. background-size: 100% 100%;
  50. z-index: -1;
  51. }
  52.  
  53.  
  54. /**
  55.  * 窗户底边
  56.  * @type {[type]}
  57.  */
  58.  
  59. .window:before {
  60. content: "";
  61. background: url(http://img.mukewang.com/565d07e40001088402410017.png);
  62. width: 100%;
  63. height: 0.17rem;
  64. display: block;
  65. position: absolute;
  66. bottom: 0.05rem;
  67. background-size: 100% 100%;
  68. z-index: 100;
  69. }
  70.  
  71.  
  72. /**
  73.  * 底边阴影
  74.  * @type {[type]}
  75.  */
  76.  
  77. .window:after {
  78. content: "";
  79. background: url(http://img.mukewang.com/565d080400018d2702270009.png);
  80. width: 100%;
  81. height: 0.09rem;
  82. display: block;
  83. position: absolute;
  84. bottom: 0;
  85. background-size: 100% 100%;
  86. z-index: 100;
  87. }
  88.  
  89. .wood {
  90. display: block;
  91. overflow: hidden;
  92. }
  93.  
  94.  
  95. /**
  96.  * 左侧门
  97.  */
  98.  
  99. .window-left {
  100. float: left;
  101. background: url(http://img.mukewang.com/565d081d0001cfd901140134.png);
  102. -webkit-border-top-left-radius: 0.1rem;
  103. -moz-border-top-left-radius: 0.1rem;
  104. }
  105.  
  106.  
  107. /**
  108.  * 右侧门
  109.  */
  110.  
  111. .window-right {
  112. float: right;
  113. background: url(http://img.mukewang.com/565d084c0001431b01140134.png);
  114. -webkit-border-top-right-radius: 0.1rem;
  115. -moz-border-top-left-radius: 0.1rem;
  116. }
  117.  
  118. .window-left,
  119. .window-right {
  120. width: 1.17rem;
  121. height: 1.3rem;
  122. z-index: 110;
  123. box-shadow: 0 0 0.15rem #FCF0BC;
  124. background-size: 100% 100%;
  125. }
  126.  
  127. .window-animation {
  128. -webkit-transition: 2s ease-in-out;
  129. -moz-transition: 2s ease-in-out;
  130. }
  131.  
  132.  
  133. /**
  134.  * 动画过程
  135.  */
  136.  
  137. .window-transition {
  138. -webkit-transition: 2s ease-in-out;
  139. -moz-transition: 2s ease-in-out;
  140. }
  141.  
  142. .window-left.hover {
  143. /**?**/
  144. }
  145.  
  146. .window-right.hover {
  147. /**?**/
  148. }
  149.  
下一节