diff --git a/components/datepicker/demo/basic.md b/components/datepicker/demo/basic.md index 4351c6322bcbbb544b327a0d9f3a9e403c8426d6..2d650bf0678352ea2ba450efd2b39508c90b54bc 100644 --- a/components/datepicker/demo/basic.md +++ b/components/datepicker/demo/basic.md @@ -7,6 +7,7 @@ --- ````jsx +// or require('antd/components/datepicker'); var Datepicker = antd.Datepicker; React.render( diff --git a/components/motion/demo/basic.md b/components/motion/demo/basic.md new file mode 100644 index 0000000000000000000000000000000000000000..0572d998c23b24a725c21001a4b0741aac2f323d --- /dev/null +++ b/components/motion/demo/basic.md @@ -0,0 +1,226 @@ +# 基本 + +- order: 0 + +动画效果示例。 + +--- + +````jsx +var cssAnimation = antd.cssAnimation; +var motions = []; +motions = motions.concat([[{ + name: '淡入', + value: 'fade', + direction: 'enter', + type: '渐隐' +}, { + name: '淡出', + value: 'fade', + direction: 'leave', + type: '渐隐' +}]]); +motions = motions.concat([[{ + name: '中心放大', + value: 'zoom', + direction: 'enter', + type: '缩放' +}, { + name: '中心缩小', + value: 'zoom', + direction: 'leave', + type: '缩放' +}, { + name: '上方放大', + value: 'zoom-up', + direction: 'enter', + type: '缩放' +}, { + name: '上方缩小', + value: 'zoom-up', + direction: 'leave', + type: '缩放' +}, { + name: '下方放大', + value: 'zoom-down', + direction: 'enter', + type: '缩放' +}, { + name: '下方缩小', + value: 'zoom-down', + direction: 'leave', + type: '缩放' +}, { + name: '左方放大', + value: 'zoom-left', + direction: 'enter', + type: '缩放' +}, { + name: '左方缩小', + value: 'zoom-left', + direction: 'leave', + type: '缩放' +}, { + name: '右方放大', + value: 'zoom-right', + direction: 'enter', + type: '缩放' +}, { + name: '右方缩小', + value: 'zoom-right', + direction: 'leave', + type: '缩放' +}]]); +motions = motions.concat([[{ + name: '上方滑入', + value: 'move-up', + direction: 'enter', + type: '移动' +}, { + name: '上方滑出', + value: 'move-up', + direction: 'leave', + type: '移动' +}, { + name: '下方滑入', + value: 'move-down', + direction: 'enter', + type: '移动' +}, { + name: '下方滑出', + value: 'move-down', + direction: 'leave', + type: '移动' +}, { + name: '左方滑入', + value: 'move-left', + direction: 'enter', + type: '移动' +}, { + name: '左方滑出', + value: 'move-left', + direction: 'leave', + type: '移动' +}, { + name: '右方滑入', + value: 'move-right', + direction: 'enter', + type: '移动' +}, { + name: '右方滑入', + value: 'move-right', + direction: 'leave', + type: '移动' +}]]); +motions = motions.concat([[{ + name: '上方展开', + value: 'slide-up', + direction: 'enter', + type: '伸缩' +}, { + name: '上方缩回', + value: 'slide-up', + direction: 'leave', + type: '伸缩' +}, { + name: '下方展开', + value: 'slide-down', + direction: 'enter', + type: '伸缩' +}, { + name: '下方缩回', + value: 'slide-down', + direction: 'leave', + type: '伸缩' +}, { + name: '左方展开', + value: 'slide-left', + direction: 'enter', + type: '伸缩' +}, { + name: '左方缩回', + value: 'slide-left', + direction: 'leave', + type: '伸缩' +}, { + name: '右方展开', + value: 'slide-right', + direction: 'enter', + type: '伸缩' +}, { + name: '右方缩回', + value: 'slide-right', + direction: 'leave', + type: '伸缩' +}]]); +motions = motions.concat([[{ + name: '摇摆', + value: 'swing', + direction: 'enter', + type: '其他' +}]]); +var leave='-leave'; +var Test = React.createClass({ + handleChange(e) { + var value = e.target.value; + if(value){ + this.demoNode.style.visibility=''; + cssAnimation(this.demoNode, value, () => { + if(value.slice(-leave.length)===leave){ + this.demoNode.style.visibility='hidden'; + } + }); + } + }, + + componentDidMount() { + this.demoNode = React.findDOMNode(this.refs.demo); + }, + + render() { + var options = [].concat(motions.map(function (m) { + var opts = m.map(function (m2) { + return + }); + return {opts}; + })); + return
+
+
栗子
+
+
+ +
+
; + } +}); + +React.render(, document.getElementById('components-motion-demo-basic')); +```` + + \ No newline at end of file diff --git a/components/motion/index.md b/components/motion/index.md index 0cdd7cba81ba81dfc808bed873ef0a3a106e0c18..71ace50fa64886a99fbdf88b089380ed78ef12ea 100644 --- a/components/motion/index.md +++ b/components/motion/index.md @@ -6,3 +6,20 @@ --- + +## 组件的动画 + +通过设置组件的 transitionName 指定组件动画 + +| 组件 | 中文名 | 采用动画 | +|--------------|---------------------|-------------------------------------------------| +| popover | 气泡浮出层 | `zoom-up` `zoom-down` `zoom-left` `zoom-right` | +| popconfirm | 气泡确认框 | `zoom-up` `zoom-down` `zoom-left` `zoom-right` | +| tooltip | 文字提示框 | `zoom-up` `zoom-down` `zoom-left` `zoom-right` | +| modal | 弹出框 | `zoom` | +| confirm | 弹出确认框 | `zoom` | +| message | 信息提示条 | `move-up` | +| dropdown | 下拉菜单 | `slide-up` | +| select | 选择框 | `slide-up` | +| datepicker | 日期选择框 | `slide-up` | + diff --git a/index.js b/index.js index d9fa5516c6f7d00e33d2f816e5078d14701c7f08..8551595b484a7af9134fa587c3cd62d6c54963a9 100644 --- a/index.js +++ b/index.js @@ -13,7 +13,8 @@ var antd = { Popconfirm: require('./components/popconfirm'), confirm: require('./components/modal/confirm'), Steps: require('./components/steps'), - InputNumber: require('./components/input-number') + InputNumber: require('./components/input-number'), + cssAnimation: require('css-animation') }; module.exports = window.antd = antd; diff --git a/package.json b/package.json index ccc837da12a705754242b2a76e28fe71b40ccb27..548a99c5273109935fa2d39b3176155bc6db8965 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "url": "https://github.com/ant-design/ant-design/issues" }, "dependencies": { + "css-animation": "~1.0.3", "gregorian-calendar": "~3.0.0", "gregorian-calendar-format": "~3.0.1", "rc-calendar": "~3.10.0", diff --git a/style/core/motion.less b/style/core/motion.less index 0d9d9596a528c3bbb899ca7015843f94f9c64c70..8a220dc742ab873045e063c70740f2574e210d82 100644 --- a/style/core/motion.less +++ b/style/core/motion.less @@ -1,19 +1,16 @@ -.effect() { - animation-duration: 0.24s; +.motion-common() { + animation-duration: .24s; animation-fill-mode: both; display: block !important; } -.motion(@className, @keyframeName) { +.make-motion(@className, @keyframeName) { .@{className}-enter { - opacity: 0; - .effect(); - animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28); + .motion-common(); animation-play-state: paused; } .@{className}-leave { - .effect(); - animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05); + .motion-common(); animation-play-state: paused; } .@{className}-enter.@{className}-enter-active { @@ -26,240 +23,9 @@ } } -.motion(zoom,zoom); -.motion(zoom-up,zoomUp); -.motion(zoom-down,zoomDown); -.motion(zoom-left,zoomLeft); -.motion(zoom-right,zoomRight); - -@keyframes zoomIn { - 0% { - opacity: 0; - transform-origin: 50% 50%; - transform: scale(0, 0); - } - 100% { - opacity: 1; - transform-origin: 50% 50%; - transform: scale(1, 1); - } -} -@keyframes zoomOut { - 0% { - opacity: 1; - transform-origin: 50% 50%; - transform: scale(1, 1); - } - 100% { - opacity: 0; - transform-origin: 50% 50%; - transform: scale(0, 0); - } -} - -@keyframes zoomUpIn { - 0% { - opacity: 0; - transform-origin: 50% 0%; - transform: scale(0, 0); - } - 100% { - opacity: 1; - transform-origin: 50% 0%; - transform: scale(1, 1); - } -} - -@keyframes zoomUpOut { - 0% { - opacity: 1; - transform-origin: 50% 0%; - transform: scale(1, 1); - } - 100% { - opacity: 0; - transform-origin: 50% 0%; - transform: scale(0, 0); - } -} - -@keyframes zoomLeftIn { - 0% { - opacity: 0; - transform-origin: 0% 50%; - transform: scale(0, 0); - } - 100% { - opacity: 1; - transform-origin: 0% 50%; - transform: scale(1, 1); - } -} - -@keyframes zoomLeftOut { - 0% { - opacity: 1; - transform-origin: 0% 50%; - transform: scale(1, 1); - } - 100% { - opacity: 0; - transform-origin: 0% 50%; - transform: scale(0, 0); - } -} - -@keyframes zoomRightIn { - 0% { - opacity: 0; - transform-origin: 100% 50%; - transform: scale(0, 0); - } - 100% { - opacity: 1; - transform-origin: 100% 50%; - transform: scale(1, 1); - } -} - -@keyframes zoomRightOut { - 0% { - opacity: 1; - transform-origin: 100% 50%; - transform: scale(1, 1); - } - 100% { - opacity: 0; - transform-origin: 100% 50%; - transform: scale(0, 0); - } -} - -@keyframes zoomDownIn { - 0% { - opacity: 0; - transform-origin: 50% 100%; - transform: scale(0, 0); - } - 100% { - opacity: 1; - transform-origin: 50% 100%; - transform: scale(1, 1); - } -} - -@keyframes zoomDownOut { - 0% { - opacity: 1; - transform-origin: 50% 100%; - transform: scale(1, 1); - } - 100% { - opacity: 0; - transform-origin: 50% 100%; - transform: scale(0, 0); - } -} - -.slide-up-enter { - .effect(); - transform-origin: 0 0; - opacity: 0; - animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); - animation-play-state: paused; -} - -.slide-up-leave { - .effect(); - transform-origin: 0 0; - opacity: 1; - animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); - animation-play-state: paused; -} - -.slide-up-enter.slide-up-enter-active { - animation-name: slideUpIn; - animation-play-state: running; -} - -.slide-up-leave.slide-up-leave-active { - animation-name: slideUpOut; - animation-play-state: running; -} - -@keyframes slideUpIn { - 0% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleY(0); - } - 100% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleY(1); - } -} -@keyframes slideUpOut { - 0% { - opacity: 1; - transform-origin: 0% 0%; - transform: scaleY(1); - } - 100% { - opacity: 0; - transform-origin: 0% 0%; - transform: scaleY(0); - } -} - -.fade-enter { - opacity: 0; - .effect(); - animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2); - animation-play-state: paused; -} - -.fade-leave { - .effect(); - animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2); - animation-play-state: paused; -} - -.fade-enter.fade-enter-active { - animation-name: fadeIn; - animation-play-state: running; -} - -.fade-leave.fade-leave-active { - animation-name: fadeOut; - animation-play-state: running; -} - -@keyframes fadeIn { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -@keyframes fadeOut { - 0% { - opacity: 1; - } - 100% { - opacity: 0; - } -} - -@keyframes loadingCircle { - 0% { - transform-origin: 50% 50%; - transform: rotate(0deg); - } - 100% { - transform-origin: 50% 50%; - transform: rotate(360deg); - } -} +@import "motion/fade"; +@import "motion/move"; +@import "motion/other"; +@import "motion/slide"; +@import "motion/swing"; +@import "motion/zoom"; diff --git a/style/core/motion/fade.less b/style/core/motion/fade.less new file mode 100644 index 0000000000000000000000000000000000000000..a05ca9460a5b133193739c57bd881c4c2a01106f --- /dev/null +++ b/style/core/motion/fade.less @@ -0,0 +1,40 @@ +.fade-enter { + opacity: 0; + .motion-common(); + animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2); + animation-play-state: paused; +} + +.fade-leave { + .motion-common(); + animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2); + animation-play-state: paused; +} + +.fade-enter.fade-enter-active { + animation-name: fadeIn; + animation-play-state: running; +} + +.fade-leave.fade-leave-active { + animation-name: fadeOut; + animation-play-state: running; +} + +@keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes fadeOut { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} \ No newline at end of file diff --git a/style/core/motion/move.less b/style/core/motion/move.less new file mode 100644 index 0000000000000000000000000000000000000000..48f04394e7db185307c30f13ad7cccf216afd430 --- /dev/null +++ b/style/core/motion/move.less @@ -0,0 +1,119 @@ +.move-motion(@className, @keyframeName) { + .make-motion(@className, @keyframeName); + .@{className}-enter { + opacity: 0; + animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); + } + .@{className}-leave { + animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); + } +} + +.move-motion(move-up, moveUp); +.move-motion(move-down, moveDown); +.move-motion(move-left, moveLeft); +.move-motion(move-right, moveRight); + +@keyframes moveDownIn { + 0% { + transform-origin: 0 0; + transform: translateY(100%); + opacity: 0; + } + 100% { + transform-origin: 0 0; + transform: translateY(0%); + opacity: 1; + } +} + +@keyframes moveDownOut { + 0% { + transform-origin: 0 0; + transform: translateY(0%); + opacity: 1; + } + 100% { + transform-origin: 0 0; + transform: translateY(100%); + opacity: 0; + } +} + +@keyframes moveLeftIn { + 0% { + transform-origin: 0 0; + transform: translateX(-100%); + opacity: 0; + } + 100% { + transform-origin: 0 0; + transform: translateX(0%); + opacity: 1; + } +} + +@keyframes moveLeftOut { + 0% { + transform-origin: 0 0; + transform: translateX(0%); + opacity: 1; + } + 100% { + transform-origin: 0 0; + transform: translateX(-100%); + opacity: 0; + } +} + +@keyframes moveRightIn { + 0% { + opacity: 0; + transform-origin: 0 0; + transform: translateX(100%); + } + 100% { + opacity: 1; + transform-origin: 0 0; + transform: translateX(0%); + } +} + +@keyframes moveRightOut { + 0% { + transform-origin: 0 0; + transform: translateX(0%); + opacity: 1; + } + 100% { + transform-origin: 0 0; + transform: translateX(100%); + opacity: 0; + } +} + +@keyframes moveUpIn { + 0% { + transform-origin: 0 0; + transform: translateY(-100%); + opacity: 0; + } + 100% { + transform-origin: 0 0; + transform: translateY(0%); + opacity: 1; + } +} + +@keyframes moveUpOut { + 0% { + transform-origin: 0 0; + transform: translateY(0%); + opacity: 1; + } + 100% { + transform-origin: 0 0; + transform: translateY(-100%); + opacity: 0; + } +} diff --git a/style/core/motion/other.less b/style/core/motion/other.less new file mode 100644 index 0000000000000000000000000000000000000000..670442f126ec5af6e8d0d478c0b4c7017b273439 --- /dev/null +++ b/style/core/motion/other.less @@ -0,0 +1,10 @@ +@keyframes loadingCircle { + 0% { + transform-origin: 50% 50%; + transform: rotate(0deg); + } + 100% { + transform-origin: 50% 50%; + transform: rotate(360deg); + } +} \ No newline at end of file diff --git a/style/core/motion/slide.less b/style/core/motion/slide.less new file mode 100644 index 0000000000000000000000000000000000000000..25c50e1083299d9950a296438e54ace0fa146591 --- /dev/null +++ b/style/core/motion/slide.less @@ -0,0 +1,119 @@ +.slide-motion(@className, @keyframeName) { + .make-motion(@className, @keyframeName); + .@{className}-enter { + opacity: 0; + animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); + } + .@{className}-leave { + animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); + } +} + +.slide-motion(slide-up, slideUp); +.slide-motion(slide-down, slideDown); +.slide-motion(slide-left, slideLeft); +.slide-motion(slide-right, slideRight); + +@keyframes slideUpIn { + 0% { + opacity: 0; + transform-origin: 0% 0%; + transform: scaleY(0); + } + 100% { + opacity: 1; + transform-origin: 0% 0%; + transform: scaleY(1); + } +} + +@keyframes slideUpOut { + 0% { + opacity: 1; + transform-origin: 0% 0%; + transform: scaleY(1); + } + 100% { + opacity: 0; + transform-origin: 0% 0%; + transform: scaleY(0); + } +} + +@keyframes slideDownIn { + 0% { + opacity: 0; + transform-origin: 100% 100%; + transform: scaleY(0); + } + 100% { + opacity: 1; + transform-origin: 100% 100%; + transform: scaleY(1); + } +} + +@keyframes slideDownOut { + 0% { + opacity: 1; + transform-origin: 100% 100%; + transform: scaleY(1); + } + 100% { + opacity: 0; + transform-origin: 100% 100%; + transform: scaleY(0); + } +} + +@keyframes slideLeftIn { + 0% { + opacity: 0; + transform-origin: 0% 0%; + transform: scaleX(0); + } + 100% { + opacity: 1; + transform-origin: 0% 0%; + transform: scaleX(1); + } +} + +@keyframes slideLeftOut { + 0% { + opacity: 1; + transform-origin: 0% 0%; + transform: scaleX(1); + } + 100% { + opacity: 0; + transform-origin: 0% 0%; + transform: scaleX(0); + } +} + +@keyframes slideRightIn { + 0% { + opacity: 0; + transform-origin: 100% 0%; + transform: scaleX(0); + } + 100% { + opacity: 1; + transform-origin: 100% 0%; + transform: scaleX(1); + } +} + +@keyframes slideRightOut { + 0% { + opacity: 1; + transform-origin: 100% 0%; + transform: scaleX(1); + } + 100% { + opacity: 0; + transform-origin: 100% 0%; + transform: scaleX(0); + } +} \ No newline at end of file diff --git a/style/core/motion/swing.less b/style/core/motion/swing.less new file mode 100644 index 0000000000000000000000000000000000000000..03813736be6bfc8b46a22e47ca4482763b2338db --- /dev/null +++ b/style/core/motion/swing.less @@ -0,0 +1,30 @@ +.swing-motion(@className, @keyframeName) { + .@{className}-enter { + .motion-common(); + animation-play-state: paused; + } + .@{className}-enter.@{className}-enter-active { + animation-name: ~"@{keyframeName}In"; + animation-play-state: running; + } +} + +.swing-motion(swing, swing); + +@keyframes swingIn { + 0%, 100% { + transform: translateX(0px); + } + 20% { + transform: translateX(-10px); + } + 40% { + transform: translateX(10px); + } + 60% { + transform: translateX(-5px); + } + 80% { + transform: translateX(5px); + } +} \ No newline at end of file diff --git a/style/core/motion/zoom.less b/style/core/motion/zoom.less new file mode 100644 index 0000000000000000000000000000000000000000..91ad8ba6fcbe108e12f90874250a176e463a12e8 --- /dev/null +++ b/style/core/motion/zoom.less @@ -0,0 +1,146 @@ +.zoom-motion(@className, @keyframeName) { + .make-motion(@className, @keyframeName); + .@{className}-enter { + opacity: 0; + animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28); + } + .@{className}-leave { + animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05); + } +} + +.zoom-motion(zoom, zoom); +.zoom-motion(zoom-up, zoomUp); +.zoom-motion(zoom-down, zoomDown); +.zoom-motion(zoom-left, zoomLeft); +.zoom-motion(zoom-right, zoomRight); + +@keyframes zoomIn { + 0% { + opacity: 0; + transform-origin: 50% 50%; + transform: scale(0, 0); + } + 100% { + opacity: 1; + transform-origin: 50% 50%; + transform: scale(1, 1); + } +} + +@keyframes zoomOut { + 0% { + opacity: 1; + transform-origin: 50% 50%; + transform: scale(1, 1); + } + 100% { + opacity: 0; + transform-origin: 50% 50%; + transform: scale(0, 0); + } +} + +@keyframes zoomUpIn { + 0% { + opacity: 0; + transform-origin: 50% 0%; + transform: scale(0, 0); + } + 100% { + opacity: 1; + transform-origin: 50% 0%; + transform: scale(1, 1); + } +} + +@keyframes zoomUpOut { + 0% { + opacity: 1; + transform-origin: 50% 0%; + transform: scale(1, 1); + } + 100% { + opacity: 0; + transform-origin: 50% 0%; + transform: scale(0, 0); + } +} + +@keyframes zoomLeftIn { + 0% { + opacity: 0; + transform-origin: 0% 50%; + transform: scale(0, 0); + } + 100% { + opacity: 1; + transform-origin: 0% 50%; + transform: scale(1, 1); + } +} + +@keyframes zoomLeftOut { + 0% { + opacity: 1; + transform-origin: 0% 50%; + transform: scale(1, 1); + } + 100% { + opacity: 0; + transform-origin: 0% 50%; + transform: scale(0, 0); + } +} + +@keyframes zoomRightIn { + 0% { + opacity: 0; + transform-origin: 100% 50%; + transform: scale(0, 0); + } + 100% { + opacity: 1; + transform-origin: 100% 50%; + transform: scale(1, 1); + } +} + +@keyframes zoomRightOut { + 0% { + opacity: 1; + transform-origin: 100% 50%; + transform: scale(1, 1); + } + 100% { + opacity: 0; + transform-origin: 100% 50%; + transform: scale(0, 0); + } +} + +@keyframes zoomDownIn { + 0% { + opacity: 0; + transform-origin: 50% 100%; + transform: scale(0, 0); + } + 100% { + opacity: 1; + transform-origin: 50% 100%; + transform: scale(1, 1); + } +} + +@keyframes zoomDownOut { + 0% { + opacity: 1; + transform-origin: 50% 100%; + transform: scale(1, 1); + } + 100% { + opacity: 0; + transform-origin: 50% 100%; + transform: scale(0, 0); + } +} \ No newline at end of file