6-6 3D旋转视频
本节编程练习不计算学习进度,请电脑登录imooc.com操作

3D旋转视频

3D动画旋转停止后会播放对应页面的视频,这里视频采用的是HTML5的Video标签播放的。为了便于理解,我把视频的代码也一并写到了Carousel类里面,具体请参考this.palyVideo这个方法,然后在Carousel的入口处传入视频的源地址。

视频的衔接是必须在动画之后的,所以这里同样会与旋转动画绑定一个transitionend事件(旋转式通过过渡transitions的方式实现的)

pageB.js中的调用代码,在run方法中传递一个回调,监听了transitionend事件结束后触发视频,流程部分就是这样衔接的。

carousel.run(i++, function() {
    //播放视频
    carousel.palyVideo()
})

视频的代码结构:

通过jQuery动态创建一个video结构,并赋予了视频地址 options.videoUrls[index]),index是页码的索引,videoUrls是传入的视频地址数组,并加入到页面中去。

绑定loadeddata,监听到视频数据加载完成后开始播放视频。视频在出现是时候会带有一个弹跳的效果bounceIn,这个是用css3动画实现的,具体在pageB.css里面。

绑定ended事件,监听视频播放结束后删除这个节点。

同样的视频可能需要衔接后续的动作,可以在loadeddata与ended中加入完成的回调函数即可。

任务

在carousel.js文件中182处填入任务代码

