├── src ├── images │ ├── icon.png │ ├── logo.png │ └── favicon.png ├── components │ ├── Mandala │ │ ├── mandala.css │ │ └── mandala.js │ ├── TextLink.js │ ├── header.js │ ├── Background.js │ ├── Button.js │ ├── footer.js │ ├── LogoImage.js │ ├── layout.js │ ├── TextLink.css │ └── seo.js ├── pages │ ├── 404.js │ ├── learn.js │ └── index.js └── gatsby-plugin-theme-ui │ └── index.js ├── README.md ├── .prettierrc ├── .prettierignore ├── gatsby-config.js ├── LICENSE ├── .gitignore └── package.json /src/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MetaFam/MetaGameWebsite/HEAD/src/images/icon.png -------------------------------------------------------------------------------- /src/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MetaFam/MetaGameWebsite/HEAD/src/images/logo.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repo is no longer used, please see https://github.com/MetaFam/metagame-wiki instead 2 | -------------------------------------------------------------------------------- /src/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MetaFam/MetaGameWebsite/HEAD/src/images/favicon.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "singleQuote": true, 4 | "tabWidth": 2, 5 | "trailingComma": "es5" 6 | } 7 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.min.js 2 | **/node_modules/** 3 | 4 | # built sites 5 | public 6 | 7 | # cache-dirs 8 | **/.cache 9 | 10 | # coverage 11 | coverage 12 | 13 | # forestry files 14 | .forestry/**/* 15 | -------------------------------------------------------------------------------- /src/components/Mandala/mandala.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | right: 0; 6 | bottom: 0; 7 | overflow: hidden; 8 | } 9 | 10 | .typed-cursor { 11 | color: #FFFFFF; 12 | font-size: 1.7rem; 13 | } 14 | -------------------------------------------------------------------------------- /src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Styled } from 'theme-ui'; 3 | 4 | import Layout from '../components/layout'; 5 | import SEO from '../components/seo'; 6 | 7 | const NotFoundPage = () => ( 8 | 9 | 10 | NOT FOUND 11 | 12 | You just hit a route that doesn't exist... the sadness. 13 | 14 | 15 | ); 16 | 17 | export default NotFoundPage; 18 | -------------------------------------------------------------------------------- /src/components/TextLink.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from 'theme-ui'; 3 | import React from 'react'; 4 | import './TextLink.css'; 5 | 6 | export const TextLink = ({ children, styleProps, ...props }) => ( 7 | 19 | {children} 20 | 21 | ); 22 | -------------------------------------------------------------------------------- /src/components/header.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx, Styled } from 'theme-ui'; 3 | import React from 'react'; 4 | 5 | export default ({ children, title, ...props }) => { 6 | return ( 7 |
8 | 15 |
22 | {children} 23 |
24 |
25 |
26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Customize your site metadata: 3 | siteMetadata: { 4 | title: `MetaGame`, 5 | author: `@MetaFam`, 6 | description: `🐙 A Massive Online Coordination Game.`, 7 | social: [ 8 | { 9 | name: `twitter`, 10 | url: `https://twitter.com/metafam`, 11 | }, 12 | { 13 | name: `github`, 14 | url: `https://github.com/MetaFam`, 15 | }, 16 | ], 17 | }, 18 | plugins: [ 19 | 'gatsby-plugin-theme-ui', 20 | 'gatsby-plugin-react-helmet', 21 | `gatsby-transformer-sharp`, 22 | 'gatsby-plugin-remove-serviceworker', 23 | { 24 | resolve: `gatsby-source-filesystem`, 25 | options: { 26 | name: `images`, 27 | path: `${__dirname}/src/images`, 28 | }, 29 | }, 30 | { 31 | resolve: `gatsby-plugin-layout`, 32 | options: { 33 | component: require.resolve(`./src/components/layout`), 34 | }, 35 | }, 36 | ], 37 | }; 38 | -------------------------------------------------------------------------------- /src/components/Background.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from "theme-ui" 3 | import React from "react" 4 | import { useStaticQuery, graphql } from "gatsby" 5 | import BackgroundImage from 'gatsby-background-image' 6 | 7 | 8 | const Background = ({ children }) => { 9 | const data = useStaticQuery(graphql` 10 | query { 11 | icon: file(relativePath: { eq: "icon.png" }) { 12 | childImageSharp { 13 | fluid(maxWidth: 600) { 14 | ...GatsbyImageSharpFluid 15 | } 16 | } 17 | } 18 | } 19 | `); 20 | const imageData = data.icon && data.icon.childImageSharp && data.icon.childImageSharp.fluid; 21 | 22 | return( 23 | 33 | {children} 34 | 35 | ); 36 | }; 37 | 38 | export default Background 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 MetaFam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/components/Button.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import React from 'react'; 3 | import { jsx, Styled } from 'theme-ui'; 4 | 5 | const StyledButton = ({ color = 'primary', text = '', ...props }) => { 6 | return ( 7 | 8 | 40 | 41 | ); 42 | }; 43 | 44 | export default StyledButton; 45 | -------------------------------------------------------------------------------- /src/components/footer.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import React from "react" 3 | import { jsx } from "theme-ui" 4 | import { TextLink } from './TextLink'; 5 | 6 | const Footer = () => ( 7 | 45 | ); 46 | 47 | export default Footer; 48 | -------------------------------------------------------------------------------- /src/components/LogoImage.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from "theme-ui" 3 | import React from "react" 4 | import { useStaticQuery, graphql } from "gatsby" 5 | import Img from "gatsby-image" 6 | 7 | /* 8 | * This component is built using `gatsby-image` to automatically serve optimized 9 | * images with lazy loading and reduced file sizes. The image is loaded using a 10 | * `useStaticQuery`, which allows us to load the image from directly within this 11 | * component, rather than having to pass the image data down from pages. 12 | * 13 | * For more information, see the docs: 14 | * - `gatsby-image`: https://gatsby.dev/gatsby-image 15 | * - `useStaticQuery`: https://www.gatsbyjs.org/docs/use-static-query/ 16 | */ 17 | 18 | 19 | const LogoImage = () => { 20 | const data = useStaticQuery(graphql` 21 | query { 22 | logo: file(relativePath: { eq: "logo.png" }) { 23 | childImageSharp { 24 | fluid(maxWidth: 600) { 25 | ...GatsbyImageSharpFluid 26 | } 27 | } 28 | } 29 | } 30 | `); 31 | 32 | return( 33 | 41 | ); 42 | } 43 | 44 | export default LogoImage 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # dotenv environment variable files 55 | .env* 56 | 57 | # gatsby files 58 | .cache/ 59 | public 60 | 61 | # Mac files 62 | .DS_Store 63 | 64 | # Yarn 65 | yarn-error.log 66 | .pnp/ 67 | .pnp.js 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # IDE 72 | .idea 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metagame", 3 | "private": true, 4 | "version": "0.0.1", 5 | "scripts": { 6 | "develop": "gatsby develop", 7 | "start": "gatsby develop", 8 | "build": "gatsby build", 9 | "clean": "gatsby clean", 10 | "format": "prettier --write \"**/*.{js,jsx,json,md}\"" 11 | }, 12 | "dependencies": { 13 | "@emotion/core": "^10.0.22", 14 | "@mdx-js/react": "^1.5.1", 15 | "@theme-ui/components": "^0.2.50", 16 | "@theme-ui/presets": "^0.2.44", 17 | "gatsby": "^2.18.4", 18 | "gatsby-background-image": "^0.9.12", 19 | "gatsby-image": "^2.2.38", 20 | "gatsby-plugin-layout": "^1.1.21", 21 | "gatsby-plugin-prefetch-google-fonts": "^1.4.3", 22 | "gatsby-plugin-react-helmet": "^3.1.16", 23 | "gatsby-plugin-remove-serviceworker": "^1.0.0", 24 | "gatsby-plugin-sharp": "^2.3.13", 25 | "gatsby-plugin-theme-ui": "^0.2.43", 26 | "gatsby-source-filesystem": "^2.1.46", 27 | "gatsby-transformer-sharp": "^2.3.12", 28 | "gsap": "^3.0.5", 29 | "lodash.shuffle": "^4.2.0", 30 | "normalize.css": "^8.0.1", 31 | "react": "^16.12.0", 32 | "react-dom": "^16.12.0", 33 | "react-helmet": "^5.2.1", 34 | "react-icons": "^3.8.0", 35 | "theme-ui": "^0.2.49", 36 | "three": "^0.112.1", 37 | "typed.js": "^2.0.11" 38 | }, 39 | "devDependencies": { 40 | "prettier": "^1.19.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/components/layout.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from 'theme-ui'; 3 | import React, { useEffect } from 'react'; 4 | import { useStaticQuery, graphql } from 'gatsby'; 5 | import { Styled } from 'theme-ui'; 6 | import { Global } from '@emotion/core' 7 | import "normalize.css" 8 | import Header from './header'; 9 | import Footer from './footer'; 10 | import "./Mandala/mandala.css" 11 | import { setup } from "./Mandala/mandala" 12 | import Background from './Background'; 13 | 14 | const Layout = ({ children, ...props }) => { 15 | const data = useStaticQuery(graphql` 16 | query SiteTitleQuery { 17 | site { 18 | siteMetadata { 19 | title 20 | } 21 | } 22 | } 23 | `); 24 | 25 | useEffect(() => { 26 | setup(); 27 | }, []); 28 | 29 | return ( 30 | 31 | ({ 33 | body: { 34 | backgroundColor: theme.colors.background, 35 | overflow: 'hidden', 36 | cursor: 'crosshair', 37 | userSelect: 'none' 38 | } 39 | })} 40 | /> 41 |
42 | 43 |
44 |
52 | {children} 53 |
54 |
57 |
58 | ); 59 | }; 60 | 61 | export default Layout; 62 | -------------------------------------------------------------------------------- /src/components/TextLink.css: -------------------------------------------------------------------------------- 1 | .animated-links { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | 6 | .mg-link { 7 | position: relative; 8 | display: inline-block; 9 | color: #fff; 10 | text-decoration: none; 11 | text-align: center; 12 | text-transform: uppercase; 13 | font-weight: 400; 14 | text-shadow: 0 0 15px rgba(0,0,0,0.9), 0 0 5px rgba(0,0,0,0.9); 15 | outline: none; 16 | -webkit-tap-highlight-color: transparent; 17 | -webkit-tap-highlight-color: rgba(0,0,0,0); 18 | -webkit-appearance: none; 19 | } 20 | 21 | .mg-link:visited { 22 | color: rgba(255,255,255,0.5) !important; 23 | } 24 | 25 | .mg-link:hover, 26 | .mg-link:focus { 27 | outline: none; 28 | -webkit-tap-highlight-color: transparent; 29 | -webkit-tap-highlight-color: rgba(0,0,0,0); 30 | -webkit-appearance: none; 31 | } 32 | /* Effect 7: second border slides up */ 33 | .mg-link { 34 | padding: 12px 10px 10px; 35 | } 36 | 37 | .mg-link::before, 38 | .mg-link::after { 39 | position: absolute; 40 | top: 90%; 41 | left: 0; 42 | width: 100%; 43 | height: 3px; 44 | background: #FF247C; 45 | opacity: 0.2; 46 | content: ''; 47 | -webkit-transition: -webkit-transform 0.3s; 48 | -moz-transition: -moz-transform 0.3s; 49 | transition: transform 0.3s, opacity 0.3s; 50 | -webkit-transform: scale(0.85); 51 | -moz-transform: scale(0.85); 52 | transform: scale(0.85); 53 | } 54 | 55 | .mg-link::after { 56 | opacity: 0; 57 | -webkit-transition: top 0.3s, opacity 0.3s, -webkit-transform 0.3s; 58 | -moz-transition: top 0.3s, opacity 0.3s, -moz-transform 0.3s; 59 | transition: top 0.3s, opacity 0.3s, transform 0.3s; 60 | } 61 | 62 | .mg-link:hover::before, 63 | .mg-link:hover::after, 64 | .mg-link:focus::before, 65 | .mg-link:focus::after { 66 | -webkit-transform: scale(1); 67 | -moz-transform: scale(1); 68 | transform: scale(1); 69 | opacity: 1; 70 | } 71 | 72 | .mg-link:hover::after, 73 | .mg-link:focus::after { 74 | top: 10%; 75 | opacity: 1; 76 | } 77 | -------------------------------------------------------------------------------- /src/components/seo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Helmet from 'react-helmet'; 3 | import { useStaticQuery, graphql } from 'gatsby'; 4 | import favicon from '../images/favicon.png' 5 | 6 | function SEO({ description, lang, meta, keywords, title }) { 7 | const { site } = useStaticQuery( 8 | graphql` 9 | query { 10 | site { 11 | siteMetadata { 12 | title 13 | description 14 | author 15 | } 16 | } 17 | } 18 | ` 19 | ); 20 | 21 | const metaDescription = description || site.siteMetadata.description; 22 | 23 | return ( 24 | 0 70 | ? { 71 | name: `keywords`, 72 | content: keywords.join(`, `), 73 | } 74 | : [] 75 | ) 76 | .concat(meta)} 77 | > 78 | 79 | 80 | ); 81 | } 82 | 83 | SEO.defaultProps = { 84 | lang: `en`, 85 | meta: [], 86 | keywords: [], 87 | }; 88 | 89 | export default SEO; 90 | -------------------------------------------------------------------------------- /src/pages/learn.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from 'theme-ui'; 3 | import React from 'react'; 4 | import Button from '../components/Button'; 5 | import SEO from '../components/seo'; 6 | import { Link } from 'gatsby'; 7 | import { TextLink } from '../components/TextLink'; 8 | 9 | const IndexPage = () => ( 10 |
11 | 12 | 15 | I. In Search of Commons that Scale 16 | 17 | 20 | II. On Gamification 21 | 22 | 25 | III. The Coming of MetaGame 26 | 27 | 30 | IV. WTF is MetaGame 31 | 32 | 35 | V. The Decentralized Factory 36 | 37 | 40 | VI. The Web of Opportunity 41 | 42 | 45 | VII. The Way of Web3 Founders 46 | 47 | 50 | VIII. How To Become a Founder of MetaGame 51 | 52 |
60 | 63 |
75 |
76 | ); 77 | 78 | export default IndexPage; 79 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from 'theme-ui'; 3 | import React from 'react'; 4 | import { Link } from 'gatsby'; 5 | import { Styled } from 'theme-ui'; 6 | import Button from '../components/Button'; 7 | import SEO from '../components/seo'; 8 | import LogoImage from '../components/LogoImage'; 9 | import shuffle from 'lodash.shuffle'; 10 | import Typed from 'typed.js'; 11 | 12 | const SENTENCES = [ 13 | 'The Virtual Silicon Valley Of The Web3 Universe', 14 | 'An Operating System For A Remote World', 15 | 'A Real Life Role Playing Game For Building The Future', 16 | 'Social Media x Freelancing x MMORPG', 17 | 'A Cult With Your Best Interests At Heart', 18 | 'A Decentralized Factory, a Web of Opportunity', 19 | 'Sort of like LinkedIn, except not boring and nothing like LinkedIn', 20 | 'This is not a coincidence', 21 | 'Help us help you help the world', 22 | 'A Massive Online Coordination Game', 23 | 'A Collaborative Guide For Your Journey Into Web3', 24 | "Confused? We're not really sure what it is either", 25 | 'A Game To Change The Game', 26 | ]; 27 | 28 | 29 | const IndexPage = () => { 30 | 31 | React.useEffect(() => { 32 | window.location.replace("https://wiki.metagame.wtf"); 33 | }, []); 34 | return
35 | } 36 | // 37 | // const IndexPage = () => { 38 | // const typingRef = React.useRef(null); 39 | // 40 | // React.useEffect(() => { 41 | // window.location.replace("https://wiki.metagame.wtf"); 42 | // if (!typingRef.current) return () => {}; 43 | // 44 | // const typed = new Typed(typingRef.current, { 45 | // strings: shuffle(SENTENCES), 46 | // typeSpeed: 30, 47 | // loop: true, 48 | // backDelay: 1500, 49 | // backSpeed: 10, 50 | // }); 51 | // 52 | // return () => typed.destroy(); 53 | // }, []); 54 | // 55 | // return ( 56 | // <> 57 | // 58 | // 59 | //
73 | // 74 | //
75 | //
83 | // 84 | //
93 | // 94 | // ); 95 | // }; 96 | 97 | export default IndexPage; 98 | -------------------------------------------------------------------------------- /src/gatsby-plugin-theme-ui/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | space: [0, 4, 8, 16, 32, 64, 96, 128, 256, 512], 3 | fonts: { 4 | body: 'IBM Plex Mono, monospace', 5 | heading: 'Aldrich, sans-serif', 6 | monospace: "'Press Start 2P', monospace", 7 | }, 8 | fontSizes: [ 9 | '0.875rem', 10 | '1rem', 11 | '1.15rem', 12 | '1.5rem', 13 | '1.875rem', 14 | '2.25rem', 15 | '3rem', 16 | '4rem', 17 | '4.5rem', 18 | ], 19 | fontWeights: { 20 | body: 400, 21 | heading: 500, 22 | bold: 700, 23 | }, 24 | lineHeights: { 25 | body: 1.5, 26 | heading: 1.25, 27 | }, 28 | colors: { 29 | text: '#fff', 30 | background: '#110A31', 31 | secondary: '#FF0077', 32 | secondary25: 'rgba(255,0,119,0.25)', 33 | primary: '#0dc3cf', 34 | primary25: 'rgba(13, 195, 207, 0.25)', 35 | muted: '#eeeeee', 36 | dark: '#000', 37 | dark50: 'rgba(0,0,0,0.5)', 38 | purple: '#4b30ff', 39 | purple25: 'rgba(76,48,255,0.25)', 40 | gray: '#606060', 41 | disabled: '#B5B5B5', 42 | light: '#fff', 43 | light50: 'rgba(255,255,255,0.5)', 44 | light25: 'rgba(255,255,255,0.25)', 45 | transparent: 'rgba(0,0,0,0)', 46 | warning: '#D83E3E', 47 | }, 48 | shadows: { 49 | primary: '0px 0px 7px rgba(13,195,207,0.8)', 50 | secondary: '0px 0px 7px rgba(255,36,124,0.8)', 51 | light: '0px 0px 7px rgba(255,255,255,0.6)', 52 | }, 53 | text: { 54 | monoTitle: { 55 | fontFamily: 'monospace', 56 | fontSize: 1, 57 | }, 58 | }, 59 | styles: { 60 | root: { 61 | fontFamily: 'body', 62 | lineHeight: 'body', 63 | fontWeight: 'body', 64 | fontSize: '16px', 65 | }, 66 | h1: { 67 | color: 'text', 68 | fontFamily: 'heading', 69 | lineHeight: 'heading', 70 | fontWeight: 'heading', 71 | fontSize: 5, 72 | }, 73 | h2: { 74 | color: 'text', 75 | fontFamily: 'heading', 76 | lineHeight: 'heading', 77 | fontWeight: 'heading', 78 | fontSize: 4, 79 | }, 80 | h3: { 81 | color: 'text', 82 | fontFamily: 'heading', 83 | lineHeight: 'heading', 84 | fontWeight: 'heading', 85 | fontSize: 3, 86 | }, 87 | h4: { 88 | color: 'text', 89 | fontFamily: 'heading', 90 | lineHeight: 'heading', 91 | fontWeight: 'heading', 92 | fontSize: 2, 93 | }, 94 | h5: { 95 | color: 'text', 96 | fontFamily: 'heading', 97 | lineHeight: 'heading', 98 | fontWeight: 'heading', 99 | fontSize: 1, 100 | }, 101 | h6: { 102 | color: 'text', 103 | fontFamily: 'heading', 104 | lineHeight: 'heading', 105 | fontWeight: 'heading', 106 | fontSize: 0, 107 | }, 108 | p: { 109 | color: 'text', 110 | fontFamily: 'body', 111 | fontWeight: 'body', 112 | lineHeight: 'body', 113 | }, 114 | a: { 115 | color: 'light', 116 | }, 117 | pre: { 118 | fontFamily: 'monospace', 119 | overflowX: 'auto', 120 | code: { 121 | color: 'inherit', 122 | }, 123 | }, 124 | code: { 125 | fontFamily: 'monospace', 126 | fontSize: 'inherit', 127 | }, 128 | table: { 129 | width: '100%', 130 | borderCollapse: 'separate', 131 | borderSpacing: 0, 132 | }, 133 | th: { 134 | textAlign: 'left', 135 | borderBottomStyle: 'solid', 136 | }, 137 | td: { 138 | textAlign: 'left', 139 | borderBottomStyle: 'solid', 140 | }, 141 | img: { 142 | maxWidth: '100%', 143 | }, 144 | }, 145 | }; 146 | -------------------------------------------------------------------------------- /src/components/Mandala/mandala.js: -------------------------------------------------------------------------------- 1 | import { TweenMax, Elastic } from 'gsap'; 2 | import * as THREE from 'three'; 3 | import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; 4 | 5 | 6 | var camera, scene, renderer, mouse, controls, drawCount; 7 | var gradientLength, gradientOffset, gradientOffset2; 8 | var line, linesGroup, lastPointZ; 9 | var dragging, d, offset, parentInfo, parent, speed; 10 | var deleteQueue, MAX_POINTS, fibonacci, colorChangeSpeed, views; 11 | 12 | //preventi scrolling on mobile devices 13 | export function setup() { 14 | var windowHeight = window.innerHeight; 15 | var wrapper = document.getElementById('wrapper'); 16 | 17 | var a = setInterval(function() { 18 | document.scrollTop = -1; 19 | resize(); 20 | }, 500); 21 | var resize = function() { 22 | onWindowResize(); 23 | if(window.innerHeight !== windowHeight) { 24 | windowHeight = window.innerHeight; 25 | wrapper.style.height = windowHeight; 26 | } 27 | }; 28 | 29 | 30 | 31 | parent = document.getElementById( 'wrapper' ); 32 | parentInfo = parent.getBoundingClientRect(); 33 | d = 0; 34 | speed = 0.1; 35 | deleteQueue = []; 36 | MAX_POINTS = 500; 37 | dragging = false; 38 | fibonacci = [5,8,13,21,34,55,89]; 39 | colorChangeSpeed = 6; 40 | offset = -40; 41 | views = { 42 | 'inside':{z:offset}, 43 | 'axial':{x:0, y:0} 44 | } 45 | 46 | //HTML VIEW OPTIONS BUTTONS 47 | var viewButtons = document.getElementsByClassName('option'); 48 | 49 | for(var i = 0; i < viewButtons.length; i++) { 50 | var viewButton = viewButtons[i]; 51 | viewButton.onclick = function(event) { 52 | event.preventDefault(); 53 | let target = event.target || event.srcElement; 54 | if (!target.classList.contains('active')) { 55 | toggleActiveView(target); 56 | } 57 | } 58 | } 59 | 60 | init(); 61 | setView('inside'); 62 | } 63 | 64 | function toggleActiveView(t) { 65 | var elems = t.parentElement.children; 66 | [].forEach.call(elems, function(el) { 67 | if (t != el) { 68 | el.classList.remove('active'); 69 | } else { 70 | el.classList.add('active'); 71 | } 72 | }); 73 | } 74 | 75 | // THREE.JS CODE 76 | 77 | 78 | function init() { 79 | camera = new THREE.PerspectiveCamera(110, window.innerWidth/window.innerHeight, 0.001, 1000); 80 | camera.position.z = offset; 81 | camera.position.x = 0; 82 | camera.position.y = 0; 83 | 84 | scene = new THREE.Scene(); 85 | scene.fog = new THREE.FogExp2(0x151515, 0.024, 150 , 220); 86 | 87 | let ambientLight = new THREE.AmbientLight(0xffffff); 88 | scene.add(ambientLight); 89 | 90 | linesGroup = new THREE.Group(); 91 | scene.add(linesGroup); 92 | 93 | /////////////////// 94 | // CONTROLS // 95 | /////////////////// 96 | controls = new OrbitControls( camera, parent ); 97 | controls.mouseButtons = { 98 | ORBIT: THREE.MOUSE.RIGHT 99 | } 100 | controls.enableZoom = false; 101 | controls.update(); 102 | controls.enabled=false; 103 | 104 | /////////////////// 105 | // EVENT LISTENERS // 106 | /////////////////// 107 | parent.addEventListener('mousemove', handleDraw, false); 108 | parent.addEventListener('touchmove', handleDraw, false); 109 | parent.addEventListener('mousedown', function(e){ 110 | e.preventDefault(); 111 | if (e.which === 1) { 112 | newGroup(); 113 | dragging = true; 114 | } 115 | }); 116 | parent.addEventListener('touchstart', function(e){ 117 | newGroup(); 118 | dragging = true; 119 | 120 | }); 121 | 122 | 123 | parent.addEventListener('mouseup', function(e) { 124 | e.preventDefault(); 125 | let lastPointIndex = drawCount >= 500 ? 499 : drawCount-1; 126 | deleteQueue.push(lastPointZ); 127 | dragging = false; 128 | }); 129 | parent.addEventListener('touchend', function(e) { 130 | let lastPointIndex = drawCount >= 500 ? 499 : drawCount-1; 131 | deleteQueue.push(lastPointZ); 132 | console.log(deleteQueue.length); 133 | dragging = false; 134 | }); 135 | window.addEventListener( 'resize', onWindowResize, false ); 136 | // window.addEventListener('orientationchange', onWindowResize, false ); 137 | /////////////////// 138 | // RENDERER // 139 | /////////////////// 140 | renderer = new THREE.WebGLRenderer( { antialias: true }); 141 | renderer.setClearColor(scene.fog.color); 142 | renderer.setPixelRatio( window.devicePixelRatio ); 143 | renderer.setSize( window.innerWidth, window.innerHeight ); 144 | document.body.appendChild( renderer.domElement ); 145 | 146 | mouse = new THREE.Vector2(); 147 | setView('outside'); 148 | animate(); 149 | } 150 | 151 | function animate() { 152 | requestAnimationFrame(animate); 153 | updateBoundingClient(); 154 | deletePassedLines(); 155 | controls.update(); 156 | render(); 157 | 158 | d += speed; 159 | scene.position.z = -d; 160 | } 161 | 162 | function render() { 163 | renderer.render( scene, camera ); 164 | } 165 | 166 | 167 | 168 | 169 | 170 | 171 | function deletePassedLines() { 172 | if (deleteQueue && (scene.position.z-offset)+deleteQueue[0] <= -110) { 173 | linesGroup.remove(linesGroup.children[0]); 174 | deleteQueue.shift(); 175 | } 176 | } 177 | 178 | function newGroup() { 179 | let geometry = new THREE.BufferGeometry(); 180 | // CREATING POSITIONS AND COLORS ARRAY TO MANIPULATE THEIR VALUES LATER ON 181 | let positions = new Float32Array( MAX_POINTS * 3 ); 182 | geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); 183 | let colors = new Uint8Array( MAX_POINTS * 3); 184 | geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3, true) ); 185 | 186 | // SHOWS ONLY POINTS FROM INDEX 0 UP TO DRAW COUNT (WHICH WILL BE GRADUALLY INCREASED) 187 | drawCount = 0; 188 | geometry.setDrawRange( 0, drawCount ); 189 | 190 | var material = new THREE.LineBasicMaterial({ 191 | color: 0xffffff, 192 | vertexColors: THREE.VertexColors 193 | }); 194 | 195 | line = new THREE.Line( geometry, material ); 196 | line.frustumCulled = false; 197 | // SETS PROPERTIES FOR COLOR MODE ETC 198 | setProperties(); 199 | 200 | // CLONING AND ADDING LINES TO GROUP 201 | var group = new THREE.Group(); 202 | let angle = getAngle(); 203 | let segments = 2*Math.PI/angle; 204 | let direction = Math.random()<0.5 ? -1 : 1; 205 | for (var s = 0; s < segments; s++) { 206 | let clone = line.clone(); 207 | 208 | if (segments <= 21) { 209 | let config = { 210 | ease : Elastic.easeOut, 211 | delay : 0, 212 | repeat : 0 213 | } 214 | 215 | config["z"] = s*angle*direction; 216 | TweenMax.to( 217 | clone.rotation, 218 | 0.2*s, 219 | config 220 | ); 221 | } else { 222 | clone.rotation.z = s*angle; 223 | } 224 | group.add( clone ); 225 | } 226 | linesGroup.add( group ); 227 | } 228 | 229 | function getAngle() { 230 | return (Math.PI*2/fibonacci[Math.floor(Math.random()*fibonacci.length)]); 231 | } 232 | 233 | function map(value, maxOne, maxTwo) { 234 | let dir = Math.pow(-1, Math.floor(value/maxTwo)); 235 | let reducedValue = value-Math.floor(value/maxTwo)*maxTwo; 236 | let finalValue = maxOne*(reducedValue/maxTwo); 237 | return dir == -1 ? 255-finalValue:finalValue; 238 | } 239 | 240 | function setPosition(x, y, z, index) { 241 | var positionsArr = line.geometry.attributes.position.array; 242 | positionsArr[ index ] = x; 243 | positionsArr[ index + 1 ] = y; 244 | positionsArr[ index + 2 ] = z; 245 | } 246 | 247 | function setProperties() { 248 | gradientLength = MAX_POINTS / colorChangeSpeed; 249 | gradientOffset = Math.floor(Math.random()*MAX_POINTS); 250 | gradientOffset2 = Math.floor(Math.random()*MAX_POINTS); 251 | } 252 | 253 | function setColor(index) { 254 | var colorsArr = line.geometry.attributes.color.array; 255 | colorsArr[ index ] = map(index +gradientOffset, 255, gradientLength); 256 | colorsArr[ index +1 ] =255-colorsArr[ index ]; 257 | // MAP FUNCTION MAKES SMOOTH TRANSITION FROM ONE COLOR TO THE OTHER 258 | colorsArr[ index +2 ] = map(index +gradientOffset2, 255, gradientLength*4); 259 | } 260 | 261 | function setView(v){ 262 | let config = { 263 | ease : Elastic.easeOut, 264 | delay : 0, 265 | repeat : 0 266 | } 267 | for(var propt in views[v]){ 268 | if (propt == "z") { 269 | offset = views[v][propt]; 270 | } 271 | config[propt] = views[v][propt]; 272 | TweenMax.to( 273 | camera.position, 274 | 0.6, 275 | config 276 | ); 277 | } 278 | } 279 | 280 | 281 | // HANDLING EVENTS 282 | 283 | 284 | function handleDraw( event ) { 285 | // event.preventDefault(); 286 | //checking if user is on mouse drag or touchmove 287 | if ((dragging & event.which == 1) || event.touches){ 288 | let x = event.clientX ? event.clientX: event.touches && event.touches[0].pageX ; 289 | let y = event.clientY ? event.clientY: event.touches && event.touches[0].pageY ; 290 | mouse.x = (x/ window.innerWidth ) * 2 - 1; 291 | mouse.y = - (y/ window.innerHeight ) * 2 + 1; 292 | // DEALING WITH PERSPECTIVE - TRANSLATING MOUSE POS ON SCREEN TO TRUE POINT POSITION ON OFFSET PLANE 293 | var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5); 294 | vector.unproject( camera ); 295 | var dir = vector.sub( camera.position ).normalize(); 296 | var distance = - (camera.position.z )/ dir.z; 297 | var pos = camera.position.clone().add( dir.multiplyScalar( distance ) ); 298 | 299 | // SETTING POSITION OF THE NEXT POINT 300 | lastPointZ = camera.position.z-offset+d; 301 | setPosition( pos.x, pos.y, lastPointZ, drawCount*3); 302 | setColor( drawCount*3); 303 | line.geometry.setDrawRange( 0, drawCount ); 304 | line.geometry.attributes.position.needsUpdate = true; 305 | line.geometry.attributes.color.needsUpdate = true; 306 | 307 | // UPDATING DRAW COUNT 308 | drawCount ++; 309 | } 310 | } 311 | 312 | function onWindowResize() { 313 | camera.aspect = window.innerWidth / window.innerHeight; 314 | camera.updateProjectionMatrix(); 315 | renderer.setSize( window.innerWidth, window.innerHeight ); 316 | render(); 317 | } 318 | 319 | 320 | function updateBoundingClient() { 321 | parentInfo = parent.getBoundingClientRect(); 322 | } 323 | 324 | 325 | 326 | 327 | 328 | 329 | --------------------------------------------------------------------------------