对话框/Tips

html5 svg和css3超酷模态窗口动画特效

阿里云


这是一款使用 html5 svg 和 css3 制作的超酷模态窗口动画特效插件。该模态窗口特效共分 6 大类 17 种不同的效果。最后 5 种效果使用 html5 svg 和 js 制作,其余特效使用 css3 和 js 制作而成。

注意:似乎 IE11 不支持在 transform 中使用 calc()

section

html 结构相当简单:

也想出现在这里?联系我们
创客主机
  1. <div id="somedialog" class="dialog">
  2.     <div class="dialog__overlay"></div>
  3.     <div class="dialog__content">
  4.         <h2><strong>Howdy</strong>, I'm a dialog box</h2><
  5.         div><button class="action" data-dialog-close>Close</button></div>
  6.     </div>
  7. </div>

在不久的将来,也许我们就能直接使用<dialog>标签,现在它还比较弱,IE、Firefox 和 Safari 都不支持它。

section

下面是模态窗口的基本样式:

  1. .dialog,
  2. .dialog__overlay {
  3.     width: 100%;
  4.     height: 100%;
  5.     top: 0;
  6.     left: 0;
  7. }
  8. .dialog {
  9.     position: fixed;
  10.     display: flex;
  11.     align-items: center;
  12.     justify-content: center;
  13.     pointer-events: none;
  14. }
  15. .dialog__overlay {
  16.     position: absolute;
  17.     z-index: 1;
  18.     background: rgba(55, 58, 71, 0.9);
  19.     opacity: 0;
  20.     transition: opacity 0.3s;
  21. }
  22. .dialog--open .dialog__overlay {
  23.     opacity: 1;
  24.     pointer-events: auto;
  25. }
  26. .dialog__content {
  27.     width: 50%;
  28.     max-width: 560px;
  29.     min-width: 290px;
  30.     background: #fff;
  31.     padding: 4em;
  32.     text-align: center;
  33.     position: relative;
  34.     z-index: 5;
  35.     opacity: 0;
  36. }
  37. .dialog--open .dialog__content {
  38.     pointer-events: auto;
  39. }
  40. /* Content */
  41. .dialog h2 {
  42.     margin: 0;
  43.     font-weight: 400;
  44.     font-size: 2em;
  45.     padding: 0 0 2em;
  46.     margin: 0;
  47. }

我们在.dialog 上使用 flexbox 是为了让对话框的内容居中。注意:IE11 以下的 IE 浏览器不支持 pointer 事件。

某些效果中有一些额外的 div,在开始时他们是隐藏的,模态窗口动画结束后它们以 fade in 的方式出现,这是为了制作缩放和扭曲的效果。

下面是 Sandra 模态窗口动画效果的 css 代码:

  1. .dialog.dialog--open .dialog__content,
  2. .dialog.dialog--close .dialog__content {
  3.     animation-duration: 0.3s;
  4.     animation-fill-mode: forwards;
  5. }
  6.  
  7. .dialog.dialog--open .dialog__content {
  8.     animation-name: anim-open;
  9. }
  10.  
  11. .dialog.dialog--close .dialog__content {
  12.     animation-name: anim-close;
  13. }
  14.  
  15. @keyframes anim-open {
  16.     0% { opacity: 0; transform: scale3d(1.1, 1.1, 1); }
  17.     100% { opacity: 1; transform: scale3d(1, 1, 1); }
  18. }
  19.  
  20. @keyframes anim-close {
  21.     0% { opacity: 1; }
  22.     100% { opacity: 0; transform: scale3d(0.9, 0.9, 1); }
  23. }

通过添加 dialog--open 和 dialog--close 类,我们可以很好的控制模态窗口和它里面的内容。

