├── .gitignore
├── src
└── Home
│ ├── static
│ ├── style.js
│ ├── custom.less
│ ├── default.less
│ ├── footer.less
│ ├── header.less
│ ├── responsive.less
│ └── home.less
│ ├── Page4.jsx
│ ├── Header.jsx
│ ├── index.jsx
│ ├── Page3.jsx
│ ├── Banner.jsx
│ ├── Footer.jsx
│ ├── Page2.jsx
│ ├── Page1.jsx
│ ├── data.js
│ └── technology-comp
│ ├── Tetris.jsx
│ ├── Coordinate.jsx
│ ├── Column.jsx
│ └── Building.jsx
├── index.js
├── deploy.js
├── .eslintrc
├── webpack.config.js
├── README.md
├── index.html
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | .DS_Store
--------------------------------------------------------------------------------
/src/Home/static/style.js:
--------------------------------------------------------------------------------
1 | import './header.less';
2 | import './home.less';
3 | import './footer.less';
4 | import './responsive.less';
5 |
--------------------------------------------------------------------------------
/src/Home/static/custom.less:
--------------------------------------------------------------------------------
1 | body {
2 | -webkit-font-smoothing: antialiased;
3 | }
4 |
5 | .text-center {
6 | text-align: center!important;
7 | }
8 | a:focus {
9 | text-decoration: none;
10 | }
11 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import Home from './src/Home';
4 |
5 | function App() {
6 | return (
7 |
8 | );
9 | }
10 |
11 | ReactDOM.render(, document.getElementById('root'));
12 |
--------------------------------------------------------------------------------
/deploy.js:
--------------------------------------------------------------------------------
1 | var ghPages = require('gh-pages');
2 | var path = require('path');
3 | ghPages.publish(path.join(process.cwd(), 'dist'), {
4 | depth: 1,
5 | logger: function (message) {
6 | console.log(message);
7 | }
8 | }, function (err) {
9 | if (err) {
10 | throw err;
11 | }
12 | console.log('Site has been published.');
13 | });
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint-config-airbnb",
3 | "parser": "babel-eslint",
4 | "rules": {
5 | "import/no-unresolved": 0,
6 | "react/jsx-no-target-blank": 0,
7 | "jsx-a11y/anchor-is-valid": 0,
8 | "react/jsx-no-comment-textnodes": 0,
9 | "react/prop-types": 0,
10 | "no-mixed-operators": 0,
11 | "no-undef": 0
12 | }
13 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | // Learn more on how to config.
2 | // - https://github.com/ant-tool/atool-build#配置扩展
3 |
4 | module.exports = function(webpackConfig) {
5 | webpackConfig.babel.plugins.push('transform-runtime');
6 | webpackConfig.babel.plugins.push(['import', {
7 | libraryName: 'antd',
8 | style: 'css',
9 | }]);
10 |
11 | return webpackConfig;
12 | };
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### experience-cloud
2 |
3 | 体验云的 landing page.
4 |
5 | 脚手架使用的是: [antd-init](https://github.com/ant-design/antd-init);
6 |
7 | ## preview
8 |
9 | https://xcloud.alipay.com/
10 |
11 | https://ant-motion.github.io/experience-cloud-landing-page/
12 |
13 |
14 | ## install
15 | ```
16 | $ npm i
17 | ```
18 |
19 | ## Development
20 |
21 | ```
22 | $ npm start
23 | ```
--------------------------------------------------------------------------------
/src/Home/static/default.less:
--------------------------------------------------------------------------------
1 | @import "~antd/lib/style/themes/default.less";
2 |
3 | @banner-text-color: #5C6899;
4 |
5 |
6 | .card-style() {
7 | background: linear-gradient(to bottom, #2469F4, #113BBF);
8 | box-shadow: 0px 16px 40px #0F2DA0;
9 | transition: transform .3s @ease-in-out, box-shadow .3s @ease-in-out;
10 | &:hover {
11 | transform: translateY(-4px);
12 | box-shadow: 0px 20px 40px #0F2DA0;
13 | }
14 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Demo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/Home/static/footer.less:
--------------------------------------------------------------------------------
1 | .footer {
2 | background:linear-gradient(to bottom, #031D6A, #000E48);
3 | color: #fff;
4 | }
5 | .footer-wrap {
6 | padding: 72px 24px 144px;
7 | .footer-item {
8 | display: inline-block;
9 | text-align: left;
10 | h2 {
11 | margin-bottom: 24px;
12 | color: #fff;
13 | font-size: 16px;
14 | }
15 | div {
16 | margin-bottom: 12px;
17 | font-size: 14px;
18 | a {
19 | color: rgba(256, 256, 256, 0.9);
20 | }
21 | }
22 | }
23 | }
24 | .footer-bottom {
25 | border-top: 1px solid rgba(255, 255, 255, 0.15);
26 | padding: 21px 0;
27 | line-height: 22px;
28 | text-align: right;
29 | color: rgba(255, 255, 255, 0.6);
30 | a {
31 | color: rgba(255, 255, 255, 0.6);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Home/Page4.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Row, Col } from 'antd';
3 | import QueueAnim from 'rc-queue-anim';
4 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
5 | import { page4 } from './data';
6 |
7 | export default function Page4() {
8 | const children = page4.children.map((img, i) => (
9 |
10 |
11 |
12 | ));
13 | return (
14 |
15 |
16 |
{page4.title}
17 |
18 |
19 |
26 | {children}
27 |
28 |
29 |
30 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/src/Home/Header.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Row, Col, Tooltip } from 'antd';
3 | import { header } from './data';
4 |
5 | export default function Header(props) {
6 | const menuChild = header.map((item, i) => {
7 | const content = item.children.map((child, ii) => (
8 |
9 |
10 |
11 | {child.title}
12 |
{child.desc}
13 |
14 |
15 | ));
16 | return (
17 |
18 |
19 | {item.title}
20 |
21 |
22 | );
23 | });
24 | return (
25 |
26 |
27 | {menuChild}
28 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/src/Home/index.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import DocumentTitle from 'react-document-title';
3 | import { enquireScreen } from 'enquire-js';
4 | import Header from './Header';
5 | import Banner from './Banner';
6 | import Page1 from './Page1';
7 | import Page2 from './Page2';
8 | import Page3 from './Page3';
9 | import Page4 from './Page4';
10 | import Footer from './Footer';
11 | import './static/style';
12 |
13 |
14 | let isMobile = false;
15 | enquireScreen((b) => {
16 | isMobile = b;
17 | });
18 |
19 |
20 | class Home extends React.PureComponent {
21 | state = {
22 | isMobile,
23 | showShadow: false,
24 | };
25 |
26 | componentDidMount() {
27 | enquireScreen((b) => {
28 | this.setState({
29 | isMobile: !!b,
30 | });
31 | });
32 | }
33 | navToShadow = (e) => {
34 | this.setState({ showShadow: e.mode === 'leave' });
35 | }
36 | render() {
37 | return (
38 | [
39 | ,
40 | ,
41 | ,
42 | ,
43 | ,
44 | ,
45 | ,
46 | ,
47 | ]
48 | );
49 | }
50 | }
51 | export default Home;
52 |
--------------------------------------------------------------------------------
/src/Home/static/header.less:
--------------------------------------------------------------------------------
1 | @import './default';
2 | header {
3 | position: absolute;
4 | width: 100%;
5 | z-index: 10;
6 | .nav {
7 | max-width: 424px;
8 | text-align: center;
9 | margin: auto;
10 | &-title {
11 | display: block;
12 | padding-top: 22px;
13 | border-top: 2px solid transparent;
14 | transition: border .3s @ease-out;
15 | color: #fff;
16 | cursor: pointer;
17 | &:hover {
18 | border-top-color: #fff;
19 | }
20 | }
21 | }
22 | }
23 |
24 | .header-tip-wrap {
25 | .ant-tooltip-arrow {
26 | border-bottom-color: rgba(1, 24, 116, .96);
27 | }
28 | .ant-tooltip-inner {
29 | background-color: rgba(1, 24, 116, .96);
30 | box-shadow: 0 8px 16px #001b72;
31 | padding: 0;
32 | max-width: none;
33 | overflow: hidden;
34 | .tip-block {
35 | display: flex;
36 | align-items: center;
37 | padding: 26px;
38 | min-width: 296px;
39 | transition: background .3s @ease-in-out;
40 | background: rgba(1, 24, 116, 0);
41 | .tip-img {
42 | display: inline-block;
43 | }
44 | .tip-content {
45 | display: inline-block;
46 | color: #fff;
47 | margin-left: 16px;
48 | line-height: 22px;
49 | >div {
50 | opacity: 0.65;
51 | font-size: 12px;
52 | line-height: 20px;
53 | }
54 | }
55 | &:hover{
56 | background-color: rgb(1, 24, 116);
57 | }
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "entry": {
4 | "index": "./index.js"
5 | },
6 | "dependencies": {
7 | "antd": "^3.0.0",
8 | "enquire-js": "^0.1.0",
9 | "prop-types": "^15.6.0",
10 | "rc-banner-anim": "^1.0.0",
11 | "rc-queue-anim": "^1.4.0",
12 | "rc-scroll-anim": "^2.1.0",
13 | "rc-tween-one": "^1.5.5",
14 | "react": "^16.1.1",
15 | "react-document-title": "^2.0.3",
16 | "react-dom": "^16.1.1",
17 | "react-github-button": "^0.1.11",
18 | "react-html5video": "^2.5.1"
19 | },
20 | "devDependencies": {
21 | "atool-build": "^1.0.2",
22 | "atool-test-mocha": "^0.1.7",
23 | "babel-eslint": "^8.0.2",
24 | "babel-plugin-import": "^1.6.2",
25 | "babel-plugin-transform-runtime": "^6.23.0",
26 | "babel-runtime": "^6.26.0",
27 | "dora": "^0.4.5",
28 | "dora-plugin-webpack": "^1.0.0",
29 | "eslint": "^4.11.0",
30 | "eslint-config-airbnb": "^16.1.0",
31 | "eslint-plugin-import": "^2.8.0",
32 | "eslint-plugin-jsx-a11y": "^6.0.2",
33 | "eslint-plugin-react": "^7.5.1",
34 | "expect": "^21.2.1",
35 | "gh-pages": "^1.1.0",
36 | "pre-commit": "^1.2.2",
37 | "redbox-react": "^1.5.0"
38 | },
39 | "pre-commit": [
40 | "lint"
41 | ],
42 | "scripts": {
43 | "build": "atool-build && cp index.html dist",
44 | "lint": "eslint --ext .js,.jsx src/",
45 | "eslint-fix": "eslint --fix src/ --ext .js,.jsx",
46 | "start": "dora --plugins webpack",
47 | "test": "atool-test-mocha ./**/__tests__/*-test.js",
48 | "deploy": "rm -rf dist && npm run build && node ./deploy.js"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Home/Page3.jsx:
--------------------------------------------------------------------------------
1 | import 'react-html5video/dist/styles.css';
2 | import React from 'react';
3 | import TweenOne from 'rc-tween-one';
4 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
5 | import BannerAnim from 'rc-banner-anim';
6 | import { DefaultPlayer as Video } from 'react-html5video';
7 | import { page3 } from './data';
8 |
9 | const { Element } = BannerAnim;
10 | const { BgElement } = Element;
11 |
12 | export default class Page3 extends React.PureComponent {
13 | render() {
14 | const { isMobile } = this.props;
15 | const children = page3.children.map((item, i) => (
16 |
17 |
18 |
27 |
28 |
29 |
30 | ));
31 | const childrenToRender = (
32 |
33 |
34 | {children}
35 |
36 |
37 | );
38 | return (
39 |
40 |
41 |
{page3.title}
42 |
43 | {
44 | React.createElement(
45 | isMobile ? 'div' : OverPack,
46 | { className: 'banner-wrapper' },
47 | childrenToRender,
48 | )}
49 |
50 |
51 | );
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Home/Banner.jsx:
--------------------------------------------------------------------------------
1 | import 'rc-banner-anim/assets/index.css';
2 | import React from 'react';
3 | import QueueAnim from 'rc-queue-anim';
4 | import BannerAnim from 'rc-banner-anim';
5 | import { Button } from 'antd';
6 | import { banner } from './data';
7 |
8 | const { Element } = BannerAnim;
9 | const { BgElement } = Element;
10 |
11 | class Banner extends React.PureComponent {
12 | getDuration = (e) => {
13 | if (e.key === 'map') {
14 | return 800;
15 | }
16 | return 1000;
17 | };
18 | render() {
19 | const { isMobile } = this.props;
20 | const bannerChildren = banner.map((item, i) => {
21 | const children = item.children.map((child, ii) => {
22 | const tag = child.tag === 'button' ? 'div' : child.tag || 'p';
23 | const childrenToRender = child.tag === 'button' ?
24 | :
25 | child.children;
26 | return React.createElement(tag, {
27 | key: ii.toString(),
28 | className: child.className,
29 | style: child.style || {},
30 | }, childrenToRender);
31 | });
32 | return (
33 |
34 |
39 |
45 | {children}
46 |
47 | );
48 | });
49 | return (
50 |
51 |
52 |
53 |
54 | {bannerChildren}
55 |
56 |
57 |
58 | );
59 | }
60 | }
61 |
62 | export default Banner;
63 |
--------------------------------------------------------------------------------
/src/Home/static/responsive.less:
--------------------------------------------------------------------------------
1 | @import "./default.less";
2 | @media only screen and (max-width: 1440px) {
3 | .banner {
4 | background-size: auto 459px;
5 | }
6 | }
7 |
8 | @media only screen and (max-width: 767.99px) {
9 | .banner{
10 | .banner-anim{
11 | height: 472px;
12 | }
13 | .seeconf{
14 | &-en-name{
15 | margin-top: 24px;
16 | transform: scale(0.75);
17 | transform-origin: top center;
18 | }
19 | &-title{
20 | margin: 4px 0 8px;
21 | font-size: 26px;
22 | line-height: 36px;
23 | }
24 | &-cn-name{
25 | font-size: 12px;
26 | line-height: 20px;
27 | }
28 | &-wrap{
29 | .banner-button{
30 | margin: 240px 0 16px;
31 | }
32 | }
33 | &-time{
34 | font-size: 12px;
35 | }
36 | }
37 |
38 | }
39 | .page{
40 | h1{
41 | font-size: 28px;
42 | margin: 64px 0 32px;
43 | }
44 | }
45 | .page1{
46 | min-height: 1464px;
47 | }
48 | .page2{
49 | min-height: 2064px;
50 | background: url(https://gw.alipayobjects.com/zos/rmsportal/pEjmWuMTpIaaAsCjpVhE.svg) no-repeat top;
51 | background-size: cover;
52 | h1{
53 | margin: 107px 0 32px;
54 | }
55 | &-content{
56 | margin-top: 72px;
57 | }
58 | &-item{
59 | &.full{
60 | max-width: 340px;
61 | height: 384px;
62 | }
63 | }
64 | }
65 | .page3{
66 | min-height: 270px;
67 | .page{
68 | padding: 0;
69 | h1, i {
70 | display: none;
71 | }
72 | .banner-wrapper{
73 | margin: 0;
74 | min-height: 270px;
75 | .banner-anim{
76 | height: 270px;
77 | }
78 | video{
79 | height: 270px;
80 | }
81 | }
82 | }
83 | }
84 | .page4{
85 | min-height: 1368px;
86 | h1{
87 | color: #697b8c;
88 | }
89 | }
90 | .footer-wrap {
91 | padding: 56px 0 0;
92 | text-align: center;
93 | .footer-item-col:nth-child(2n) {
94 | display: none;
95 | };
96 | .footer-item {
97 | margin-bottom: 48px;
98 | text-align: center;
99 | }
100 | }
101 | .footer-bottom {
102 | text-align: center;
103 | padding: 16px 0;
104 | span {
105 | display: block;
106 | }
107 | .mobile-hide {
108 | display: none;
109 | }
110 | }
111 | }
--------------------------------------------------------------------------------
/src/Home/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Row, Col } from 'antd';
3 | import { footer } from './data';
4 |
5 | export default function Footer() {
6 | return (
7 | );
78 | }
79 |
--------------------------------------------------------------------------------
/src/Home/Page2.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import QueueAnim from 'rc-queue-anim';
3 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
4 | import { Row, Col, Icon } from 'antd';
5 |
6 | import Tetris from './technology-comp/Tetris';
7 | import Column from './technology-comp/Column';
8 | import Coordinate from './technology-comp/Coordinate';
9 | import Building from './technology-comp/Building';
10 |
11 |
12 | const pageData = [
13 | {
14 | title: 'Ant Design',
15 | content: '一个面向企业级应用的 UI 设计语言与技术实现',
16 | links: [
17 | Web ,
18 | Mobile ,
19 | Pro ,
20 | ],
21 | Bg: Tetris,
22 | },
23 | {
24 | title: 'AntV',
25 | content: '简单、专业、拥有无限可能的数据可视化方案',
26 | links: (查看详情 ),
27 | Bg: Column,
28 | },
29 | {
30 | title: 'AntG',
31 | content: '智能、自然、惊艳的互联网互动体验',
32 | links: (敬请期待),
33 | Bg: Coordinate,
34 | },
35 | {
36 | title: 'Egg',
37 | content: 'Node.js & Koa,为企业级框架和应用而生',
38 | links: (查看详情 ),
39 | full: true,
40 | Bg: Building,
41 | },
42 | ];
43 |
44 | export default class Design extends React.PureComponent {
45 | state = {
46 | hover: null,
47 | };
48 | onMouseEnter = (hover) => {
49 | this.setState({
50 | hover,
51 | });
52 | }
53 | onMouseLeave = () => {
54 | this.setState({
55 | hover: null,
56 | });
57 | }
58 | render() {
59 | const { isMobile } = this.props;
60 | const children = pageData.map((item, i) => {
61 | const colProps = {
62 | md: item.full ? 24 : 8, xs: 24,
63 | };
64 | return (
65 |
66 | { this.onMouseEnter(item.title); }}
69 | onMouseLeave={this.onMouseLeave}
70 | >
71 |
72 | {item.Bg && React.createElement(item.Bg, {
73 | hover: !isMobile && this.state.hover === item.title,
74 | isMobile,
75 | })}
76 |
77 |
78 |
{item.title}
79 |
{item.content}
80 |
81 | {item.links}
82 |
83 |
84 |
85 |
86 | );
87 | });
88 | return (
89 |
90 |
91 |
简单可靠的技术
92 |
93 |
94 |
95 | {children}
96 |
97 |
98 |
99 |
);
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/Home/Page1.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import QueueAnim from 'rc-queue-anim';
3 | import { TweenOneGroup } from 'rc-tween-one';
4 | import OverPack from 'rc-scroll-anim/lib/ScrollOverPack';
5 | import { Row, Col } from 'antd';
6 | import { page1 } from './data';
7 |
8 | const pointPos = [
9 | { x: -90, y: -20 },
10 | { x: 35, y: -25 },
11 | { x: -120, y: 125 },
12 | { x: -100, y: 165 },
13 | { x: 95, y: -5 },
14 | { x: 90, y: 160, opacity: 0.2 },
15 | { x: 110, y: 50 },
16 | ];
17 |
18 | export default class Design extends React.PureComponent {
19 | state = {
20 | hoverNum: null,
21 | }
22 | onMouseOver = (i) => {
23 | this.setState({
24 | hoverNum: i,
25 | });
26 | }
27 |
28 | onMouseOut = () => {
29 | this.setState({
30 | hoverNum: null,
31 | });
32 | }
33 | getEnter = (e) => {
34 | const i = e.index;
35 | const r = (Math.random() * 2) - 1;
36 | const y = (Math.random() * 10) + 5;
37 | const delay = Math.round(Math.random() * (i * 50));
38 | return [
39 | {
40 | delay, opacity: 0.4, ...pointPos[e.index], ease: 'easeOutBack', duration: 300,
41 | },
42 | {
43 | y: r > 0 ? `+=${y}` : `-=${y}`,
44 | duration: (Math.random() * 1000) + 2000,
45 | yoyo: true,
46 | repeat: -1,
47 | }];
48 | }
49 |
50 | render() {
51 | const { hoverNum } = this.state;
52 | const { isMobile } = this.props;
53 | const children = page1.children.map((item, i) => {
54 | const isHover = hoverNum === i;
55 | const pointChild = [
56 | 'point-ring left', 'point-ring point-ring-0 right',
57 | 'point-0', 'point-2', 'point-1', 'point-3', 'point-2',
58 | ].map((className, ii) => (
59 |
67 | ));
68 | return (
69 |
70 | { this.onMouseOver(i); }}
75 | onMouseLeave={this.onMouseOut}
76 | >
77 |
85 | {(isHover || isMobile) && pointChild}
86 |
87 |
88 |

89 |
90 | {item.title}
91 | {item.content}
92 |
93 | );
94 | });
95 | return (
96 |
97 |
98 |
{page1.title}
99 |
100 |
101 |
102 | {children}
103 |
104 |
105 |
106 |
);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/Home/static/home.less:
--------------------------------------------------------------------------------
1 | @import "./default.less";
2 | @import "./custom.less";
3 | .page {
4 | &-wrapper {
5 | width: 100%;
6 | will-change: transform;
7 | }
8 | width: 100%;
9 | max-width: 1200px;
10 | padding: 0 24px;
11 | margin: auto;
12 | overflow: hidden;
13 | >h1 {
14 | margin: 144px auto 32px;
15 | font-size: 38px;
16 | line-height: 46px;
17 | color: #0d1a26;
18 | font-weight: 400;
19 | text-align: center;
20 | }
21 | >i {
22 | width: 64px;
23 | margin: auto;
24 | height: 2px;
25 | display: block;
26 | background: rgb(22, 217, 227);
27 | background: linear-gradient(to right, rgba(22, 217, 227, 1) 0%, rgba(22, 119, 227, 1) 100%);
28 | }
29 | }
30 |
31 | .banner-anim {
32 | &-arrow {
33 | opacity: 0;
34 | transition: opacity .3s @ease-out;
35 | }
36 | &:hover {
37 | .banner-anim-arrow {
38 | opacity: 1;
39 | }
40 | }
41 | }
42 |
43 | .banner {
44 | background: url(https://gw.alipayobjects.com/zos/rmsportal/okhVRKJXxQpbpKGtKneS.svg) no-repeat center top;
45 | background-size: contain;
46 | overflow: hidden;
47 | font-family: PingFang SC, Helvetica Neue For Number, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif;
48 | .page {
49 | max-width: 1248px;
50 | }
51 | .logo {
52 | background: url(https://gw.alipayobjects.com/zos/rmsportal/khXpcyRYlACLokoNTzwc.svg) no-repeat;
53 | width: 127px;
54 | height: 110px;
55 | margin: 86px auto 40px;
56 | }
57 | & &-anim {
58 | margin: 0 auto 64px;
59 | height: 600px;
60 | box-shadow: 0 20px 32px rgba(1, 4, 8, .12);
61 | background: #fff;
62 | border-radius: 8px;
63 | &-elem {
64 | .banner-bg {
65 | width: 100%;
66 | height: 100%;
67 | position: absolute;
68 | top: 0;
69 | left: 0;
70 | overflow: hidden;
71 | background-position: center;
72 | background-repeat: no-repeat;
73 | }
74 | }
75 | }
76 | .seeconf {
77 | &-wrap {
78 | text-align: center;
79 | color: @banner-text-color;
80 | .banner-button {
81 | margin: 64px 0 26px;
82 | .ant-btn {
83 | height: 35px;
84 | line-height: 35px;
85 | border-radius: 35px;
86 | background: #2354eb;
87 | box-shadow: 0 7px 13px #91a5f2;
88 | padding: 0 28px;
89 | font-size: 12px;
90 | a {
91 | text-decoration: none;
92 | }
93 | }
94 | }
95 | }
96 | &-en-name {
97 | margin: 140px 0 0;
98 | font-size: 12px;
99 | line-height: 32px;
100 | }
101 | &-title {
102 | margin: 16px 0 24px;
103 | font-size: 56px;
104 | line-height: 68px;
105 | text-indent: 2px;
106 | font-weight: 600;
107 | color: #02063D;
108 | }
109 | &-cn-name {
110 | font-size: 18px;
111 | }
112 | }
113 | &-button {
114 | .ant-btn {
115 | color: #fff;
116 | border: none;
117 | }
118 | }
119 | }
120 |
121 | .page1 {
122 | min-height: 720px;
123 | .page {
124 | >h1 {
125 | margin-top: 64px;
126 | }
127 | }
128 | &-item {
129 | text-align: center;
130 | margin-top: 96px;
131 | &-link {
132 | display: block;
133 | width: 180px;
134 | margin: auto;
135 | }
136 | &-img {
137 | width: 180px;
138 | height: 180px;
139 | display: flex;
140 | align-items: center;
141 | justify-content: center;
142 | border-radius: 100%;
143 | background: #fff;
144 | position: relative;
145 | z-index: 1;
146 | }
147 | &-title {
148 | margin-top: 56px;
149 | font-size: 20px;
150 | color: #0D1A26;
151 | }
152 | p {
153 | color: #697B8C;
154 | margin-top: 8px;
155 | }
156 | }
157 | .point-wrapper {
158 | position: absolute;
159 | width: 0;
160 | left: 50%;
161 | top: 0;
162 | z-index: 0;
163 | .point-0 {
164 | width: 4px;
165 | height: 4px;
166 | }
167 | .point-2 {
168 | width: 10px;
169 | height: 10px;
170 | }
171 | .point-ring {
172 | width: 12px;
173 | height: 12px;
174 | border-style: solid;
175 | border-width: 1px;
176 | background: transparent !important;
177 | }
178 | .point-ring-0 {
179 | width: 4px;
180 | height: 4px;
181 | }
182 | .point-1 {
183 | width: 12px;
184 | height: 12px;
185 | }
186 | .point-3 {
187 | width: 21px;
188 | height: 21px;
189 | }
190 | i {
191 | display: inline-block;
192 | border-radius: 100%;
193 | position: absolute;
194 | opacity: 0;
195 | transform: translate(0, 30px);
196 | }
197 | }
198 | }
199 |
200 | .page2 {
201 | background: url(https://gw.alipayobjects.com/zos/rmsportal/OciuRSqhtmcYCwJRJWSz.svg) no-repeat top;
202 | background-size: cover;
203 | min-height: 1475px;
204 | text-align: center;
205 | &-content {
206 | margin-top: 116px;
207 | }
208 | h1 {
209 | margin: 220px auto 32px;
210 | color: #fff;
211 | }
212 | h4 {
213 | color: #fff;
214 | }
215 | h4 {
216 | font-size: 24px;
217 | line-height: 28px;
218 | margin-bottom: 24px;
219 | text-shadow: 0 8px 12px #194EC1;
220 | }
221 | p {
222 | font-size: 12px;
223 | line-height: 20px;
224 | margin-bottom: 32px;
225 | color: rgba(256, 256, 256, 0.7);
226 | }
227 | &-item {
228 | .card-style();
229 | max-width: 340px;
230 | width: 94%;
231 | border-radius: 4px;
232 | height: 384px;
233 | position: relative;
234 | margin: auto;
235 | &-wrapper {
236 | margin-bottom: 48px;
237 | }
238 | &.full {
239 | width: 100%;
240 | max-width: none;
241 | height: 420px;
242 | }
243 | &-bg {
244 | position: absolute;
245 | bottom: 0;
246 | left: 0;
247 | display: flex;
248 | justify-content: center;
249 | width: 100%;
250 | }
251 | &-desc {
252 | padding: 59px 46px 0;
253 | position: relative;
254 | z-index: 1;
255 | }
256 | &-links {
257 | margin-bottom: 58px;
258 | a {
259 | color: #fff;
260 | margin: 0 12px;
261 | }
262 | }
263 | .effect {
264 | height: 205px;
265 | background: url(https://gw.alipayobjects.com/zos/rmsportal/tGoBjrGoqlhsmCSSabgQ.svg) no-repeat;
266 | background-size: 100% 100%;
267 | }
268 | }
269 | }
270 |
271 | .page3 {
272 | min-height: 1080px;
273 | .page {
274 | .banner-wrapper {
275 | margin-top: 88px;
276 | }
277 | .banner-anim {
278 | height: 600px;
279 | video {
280 | height: 600px;
281 | }
282 | .rh5v-Volume_icon,
283 | .rh5v-Fullscreen_icon {
284 | padding: 0;
285 | }
286 | }
287 | }
288 | }
289 |
290 | .page4 {
291 | min-height: 664px;
292 | background: #f7f7f7;
293 | &-item {
294 | &-wrapper {
295 | margin-top: 96px;
296 | }
297 | height: 68px;
298 | display: flex;
299 | align-items: center;
300 | justify-content: center;
301 | margin-bottom: 68px;
302 | img {
303 | max-width: 94%;
304 | display: inline-block;
305 | }
306 | }
307 | }
--------------------------------------------------------------------------------
/src/Home/data.js:
--------------------------------------------------------------------------------
1 | export const header = [
2 | {
3 | title: '产品',
4 | children: [
5 | {
6 | title: '云凤蝶', desc: '移动建站平台', img: 'https://gw.alipayobjects.com/zos/rmsportal/fLPzRmwAurHkPDVfHHiQ.svg', link: 'https://fengdie.alipay-eco.com/intro', top: '2px',
7 | },
8 | ],
9 | },
10 | {
11 | title: '设计体系',
12 | children: [
13 | {
14 | title: '设计价值观', desc: 'Design Values', img: 'https://gw.alipayobjects.com/zos/rmsportal/zMeJnhxAtpXPZAUhUKJH.svg', link: 'https://ant.design/docs/spec/values-cn',
15 | },
16 | {
17 | title: '视觉', desc: 'Visual', img: 'https://gw.alipayobjects.com/zos/rmsportal/qkNZxQRDqvFJscXVDmKp.svg', link: 'https://ant.design/docs/spec/colors-cn',
18 | },
19 | {
20 | title: '可视化', desc: 'Visualisation', img: 'https://gw.alipayobjects.com/zos/rmsportal/MrUQjZNOJhYJCSZZuJDr.svg', link: 'https://antv.alipay.com/zh-cn/vis/index.html',
21 | },
22 | ],
23 | },
24 | {
25 | title: '技术方案',
26 | children: [
27 | {
28 | title: 'Ant Design', desc: '蚂蚁 UI 体系', img: 'https://gw.alipayobjects.com/zos/rmsportal/ruHbkzzMKShUpDYMEmHM.svg', link: 'https://ant.design',
29 | },
30 | {
31 | title: 'AntV', desc: '蚂蚁数据可视化解决方案', img: 'https://gw.alipayobjects.com/zos/rmsportal/crqUoMinEgjMeGGFAKzG.svg', link: 'https://antv.alipay.com',
32 | },
33 | {
34 | title: 'Egg', desc: '企业级 Node 开发框架', img: 'https://gw.alipayobjects.com/zos/rmsportal/nEEwwpmNVihZimnBAtMf.svg', link: 'https://eggjs.org',
35 | },
36 | ],
37 | },
38 | {
39 | title: '关于',
40 | children: [
41 | {
42 | title: '蚂蚁金服体验科技专栏', desc: '探索极致用户体验与最佳工程实践', img: 'https://gw.alipayobjects.com/zos/rmsportal/VsVqfjYxPTJaFbPcZqMb.svg', link: 'https://zhuanlan.zhihu.com/xtech',
43 | },
44 | ],
45 | },
46 | ];
47 | export const banner = [
48 | {
49 | img: 'https://gw.alipayobjects.com/zos/rmsportal/cTyLQiaRrpzxFAuWwoDQ.svg',
50 | imgMobile: 'https://gw.alipayobjects.com/zos/rmsportal/ksMYqrCyhwQNdBKReFIU.svg',
51 | className: 'seeconf-wrap',
52 | children: [
53 | { children: 'Seeking Experience & Engineering Conference', className: 'seeconf-en-name' },
54 | { children: '首届蚂蚁体验科技大会', className: 'seeconf-title', tag: 'h1' },
55 | { children: '探索极致用户体验与最佳工程实践', className: 'seeconf-cn-name' },
56 | {
57 | children: '了解详细',
58 | className: 'banner-button',
59 | tag: 'button',
60 | link: 'https://seeconf.alipay.com/',
61 | },
62 | { children: '2018.01.06 / 中国·杭州', className: 'seeconf-time' },
63 | ],
64 | },
65 | {
66 | img: 'https://gw.alipayobjects.com/zos/rmsportal/cTyLQiaRrpzxFAuWwoDQ.svg',
67 | imgMobile: 'https://gw.alipayobjects.com/zos/rmsportal/ksMYqrCyhwQNdBKReFIU.svg',
68 | className: 'seeconf-wrap',
69 | children: [
70 | { children: 'Seeking Experience & Engineering Conference', className: 'seeconf-en-name' },
71 | { children: '首届蚂蚁体验科技大会', className: 'seeconf-title', tag: 'h1' },
72 | { children: '探索极致用户体验与最佳工程实践', className: 'seeconf-cn-name' },
73 | {
74 | children: '了解详细',
75 | className: 'banner-button',
76 | tag: 'button',
77 | link: 'https://seeconf.alipay.com/',
78 | },
79 | { children: '2018.01.06 / 中国·杭州', className: 'seeconf-time' },
80 | ],
81 | },
82 | ];
83 | export const page1 = {
84 | title: '自然好用的设计',
85 | children: [
86 | {
87 | title: '设计价值观',
88 | content: 'Design Values',
89 | src: 'https://gw.alipayobjects.com/zos/rmsportal/KtRzkMmxBuWCVjPbBgRY.svg',
90 | color: '#EB2F96',
91 | shadowColor: 'rgba(166, 55, 112, 0.08)',
92 | link: 'https://ant.design/docs/spec/values-cn',
93 | },
94 | {
95 | title: '视觉',
96 | content: 'Visual',
97 | src: 'https://gw.alipayobjects.com/zos/rmsportal/qIcZMXoztWjrnxzCNTHv.svg',
98 | color: '#1890FF',
99 | shadowColor: 'rgba(15, 93, 166, 0.08)',
100 | link: 'https://ant.design/docs/spec/colors-cn',
101 | },
102 | {
103 | title: '可视化',
104 | content: 'Visualisation',
105 | src: 'https://gw.alipayobjects.com/zos/rmsportal/eLtHtrKjXfabZfRchvVT.svg',
106 | color: '#AB33F7',
107 | shadowColor: 'rgba(112, 73, 166, 0.08)',
108 | link: 'https://antv.alipay.com/zh-cn/vis/index.html',
109 | },
110 | ],
111 | };
112 |
113 | export const page3 = {
114 | title: '大家都喜爱的产品',
115 | children: [
116 | {
117 | img: 'https://gw.alipayobjects.com/zos/rmsportal/iVOzVyhyQkQDhRsuyBXC.svg',
118 | imgMobile: 'https://gw.alipayobjects.com/zos/rmsportal/HxEfljPlykWElfhidpxR.svg',
119 | src: 'https://gw.alipayobjects.com/os/rmsportal/gCFHQneMNZMMYEdlHxqK.mp4',
120 | },
121 | {
122 | img: 'https://gw.alipayobjects.com/zos/rmsportal/iVOzVyhyQkQDhRsuyBXC.svg',
123 | imgMobile: 'https://gw.alipayobjects.com/zos/rmsportal/HxEfljPlykWElfhidpxR.svg',
124 | src: 'https://gw.alipayobjects.com/os/rmsportal/gCFHQneMNZMMYEdlHxqK.mp4',
125 | },
126 | ],
127 | };
128 |
129 | export const page4 = {
130 | title: '众多企业正在使用',
131 | children: [
132 | 'https://gw.alipayobjects.com/zos/rmsportal/qImQXNUdQgqAKpPgzxyK.svg', // 阿里巴巴
133 | 'https://gw.alipayobjects.com/zos/rmsportal/LqRoouplkwgeOVjFBIRp.svg', // 蚂蚁金服
134 | 'https://gw.alipayobjects.com/zos/rmsportal/TLCyoAagnCGXUlbsMTWq.svg', // 人民网
135 | 'https://gw.alipayobjects.com/zos/rmsportal/HmCGMKcJQMwfPLNCIhOH.svg', // cisco
136 | 'https://gw.alipayobjects.com/zos/rmsportal/aqldfFDDqRVFRxqLUZOk.svg', // GrowingIO
137 | 'https://gw.alipayobjects.com/zos/rmsportal/rqNeEFCGFuwiDKHaVaPp.svg', // 饿了么
138 | 'https://gw.alipayobjects.com/zos/rmsportal/FdborlfwBxkWIqKbgRtq.svg', // 滴滴出行
139 | 'https://gw.alipayobjects.com/zos/rmsportal/coPmiBkAGVTuTNFVRUcg.png', // 飞凡网
140 | ],
141 | };
142 |
143 | export const footer = [
144 | {
145 | title: '蚂蚁科技',
146 | children: [
147 | { title: '蚂蚁金服开放平台', link: 'https://open.alipay.com' },
148 | { title: '蚂蚁体验云', link: 'https://xcloud.alipay.com' },
149 | { title: '蚂蚁金融云', link: 'https://www.cloud.alipay.com' },
150 | ],
151 | },
152 | {
153 | title: '相关会议',
154 | children: [
155 | { title: 'ATEC', link: 'https://atec.antfin.com' },
156 | { title: 'SEE Conf', link: 'https://seeconf.alipay.com' },
157 | ],
158 | },
159 | {
160 | title: '联系我们',
161 | children: [
162 | { title: '蚂蚁金服体验科技专栏', link: 'https://zhuanlan.zhihu.com/xtech' },
163 | { title: '蚂蚁金服体验科技官微', link: 'https://weibo.com/p/1005056420205486' },
164 | { title: 'AntV 官微', link: 'https://weibo.com/antv2017' },
165 | { title: 'Ant Design 专栏', link: 'https://zhuanlan.zhihu.com/antdesign' },
166 | ],
167 | },
168 | {
169 | title: '蚂蚁体验云',
170 | icon: 'https://gw.alipayobjects.com/zos/rmsportal/wdarlDDcdCaVoCprCRwB.svg',
171 | children: [
172 | { title: 'Ant Design', desc: '蚂蚁 UI 体系', link: 'https://ant.design' },
173 | { title: 'AntV', desc: '蚂蚁数据可视化方案', link: 'https://antv.alipay.com' },
174 | // { title: 'AntG', desc: '蚂蚁互动图形技术', link: 'http://antg.alipay.net' },
175 | { title: 'Egg', desc: '企业级 Node Web 开发框架', link: 'https://eggjs.org' },
176 | { title: '云凤蝶', desc: '移动建站平台', link: 'https://fengdie.alipay-eco.com/intro' },
177 | ],
178 | },
179 | ];
180 |
181 | // 图处预加载;
182 | if (typeof document !== 'undefined') {
183 | const div = document.createElement('div');
184 | div.style.display = 'none';
185 | document.body.appendChild(div);
186 | [
187 | 'https://gw.alipayobjects.com/zos/rmsportal/KtRzkMmxBuWCVjPbBgRY.svg',
188 | 'https://gw.alipayobjects.com/zos/rmsportal/qIcZMXoztWjrnxzCNTHv.svg',
189 | 'https://gw.alipayobjects.com/zos/rmsportal/eLtHtrKjXfabZfRchvVT.svg',
190 | 'https://gw.alipayobjects.com/zos/rmsportal/iVOzVyhyQkQDhRsuyBXC.svg',
191 | 'https://gw.alipayobjects.com/zos/rmsportal/HxEfljPlykWElfhidpxR.svg',
192 | 'https://gw.alipayobjects.com/zos/rmsportal/wdarlDDcdCaVoCprCRwB.svg',
193 | ].concat(page4.children).forEach((src) => {
194 | const img = new Image();
195 | img.src = src;
196 | div.appendChild(img);
197 | });
198 | }
199 |
--------------------------------------------------------------------------------
/src/Home/technology-comp/Tetris.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import TweenOne from 'rc-tween-one';
3 |
4 | const fall = [
5 | { y: 20, opacity: 1, duration: 0 },
6 | { delay: 200, y: 40, duration: 0 },
7 | { delay: 200, y: 63, duration: 0 },
8 | { delay: 600, y: 86, duration: 1 },
9 | ];
10 | const removeAnim = [
11 | { delay: 600, opacity: 0, duration: 0 },
12 | { delay: 100, opacity: 1, duration: 0 },
13 | { delay: 100, opacity: 0, duration: 0 },
14 | { delay: 100, opacity: 1, duration: 0 },
15 | { delay: 100, opacity: 0, duration: 0 },
16 | ];
17 | export default class Tetris extends React.PureComponent {
18 | componentDidMount() {
19 | this.oneEnter = true;
20 | }
21 | oneEnter = false;
22 |
23 | render() {
24 | const { hover } = this.props;
25 | const fallRe = this.oneEnter ? [{ opacity: 0 }, { y: 0, duration: 0 }, { opacity: 1 }] : {};
26 | return (
27 |
128 | );
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/Home/technology-comp/Coordinate.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import TweenOne from 'rc-tween-one';
3 |
4 | const rectArray = [
5 | ,
6 | ,
7 | ,
8 | ,
9 | ,
10 | ,
11 | ,
12 | ,
13 | ,
14 | ,
15 | ,
16 | ,
17 | ,
18 | ,
19 | ,
20 | ,
21 | ,
22 | ,
23 | ,
24 | ,
25 | ,
26 | ,
27 | ,
28 | ,
29 | ,
30 | ,
31 | ,
32 | ,
33 | ,
34 | ,
35 | ,
36 | ,
37 | ,
38 | ,
39 | ,
40 | ,
41 | ,
42 | ,
43 | ,
44 | ,
45 | ,
46 | ,
47 | ,
48 | ,
49 | ,
50 | ,
51 | ,
52 | ,
53 | ,
54 |
55 |
56 |
57 | ,
58 |
59 |
60 |
61 | ,
62 |
63 |
64 |
65 | ,
66 |
67 |
68 |
69 | ,
70 |
71 |
72 |
73 | ,
74 |
75 |
76 |
77 | ,
78 |
79 |
80 |
81 | ,
82 |
83 |
84 |
85 | ,
86 |
87 |
88 |
89 | ,
90 | ];
91 |
92 | export default class Coordinate extends React.PureComponent {
93 | getRect = hover => (rectArray.map((item, i) => (
94 |
109 | {item}
110 |
111 | )))
112 | render() {
113 | const { hover } = this.props;
114 | return (
115 |
160 | );
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/src/Home/technology-comp/Column.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import TweenOne from 'rc-tween-one';
3 |
4 | function TweenOneG(props) {
5 | function getAnimation() {
6 | if (!Array.isArray(props.animation)) {
7 | return { ...props.animation, duration: 400 };
8 | }
9 | return props.animation.map((item, i) => {
10 | if (!i) {
11 | return { ...item, duration: 400, delay: Math.random() * 300 };
12 | }
13 | return { ...item, duration: 400 };
14 | });
15 | }
16 | return (
17 | );
26 | }
27 |
28 | export default class Column extends React.PureComponent {
29 | startTween = false;
30 | default1Anim = { y: 0 };
31 | render() {
32 | const { hover } = this.props;
33 | return (
34 | );
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/src/Home/technology-comp/Building.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import TweenOne from 'rc-tween-one';
3 |
4 | let dataArray = [
5 | [
6 | ,
7 | ,
8 | ,
9 | ,
10 | ,
11 | ,
12 | ,
13 | ,
14 | ,
15 | ,
16 | ,
17 | ,
18 | ,
19 | ,
20 | ,
21 | ,
22 | ,
23 | ,
24 | ,
25 | ,
26 | ,
27 | ,
28 | ,
29 | ,
30 | ,
31 | ],
32 | [
33 | ,
34 | ,
35 | ,
36 | ,
37 | ,
38 | ,
39 | ,
40 | ,
41 | ,
42 | ,
43 | ,
44 | ,
45 | ,
46 | ,
47 | ,
48 | ,
49 | ,
50 | ,
51 | ,
52 | ,
53 | ,
54 | ],
55 | [
56 | ,
57 | ,
58 | ,
59 | ,
60 | ,
61 | ,
62 | ,
63 | ,
64 | ,
65 | ,
66 | ,
67 | ,
68 | ,
69 | ,
70 | ,
71 | ,
72 | ,
73 | ,
74 | ,
75 | ,
76 | ,
77 | ],
78 | [
79 | ,
80 | ,
81 | ,
82 | ,
83 | ,
84 | ,
85 | ,
86 | ,
87 | ,
88 | ,
89 | ,
90 | ,
91 | ,
92 | ,
93 | ,
94 | ,
95 | ,
96 | ,
97 | ,
98 | ,
99 | ,
100 | ],
101 | [
102 | ,
103 | ,
104 | ,
105 | ,
106 | ,
107 | ,
108 | ,
109 | ,
110 | ,
111 | ,
112 | ,
113 | ,
114 | ,
115 | ,
116 | ,
117 | ,
118 | ,
119 | ,
120 | ,
121 | ,
122 | ,
123 | ,
124 | ,
125 | ,
126 | ,
127 | ],
128 | [
129 | ,
130 | ,
131 | ,
132 | ,
133 | ,
134 | ,
135 | ,
136 | ,
137 | ,
138 | ,
139 | ,
140 | ,
141 | ,
142 | ,
143 | ,
144 | ,
145 | ,
146 | ,
147 | ,
148 | ,
149 | ,
150 | ,
151 | ,
152 | ,
153 | ,
154 | ],
155 | [
156 | ,
157 | ,
158 | ,
159 | ,
160 | ,
161 | ,
162 | ,
163 | ,
164 | ,
165 | ,
166 | ,
167 | ,
168 | ,
169 | ,
170 | ,
171 | ,
172 | ,
173 | ,
174 | ,
175 | ,
176 | ,
177 | ,
178 | ,
179 | ,
180 | ,
181 | ],
182 | [
183 | ,
184 | ,
185 | ,
186 | ,
187 | ,
188 | ,
189 | ,
190 | ,
191 | ,
192 | ,
193 | ,
194 | ,
195 | ,
196 | ,
197 | ,
198 | ,
199 | ,
200 | ,
201 | ,
202 | ,
203 | ,
204 | ,
205 | ,
206 | ,
207 | ,
208 | ],
209 | [
210 | ,
211 | ,
212 | ,
213 | ,
214 | ,
215 | ,
216 | ,
217 | ,
218 | ,
219 | ,
220 | ,
221 | ,
222 | ,
223 | ,
224 | ,
225 | ,
226 | ,
227 | ,
228 | ,
229 | ,
230 | ,
231 | ,
232 | ,
233 | ,
234 | ,
235 | ,
236 | ,
237 | ,
238 | ,
239 | ,
240 | ],
241 | [
242 | ,
243 | ,
244 | ,
245 | ,
246 | ,
247 | ,
248 | ,
249 | ,
250 | ,
251 | ,
252 | ,
253 | ,
254 | ],
255 | ];
256 | function setTweenOne(item, i) {
257 | if (Math.random() <= 0.8) {
258 | return (
259 |
260 | {item}
261 | );
262 | }
263 | return React.cloneElement(item, { key: i.toString() });
264 | }
265 | dataArray = dataArray.map(item => item.map(setTweenOne));
266 | export default class Building extends React.PureComponent {
267 | setAnimToTweenOne = (hover) => {
268 | const setAnim = (item) => {
269 | if (item.type.isTweenOne) {
270 | return React.cloneElement(item, {
271 | animation: hover ?
272 | {
273 | opacity: Math.random() * 0.5,
274 | yoyo: true,
275 | repeat: -1,
276 | duration: Math.random() * 2000 + 1000,
277 | delay: Math.random() * 300,
278 | } :
279 | { opacity: 1 },
280 | });
281 | }
282 | return item;
283 | };
284 | return dataArray.map(item => item.map(setAnim));
285 | }
286 | render() {
287 | const { hover, isMobile } = this.props;
288 | if (isMobile) {
289 | return
;
290 | }
291 | const children = this.setAnimToTweenOne(hover);
292 | return (
293 |
523 | );
524 | }
525 | }
526 |
--------------------------------------------------------------------------------