监听视频数据完成后,并让其播放

  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. <link rel="stylesheet" type="text/css" href="pageB.css">
  9. <script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script>
  10. <script type="text/javascript" src="http://img1.sycdn.imooc.com//down/55ac9ea30001ace700000000.js"></script>
  11. <script src="carousel.js"></script>
  12. <script src="pageB.js"></script>
  13. <script src="christmas.js"></script>
  14. </head>
  15.  
  16. <body>
  17. <section class="container">
  18. <!-- 第一幅画面 -->
  19. <section class="page-a bg-adaptive">
  20. </section>
  21. <!-- 第二幅画面 -->
  22. <section class="page-b bg-adaptive">
  23. <!-- 猫 -->
  24. <figure class="cat"></figure>
  25. <!-- 小女孩 -->
  26. <figure class="girl"></figure>
  27. <!-- 圣诞男孩 -->
  28. <figure class="christmas-boy-head"></figure>
  29. <figure class="christmas-boy boy-walk"> </figure>
  30. <!-- 旋转木马 -->
  31. <div id="carousel">
  32. <figure id="spinner"></figure>
  33. </div>
  34. </section>
  35. <!-- 第三幅画面 -->
  36. <section class="page-c bg-adaptive">
  37. </section>
  38. </section>
  39. <button>点击执行</button>
  40. <script type="text/javascript">
  41. //rem设置
  42. (function(doc, win) {
  43. var docEl = doc.documentElement,
  44. resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
  45. recalc = function() {
  46. var clientWidth = docEl.clientWidth;
  47. if (!clientWidth) return;
  48. docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';
  49. //宽与高度
  50. document.body.style.height = clientWidth * (900 / 1440) + "px"
  51. };
  52. win.addEventListener(resizeEvt, recalc, false);
  53. doc.addEventListener('DOMContentLoaded', recalc, false);
  54. })(document, window);
  55. </script>
  56. </body>
  57.  
  58. </html>
  59.  
  1. /**
  2.  * 慕课网特制
  3.  * 圣诞主题效果
  4.  * @type {Object}
  5.  */
  6.  
  7. /**
  8.  * 中间调用
  9.  */
  10. var Christmas = function() {
  11. //页面容器元素
  12. var $pageB = $(".page-b");
  13. //构建第二个场景页面对象
  14. new pageB($pageB);
  15. };
  16.  
  17. $(function() {
  18. Christmas();
  19. })
  1. /**
  2.  * 第二副场景页面
  3.  *
  4.  */
  5. function pageB(element, pageComplete) {
  6.  
  7. //3d旋转节点
  8. var $carousel = element.find("#carousel");
  9.  
  10. //旋转木马对象
  11. var carousel = new Carousel($carousel, {
  12. imgUrls: [
  13. "http://img1.sycdn.imooc.com//5662e29a0001905a14410901.png",
  14. "http://img1.sycdn.imooc.com//5662e2960001f16314410901.png",
  15. "http://img1.sycdn.imooc.com//5662e26f00010dea14410901.png"
  16. ],
  17. videoUrls: [
  18. "http://www.imooc.com/upload/media/qx-one.mp4",
  19. "http://www.imooc.com/upload/media/qx-two.mp4",
  20. "http://www.imooc.com/upload/media/qx-three.mp4"
  21. ]
  22. });
  23.  
  24. var i = 0;
  25. $("button").on("click", function() {
  26. carousel.run(i++, function() {
  27. //播放视频
  28. carousel.palyVideo()
  29. })
  30. })
  31.  
  32.  
  33. }
  34.  
  1. //================================================
  2. //格式化字符串
  3. var slice = Array.prototype.slice
  4.  
  5. function toArray(a, i, j) {
  6. return slice.call(a, i || 0, j || a.length);
  7. }
  8. /**
  9.  * 返回true,如果传递的值不是未定义。
  10.  * @param {Mixed}
  11.  * @return {Boolean}
  12.  */
  13. function isDefined(v) {
  14. return typeof v !== 'undefined';
  15. }
  16.  
  17. /**
  18.  * 拷贝对象,跳过已存在的
  19.  * @param {[type]} o [接受方对象]
  20.  * @param {[type]} c [源对象]
  21.  * @return {[type]} [description]
  22.  */
  23. function applyIf(o, c) {
  24. if (o) {
  25. for (var p in c) {
  26. //跳过已存在
  27. if (!isDefined(o[p])) {
  28. o[p] = c[p];
  29. }
  30. }
  31. }
  32. return o;
  33. }
  34. /**
  35.  * @class String
  36.  * 格式化字符串
  37.  */
  38. applyIf(String, {
  39. format: function(format) {
  40. var args = toArray(arguments, 1);
  41. return format.replace(/\{(\d+)\}/g, function(m, i) {
  42. return args[i];
  43. });
  44. }
  45. });
  46.  
  47.  
  48. /**
  49.  * 3d旋转木马
  50.  * @param {[type]} argument [description]
  51.  * @return {[type]} [description]
  52.  */
  53. function Carousel(carousel, options) {
  54. //图片
  55. var imgUrls = options.imgUrls;
  56. //场景元素
  57. var $carousel = carousel;
  58. //容器元素
  59. var $spinner = carousel.find("#spinner");
  60. var angle = 0;
  61. //图片数
  62. var numpics = imgUrls.length;
  63. //角度
  64. var rotate = 360 / numpics;
  65. var start = 0;
  66. var current = 1;
  67. //子元素
  68. var $contentElements;
  69.  
  70. //图片数量
  71. this.numpics = numpics;
  72.  
  73. /**
  74.   * 创建结构
  75.   * @param {[type]} imgUrl [description]
  76.   * @return {[type]} [description]
  77.   */
  78. function createStr(imgUrl) {
  79. var str = '<figure style="transform:rotateY({0}deg) translateZ({1}) scaleY(.9);position:absolute;">' + '<img src="{2}" style="width:100%;height:100%;">' + '</figure>';
  80.  
  81. return String.format(str,
  82. start,
  83. "2.5rem",
  84. imgUrl
  85. )
  86. }
  87.  
  88. /**
  89.   * 初始化样式
  90.   * @return {[type]} [description]
  91.   */
  92. function initStyle() {
  93. //场景元素
  94. $carousel.css({
  95. // "transform": "scale(0.3)",
  96. "-webkit-perspective": "500",
  97. "-moz-perspective": "500px",
  98. "position": "absolute",
  99. "left": "6.8rem",
  100. "top": "4.5rem"
  101. });
  102. //容器
  103. $spinner.css({
  104. "width": "4rem",
  105. "transform-style": "preserve-3d",
  106. "transition": "1s"
  107. })
  108. }
  109.  
  110. /**
  111.   * 绘制页面节点
  112.   * @return {[type]} [description]
  113.   */
  114. function render() {
  115. //创建内容
  116. var contentStr = '';
  117. $.each(imgUrls, function(index, url) {
  118. contentStr += createStr(url);
  119. start = start + rotate;
  120. })
  121. $contentElements = $(contentStr);
  122. $spinner.append($contentElements)
  123. }
  124.  
  125. //样式
  126. initStyle();
  127. //绘制节点
  128. render();
  129.  
  130.  
  131. //旋转次数,游标,当前页码
  132. var currIndex;
  133.  
  134. /**
  135.   * 运行旋转
  136.   * @param {[type]} count [description]
  137.   * @param {Function} callback [description]
  138.   * @return {[type]} [description]
  139.   */
  140. this.run = function(count, callback) {
  141. currIndex = count;
  142. //360
  143. //480
  144. //600
  145. angle = (count - 1) * rotate + 360
  146. $spinner
  147. .css("-moz-transform", "rotateY(-" + angle + "deg)")
  148. .css("transform", "rotateY(-" + angle + "deg)")
  149. .one("transitionend webkitTransitionend", function() {
  150. callback()
  151. })
  152. }
  153.  
  154. /**
  155.   * 视频播放
  156.   * @param {[type]} index [description]
  157.   * @param {[type]} element [description]
  158.   * @return {[type]} [description]
  159.   */
  160. this.palyVideo = function() {
  161. //索引从0开始
  162. var index = currIndex
  163.  
  164. var element = element || $contentElements.eq(index)
  165.  
  166. /**
  167.   * vide标签
  168.   * @type {[type]}
  169.   */
  170. var $video = $('<video preload="auto" class="bounceIn" style="width:50%;height:50%;position:absolute;left:30%;top:35%;"></video>');
  171.  
  172. $video.css({
  173. "position": "absolute",
  174. "z-index": "999"
  175. })
  176.  
  177. //地址
  178. $video.attr('src', options.videoUrls[index]);
  179.  
  180. //播放
  181. ///?
  182.  
  183. //停止
  184. $video.on("ended", function() {
  185. $video[0].pause()
  186. //退出效果
  187. $video.addClass("bounceOut").one("animationend webkitAnimationEnd", function() {
  188. $video.remove();
  189. })
  190. })
  191.  
  192. $carousel.after($video)
  193. }
  194.  
  195.  
  196. }
  197.  
  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. }
  1. .container .page-b {
  2. width : 100%;
  3. height : 100%;
  4. background-image: url("http://img1.sycdn.imooc.com//565d09fa000145a614410901.png");
  5. position: absolute;
  6. z-index: 40;
  7. }
  8.  
  9.  
  10. @-webkit-keyframes bounceIn {
  11. from, 20%, 40%, 60%, 80%, to {
  12. -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
  13. animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
  14. }
  15.  
  16. 0% {
  17. opacity: 0;
  18. -webkit-transform: scale3d(.3, .3, .3);
  19. transform: scale3d(.3, .3, .3);
  20. }
  21.  
  22. 20% {
  23. -webkit-transform: scale3d(1.1, 1.1, 1.1);
  24. transform: scale3d(1.1, 1.1, 1.1);
  25. }
  26.  
  27. 40% {
  28. -webkit-transform: scale3d(.9, .9, .9);
  29. transform: scale3d(.9, .9, .9);
  30. }
  31.  
  32. 60% {
  33. opacity: 1;
  34. -webkit-transform: scale3d(1.03, 1.03, 1.03);
  35. transform: scale3d(1.03, 1.03, 1.03);
  36. }
  37.  
  38. 80% {
  39. -webkit-transform: scale3d(.97, .97, .97);
  40. transform: scale3d(.97, .97, .97);
  41. }
  42.  
  43. to {
  44. opacity: 1;
  45. -webkit-transform: scale3d(1, 1, 1);
  46. transform: scale3d(1, 1, 1);
  47. }
  48. }
  49.  
  50. @keyframes bounceIn {
  51. from, 20%, 40%, 60%, 80%, to {
  52. -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
  53. animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
  54. }
  55.  
  56. 0% {
  57. opacity: 0;
  58. -webkit-transform: scale3d(.3, .3, .3);
  59. transform: scale3d(.3, .3, .3);
  60. }
  61.  
  62. 20% {
  63. -webkit-transform: scale3d(1.1, 1.1, 1.1);
  64. transform: scale3d(1.1, 1.1, 1.1);
  65. }
  66.  
  67. 40% {
  68. -webkit-transform: scale3d(.9, .9, .9);
  69. transform: scale3d(.9, .9, .9);
  70. }
  71.  
  72. 60% {
  73. opacity: 1;
  74. -webkit-transform: scale3d(1.03, 1.03, 1.03);
  75. transform: scale3d(1.03, 1.03, 1.03);
  76. }
  77.  
  78. 80% {
  79. -webkit-transform: scale3d(.97, .97, .97);
  80. transform: scale3d(.97, .97, .97);
  81. }
  82.  
  83. to {
  84. opacity: 1;
  85. -webkit-transform: scale3d(1, 1, 1);
  86. transform: scale3d(1, 1, 1);
  87. }
  88. }
  89.  
  90.  
  91. .bounceIn {
  92. -webkit-animation-duration: 1s;
  93. animation-duration: 1s;
  94. -webkit-animation-name: bounceIn;
  95. animation-name: bounceIn;
  96. }
  97.  
  98.  
  99.  
  100. @-webkit-keyframes bounceOut {
  101. 20% {
  102. -webkit-transform: scale3d(.9, .9, .9);
  103. transform: scale3d(.9, .9, .9);
  104. }
  105.  
  106. 50%, 55% {
  107. opacity: 1;
  108. -webkit-transform: scale3d(1.1, 1.1, 1.1);
  109. transform: scale3d(1.1, 1.1, 1.1);
  110. }
  111.  
  112. to {
  113. opacity: 0;
  114. -webkit-transform: scale3d(.3, .3, .3);
  115. transform: scale3d(.3, .3, .3);
  116. }
  117. }
  118.  
  119. @keyframes bounceOut {
  120. 20% {
  121. -webkit-transform: scale3d(.9, .9, .9);
  122. transform: scale3d(.9, .9, .9);
  123. }
  124.  
  125. 50%, 55% {
  126. opacity: 1;
  127. -webkit-transform: scale3d(1.1, 1.1, 1.1);
  128. transform: scale3d(1.1, 1.1, 1.1);
  129. }
  130.  
  131. to {
  132. opacity: 0;
  133. -webkit-transform: scale3d(.3, .3, .3);
  134. transform: scale3d(.3, .3, .3);
  135. }
  136. }
  137.  
  138. .bounceOut {
  139. -webkit-animation-duration: 1s;
  140. animation-duration: 1s;
  141. -webkit-animation-name: bounceOut;
  142. animation-name: bounceOut;
  143. }
下一节