当圣诞雪橇飞到窗户前时,在设计上窗户会开打了。在圣诞中采用了"开门式","开门式"可以营造一个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
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title>圣诞主题</title> <link rel='stylesheet' href='common.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> <link rel="stylesheet" type="text/css" href="pageA.css"> <script src="pageA.js"></script> <script src="christmas.js"></script> </head> <body> <section class="container"> <!-- 第一幅画面 --> <section class="page-a bg-adaptive"> <!-- 男孩 --> <div class="chs-boy chs-boy-deer"></div> <!-- 窗户 --> <div class="window wood"> <div class="window-bg"></div> <div class="window-content"> <div class="window-left"></div> <div class="window-right"></div> </div> </div> </section> <!-- 第二幅画面 --> <section class="page-b bg-adaptive"> </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 $pageA = $(".page-a"); //构建第一个场景页面对象 new pageA($pageA); }; $(function() { //圣诞主题效果,开始 $("button").on("click",function(){Christmas()}) })
/** * 第一副场景页面 * @param {[type]} argument [description] * @return {[type]} [description] */ function pageA(element) { //根元素 this.$root = element; //小男孩 this.$boy = element.find(".chs-boy"); //窗户 this.$window = element.find(".window"); this.$leftWin = this.$window.find(".window-left") this.$rightWin = this.$window.find(".window-right") //运行动画 this.run(); } /** * 开窗 * @return {[type]} [description] */ pageA.prototype.openWindow = function(callback) { var count = 1; var complete = function() { ++count if (count === 2) { callback && callback(); } } var bind = function(data) { data.one("transitionend webkitTransitionEnd", function(event) { data.removeClass("window-transition") complete() }) } bind(this.$leftWin.addClass("window-transition").addClass("hover")) bind(this.$rightWin.addClass("window-transition").addClass("hover")) } /** * 运行下一个动画 * @return {Function} [description] */ pageA.prototype.next = function(options) { var dfd = $.Deferred(); this.$boy.transition(options.style, options.time, "linear", function() { dfd.resolve() }); return dfd; } /** * 停止走路 * @return {[type]} [description] */ pageA.prototype.stopWalk = function() { this.$boy.removeClass("chs-boy-deer") } /** * 路径 * @return {[type]} [description] */ pageA.prototype.run = function(callback) { var that = this; var next = function() { return this.next.apply(this, arguments) }.bind(this) next({}) .then(function() { // that.stopWalk(); that.openWindow(function() { alert("窗户已打开") }); }) }
*{ margin: 0; padding: 0; } .container { width: 100%; height: 100%; position: relative; overflow: hidden; } .bg-adaptive { background-size: 100% 100%; }
/** * 背景布置 */ .container .page-a { width : 100%; height : 100%; background-image: url("http://img1.sycdn.imooc.com//565d07770001790814410901.png"); position: absolute; z-index: 5; } /** * 窗户 */ .window { width: 2.6rem; height: 1.5rem; position: absolute; left: 9.7rem; top: 6.2rem; cursor: pointer; -webkit-perspective: 500px; -moz-perspective: 500px; } .window-content { -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; width: 91%; margin: 0 auto; height: 100%; overflow: hidden; } /** * 窗户背景 */ .window-bg { width: 86%; height: 92%; position: absolute; left: 50%; margin-left: -43%; bottom: 0; background: url(http://img.mukewang.com/565d07770001790814410901.png); background-size: 100% 100%; z-index: -1; } /** * 窗户底边 * @type {[type]} */ .window:before { content: ""; background: url(http://img.mukewang.com/565d07e40001088402410017.png); width: 100%; height: 0.17rem; display: block; position: absolute; bottom: 0.05rem; background-size: 100% 100%; z-index: 100; } /** * 底边阴影 * @type {[type]} */ .window:after { content: ""; background: url(http://img.mukewang.com/565d080400018d2702270009.png); width: 100%; height: 0.09rem; display: block; position: absolute; bottom: 0; background-size: 100% 100%; z-index: 100; } .wood { display: block; overflow: hidden; } /** * 左侧门 */ .window-left { float: left; background: url(http://img.mukewang.com/565d081d0001cfd901140134.png); -webkit-border-top-left-radius: 0.1rem; -moz-border-top-left-radius: 0.1rem; } /** * 右侧门 */ .window-right { float: right; background: url(http://img.mukewang.com/565d084c0001431b01140134.png); -webkit-border-top-right-radius: 0.1rem; -moz-border-top-left-radius: 0.1rem; } .window-left, .window-right { width: 1.17rem; height: 1.3rem; z-index: 110; box-shadow: 0 0 0.15rem #FCF0BC; background-size: 100% 100%; } .window-animation { -webkit-transition: 2s ease-in-out; -moz-transition: 2s ease-in-out; } /** * 动画过程 */ .window-transition { -webkit-transition: 2s ease-in-out; -moz-transition: 2s ease-in-out; } .window-left.hover { /**?**/ } .window-right.hover { /**?**/ }