下面是控制模态窗口的 js 代码:

  1. ( function( window ) { 
  2.     'use strict';
  3.     var support = { animations : Modernizr.cssanimations },
  4.         animEndEventNames = { 'WebkitAnimation' : 'webkitAnimationEnd', 'OAnimation' : 'oAnimationEnd', 'msAnimation' : 'MSAnimationEnd', 'animation' : 'animationend' },
  5.         animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ],
  6.         onEndAnimation = function( el, callback ) {
  7.             var onEndCallbackFn = function( ev ) {
  8.                 if( support.animations ) {
  9.                     if( ev.target != this ) return;
  10.                     this.removeEventListener( animEndEventName, onEndCallbackFn );
  11.                 }
  12.                 if( callback && typeof callback === 'function' ) { callback.call(); }
  13.             };
  14.             if( support.animations ) {
  15.                 el.addEventListener( animEndEventName, onEndCallbackFn );
  16.             }
  17.             else {
  18.                 onEndCallbackFn();
  19.             }
  20.         };
  21.     function extend( a, b ) {
  22.         for( var key in b ) { 
  23.             if( b.hasOwnProperty( key ) ) {
  24.                 a[key] = b[key];
  25.             }
  26.         }
  27.         return a;
  28.     }
  29.     function DialogFx( el, options ) {
  30.         this.el = el;
  31.         this.options = extend( {}, this.options );
  32.         extend( this.options, options );
  33.         this.ctrlClose = this.el.querySelector( '[data-dialog-close]' );
  34.         this.isOpen = false;
  35.         this._initEvents();
  36.     }
  37.     DialogFx.prototype.options = {
  38.         // callbacks
  39.         onOpenDialog : function() { return false; },
  40.         onCloseDialog : function() { return false; }
  41.     }
  42.     DialogFx.prototype._initEvents = function() {
  43.         var self = this;
  44.         // close action
  45.         this.ctrlClose.addEventListener( 'click', this.toggle.bind(this) );
  46.         // esc key closes dialog
  47.         document.addEventListener( 'keydown', function( ev ) {
  48.             var keyCode = ev.keyCode || ev.which;
  49.             if( keyCode === 27 && self.isOpen ) {
  50.                 self.toggle();
  51.             }
  52.         } );
  53.         this.el.querySelector( '.dialog__overlay' ).addEventListener( 'click', this.toggle.bind(this) );
  54.     }
  55.     DialogFx.prototype.toggle = function() {
  56.         var self = this;
  57.         if( this.isOpen ) {
  58.             classie.remove( this.el, 'dialog--open' );
  59.             classie.add( self.el, 'dialog--close' );
  60.  
  61.             onEndAnimation( this.el.querySelector( '.dialog__content' ), function() {
  62.                 classie.remove( self.el, 'dialog--close' );
  63.             } );
  64.             // callback on close
  65.             this.options.onCloseDialog( this );
  66.         }
  67.         else {
  68.             classie.add( this.el, 'dialog--open' );
  69.  
  70.             // callback on open
  71.             this.options.onOpenDialog( this );
  72.         }
  73.         this.isOpen = !this.isOpen;
  74.     };
  75.     // add to global namespace
  76.     window.DialogFx = DialogFx;
  77. })( window );

我们也能够想下面这样调用模态窗口:

  1. <script src="js/classie.js"></script>
  2. <script src="js/dialogFx.js"></script>
  3. <script>
  4.     (function() {
  5.         var dlgtrigger = document.querySelector( '[data-dialog]' ),
  6.             somedialog = document.getElementById( dlgtrigger.getAttribute( 'data-dialog' ) ),
  7.             dlg = new DialogFx( somedialog );
  8.         dlgtrigger.addEventListener( 'click', dlg.toggle.bind(dlg) );
  9.     })();
  10. </script>

以上是通过 data-属性的 data-dialog="somedialog"来触发控制按钮。

插件中的 SVG 效果(除了 Wilma 效果)都是使用 Snap.svg 来做路径变形动画。我们添加 SVG 图形到模态窗口的内容中,然后在 data-morph-open 中定义不同的路径变形动画。

  1. (function() {
  2.     var dlgtrigger = document.querySelector( '[data-dialog]' ),
  3.         somedialog = document.getElementById( dlgtrigger.getAttribute( 'data-dialog' ) ),
  4.         // svg..
  5.         morphEl = somedialog.querySelector( '.morph-shape' ),
  6.         s = Snap( morphEl.querySelector( 'svg' ) ),
  7.         path = s.select( 'path' ),
  8.         initialPath = path.attr('d'),
  9.         steps = { 
  10.             open : morphEl.getAttribute( 'data-morph-open' )
  11.         },
  12.         dlg = new DialogFx( somedialog, {
  13.             onOpenDialog : function( instance ) {
  14.                 // reset path
  15.                 morphEl.querySelector( 'svg > path' ).setAttribute( 'd', initialPath );
  16.                 // animate path
  17.                 path.stop().animate( { 'path' : steps.open }, 300, mina.easein );
  18.             }
  19.         } );
  20.     dlgtrigger.addEventListener( 'click', dlg.toggle.bind(dlg) );
  21. })();

在 Safari 浏览器中透视效果似乎有些问题,你想了解更多可以阅读:Weird CSS Rotation Animation Glitch in Safari

html5 svg 和 css3 超酷模态窗口动画特效

已有 202 人购买
  • lwfr
查看演示升级 VIP立刻购买

演示地址 下载地址
收藏
(0)

发表回复

热销模板

Ashade - 作品展示摄影相册WordPress汉化主题
LensNews

本站承接 WordPress / PbootCMS / DedeCMS 等
系统建站、仿站、开发、定制等业务!