├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .stylelintrc.json ├── .umirc.js ├── README.md ├── package.json └── src ├── Home ├── Banner0.jsx ├── Content0.jsx ├── Content1.jsx ├── Content3.jsx ├── Footer0.jsx ├── Nav0.jsx ├── data.source.js ├── documentation.md ├── index.jsx ├── less │ ├── antMotionStyle.less │ ├── banner0.less │ ├── common.less │ ├── content.less │ ├── content0.less │ ├── content1.less │ ├── content3.less │ ├── custom.less │ ├── edit.less │ ├── footer0.less │ └── nav0.less └── utils.js ├── global.less └── pages ├── index.css └── index.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const eslintrc = { 2 | extends: ['eslint-config-airbnb'], 3 | env: { 4 | browser: true, 5 | node: true, 6 | jasmine: true, 7 | jest: true, 8 | es6: true, 9 | }, 10 | parser: 'babel-eslint', 11 | parserOptions: { 12 | ecmaVersion: 6, 13 | ecmaFeatures: { 14 | jsx: true, 15 | experimentalObjectRestSpread: true, 16 | }, 17 | }, 18 | plugins: [ 19 | 'markdown', 20 | 'react', 21 | 'babel', 22 | ], 23 | rules: { 24 | 'func-names': 0, 25 | 'arrow-body-style': 0, 26 | 'react/sort-comp': 0, 27 | 'react/prop-types': 0, 28 | 'react/jsx-first-prop-new-line': 0, 29 | 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', '.md'] }], 30 | 'import/extensions': 0, 31 | 'import/no-unresolved': 0, 32 | 'import/no-extraneous-dependencies': 0, 33 | 'prefer-destructuring': 0, 34 | 'no-param-reassign': 0, 35 | 'no-return-assign': 0, 36 | 'max-len': 0, 37 | 'consistent-return': 0, 38 | 'no-redeclare': 0, 39 | 'react/require-extension': 0, 40 | 'jsx-a11y/no-static-element-interactions': 0, 41 | 'jsx-a11y/anchor-has-content': 0, 42 | 'jsx-a11y/click-events-have-key-events': 0, 43 | 'jsx-a11y/no-noninteractive-element-interactions': 0, 44 | 'jsx-a11y/anchor-is-valid': 0, 45 | 'react/no-danger': 0, 46 | 'comma-dangle': ['error', 'always-multiline'], 47 | 'function-paren-newline': 0, 48 | 'object-curly-newline': 0, 49 | 'no-restricted-globals': 0, 50 | 'jsx-a11y/mouse-events-have-key-events': 0, 51 | 'react/jsx-no-target-blank': 0, 52 | 'react/no-find-dom-node': 0, 53 | 'react/no-unescaped-entities': 0, 54 | 'react/prefer-stateless-function': 0, 55 | 'import/no-webpack-loader-syntax': 0, 56 | 'react/forbid-prop-types': 0, 57 | 'react/destructuring-assignment': 0, 58 | 'react/no-access-state-in-setstate': 0, 59 | 'import/no-cycle': 0, 60 | 'react/jsx-props-no-spreading': 0, 61 | 'react/state-in-constructor': 0, 62 | 'react/static-property-placement': 0 63 | }, 64 | }; 65 | 66 | if (process.env.RUN_ENV === 'DEMO') { 67 | eslintrc.globals = { 68 | React: true, 69 | ReactDOM: true, 70 | mountNode: true, 71 | }; 72 | 73 | Object.assign(eslintrc.rules, { 74 | indent: 0, 75 | 'no-console': 0, 76 | 'no-plusplus': 0, 77 | 'eol-last': 0, 78 | 'prefer-rest-params': 0, 79 | 'react/no-multi-comp': 0, 80 | 'jsx-a11y/href-no-hash': 0, 81 | 'import/newline-after-import': 0, 82 | }); 83 | } 84 | 85 | module.exports = eslintrc; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # production 7 | /dist 8 | 9 | # misc 10 | .DS_Store 11 | npm-debug.log* 12 | 13 | # umi 14 | .umi -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard", "stylelint-config-prettier"], 3 | "rules": { 4 | "declaration-empty-line-before": null, 5 | "no-descending-specificity": null, 6 | "selector-pseudo-class-no-unknown": null, 7 | "selector-pseudo-element-colon-notation": null, 8 | "no-empty-source": null 9 | } 10 | } -------------------------------------------------------------------------------- /.umirc.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | exportStatic: { 4 | htmlSuffix: true, 5 | dynamicRoot: true, 6 | }, 7 | targets: { 8 | ie: 11, 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # landing-umi-example 2 | 3 | 详细使用请查看 landing 里的 [use in umi](https://landing.ant.design/docs/use/umi) 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "landing-test", 3 | "private": true, 4 | "scripts": { 5 | "start": "umi dev", 6 | "build": "umi build", 7 | "lint": "eslint --ext .jsx src && npm run lint:style", 8 | "lint:style": "stylelint \"src/Home/**/*.less\" --syntax less", 9 | "gh-pages": "gh-pages -d dist" 10 | }, 11 | "dependencies": { 12 | "enquire-js": "^0.2.1", 13 | "rc-banner-anim": "^2.1.0", 14 | "rc-queue-anim": "^1.6.7", 15 | "rc-scroll-anim": "^2.5.6", 16 | "rc-texty": "^0.2.0", 17 | "rc-tween-one": "^2.2.14", 18 | "react-sublime-video": "^0.2.5", 19 | "react": "^16.6.0", 20 | "react-dom": "^16.6.0" 21 | }, 22 | "devDependencies": { 23 | "babel-eslint": "^10.0.1", 24 | "eslint": "^6.0.0", 25 | "eslint-config-airbnb": "^18.0.0", 26 | "eslint-loader": "^3.0.2", 27 | "eslint-plugin-babel": "^5.1.0", 28 | "eslint-plugin-compat": "^3.1.1", 29 | "eslint-plugin-import": "^2.14.0", 30 | "eslint-plugin-jsx-a11y": "^6.1.2", 31 | "eslint-plugin-markdown": "^1.0.0-beta.6", 32 | "eslint-plugin-react": "^7.11.1", 33 | "eslint-tinker": "^0.5.0", 34 | "extract-text-webpack-plugin": "^3.0.2", 35 | "gh-pages": "^2.0.1", 36 | "husky": "^1.3.1", 37 | "pre-commit": "1.x", 38 | "stylelint": "^9.4.0", 39 | "stylelint-config-prettier": "^4.0.0", 40 | "stylelint-config-standard": "^18.0.0", 41 | "umi": "^3.0.0", 42 | "@umijs/preset-react": "^1.4.5" 43 | }, 44 | "pre-commit": [ 45 | "lint" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /src/Home/Banner0.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button } from 'antd'; 3 | import { DownOutlined } from '@ant-design/icons'; 4 | import QueueAnim from 'rc-queue-anim'; 5 | import TweenOne from 'rc-tween-one'; 6 | import { isImg } from './utils'; 7 | 8 | class Banner extends React.PureComponent { 9 | render() { 10 | const { ...currentProps } = this.props; 11 | const { dataSource } = currentProps; 12 | delete currentProps.dataSource; 13 | delete currentProps.isMobile; 14 | return ( 15 |
16 | 22 |
23 | {typeof dataSource.title.children === 'string' 24 | && dataSource.title.children.match(isImg) ? ( 25 | img 26 | ) : ( 27 | dataSource.title.children 28 | )} 29 |
30 |
31 | {dataSource.content.children} 32 |
33 | 36 |
37 | 47 | 48 | 49 |
50 | ); 51 | } 52 | } 53 | export default Banner; 54 | -------------------------------------------------------------------------------- /src/Home/Content0.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import QueueAnim from 'rc-queue-anim'; 3 | import { Row, Col } from 'antd'; 4 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack'; 5 | import { getChildrenToRender } from './utils'; 6 | 7 | class Content extends React.PureComponent { 8 | render() { 9 | const { dataSource, isMobile, ...props } = this.props; 10 | const { 11 | wrapper, 12 | titleWrapper, 13 | page, 14 | OverPack: overPackData, 15 | childWrapper, 16 | } = dataSource; 17 | return ( 18 |
19 |
20 |
21 | {titleWrapper.children.map(getChildrenToRender)} 22 |
23 | 24 | 31 | {childWrapper.children.map((block, i) => { 32 | const { children: item, ...blockProps } = block; 33 | return ( 34 | 35 |
36 | {item.children.map(getChildrenToRender)} 37 |
38 | 39 | ); 40 | })} 41 |
42 |
43 |
44 |
45 | ); 46 | } 47 | } 48 | 49 | export default Content; 50 | -------------------------------------------------------------------------------- /src/Home/Content1.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import QueueAnim from 'rc-queue-anim'; 3 | import TweenOne from 'rc-tween-one'; 4 | import { Row, Col } from 'antd'; 5 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack'; 6 | 7 | function Content1(props) { 8 | const { ...tagProps } = props; 9 | const { dataSource, isMobile } = tagProps; 10 | delete tagProps.dataSource; 11 | delete tagProps.isMobile; 12 | const animType = { 13 | queue: isMobile ? 'bottom' : 'right', 14 | one: isMobile 15 | ? { 16 | scaleY: '+=0.3', 17 | opacity: 0, 18 | type: 'from', 19 | ease: 'easeOutQuad', 20 | } 21 | : { 22 | x: '-=30', 23 | opacity: 0, 24 | type: 'from', 25 | ease: 'easeOutQuad', 26 | }, 27 | }; 28 | return ( 29 |
30 | 31 | 42 | 43 | img 44 | 45 | 46 | 58 |

