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处填入任务代码
监听视频数据完成后,并让其播放
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title>圣诞主题</title> <link rel='stylesheet' href='common.css' /> <link rel="stylesheet" type="text/css" href="pageB.css"> <script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script> <script type="text/javascript" src="http://img1.sycdn.imooc.com//down/55ac9ea30001ace700000000.js"></script> <script src="carousel.js"></script> <script src="pageB.js"></script> <script src="christmas.js"></script> </head> <body> <section class="container"> <!-- 第一幅画面 --> <section class="page-a bg-adaptive"> </section> <!-- 第二幅画面 --> <section class="page-b bg-adaptive"> <!-- 猫 --> <figure class="cat"></figure> <!-- 小女孩 --> <figure class="girl"></figure> <!-- 圣诞男孩 --> <figure class="christmas-boy-head"></figure> <figure class="christmas-boy boy-walk"> </figure> <!-- 旋转木马 --> <div id="carousel"> <figure id="spinner"></figure> </div> </section> <!-- 第三幅画面 --> <section class="page-c bg-adaptive"> </section> </section> <button>点击执行</button> <script type="text/javascript"> //rem设置 (function(doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function() { var clientWidth = docEl.clientWidth; if (!clientWidth) return; docEl.style.fontSize = 20 * (clientWidth / 320) + 'px'; //宽与高度 document.body.style.height = clientWidth * (900 / 1440) + "px" }; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener('DOMContentLoaded', recalc, false); })(document, window); </script> </body> </html>
/** * 慕课网特制 * 圣诞主题效果 * @type {Object} */ /** * 中间调用 */ var Christmas = function() { //页面容器元素 var $pageB = $(".page-b"); //构建第二个场景页面对象 new pageB($pageB); }; $(function() { Christmas(); })
/** * 第二副场景页面 * */ function pageB(element, pageComplete) { //3d旋转节点 var $carousel = element.find("#carousel"); //旋转木马对象 var carousel = new Carousel($carousel, { imgUrls: [ "http://img1.sycdn.imooc.com//5662e29a0001905a14410901.png", "http://img1.sycdn.imooc.com//5662e2960001f16314410901.png", "http://img1.sycdn.imooc.com//5662e26f00010dea14410901.png" ], videoUrls: [ "http://www.imooc.com/upload/media/qx-one.mp4", "http://www.imooc.com/upload/media/qx-two.mp4", "http://www.imooc.com/upload/media/qx-three.mp4" ] }); var i = 0; $("button").on("click", function() { carousel.run(i++, function() { //播放视频 carousel.palyVideo() }) }) }
//================================================ //格式化字符串 var slice = Array.prototype.slice function toArray(a, i, j) { return slice.call(a, i || 0, j || a.length); } /** * 返回true,如果传递的值不是未定义。 * @param {Mixed} * @return {Boolean} */ function isDefined(v) { return typeof v !== 'undefined'; } /** * 拷贝对象,跳过已存在的 * @param {[type]} o [接受方对象] * @param {[type]} c [源对象] * @return {[type]} [description] */ function applyIf(o, c) { if (o) { for (var p in c) { //跳过已存在 if (!isDefined(o[p])) { o[p] = c[p]; } } } return o; } /** * @class String * 格式化字符串 */ applyIf(String, { format: function(format) { var args = toArray(arguments, 1); return format.replace(/\{(\d+)\}/g, function(m, i) { return args[i]; }); } }); /** * 3d旋转木马 * @param {[type]} argument [description] * @return {[type]} [description] */ function Carousel(carousel, options) { //图片 var imgUrls = options.imgUrls; //场景元素 var $carousel = carousel; //容器元素 var $spinner = carousel.find("#spinner"); var angle = 0; //图片数 var numpics = imgUrls.length; //角度 var rotate = 360 / numpics; var start = 0; var current = 1; //子元素 var $contentElements; //图片数量 this.numpics = numpics; /** * 创建结构 * @param {[type]} imgUrl [description] * @return {[type]} [description] */ function createStr(imgUrl) { var str = '<figure style="transform:rotateY({0}deg) translateZ({1}) scaleY(.9);position:absolute;">' + '<img src="{2}" style="width:100%;height:100%;">' + '</figure>'; return String.format(str, start, "2.5rem", imgUrl ) } /** * 初始化样式 * @return {[type]} [description] */ function initStyle() { //场景元素 $carousel.css({ // "transform": "scale(0.3)", "-webkit-perspective": "500", "-moz-perspective": "500px", "position": "absolute", "left": "6.8rem", "top": "4.5rem" }); //容器 $spinner.css({ "width": "4rem", "transform-style": "preserve-3d", "transition": "1s" }) } /** * 绘制页面节点 * @return {[type]} [description] */ function render() { //创建内容 var contentStr = ''; $.each(imgUrls, function(index, url) { contentStr += createStr(url); start = start + rotate; }) $contentElements = $(contentStr); $spinner.append($contentElements) } //样式 initStyle(); //绘制节点 render(); //旋转次数,游标,当前页码 var currIndex; /** * 运行旋转 * @param {[type]} count [description] * @param {Function} callback [description] * @return {[type]} [description] */ this.run = function(count, callback) { currIndex = count; //360 //480 //600 angle = (count - 1) * rotate + 360 $spinner .css("-moz-transform", "rotateY(-" + angle + "deg)") .css("transform", "rotateY(-" + angle + "deg)") .one("transitionend webkitTransitionend", function() { callback() }) } /** * 视频播放 * @param {[type]} index [description] * @param {[type]} element [description] * @return {[type]} [description] */ this.palyVideo = function() { //索引从0开始 var index = currIndex var element = element || $contentElements.eq(index) /** * vide标签 * @type {[type]} */ var $video = $('<video preload="auto" class="bounceIn" style="width:50%;height:50%;position:absolute;left:30%;top:35%;"></video>'); $video.css({ "position": "absolute", "z-index": "999" }) //地址 $video.attr('src', options.videoUrls[index]); //播放 ///? //停止 $video.on("ended", function() { $video[0].pause() //退出效果 $video.addClass("bounceOut").one("animationend webkitAnimationEnd", function() { $video.remove(); }) }) $carousel.after($video) } }
*{ margin: 0; padding: 0; } .container { width: 100%; height: 100%; position: relative; overflow: hidden; } .bg-adaptive { background-size: 100% 100%; }
.container .page-b { width : 100%; height : 100%; background-image: url("http://img1.sycdn.imooc.com//565d09fa000145a614410901.png"); position: absolute; z-index: 40; } @-webkit-keyframes bounceIn { from, 20%, 40%, 60%, 80%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 0% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 20% { -webkit-transform: scale3d(1.1, 1.1, 1.1); transform: scale3d(1.1, 1.1, 1.1); } 40% { -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 60% { opacity: 1; -webkit-transform: scale3d(1.03, 1.03, 1.03); transform: scale3d(1.03, 1.03, 1.03); } 80% { -webkit-transform: scale3d(.97, .97, .97); transform: scale3d(.97, .97, .97); } to { opacity: 1; -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } @keyframes bounceIn { from, 20%, 40%, 60%, 80%, to { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 0% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 20% { -webkit-transform: scale3d(1.1, 1.1, 1.1); transform: scale3d(1.1, 1.1, 1.1); } 40% { -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 60% { opacity: 1; -webkit-transform: scale3d(1.03, 1.03, 1.03); transform: scale3d(1.03, 1.03, 1.03); } 80% { -webkit-transform: scale3d(.97, .97, .97); transform: scale3d(.97, .97, .97); } to { opacity: 1; -webkit-transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } } .bounceIn { -webkit-animation-duration: 1s; animation-duration: 1s; -webkit-animation-name: bounceIn; animation-name: bounceIn; } @-webkit-keyframes bounceOut { 20% { -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 50%, 55% { opacity: 1; -webkit-transform: scale3d(1.1, 1.1, 1.1); transform: scale3d(1.1, 1.1, 1.1); } to { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } } @keyframes bounceOut { 20% { -webkit-transform: scale3d(.9, .9, .9); transform: scale3d(.9, .9, .9); } 50%, 55% { opacity: 1; -webkit-transform: scale3d(1.1, 1.1, 1.1); transform: scale3d(1.1, 1.1, 1.1); } to { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } } .bounceOut { -webkit-animation-duration: 1s; animation-duration: 1s; -webkit-animation-name: bounceOut; animation-name: bounceOut; }