├── .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 |

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 |
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 |
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 |
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 |
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 |
--------------------------------------------------------------------------------