59 | {dataSource.title.children} 60 |

61 |
62 | {dataSource.content.children} 63 |
64 |
65 |
66 |
67 | ); 68 | } 69 | 70 | export default Content1; 71 | -------------------------------------------------------------------------------- /src/Home/Content3.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import QueueAnim from 'rc-queue-anim'; 3 | import TweenOne from 'rc-tween-one'; 4 | import { Row, Col } from 'antd'; 5 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack'; 6 | import { getChildrenToRender } from './utils'; 7 | 8 | class Content3 extends React.PureComponent { 9 | getDelay = (e, b) => (e % b) * 100 + Math.floor(e / b) * 100 + b * 100; 10 | 11 | render() { 12 | const { ...props } = this.props; 13 | const { dataSource, isMobile } = props; 14 | delete props.dataSource; 15 | delete props.isMobile; 16 | let clearFloatNum = 0; 17 | const children = dataSource.block.children.map((item, i) => { 18 | const childObj = item.children; 19 | const delay = isMobile ? i * 50 : this.getDelay(i, 24 / item.md); 20 | const liAnim = { 21 | opacity: 0, 22 | type: 'from', 23 | ease: 'easeOutQuad', 24 | delay, 25 | }; 26 | const childrenAnim = { ...liAnim, x: '+=10', delay: delay + 100 }; 27 | clearFloatNum += item.md; 28 | clearFloatNum = clearFloatNum > 24 ? 0 : clearFloatNum; 29 | return ( 30 | 42 | 52 | img 53 | 54 |
55 | 61 | {childObj.title.children} 62 | 63 | 69 | {childObj.content.children} 70 | 71 |
72 |
73 | ); 74 | }); 75 | return ( 76 |
77 |
78 |
79 | {dataSource.titleWrapper.children.map(getChildrenToRender)} 80 |
81 | 82 | 83 | 84 | {children} 85 | 86 | 87 | 88 |
89 |
90 | ); 91 | } 92 | } 93 | 94 | export default Content3; 95 | -------------------------------------------------------------------------------- /src/Home/Footer0.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TweenOne from 'rc-tween-one'; 3 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack'; 4 | 5 | class Footer extends React.PureComponent { 6 | render() { 7 | const { ...props } = this.props; 8 | const { dataSource } = props; 9 | delete props.dataSource; 10 | delete props.isMobile; 11 | return ( 12 |
13 | 14 | 19 | {dataSource.copyright.children} 20 | 21 | 22 |
23 | ); 24 | } 25 | } 26 | 27 | export default Footer; 28 | -------------------------------------------------------------------------------- /src/Home/Nav0.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TweenOne from 'rc-tween-one'; 3 | import { Menu } from 'antd'; 4 | import { getChildrenToRender } from './utils'; 5 | 6 | const { Item, SubMenu } = Menu; 7 | 8 | class Header extends React.Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = { 12 | phoneOpen: undefined, 13 | }; 14 | } 15 | 16 | phoneClick = () => { 17 | const phoneOpen = !this.state.phoneOpen; 18 | this.setState({ 19 | phoneOpen, 20 | }); 21 | }; 22 | 23 | render() { 24 | const { dataSource, isMobile, ...props } = this.props; 25 | const { phoneOpen } = this.state; 26 | const navData = dataSource.Menu.children; 27 | const navChildren = navData.map((item) => { 28 | const { children: a, subItem, ...itemProps } = item; 29 | if (subItem) { 30 | return ( 31 | 39 | {a.children.map(getChildrenToRender)} 40 | 41 | )} 42 | popupClassName="header0-item-child" 43 | > 44 | {subItem.map(($item, ii) => { 45 | const { children: childItem } = $item; 46 | const child = childItem.href ? ( 47 | 48 | {childItem.children.map(getChildrenToRender)} 49 | 50 | ) : ( 51 |
52 | {childItem.children.map(getChildrenToRender)} 53 |
54 | ); 55 | return ( 56 | 57 | {child} 58 | 59 | ); 60 | })} 61 |
62 | ); 63 | } 64 | return ( 65 | 66 | 67 | {a.children.map(getChildrenToRender)} 68 | 69 | 70 | ); 71 | }); 72 | const moment = phoneOpen === undefined ? 300 : null; 73 | return ( 74 | 80 |
84 | 88 | img 89 | 90 | {isMobile && ( 91 |
{ 94 | this.phoneClick(); 95 | }} 96 | > 97 | 98 | 99 | 100 |
101 | )} 102 | { 110 | if (this.state.phoneOpen) { 111 | e.target.style.height = 'auto'; 112 | } 113 | }, 114 | ease: 'easeInOutQuad', 115 | } 116 | : null 117 | } 118 | moment={moment} 119 | reverse={!!phoneOpen} 120 | > 121 | 126 | {navChildren} 127 | 128 | 129 |
130 |
131 | ); 132 | } 133 | } 134 | 135 | export default Header; 136 | -------------------------------------------------------------------------------- /src/Home/data.source.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | export const Nav00DataSource = { 3 | wrapper: { className: 'header0 home-page-wrapper' }, 4 | page: { className: 'home-page' }, 5 | logo: { 6 | className: 'header0-logo', 7 | children: 'https://os.alipayobjects.com/rmsportal/mlcYmsRilwraoAe.svg', 8 | }, 9 | Menu: { 10 | className: 'header0-menu', 11 | children: [ 12 | { 13 | name: 'item0', 14 | className: 'header0-item', 15 | children: { 16 | href: '#', 17 | children: [{ children: '导航一', name: 'text' }], 18 | }, 19 | subItem: [ 20 | { 21 | name: 'sub0', 22 | className: 'item-sub', 23 | children: { 24 | className: 'item-sub-item', 25 | children: [ 26 | { 27 | name: 'image0', 28 | className: 'item-image', 29 | children: 30 | 'https://gw.alipayobjects.com/zos/rmsportal/ruHbkzzMKShUpDYMEmHM.svg', 31 | }, 32 | { 33 | name: 'title', 34 | className: 'item-title', 35 | children: 'Ant Design', 36 | }, 37 | { 38 | name: 'content', 39 | className: 'item-content', 40 | children: '企业级 UI 设计体系', 41 | }, 42 | ], 43 | }, 44 | }, 45 | { 46 | name: 'sub1', 47 | className: 'item-sub', 48 | children: { 49 | className: 'item-sub-item', 50 | children: [ 51 | { 52 | name: 'image0', 53 | className: 'item-image', 54 | children: 55 | 'https://gw.alipayobjects.com/zos/rmsportal/ruHbkzzMKShUpDYMEmHM.svg', 56 | }, 57 | { 58 | name: 'title', 59 | className: 'item-title', 60 | children: 'Ant Design', 61 | }, 62 | { 63 | name: 'content', 64 | className: 'item-content', 65 | children: '企业级 UI 设计体系', 66 | }, 67 | ], 68 | }, 69 | }, 70 | ], 71 | }, 72 | { 73 | name: 'item1', 74 | className: 'header0-item', 75 | children: { 76 | href: '#', 77 | children: [{ children: '导航二', name: 'text' }], 78 | }, 79 | }, 80 | { 81 | name: 'item2', 82 | className: 'header0-item', 83 | children: { 84 | href: '#', 85 | children: [{ children: '导航三', name: 'text' }], 86 | }, 87 | }, 88 | { 89 | name: 'item3', 90 | className: 'header0-item', 91 | children: { 92 | href: '#', 93 | children: [{ children: '导航四', name: 'text' }], 94 | }, 95 | }, 96 | ], 97 | }, 98 | mobileMenu: { className: 'header0-mobile-menu' }, 99 | }; 100 | export const Banner00DataSource = { 101 | wrapper: { className: 'banner0' }, 102 | textWrapper: { className: 'banner0-text-wrapper' }, 103 | title: { 104 | className: 'banner0-title', 105 | children: 'https://zos.alipayobjects.com/rmsportal/HqnZZjBjWRbjyMr.png', 106 | }, 107 | content: { 108 | className: 'banner0-content', 109 | children: '一个高效的页面动画解决方案', 110 | }, 111 | button: { className: 'banner0-button', children: 'Learn More' }, 112 | }; 113 | export const Content00DataSource = { 114 | wrapper: { className: 'home-page-wrapper content0-wrapper' }, 115 | page: { className: 'home-page content0' }, 116 | OverPack: { playScale: 0.3, className: '' }, 117 | titleWrapper: { 118 | className: 'title-wrapper', 119 | children: [{ name: 'title', children: '产品与服务' }], 120 | }, 121 | childWrapper: { 122 | className: 'content0-block-wrapper', 123 | children: [ 124 | { 125 | name: 'block0', 126 | className: 'content0-block', 127 | md: 8, 128 | xs: 24, 129 | children: { 130 | className: 'content0-block-item', 131 | children: [ 132 | { 133 | name: 'image', 134 | className: 'content0-block-icon', 135 | children: 136 | 'https://zos.alipayobjects.com/rmsportal/WBnVOjtIlGWbzyQivuyq.png', 137 | }, 138 | { 139 | name: 'title', 140 | className: 'content0-block-title', 141 | children: '一站式业务接入', 142 | }, 143 | { name: 'content', children: '支付、结算、核算接入产品效率翻四倍' }, 144 | ], 145 | }, 146 | }, 147 | { 148 | name: 'block1', 149 | className: 'content0-block', 150 | md: 8, 151 | xs: 24, 152 | children: { 153 | className: 'content0-block-item', 154 | children: [ 155 | { 156 | name: 'image', 157 | className: 'content0-block-icon', 158 | children: 159 | 'https://zos.alipayobjects.com/rmsportal/YPMsLQuCEXtuEkmXTTdk.png', 160 | }, 161 | { 162 | name: 'title', 163 | className: 'content0-block-title', 164 | children: '一站式事中风险监控', 165 | }, 166 | { 167 | name: 'content', 168 | children: '在所有需求配置环节事前风险控制和质量控制能力', 169 | }, 170 | ], 171 | }, 172 | }, 173 | { 174 | name: 'block2', 175 | className: 'content0-block', 176 | md: 8, 177 | xs: 24, 178 | children: { 179 | className: 'content0-block-item', 180 | children: [ 181 | { 182 | name: 'image', 183 | className: 'content0-block-icon', 184 | children: 185 | 'https://zos.alipayobjects.com/rmsportal/EkXWVvAaFJKCzhMmQYiX.png', 186 | }, 187 | { 188 | name: 'title', 189 | className: 'content0-block-title', 190 | children: '一站式数据运营', 191 | }, 192 | { 193 | name: 'content', 194 | children: '沉淀产品接入效率和运营小二工作效率数据', 195 | }, 196 | ], 197 | }, 198 | }, 199 | ], 200 | }, 201 | }; 202 | export const Content10DataSource = { 203 | wrapper: { className: 'home-page-wrapper content1-wrapper' }, 204 | OverPack: { className: 'home-page content1', playScale: 0.3 }, 205 | imgWrapper: { className: 'content1-img', md: 10, xs: 24 }, 206 | img: { 207 | children: 'https://zos.alipayobjects.com/rmsportal/nLzbeGQLPyBJoli.png', 208 | }, 209 | textWrapper: { className: 'content1-text', md: 14, xs: 24 }, 210 | title: { className: 'content1-title', children: '企业资源管理' }, 211 | content: { 212 | className: 'content1-content', 213 | children: 214 | '云资源集中编排、弹性伸缩、持续发布和部署,高可用及容灾。云资源集中编排、弹性伸缩、持续发布和部署,高可用及容灾。云资源集中编排、弹性伸缩、持续发布和部署,高可用及容灾。', 215 | }, 216 | }; 217 | export const Content30DataSource = { 218 | wrapper: { className: 'home-page-wrapper content3-wrapper' }, 219 | page: { className: 'home-page content3' }, 220 | OverPack: { playScale: 0.3 }, 221 | titleWrapper: { 222 | className: 'title-wrapper', 223 | children: [ 224 | { 225 | name: 'title', 226 | children: '蚂蚁金融云提供专业的服务', 227 | className: 'title-h1', 228 | }, 229 | { 230 | name: 'content', 231 | className: 'title-content', 232 | children: '基于阿里云强大的基础资源', 233 | }, 234 | ], 235 | }, 236 | block: { 237 | className: 'content3-block-wrapper', 238 | children: [ 239 | { 240 | name: 'block0', 241 | className: 'content3-block', 242 | md: 8, 243 | xs: 24, 244 | children: { 245 | icon: { 246 | className: 'content3-icon', 247 | children: 248 | 'https://zos.alipayobjects.com/rmsportal/ScHBSdwpTkAHZkJ.png', 249 | }, 250 | textWrapper: { className: 'content3-text' }, 251 | title: { className: 'content3-title', children: '企业资源管理' }, 252 | content: { 253 | className: 'content3-content', 254 | children: 255 | '云资源集中编排、弹性伸缩、持续发布和部署,高可用及容灾。', 256 | }, 257 | }, 258 | }, 259 | { 260 | name: 'block1', 261 | className: 'content3-block', 262 | md: 8, 263 | xs: 24, 264 | children: { 265 | icon: { 266 | className: 'content3-icon', 267 | children: 268 | 'https://zos.alipayobjects.com/rmsportal/NKBELAOuuKbofDD.png', 269 | }, 270 | textWrapper: { className: 'content3-text' }, 271 | title: { className: 'content3-title', children: '云安全' }, 272 | content: { 273 | className: 'content3-content', 274 | children: 275 | '按金融企业安全要求打造的完整云上安全体系,全方位保障金融应用及数据安全。', 276 | }, 277 | }, 278 | }, 279 | { 280 | name: 'block2', 281 | className: 'content3-block', 282 | md: 8, 283 | xs: 24, 284 | children: { 285 | icon: { 286 | className: 'content3-icon', 287 | children: 288 | 'https://zos.alipayobjects.com/rmsportal/xMSBjgxBhKfyMWX.png', 289 | }, 290 | textWrapper: { className: 'content3-text' }, 291 | title: { className: 'content3-title', children: '云监控' }, 292 | content: { 293 | className: 'content3-content', 294 | children: 295 | '分布式云环境集中监控,统一资源及应用状态视图,智能分析及故障定位。', 296 | }, 297 | }, 298 | }, 299 | { 300 | name: 'block3', 301 | className: 'content3-block', 302 | md: 8, 303 | xs: 24, 304 | children: { 305 | icon: { 306 | className: 'content3-icon', 307 | children: 308 | 'https://zos.alipayobjects.com/rmsportal/MNdlBNhmDBLuzqp.png', 309 | }, 310 | textWrapper: { className: 'content3-text' }, 311 | title: { className: 'content3-title', children: '移动' }, 312 | content: { 313 | className: 'content3-content', 314 | children: 315 | '一站式移动金融APP开发及全面监控;丰富可用组件,动态发布和故障热修复。', 316 | }, 317 | }, 318 | }, 319 | { 320 | name: 'block4', 321 | className: 'content3-block', 322 | md: 8, 323 | xs: 24, 324 | children: { 325 | icon: { 326 | className: 'content3-icon', 327 | children: 328 | 'https://zos.alipayobjects.com/rmsportal/UsUmoBRyLvkIQeO.png', 329 | }, 330 | textWrapper: { className: 'content3-text' }, 331 | title: { className: 'content3-title', children: '分布式中间件' }, 332 | content: { 333 | className: 'content3-content', 334 | children: 335 | '金融级联机交易处理中间件,大规模分布式计算机,数万笔/秒级并发能力,严格保证交易数据统一性。', 336 | }, 337 | }, 338 | }, 339 | { 340 | name: 'block5', 341 | className: 'content3-block', 342 | md: 8, 343 | xs: 24, 344 | children: { 345 | icon: { 346 | className: 'content3-icon', 347 | children: 348 | 'https://zos.alipayobjects.com/rmsportal/ipwaQLBLflRfUrg.png', 349 | }, 350 | textWrapper: { className: 'content3-text' }, 351 | title: { className: 'content3-title', children: '大数据' }, 352 | content: { 353 | className: 'content3-content', 354 | children: 355 | '一站式、全周期大数据协同工作平台,PB级数据处理、毫秒级数据分析工具。', 356 | }, 357 | }, 358 | }, 359 | ], 360 | }, 361 | }; 362 | export const Footer01DataSource = { 363 | wrapper: { className: 'home-page-wrapper footer0-wrapper' }, 364 | OverPack: { className: 'home-page footer0', playScale: 0.05 }, 365 | copyright: { 366 | className: 'copyright', 367 | children: ( 368 | 369 | ©2018 Ant Motion All Rights 370 | Reserved 371 | 372 | ), 373 | }, 374 | }; 375 | -------------------------------------------------------------------------------- /src/Home/documentation.md: -------------------------------------------------------------------------------- 1 | # 如何使用: 2 | 3 | - umi 里如何使用[请查看](https://landing.ant.design/docs/use/umi)。 4 | - 其它脚手架使用[请查看](https://landing.ant.design/docs/use/getting-started)。 5 | -------------------------------------------------------------------------------- /src/Home/index.jsx: -------------------------------------------------------------------------------- 1 | /* eslint no-undef: 0 */ 2 | /* eslint arrow-parens: 0 */ 3 | import React from 'react'; 4 | import { enquireScreen } from 'enquire-js'; 5 | 6 | import Nav0 from './Nav0'; 7 | import Banner0 from './Banner0'; 8 | import Content0 from './Content0'; 9 | import Content1 from './Content1'; 10 | import Content3 from './Content3'; 11 | import Footer0 from './Footer0'; 12 | 13 | import { 14 | Nav00DataSource, 15 | Banner00DataSource, 16 | Content00DataSource, 17 | Content10DataSource, 18 | Content30DataSource, 19 | Footer01DataSource, 20 | } from './data.source'; 21 | import './less/antMotionStyle.less'; 22 | 23 | let isMobile; 24 | enquireScreen((b) => { 25 | isMobile = b; 26 | }); 27 | 28 | const { location } = window; 29 | 30 | export default class Home extends React.Component { 31 | constructor(props) { 32 | super(props); 33 | this.state = { 34 | isMobile, 35 | show: !location.port, // 如果不是 dva 2.0 请删除 36 | }; 37 | } 38 | 39 | componentDidMount() { 40 | // 适配手机屏幕; 41 | enquireScreen((b) => { 42 | this.setState({ isMobile: !!b }); 43 | }); 44 | // dva 2.0 样式在组件渲染之后动态加载,导致滚动组件不生效;线上不影响; 45 | /* 如果不是 dva 2.0 请删除 start */ 46 | if (location.port) { 47 | // 样式 build 时间在 200-300ms 之间; 48 | setTimeout(() => { 49 | this.setState({ 50 | show: true, 51 | }); 52 | }, 500); 53 | } 54 | /* 如果不是 dva 2.0 请删除 end */ 55 | } 56 | 57 | render() { 58 | const children = [ 59 | , 65 | , 71 | , 77 | , 83 | , 89 | , 95 | ]; 96 | return ( 97 |
{ 100 | this.dom = d; 101 | }} 102 | > 103 | {/* 如果不是 dva 2.0 替换成 {children} start */} 104 | {this.state.show && children} 105 | {/* 如果不是 dva 2.0 替换成 {children} end */} 106 |
107 | ); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/Home/less/antMotionStyle.less: -------------------------------------------------------------------------------- 1 | @import './common.less'; 2 | @import './custom.less'; 3 | @import './content.less'; 4 | @import './nav0.less'; 5 | @import './banner0.less'; 6 | @import './content0.less'; 7 | @import './content1.less'; 8 | @import './content3.less'; 9 | @import './footer0.less'; 10 | @import './edit.less'; 11 | -------------------------------------------------------------------------------- /src/Home/less/banner0.less: -------------------------------------------------------------------------------- 1 | @banner0: banner0; 2 | .@{banner0} { 3 | // 如果在第一屏且导航位置为 relative, 一屏为 height: calc(~"100vh - 64px"); 4 | width: 100%; 5 | height: 100vh; 6 | position: relative; 7 | text-align: center; 8 | border-color: #666; 9 | background-image: url("https://zos.alipayobjects.com/rmsportal/gGlUMYGEIvjDOOw.jpg"); 10 | background-size: cover; 11 | background-attachment: fixed; 12 | background-position: center; 13 | & &-text-wrapper { 14 | display: inline-block; 15 | position: absolute; 16 | top: 20%; 17 | margin: auto; 18 | left: 0; 19 | right: 0; 20 | font-size: 14px; 21 | color: @template-text-color-light; 22 | width: 550px; 23 | >.queue-anim-leaving { 24 | position: relative !important; 25 | } 26 | } 27 | & &-title { 28 | width: 350px; 29 | left: 30px; 30 | min-height: 60px; 31 | margin: auto; 32 | display: inline-block; 33 | font-size: 40px; 34 | position: relative; 35 | } 36 | & &-content { 37 | margin-bottom: 20px; 38 | word-wrap: break-word; 39 | min-height: 24px; 40 | } 41 | & &-button { 42 | border: 1px solid #fff; 43 | color: #fff; 44 | background: transparent; 45 | box-shadow: 0 0 0 transparent; 46 | font-size: 16px; 47 | height: 40px; 48 | transition: background .45s @ease-out, box-shadow .45s @ease-out; 49 | &:hover { 50 | color: #fff; 51 | border-color: #fff; 52 | background: rgba(255, 255, 255, 0.1); 53 | box-shadow: 0 0 10px rgba(50, 250, 255, 0.75); 54 | } 55 | &:focus { 56 | color: #fff; 57 | border-color: #fff; 58 | } 59 | &.queue-anim-leaving { 60 | width: auto; 61 | } 62 | } 63 | & &-icon { 64 | bottom: 20px; 65 | font-size: 24px; 66 | position: absolute; 67 | left: 50%; 68 | margin-left: -12px; 69 | color: @template-text-color-light; 70 | } 71 | } 72 | 73 | @media screen and (max-width: 767px) { 74 | .@{banner0} { 75 | background-attachment: inherit; 76 | & &-text-wrapper { 77 | width: 90%; 78 | } 79 | & &-title { 80 | width: 90%; 81 | left: 0; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Home/less/common.less: -------------------------------------------------------------------------------- 1 | 2 | // @import "~antd/lib/style/v2-compatible-reset.less"; 3 | 4 | body { 5 | word-wrap: break-word; 6 | } 7 | 8 | body, 9 | div, 10 | dl, 11 | dt, 12 | dd, 13 | ul, 14 | ol, 15 | li, 16 | h1, 17 | h2, 18 | h3, 19 | h4, 20 | h5, 21 | h6 { 22 | margin: 0; 23 | padding: 0; 24 | } 25 | 26 | /* .content-wrapper > .tween-one-leaving, 27 | .queue-anim-leaving { 28 | // position: absolute !important; 29 | // width: 100%; 30 | } */ 31 | 32 | .video { 33 | max-width: 800px; 34 | } 35 | 36 | #react-content { 37 | min-height: 100%; 38 | } 39 | .home-page-wrapper p { 40 | padding: 0; 41 | margin: 0; 42 | } 43 | -------------------------------------------------------------------------------- /src/Home/less/content.less: -------------------------------------------------------------------------------- 1 | @homepage: home-page; 2 | .@{homepage}-wrapper { 3 | width: 100%; 4 | position: relative; 5 | overflow: hidden; 6 | .@{homepage} { 7 | height: 100%; 8 | max-width: 1200px; 9 | position: relative; 10 | margin: auto; 11 | will-change: transform; 12 | } 13 | .title-wrapper > h1, > h1 { 14 | font-size: 32px; 15 | color: @text-color; 16 | margin-bottom: 16px; 17 | } 18 | .title-wrapper { 19 | margin: 0 auto 64px; 20 | text-align: center; 21 | } 22 | } 23 | 24 | .@{homepage} { 25 | padding: 128px 24px; 26 | } 27 | 28 | @media screen and (max-width: 767px) { 29 | .@{homepage}-wrapper { 30 | .@{homepage} { 31 | padding: 56px 24px; 32 | >h1 { 33 | font-size: 24px; 34 | margin: 0 auto 32px; 35 | &.title-h1 { 36 | margin-bottom: 8px; 37 | } 38 | } 39 | >p { 40 | margin-bottom: 32px; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Home/less/content0.less: -------------------------------------------------------------------------------- 1 | @content0: content0; 2 | 3 | .@{content0}-wrapper { 4 | min-height: 446px; 5 | overflow: hidden; 6 | 7 | .@{content0} { 8 | height: 100%; 9 | padding: 64px 24px; 10 | 11 | >.title-wrapper { 12 | margin: 0 auto 48px; 13 | } 14 | 15 | &-block { 16 | padding: 0 4%; 17 | display: inline-block; 18 | text-align: center; 19 | min-height: 200px; 20 | margin-bottom: 24px; 21 | img { 22 | width: 100%; 23 | } 24 | 25 | &-wrapper { 26 | position: relative; 27 | height: 100%; 28 | top: 25%; 29 | padding: 20px 0; 30 | } 31 | 32 | &.queue-anim-leaving { 33 | position: relative !important; 34 | } 35 | 36 | &-icon { 37 | width: 100px; 38 | height: 100px; 39 | margin: auto; 40 | } 41 | 42 | &-title { 43 | line-height: 32px; 44 | margin: 10px auto; 45 | font-size: 24px; 46 | } 47 | } 48 | } 49 | } 50 | 51 | @media screen and (max-width: 767px) { 52 | .@{content0}-wrapper { 53 | min-height: 880px; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Home/less/content1.less: -------------------------------------------------------------------------------- 1 | @content1: content1; 2 | .@{content1}-wrapper { 3 | height: 360px; 4 | .@{content1} { 5 | height: 100%; 6 | padding: 0 24px; 7 | &-img { 8 | height: 100%; 9 | transform-origin: top; 10 | padding: 0 32px; 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | span { 15 | display: block; 16 | width: 250px; 17 | img { 18 | display: block; 19 | } 20 | } 21 | } 22 | &-text { 23 | padding: 0 32px; 24 | height: 100%; 25 | .@{content1}-content, 26 | .@{content1}-title { 27 | position: relative !important; 28 | } 29 | .@{content1}-title { 30 | font-size: 32px; 31 | font-weight: normal; 32 | color: #404040; 33 | margin-top: 120px; 34 | } 35 | .content { 36 | margin-top: 20px; 37 | } 38 | } 39 | } 40 | } 41 | 42 | @media screen and (max-width: 767px) { 43 | .@{content1}-wrapper { 44 | height: 600px; 45 | .@{content1} { 46 | &-img { 47 | height: 200px; 48 | padding: 0; 49 | text-align: center; 50 | margin-top: 64px; 51 | span { 52 | display: inline-block; 53 | width: 180px; 54 | height: 200px; 55 | line-height: 200px; 56 | margin: auto; 57 | } 58 | } 59 | &-text { 60 | height: auto; 61 | margin-bottom: 20px; 62 | text-align: center; 63 | padding: 0; 64 | .@{content1}-content, 65 | .@{content1}-title { 66 | width: 100%; 67 | top: auto; 68 | } 69 | .@{content1}-title { 70 | margin: 32px auto 16px; 71 | font-size: 24px; 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Home/less/content3.less: -------------------------------------------------------------------------------- 1 | @content3: content3; 2 | .@{content3}-wrapper { 3 | min-height: 764px; 4 | .@{content3} { 5 | height: 100%; 6 | overflow: hidden; 7 | & .title-content { 8 | text-align: center; 9 | } 10 | &-block-wrapper { 11 | position: relative; 12 | .@{content3}-block { 13 | display: inline-block; 14 | padding: 48px 24px; 15 | vertical-align: top; 16 | .@{content3}-icon { 17 | display: inline-block; 18 | width: 15%; 19 | vertical-align: top; 20 | } 21 | .@{content3}-text { 22 | width: 85%; 23 | display: inline-block; 24 | padding-left: 8%; 25 | } 26 | &.clear-both { 27 | clear: both; 28 | } 29 | } 30 | } 31 | } 32 | } 33 | 34 | @media screen and (max-width: 767px) { 35 | .@{content3}-wrapper { 36 | min-height: 1080px; 37 | .@{content3} { 38 | &-block-wrapper { 39 | margin: 20px auto; 40 | height: auto; 41 | .@{content3}-block { 42 | .@{content3}-title { 43 | font-size: 20px; 44 | } 45 | &.queue-anim-leaving { 46 | position: relative !important; 47 | } 48 | } 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Home/less/custom.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | 3 | @line-color: #e9e9e9; 4 | 5 | @shadow-color: rgba(0, 0, 0, 0.15); 6 | 7 | @bottom-bar-bg-color: #262626; 8 | @bottom-bar-line-color: #000; 9 | 10 | @template-bg-color: #001529; 11 | @template-bg-color-light: #ececec; 12 | @template-nav-bg-color: #001529; 13 | @template-text-color: #ccc; 14 | @template-text-title-color: #bcbcbc; 15 | @template-text-color-light: #fff; 16 | @template-footer-text-color: #999; 17 | 18 | @animate-duration: .45s; 19 | 20 | /* 详细页图片或框框的样式; 21 | */ 22 | .page-shadow() { 23 | box-shadow: 0 5px 8px @shadow-color; 24 | } 25 | 26 | .page-pro() { 27 | border-radius: 6px; 28 | border: 1px solid @line-color; 29 | transform: translateY(0); 30 | transition: transform .3s @ease-out, box-shadow .3s @ease-out; 31 | &:hover { 32 | .page-shadow(); 33 | transform: translateY(-5px); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Home/less/edit.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ant-motion/landing-umi-example/18ebab5dacb4dccd371a1457850409466d93fbcf/src/Home/less/edit.less -------------------------------------------------------------------------------- /src/Home/less/footer0.less: -------------------------------------------------------------------------------- 1 | .footer0-wrapper { 2 | background-color: @template-bg-color; 3 | height: 80px; 4 | overflow: hidden; 5 | .footer0 { 6 | height: 100%; 7 | padding: 0 24px; 8 | line-height: 80px; 9 | text-align: center; 10 | color: @template-footer-text-color; 11 | position: relative; 12 | } 13 | } 14 | 15 | @media screen and (max-width: 767px) { 16 | .footer0-wrapper { 17 | .footer0 { 18 | font-size: 12px; 19 | &.home-page { 20 | padding: 0; 21 | } 22 | >div { 23 | width: 90%; 24 | margin: auto; 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Home/less/nav0.less: -------------------------------------------------------------------------------- 1 | @header0: header0; 2 | 3 | .@{header0} { 4 | background: @template-nav-bg-color; 5 | width: 100%; 6 | z-index: 1; 7 | box-shadow: 0 5px 8px fade(#000, 15); 8 | position: relative; 9 | top: 0; 10 | 11 | .home-page { 12 | padding: 0 24px; 13 | } 14 | 15 | &-logo { 16 | display: inline-block; 17 | position: relative; 18 | width: 150px; 19 | line-height: 64px; 20 | 21 | & img { 22 | vertical-align: middle; 23 | display: inline-block; 24 | } 25 | 26 | & a { 27 | display: block; 28 | } 29 | } 30 | 31 | &-menu { 32 | float: right; 33 | 34 | .ant-menu { 35 | line-height: 62px; 36 | height: 64px; 37 | 38 | a { 39 | display: block; 40 | } 41 | } 42 | } 43 | 44 | &-item { 45 | &-block { 46 | padding: 0 8px; 47 | 48 | >* { 49 | display: inline-block; 50 | } 51 | } 52 | } 53 | 54 | &-item, 55 | &-item-child, 56 | &-menu { 57 | 58 | .ant-menu-sub .ant-menu-item, 59 | .ant-menu-inline .ant-menu-item { 60 | height: auto; 61 | line-height: 1.5; 62 | } 63 | 64 | .item { 65 | &-sub-item { 66 | display: block; 67 | padding: 8px 24px; 68 | } 69 | 70 | &-image { 71 | float: left; 72 | margin-right: 16px; 73 | margin-top: 4px; 74 | position: relative; 75 | z-index: 1; 76 | } 77 | 78 | &-title { 79 | font-size: 14px; 80 | color: #fff; 81 | margin-left: 46px; 82 | } 83 | 84 | &-content { 85 | font-size: 12px; 86 | color: fade(#fff, 75); 87 | margin-left: 46px; 88 | } 89 | } 90 | } 91 | } 92 | 93 | @media screen and (max-width: 767px) { 94 | .@{header0} { 95 | &-logo { 96 | z-index: 101; 97 | } 98 | 99 | &.home-page-wrapper .home-page { 100 | padding: 0 24px; 101 | } 102 | 103 | &-menu { 104 | height: auto; 105 | float: inherit; 106 | position: relative; 107 | left: -24px; 108 | width: ~"calc(100% + 48px)"; 109 | opacity: 0; 110 | transition: opacity .3s @ease-in-out; 111 | 112 | & li { 113 | padding: 0 24px; 114 | 115 | &.ant-menu-submenu { 116 | padding: 0; 117 | } 118 | } 119 | .item { 120 | &-sub-item { 121 | padding: 8px 0; 122 | } 123 | } 124 | } 125 | 126 | &-mobile-menu { 127 | width: 16px; 128 | height: 14px; 129 | cursor: pointer; 130 | position: absolute; 131 | top: 24px; 132 | right: 24px; 133 | z-index: 100; 134 | 135 | em { 136 | display: block; 137 | width: 100%; 138 | height: 2px; 139 | background: #fff; 140 | margin-top: 4px; 141 | transition: transform .3s @ease-in-out, opacity .3s @ease-in-out; 142 | } 143 | 144 | :first-child { 145 | margin-top: 0; 146 | } 147 | } 148 | 149 | .ant-menu { 150 | height: auto; 151 | overflow: hidden; 152 | 153 | .ant-menu-item-selected { 154 | border: none; 155 | } 156 | } 157 | 158 | & .open { 159 | height: auto; 160 | 161 | .@{header0}-mobile-menu { 162 | em { 163 | &:nth-child(1) { 164 | transform: translateY(6px) rotate(45deg); 165 | } 166 | 167 | &:nth-child(2) { 168 | opacity: 0; 169 | } 170 | 171 | &:nth-child(3) { 172 | transform: translateY(-6px) rotate(-45deg); 173 | } 174 | } 175 | } 176 | 177 | >.@{header0}-menu { 178 | opacity: 1; 179 | pointer-events: auto; 180 | } 181 | } 182 | &-item-block { 183 | height: 40px; 184 | line-height: 40px; 185 | } 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/Home/utils.js: -------------------------------------------------------------------------------- 1 | 2 | import React from 'react'; 3 | import { Button } from 'antd'; 4 | 5 | export const isImg = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?/; 6 | export const getChildrenToRender = (item, i) => { 7 | let tag = item.name.indexOf('title') === 0 ? 'h1' : 'div'; 8 | tag = item.href ? 'a' : tag; 9 | let children = typeof item.children === 'string' && item.children.match(isImg) 10 | ? React.createElement('img', { src: item.children, alt: 'img' }) 11 | : item.children; 12 | if (item.name.indexOf('button') === 0 && typeof item.children === 'object') { 13 | children = React.createElement(Button, { 14 | ...item.children 15 | }); 16 | } 17 | return React.createElement(tag, { key: i.toString(), ...item }, children); 18 | }; 19 | -------------------------------------------------------------------------------- /src/global.less: -------------------------------------------------------------------------------- 1 | @import './Home/less/antMotionStyle.less'; 2 | -------------------------------------------------------------------------------- /src/pages/index.css: -------------------------------------------------------------------------------- 1 | 2 | .normal { 3 | background: #C6F279; 4 | } 5 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import Home from '../Home'; 2 | 3 | export default function () { 4 | return ( 5 | 6 | ); 7 | } 8 | --------------------------------------------------------------------------------