├── .editorconfig ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .yarnrc ├── LICENSE ├── README.md ├── package.json ├── public ├── _redirects ├── favicon.ico ├── images │ ├── bg.png │ ├── icon.png │ ├── logo.svg │ └── ogp.png └── index.html ├── res ├── 1.png ├── 2.png └── ogp.png ├── src ├── breakpoint.ts ├── common-keyframes.ts ├── components │ ├── Color │ │ ├── index.tsx │ │ ├── keyframes.ts │ │ └── styles.ts │ ├── Modal │ │ ├── index.tsx │ │ ├── keyframes.ts │ │ └── styles.ts │ ├── Preview │ │ ├── index.tsx │ │ ├── keyframes.ts │ │ └── styles.ts │ └── Top │ │ ├── index.tsx │ │ ├── keyframes.ts │ │ └── styles.ts ├── config │ └── colors.ts ├── easing.ts └── index.tsx ├── tsconfig.json ├── webpack.config.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [{package.json,*.yml}] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | public/index.js 4 | *.js.map 5 | 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | public 3 | res 4 | package.json 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "semi": false, 4 | "tabWidth": 2, 5 | "useTabs": false, 6 | "singleQuote": true, 7 | "jsxSingleQuote": true, 8 | "trailingComma": "es5", 9 | "bracketSpacing": true, 10 | "jsxBracketSameLine": false, 11 | "arrowParens": "avoid" 12 | } 13 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | save-exact true 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 yui540 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # palette - パレット 2 | 3 | palette は、今まで作ってきた作品で使った色をまとめたサイトです。 4 | 5 | 『色の一つ一つに思い出が。』 6 | 7 | ![ogp](./res/ogp.png) 8 | 9 | - デザイン・モーション・コーディング 10 | - yui540 11 | - [Twitter - @yui540](https://twitter.com/yui540) 12 | 13 | ## 色一つ一つに思い出があります 14 | 15 | 僕が作品を作る上で、重要視するのは「色」です。 16 | 17 | 『色』を変えるだけで作品の印象は、大きく変わります。 18 | 19 | なので、僕は過去に作ってきた作品でたくさんの色を使ってきました。 20 | 21 | その色一つ一つに思い入れがあります。 22 | 23 | paletteは、そんな思い入れのある色を使われた作品と共に紹介するサイトです。 24 | 25 | ![1](./res/1.png) 26 | 27 | ![2](./res/2.png) 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "palette", 3 | "version": "1.0.0", 4 | "description": "『色の一つ一つに思い出が。』", 5 | "main": "webpack.config.js", 6 | "scripts": { 7 | "build:dev": "cross-env MODE=development webpack", 8 | "build:prod": "cross-env MODE=production webpack", 9 | "build": "npm-run-all build:prod", 10 | "watch": "cross-env MODE=development webpack --watch", 11 | "serve": "cross-env MODE=development webpack-dev-server", 12 | "fmt": "prettier --write \"**/*.{ts,tsx,js,json,md}\"", 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "lint-staged": { 16 | "*.{ts,tsx,js,json,md}": [ 17 | "prettier --write", 18 | "git add" 19 | ] 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/yui540/palette.git" 24 | }, 25 | "keywords": [ 26 | "palette", 27 | "yui540" 28 | ], 29 | "author": "yui540 (https://yui540.graphics)", 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/yui540/palette/issues" 33 | }, 34 | "homepage": "https://github.com/yui540/palette#readme", 35 | "devDependencies": { 36 | "@types/styled-components": "4.1.5", 37 | "awesome-typescript-loader": "5.2.1", 38 | "cross-env": "5.2.0", 39 | "file-loader": "3.0.1", 40 | "husky": "1.3.1", 41 | "lint-staged": "8.1.0", 42 | "npm-run-all": "4.1.5", 43 | "prettier": "1.15.3", 44 | "source-map-loader": "0.2.4", 45 | "typescript": "3.2.2", 46 | "url-loader": "1.1.2", 47 | "webpack": "4.28.4", 48 | "webpack-cli": "3.2.1", 49 | "webpack-dev-server": "3.1.14" 50 | }, 51 | "dependencies": { 52 | "@types/react": "16.7.18", 53 | "@types/react-dom": "16.0.11", 54 | "@types/react-router-dom": "4.3.1", 55 | "react": "16.7.0", 56 | "react-dom": "16.7.0", 57 | "react-router-dom": "4.3.1", 58 | "styled-components": "4.1.3" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 2 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yui540/palette/903bf9fbdb3ec0e023108438bf2d9213f4c81d6c/public/favicon.ico -------------------------------------------------------------------------------- /public/images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yui540/palette/903bf9fbdb3ec0e023108438bf2d9213f4c81d6c/public/images/bg.png -------------------------------------------------------------------------------- /public/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yui540/palette/903bf9fbdb3ec0e023108438bf2d9213f4c81d6c/public/images/icon.png -------------------------------------------------------------------------------- /public/images/logo.svg: -------------------------------------------------------------------------------- 1 | logo -------------------------------------------------------------------------------- /public/images/ogp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yui540/palette/903bf9fbdb3ec0e023108438bf2d9213f4c81d6c/public/images/ogp.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | palette - パレット 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 42 | 43 | 44 | 51 | 73 | 74 | 75 |
76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /res/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yui540/palette/903bf9fbdb3ec0e023108438bf2d9213f4c81d6c/res/1.png -------------------------------------------------------------------------------- /res/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yui540/palette/903bf9fbdb3ec0e023108438bf2d9213f4c81d6c/res/2.png -------------------------------------------------------------------------------- /res/ogp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yui540/palette/903bf9fbdb3ec0e023108438bf2d9213f4c81d6c/res/ogp.png -------------------------------------------------------------------------------- /src/breakpoint.ts: -------------------------------------------------------------------------------- 1 | export const pcLayout = (styles: string): string => { 2 | return ` 3 | @media screen and (min-width: 761px) { 4 | ${styles} 5 | } 6 | ` 7 | } 8 | 9 | export const spLayout = (styles: string): string => { 10 | return ` 11 | @media screen and (max-width: 760px) { 12 | ${styles} 13 | } 14 | ` 15 | } 16 | -------------------------------------------------------------------------------- /src/common-keyframes.ts: -------------------------------------------------------------------------------- 1 | import { keyframes } from 'styled-components' 2 | 3 | export const fadein = keyframes` 4 | from { opacity: 0; } 5 | to { opacity: 1; } 6 | ` 7 | 8 | export const fadeout = keyframes` 9 | from { opacity: 1; } 10 | to { opacity: 0; } 11 | ` 12 | 13 | export const slideRight = keyframes` 14 | from { transform: translateX(-100%); } 15 | to { transform: translateX(0%); } 16 | ` 17 | 18 | export const slideLeft = keyframes` 19 | from { transform: translateX(100%); } 20 | to { transform: translateX(0%); } 21 | ` 22 | 23 | export const slideTop = keyframes` 24 | from { transform: translateY(100%); } 25 | to { transform: translateY(0%); } 26 | ` 27 | 28 | export const slideBottom = keyframes` 29 | from { transform: translateY(-100%); } 30 | to { transform: translateY(0%); } 31 | ` 32 | -------------------------------------------------------------------------------- /src/components/Color/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { Container, BgColor, ProductName, ColorCode } from './styles' 3 | 4 | interface Props { 5 | num: number 6 | color: string 7 | productName: string 8 | onMouseOver(num: number): void 9 | onMouseOut(): void 10 | showModal(num: number): void 11 | } 12 | 13 | export default class Color extends React.Component { 14 | public render() { 15 | const { 16 | productName, 17 | color, 18 | num, 19 | onMouseOver, 20 | onMouseOut, 21 | showModal 22 | } = this.props 23 | 24 | return ( 25 | onMouseOver(num)} 28 | onMouseOut={() => onMouseOut()} 29 | onClick={() => showModal(num)} 30 | > 31 | 32 | {productName} 33 | {color} 34 | 35 | ) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/components/Color/keyframes.ts: -------------------------------------------------------------------------------- 1 | import { keyframes } from 'styled-components' 2 | 3 | export const beat = keyframes` 4 | 0% { transform: scale(1); border-radius: 50%; } 5 | 50% { transform: scale(.7); border-radius: 50%; } 6 | 100% { transform: scale(1); border-radius: 50%; } 7 | ` 8 | -------------------------------------------------------------------------------- /src/components/Color/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import { pcLayout, spLayout } from '../../breakpoint' 3 | import { beat } from './keyframes' 4 | 5 | export const Container = styled.button` 6 | appearance: none; 7 | border: none; 8 | position: relative; 9 | height: 0; 10 | transition: all .15s ease-out 0s; 11 | cursor: pointer; 12 | 13 | ${pcLayout(` 14 | width: 169px; 15 | padding-top: 169px; 16 | margin: 4px; 17 | box-shadow: 0 0 6px rgba(0,0,0,.2); 18 | `)} 19 | 20 | ${spLayout(` 21 | width: calc(25% - 5px); 22 | padding-top: calc(25% - 8px); 23 | margin: 2px; 24 | box-shadow: 0 0 2px rgba(0,0,0,.2); 25 | `)} 26 | 27 | &:focus { 28 | outline: 0; 29 | box-shadow: 0 0 5px 5px ${props => props.color}; 30 | ${spLayout(`box-shadow: 0 0 0 0 transparent;`)} 31 | } 32 | 33 | &:hover div:nth-child(1) { 34 | ${pcLayout(` 35 | transform: scale(.6); 36 | border-radius: 50%; 37 | `)} 38 | } 39 | &:hover div:nth-child(1)::after { 40 | animation: ${beat} .8s cubic-bezier(0.7,-0.02, 0.24, 0.98) .3s infinite; 41 | ${spLayout(`animation: none;`)} 42 | } 43 | &:hover div:nth-child(2), 44 | &:hover div:nth-child(3) { 45 | ${pcLayout(` 46 | color: #aaa; 47 | text-shadow: 0 0 0 transparent; 48 | `)} 49 | } 50 | ` 51 | 52 | export const BgColor = styled.div` 53 | position: absolute; 54 | top: 0; 55 | left: 0; 56 | width: 100%; 57 | height: 100%; 58 | overflow: hidden; 59 | transition: all .45s cubic-bezier(0, 0, 0, 1.01) 0s; 60 | 61 | &::after { 62 | content: ""; 63 | display: block; 64 | width: 100%; 65 | height: 100%; 66 | background-color: ${props => props.color}; 67 | } 68 | ` 69 | 70 | export const ProductName = styled.div` 71 | position: absolute; 72 | top: 0; 73 | left: 0; 74 | width: 100%; 75 | box-sizing: border-box; 76 | color: #fff; 77 | text-align: left; 78 | white-space: nowrap; 79 | text-overflow: ellipsis; 80 | overflow: hidden; 81 | transition: all .45s cubic-bezier(0, 0, 0, 1.01) 0s; 82 | 83 | ${pcLayout(` 84 | font-size: 12px; 85 | padding: 5px; 86 | text-shadow: 0 0 3px rgba(0,0,0,.5); 87 | `)} 88 | 89 | ${spLayout(` 90 | font-size: 9px; 91 | padding: 2.5px; 92 | text-shadow: 0 0 1px rgba(0,0,0,.5); 93 | `)} 94 | ` 95 | 96 | export const ColorCode = styled.div` 97 | position: absolute; 98 | bottom: 0; 99 | right: 0; 100 | width: 100%; 101 | box-sizing: border-box; 102 | text-align: right; 103 | color: #fff; 104 | text-transform: uppercase; 105 | white-space: nowrap; 106 | text-overflow: ellipsis; 107 | overflow: hidden; 108 | transition: all .45s cubic-bezier(0, 0, 0, 1.01) 0s; 109 | 110 | ${pcLayout(` 111 | font-size: 12px; 112 | padding: 5px; 113 | text-shadow: 0 0 3px rgba(0,0,0,.5); 114 | `)} 115 | 116 | ${spLayout(` 117 | font-size: 9px; 118 | padding: 2.5px; 119 | text-shadow: 0 0 1px rgba(0,0,0,.5); 120 | `)} 121 | ` 122 | -------------------------------------------------------------------------------- /src/components/Modal/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { 3 | Bg, 4 | Container, 5 | Inner, 6 | Close, 7 | Panel, 8 | Header, 9 | Title, 10 | Body, 11 | ColorContent, 12 | ProductName, 13 | ColorCode, 14 | ColorLine, 15 | PrevButton, 16 | NextButton, 17 | Footer, 18 | CopyButton, 19 | LineFront, 20 | LineBack, 21 | } from './styles' 22 | 23 | interface Props { 24 | modal: boolean 25 | color: string 26 | productName: string 27 | productLink: string 28 | hiddenModal(): void 29 | prevColor(): void 30 | nextColor(): void 31 | } 32 | 33 | export default class Modal extends React.Component { 34 | private clickCopy(colorCode: string) { 35 | const ele = document.createElement('div') 36 | 37 | ele.appendChild(document.createElement('pre')).textContent = colorCode 38 | ele.style.position = 'fixed' 39 | ele.style.bottom = '-100%' 40 | 41 | document.body.appendChild(ele) 42 | document.getSelection()!.selectAllChildren(ele) 43 | document.execCommand('copy') 44 | 45 | document.body.removeChild(ele) 46 | } 47 | 48 | public render() { 49 | const { 50 | productName, 51 | productLink, 52 | color, 53 | modal, 54 | hiddenModal, 55 | prevColor, 56 | nextColor 57 | } = this.props 58 | 59 | return ( 60 | <> 61 | 62 | 63 | 64 | hiddenModal()} /> 65 | 66 |
67 |
68 | 69 | 70 |
71 | {productName} 72 |
73 | 74 | 75 | 76 | Product: 77 | {productName} 78 | 79 | 80 | ColorCode: 81 | {color} 82 | 83 | 84 | 85 | prevColor()} data-show={modal} /> 86 | nextColor()} data-show={modal} /> 87 | 88 |
89 | this.clickCopy(color)} /> 90 |
91 |
92 | 93 |
94 |
95 | 96 | 97 | 98 | 99 | ) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/components/Modal/keyframes.ts: -------------------------------------------------------------------------------- 1 | import { keyframes } from 'styled-components' 2 | 3 | export const bound = keyframes` 4 | 0% { transform: translateY(-100vh); } 5 | 15% { transform: translateY(0vh); } 6 | 30% { transform: translateY(-3vh); } 7 | 45% { transform: translateY(0vh); } 8 | 60% { transform: translateY(-1.5vh); } 9 | 75% { transform: translateY(0vh); } 10 | 90% { transform: translateY(-0.75vh); } 11 | 100% { transform: translateY(0vh); } 12 | ` 13 | 14 | export const rotate = keyframes` 15 | 0% { transform: rotateY(45deg); } 16 | 15% { transform: rotateY(-5deg); } 17 | 30% { transform: rotateY(5deg); } 18 | 45% { transform: rotateY(-2.5deg); } 19 | 60% { transform: rotateY(2.5deg); } 20 | 75% { transform: rotateY(-1.25deg); } 21 | 90% { transform: rotateY(1.25deg); } 22 | 100% { transform: rotateY(0deg); } 23 | ` 24 | 25 | export const border = keyframes` 26 | from { border: solid 1px transparent; } 27 | to { border: solid 1px #ccc; } 28 | ` 29 | 30 | export const prewButtonShow = keyframes` 31 | from { transform: translate(-50%, -50%) scale(0); } 32 | to { transform: translate(-50%, -50%) scale(1); } 33 | ` 34 | 35 | export const nextButtonShow = keyframes` 36 | from { transform: translate(50%, -50%) scale(0); } 37 | to { transform: translate(50%, -50%) scale(1); } 38 | ` 39 | -------------------------------------------------------------------------------- /src/components/Modal/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import { pcLayout, spLayout } from '../../breakpoint' 3 | import { bound, rotate, border, prewButtonShow, nextButtonShow } from './keyframes' 4 | import { fadein, slideRight } from '../../common-keyframes' 5 | 6 | const color1 = '#fbf4f1' 7 | const color2 = '#5d3523' 8 | const color3 = '#ccc' 9 | const color4 = '#c2617e' 10 | 11 | export const Bg = styled.div` 12 | position: fixed; 13 | top: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 100%; 17 | background-color: rgba(255,255,255,.8); 18 | display: none; 19 | opacity: 0; 20 | 21 | &[data-show=true] { 22 | display: block; 23 | animation: ${fadein} 2s ease 0s forwards; 24 | } 25 | ` 26 | 27 | export const Container = styled.div` 28 | position: fixed; 29 | top: 0; 30 | left: 0; 31 | width: 100%; 32 | height: 100%; 33 | perspective: 600px; 34 | transform: translateY(-100%); 35 | 36 | /* animation */ 37 | &[data-show=true] { animation: ${bound} 0.9s ease-out 0s forwards; } 38 | ` 39 | 40 | export const Inner = styled.div` 41 | position: absolute; 42 | top: 0; 43 | left: 0; 44 | width: 100%; 45 | height: 100%; 46 | 47 | /* animation */ 48 | &[data-show=true] { animation: ${rotate} 3s ease-out 0s forwards; } 49 | ` 50 | 51 | export const Close = styled.div` 52 | position: absolute; 53 | top: 0; 54 | left: 0; 55 | width: 100%; 56 | height: 100%; 57 | ` 58 | 59 | export const Panel = styled.div` 60 | position: absolute; 61 | top: 50%; 62 | left: 50%; 63 | transform: translate(-50%, -50%); 64 | 65 | ${pcLayout(` 66 | width: 600px; 67 | box-shadow: 0 0 20px rgba(0,0,0,.2); 68 | border-radius: 12px; 69 | `)} 70 | 71 | ${spLayout(` 72 | width: 320px; 73 | box-shadow: 0 0 10px rgba(0,0,0,.2); 74 | border-radius: 10px; 75 | `)} 76 | ` 77 | 78 | export const Header = styled.div` 79 | width: 100%; 80 | background-color: ${color1}; 81 | border-bottom: solid 1px ${color2}; 82 | box-sizing: border-box; 83 | 84 | ${pcLayout(` 85 | height: 50px; 86 | border-top-left-radius: 12px; 87 | border-top-right-radius: 12px; 88 | `)} 89 | 90 | ${spLayout(` 91 | height: 40px; 92 | border-top-left-radius: 10px; 93 | border-top-right-radius: 10px; 94 | `)} 95 | ` 96 | 97 | export const Title = styled.div` 98 | color: ${color2}; 99 | text-align: center; 100 | letter-spacing: 0.1em; 101 | margin: 0 auto; 102 | overflow: hidden; 103 | text-overflow: ellipsis; 104 | white-space: nowrap; 105 | 106 | ${pcLayout(` 107 | font-size: 20px; 108 | line-height: 50px; 109 | width: 85%; 110 | `)} 111 | 112 | ${spLayout(` 113 | font-size: 16px; 114 | line-height: 40px; 115 | width: 80%; 116 | `)} 117 | ` 118 | 119 | export const Body = styled.div` 120 | position: relative; 121 | width: 100%; 122 | background-color: #fff; 123 | 124 | ${pcLayout(`height: 260px;`)} 125 | ${spLayout(`height: 180px;`)} 126 | ` 127 | 128 | export const ColorContent = styled.div` 129 | position: absolute; 130 | top: 50%; 131 | left: 50%; 132 | border: solid 1px transparent; 133 | transform: translate(-50%, -50%); 134 | box-sizing: border-box; 135 | 136 | ${pcLayout(` 137 | width: 500px; 138 | height: 160px; 139 | `)} 140 | 141 | ${spLayout(` 142 | width: 280px; 143 | height: 100px; 144 | `)} 145 | 146 | /* animation */ 147 | &[data-show=true] { animation: ${border} 1.4s ease-out 2.6s forwards; } 148 | ` 149 | 150 | export const ProductName = styled.div` 151 | position: absolute; 152 | color: ${color2}; 153 | background-color: #fff; 154 | 155 | ${pcLayout(` 156 | top: -18px; 157 | left: -8px; 158 | padding: 5px; 159 | font-size: 14px; 160 | `)} 161 | 162 | ${spLayout(` 163 | top: -9px; 164 | left: -4px; 165 | padding: 2.5px; 166 | font-size: 10px; 167 | `)} 168 | 169 | span { 170 | opacity: 0; 171 | } 172 | span:nth-child(1) { 173 | color: #ccc; 174 | } 175 | 176 | /* animation */ 177 | &[data-show=true] span:nth-child(1) { 178 | animation: ${fadein} 0.6s ease-in 1s forwards; 179 | } 180 | &[data-show=true] span:nth-child(2) { 181 | animation: ${fadein} 0.6s ease-in 1.4s forwards; 182 | } 183 | ` 184 | 185 | export const ColorCode = styled.div` 186 | position: absolute; 187 | color: ${color2}; 188 | background-color: #fff; 189 | 190 | ${pcLayout(` 191 | bottom: -18px; 192 | right: -8px; 193 | padding: 5px; 194 | font-size: 14px; 195 | `)} 196 | 197 | ${spLayout(` 198 | bottom: -9px; 199 | right: -4px; 200 | padding: 2.5px; 201 | font-size: 10px; 202 | `)} 203 | 204 | span { 205 | opacity: 0; 206 | } 207 | span:nth-child(1) { 208 | color: #ccc; 209 | } 210 | span:nth-child(2) { 211 | text-transform: uppercase; 212 | } 213 | 214 | /* animation */ 215 | &[data-show=true] span:nth-child(1) { 216 | animation: ${fadein} 0.6s ease-in 1.8s forwards; 217 | } 218 | &[data-show=true] span:nth-child(2) { 219 | animation: ${fadein} 0.6s ease-in 2.2s forwards; 220 | } 221 | ` 222 | 223 | export const ColorLine = styled.div` 224 | position: absolute; 225 | top: 12px; 226 | left: 12px; 227 | width: calc(100% - 24px); 228 | height: calc(100% - 24px); 229 | overflow: hidden; 230 | 231 | &::before, 232 | &::after { 233 | content: ""; 234 | display: block; 235 | position: absolute; 236 | top: 0; 237 | left: 0; 238 | width: 100%; 239 | height: 100%; 240 | } 241 | &::before { 242 | background-color: ${props => props.color}; 243 | transform: translateX(-100%); 244 | } 245 | &::after { 246 | content: "${props => props.color}"; 247 | text-align: center; 248 | color: rgba(255,255,255,.2); 249 | letter-spacing: .2em; 250 | text-transform: uppercase; 251 | 252 | ${pcLayout(` 253 | font-size: 60px; 254 | line-height: 134px; 255 | `)} 256 | 257 | ${spLayout(` 258 | font-size: 30px; 259 | line-height: 74px; 260 | `)} 261 | } 262 | 263 | /* animation */ 264 | &[data-show=true]::before { animation: ${slideRight} .8s cubic-bezier(0.86,-0.02, 0.08, 1.02) .8s forwards; } 265 | ` 266 | 267 | export const PrevButton = styled.button` 268 | appearance: none; 269 | border: none; 270 | position: absolute; 271 | top: 50%; 272 | left: 0; 273 | border-radius: 50%; 274 | background-color: ${color1}; 275 | border: solid 1px ${color2}; 276 | transform: translate(-50%, -50%) scale(0); 277 | cursor: pointer; 278 | 279 | ${pcLayout(` 280 | width: 65px; 281 | height: 65px; 282 | `)} 283 | 284 | ${spLayout(` 285 | width: 40px; 286 | height: 40px; 287 | `)} 288 | 289 | &::before, 290 | &::after { 291 | content: ''; 292 | display: block; 293 | position: absolute; 294 | } 295 | &::before { 296 | top: 0; 297 | left: 0; 298 | width: 100%; 299 | height: 100%; 300 | border-radius: 50%; 301 | background-color: #c2617e; 302 | transform: scale(0); 303 | transition: all 0.5s cubic-bezier(0.86, -0.02, 0.08, 1.02) 0s; 304 | } 305 | &::after { 306 | top: 50%; 307 | left: 50%; 308 | width: 22%; 309 | height: 22%; 310 | border-top: solid 3px ${color2}; 311 | border-left: solid 3px ${color2}; 312 | transform: translate(-25%, -50%) rotate(-45deg); 313 | transition: all 0.5s cubic-bezier(0.86, -0.02, 0.08, 1.02) 0s; 314 | } 315 | &:hover::before { 316 | ${pcLayout(`transform: scale(1);`)} 317 | } 318 | &:hover::after { 319 | ${pcLayout(`border-color: #fff;`)} 320 | } 321 | &:focus { 322 | outline: none; 323 | } 324 | 325 | /* animation */ 326 | &[data-show=true]{ animation: ${prewButtonShow} 0.3s ease-out 2.6s forwards; } 327 | ` 328 | 329 | export const NextButton = styled.button` 330 | appearance: none; 331 | border: none; 332 | position: absolute; 333 | top: 50%; 334 | right: 0; 335 | border-radius: 50%; 336 | background-color: ${color1}; 337 | border: solid 1px ${color2}; 338 | transform: translate(50%, -50%) scale(0); 339 | cursor: pointer; 340 | 341 | ${pcLayout(` 342 | width: 65px; 343 | height: 65px; 344 | `)} 345 | 346 | ${spLayout(` 347 | width: 40px; 348 | height: 40px; 349 | `)} 350 | 351 | &::before, 352 | &::after { 353 | content: ''; 354 | display: block; 355 | position: absolute; 356 | } 357 | &::before { 358 | top: 0; 359 | left: 0; 360 | width: 100%; 361 | height: 100%; 362 | border-radius: 50%; 363 | background-color: #c2617e; 364 | transform: scale(0); 365 | transition: all 0.5s cubic-bezier(0.86, -0.02, 0.08, 1.02) 0s; 366 | } 367 | &::after { 368 | top: 50%; 369 | left: 50%; 370 | width: 22%; 371 | height: 22%; 372 | border-top: solid 3px ${color2}; 373 | border-right: solid 3px ${color2}; 374 | transform: translate(-75%, -50%) rotate(45deg); 375 | transition: all 0.5s cubic-bezier(0.86, -0.02, 0.08, 1.02) 0s; 376 | } 377 | &:hover::before { 378 | ${pcLayout(`transform: scale(1);`)} 379 | } 380 | &:hover::after { 381 | ${pcLayout(`border-color: #fff;`)} 382 | } 383 | &:focus { 384 | outline: none; 385 | } 386 | 387 | /* animation */ 388 | &[data-show=true] { animation: ${nextButtonShow} 0.3s ease-out 2.8s forwards; } 389 | ` 390 | 391 | export const Footer = styled.div` 392 | position: relative; 393 | width: 100%; 394 | background-color: ${color1}; 395 | border-top: solid 1px ${color2}; 396 | box-sizing: border-box; 397 | 398 | ${pcLayout(` 399 | height: 50px; 400 | border-bottom-left-radius: 12px; 401 | border-bottom-right-radius: 12px; 402 | `)} 403 | 404 | ${spLayout(` 405 | height: 40px; 406 | border-bottom-left-radius: 10px; 407 | border-bottom-right-radius: 10px; 408 | `)} 409 | ` 410 | 411 | export const CopyButton = styled.button` 412 | appearance: none; 413 | border: none; 414 | position: absolute; 415 | bottom: 0; 416 | left: 50%; 417 | background-color: #c2617e; 418 | transform: translate(-50%, 50%); 419 | cursor: pointer; 420 | overflow: hidden; 421 | transition: all 0.5s cubic-bezier(0.86, -0.02, 0.08, 1.02) 0s; 422 | 423 | ${pcLayout(` 424 | width: 200px; 425 | height: 50px; 426 | box-shadow: 0 0 10px #c2617e; 427 | border-radius: 30px; 428 | `)} 429 | 430 | ${spLayout(` 431 | width: 140px; 432 | height: 40px; 433 | box-shadow: 0 0 5px #c2617e; 434 | border-radius: 20px; 435 | `)} 436 | 437 | &::before, 438 | &::after { 439 | content: ''; 440 | display: block; 441 | position: absolute; 442 | top: 0; 443 | left: 0; 444 | width: 100%; 445 | height: 100%; 446 | border-radius: 30px; 447 | } 448 | &::before { 449 | background-color: #4aa9a4; 450 | transform: translateX(-100%); 451 | transition: all 0.5s cubic-bezier(0.86, -0.02, 0.08, 1.02) 0s; 452 | } 453 | &::after { 454 | content: 'COPY'; 455 | color: #fff; 456 | letter-spacing: 0.2em; 457 | 458 | ${pcLayout(` 459 | font-size: 20px; 460 | line-height: 50px; 461 | `)} 462 | 463 | ${spLayout(` 464 | font-size: 16px; 465 | line-height: 40px; 466 | `)} 467 | } 468 | &:hover::before { 469 | ${pcLayout(`transform: translateX(0);`)} 470 | } 471 | &:hover { 472 | ${pcLayout(`box-shadow: 0 0 10px #4aa9a4;`)} 473 | } 474 | &:focus { 475 | outline: none; 476 | } 477 | ` 478 | 479 | export const LineBack = styled.div` 480 | position: absolute; 481 | top: 0; 482 | left: 50%; 483 | transform: translateX(-50%); 484 | 485 | ${pcLayout(` 486 | width: 600px; 487 | height: calc(50% - 180px); 488 | `)} 489 | 490 | ${spLayout(` 491 | width: 320px; 492 | height: calc(50% - 130px); 493 | `)} 494 | 495 | div { 496 | position: absolute; 497 | bottom: 0; 498 | width: 2px; 499 | height: 150%; 500 | background-color: ${color2}; 501 | } 502 | div:nth-child(1) { 503 | left: 55px; 504 | } 505 | div:nth-child(2) { 506 | right: 55px; 507 | } 508 | ` 509 | 510 | export const LineFront = styled.div` 511 | position: absolute; 512 | top: 0; 513 | left: 50%; 514 | width: 600px; 515 | height: calc(50% - 130px); 516 | transform: translateX(-50%); 517 | 518 | ${pcLayout(` 519 | width: 600px; 520 | height: calc(50% - 180px); 521 | `)} 522 | 523 | ${spLayout(` 524 | width: 320px; 525 | height: calc(50% - 130px); 526 | `)} 527 | 528 | div { 529 | position: absolute; 530 | width: 2px; 531 | height: 150%; 532 | background-color: ${color2}; 533 | 534 | ${pcLayout(`bottom: -25px;`)} 535 | ${spLayout(`bottom: -20px;`)} 536 | 537 | &::after { 538 | content: ''; 539 | display: block; 540 | position: absolute; 541 | bottom: -4.5px; 542 | left: -4.5px; 543 | width: 10px; 544 | height: 10px; 545 | background-color: ${color2}; 546 | border-radius: 50%; 547 | } 548 | } 549 | div:nth-child(1) { 550 | left: 25px; 551 | } 552 | div:nth-child(2) { 553 | right: 25px; 554 | } 555 | ` 556 | -------------------------------------------------------------------------------- /src/components/Preview/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { 3 | Container, 4 | ColorCode 5 | } from './styles' 6 | 7 | interface Props { 8 | color: string 9 | open: boolean 10 | } 11 | 12 | export default class Preview extends React.Component { 13 | public render() { 14 | const { color, open } = this.props 15 | 16 | return ( 17 | 18 | {color} 19 | 20 | ) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/components/Preview/keyframes.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yui540/palette/903bf9fbdb3ec0e023108438bf2d9213f4c81d6c/src/components/Preview/keyframes.ts -------------------------------------------------------------------------------- /src/components/Preview/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import { spLayout } from '../../breakpoint' 3 | 4 | export const Container = styled.div` 5 | position: fixed; 6 | top: 0; 7 | right: 0; 8 | width: calc((100% - 740px) / 2); 9 | height: 100%; 10 | background-color: ${props => props.color}; 11 | transition: all .3s cubic-bezier(0, 0, 0, 1.01) 0s; 12 | transform: translateX(100%); 13 | border-radius: 70% 0 0 70%; 14 | overflow: hidden; 15 | 16 | &[data-open=true] { 17 | transform: translateX(0); 18 | border-radius: 0% 0 0 0%; 19 | } 20 | 21 | ${spLayout(`display: none;`)} 22 | ` 23 | 24 | export const ColorCode = styled.h2` 25 | position: absolute; 26 | top: 50%; 27 | left: 50%; 28 | font-size: 20px; 29 | color: rgba(255,255,255,.6); 30 | text-align: center; 31 | text-transform: uppercase; 32 | transform: translate(-50%, -50%); 33 | ` 34 | -------------------------------------------------------------------------------- /src/components/Top/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { 3 | Container, 4 | ColorWrapper, 5 | Logo, 6 | Footer, 7 | Sns 8 | } from './styles' 9 | import Color from '../Color' 10 | import Modal from '../Modal' 11 | import Preview from '../Preview' 12 | import colors from '../../config/colors' 13 | 14 | interface Props {} 15 | 16 | interface State { 17 | open: boolean 18 | num: number 19 | color: string 20 | modal: boolean 21 | productColor: string 22 | productName: string 23 | productLink: string 24 | } 25 | 26 | export default class Top extends React.Component { 27 | constructor(props: Props) { 28 | super(props) 29 | 30 | this.state = { 31 | open: false, 32 | num: 0, 33 | color: '#ffffff', 34 | modal: false, 35 | productColor: '', 36 | productName: '', 37 | productLink: '' 38 | } 39 | } 40 | 41 | private onMouseOver(num: number) { 42 | const color = colors[num] 43 | 44 | this.setState({ 45 | num, 46 | color: color.color, 47 | open: true 48 | }) 49 | } 50 | 51 | private onMouseOut() { 52 | this.setState({ open: false }) 53 | } 54 | 55 | private showModal(num: number) { 56 | const color = colors[num] 57 | 58 | this.setState({ 59 | num, 60 | modal: true, 61 | productColor: color.color, 62 | productName: color.product.name, 63 | productLink: color.product.link 64 | }) 65 | } 66 | 67 | private hiddenModal() { 68 | this.setState({ modal: false }) 69 | } 70 | 71 | private prevColor() { 72 | const { num } = this.state 73 | const _num = (num - 1) <= 0 ? colors.length - 1 : (num - 1) 74 | const color = colors[_num] 75 | 76 | this.setState({ 77 | num: _num, 78 | productColor: color.color, 79 | productName: color.product.name, 80 | productLink: color.product.link 81 | }) 82 | } 83 | 84 | private nextColor() { 85 | const { num } = this.state 86 | const _num = (num + 1) >= colors.length ? 0 : (num + 1) 87 | const color = colors[_num] 88 | 89 | this.setState({ 90 | num: _num, 91 | productColor: color.color, 92 | productName: color.product.name, 93 | productLink: color.product.link 94 | }) 95 | } 96 | 97 | public render() { 98 | const { 99 | color, 100 | open, 101 | modal, 102 | productColor, 103 | productName, 104 | productLink 105 | } = this.state 106 | 107 | return ( 108 | 109 | 110 | 111 | {colors.map((li, key) => ( 112 | 121 | ))} 122 | 123 |
124 |
125 |
126 |
127 |
128 |
129 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 153 |
154 | ) 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/components/Top/keyframes.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yui540/palette/903bf9fbdb3ec0e023108438bf2d9213f4c81d6c/src/components/Top/keyframes.ts -------------------------------------------------------------------------------- /src/components/Top/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import { pcLayout, spLayout } from '../../breakpoint' 3 | import { fadein } from '../../common-keyframes' 4 | 5 | export const Container = styled.div`` 6 | 7 | export const Logo = styled.img` 8 | display: block; 9 | margin: 0 auto; 10 | transform: translateY(-30%); 11 | opacity: 0; 12 | 13 | ${pcLayout(`width: 400px;`)} 14 | ${spLayout(`width: 65%;`)} 15 | 16 | animation: ${fadein} 1.5s ease 0s forwards; 17 | ` 18 | 19 | export const ColorWrapper = styled.div` 20 | display: flex; 21 | flex-wrap: wrap; 22 | justify-content: center; 23 | margin: 0 auto; 24 | opacity: 0; 25 | 26 | ${pcLayout(` 27 | max-width: 740px; 28 | margin-top: 10px; 29 | `)} 30 | ${spLayout(`margin-top: 5px;`)} 31 | 32 | /* animation */ 33 | animation: ${fadein} 1.5s ease .3s forwards; 34 | ` 35 | 36 | export const Footer = styled.footer` 37 | position: relative; 38 | width: 100%; 39 | overflow: hidden; 40 | 41 | ${pcLayout(` 42 | height: 120px; 43 | margin-top: 50px; 44 | `)} 45 | ${spLayout(` 46 | height: 100px; 47 | margin-top: 40px; 48 | `)} 49 | 50 | div { 51 | position: absolute; 52 | top: 0; 53 | left: 0; 54 | width: 500%; 55 | height: 500%; 56 | transform-origin: left top; 57 | } 58 | div:nth-child(1) { 59 | transform: rotate(6deg); 60 | background-color: #2089a5; 61 | } 62 | div:nth-child(2) { 63 | transform: rotate(8deg); 64 | background-color: #c7aa71; 65 | } 66 | div:nth-child(3) { 67 | transform: rotate(12deg); 68 | background-color: #ad1341; 69 | } 70 | div:nth-child(4) { 71 | transform: rotate(16deg); 72 | background-color: #5d3523; 73 | } 74 | ` 75 | 76 | export const Sns = styled.aside` 77 | position: fixed; 78 | background-color: #5d3523; 79 | padding: 10px 0; 80 | opacity: 0; 81 | 82 | ${pcLayout(` 83 | top: 50%; 84 | left: 0; 85 | transform: translateY(-50%); 86 | padding: 10px 0; 87 | width: 44px; 88 | border-radius: 0 6px 6px 0; 89 | `)} 90 | 91 | ${spLayout(` 92 | bottom: 0; 93 | left: 50%; 94 | padding: 0 5px; 95 | transform: translateX(-50%); 96 | height: 45px; 97 | display: flex; 98 | border-radius: 6px 6px 0 0; 99 | `)} 100 | 101 | a { 102 | display: block; 103 | text-align: center; 104 | color: #fbf4f1; 105 | transition: all .4s ease 0s; 106 | 107 | ${pcLayout(` 108 | width: 44px; 109 | height: 44px; 110 | line-height: 44px; 111 | font-size: 22px; 112 | `)} 113 | 114 | ${spLayout(` 115 | width: 45px; 116 | height: 45px; 117 | line-height: 45px; 118 | font-size: 22px; 119 | `)} 120 | } 121 | a:nth-child(1):hover { color: #2089a5; } 122 | a:nth-child(2):hover { color: #c7aa71; } 123 | a:nth-child(3):hover { color: #ad1341; } 124 | 125 | /* animation */ 126 | animation: ${fadein} 1.5s ease .6s forwards; 127 | ` 128 | -------------------------------------------------------------------------------- /src/config/colors.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | color: '#F2C047', 4 | product: { 5 | name: 'ヒトリゴト', 6 | link: 'https://github.com/yui540/Hitorigoto', 7 | }, 8 | }, 9 | { 10 | color: '#C7D35E', 11 | product: { 12 | name: 'ヒトリゴト', 13 | link: 'https://github.com/yui540/Hitorigoto', 14 | }, 15 | }, 16 | { 17 | color: '#DF7D81', 18 | product: { 19 | name: 'ヒトリゴト', 20 | link: 'https://github.com/yui540/Hitorigoto', 21 | }, 22 | }, 23 | { 24 | color: '#8FCDDA', 25 | product: { 26 | name: 'ヒトリゴト', 27 | link: 'https://github.com/yui540/Hitorigoto', 28 | }, 29 | }, 30 | { 31 | color: '#B980AE', 32 | product: { 33 | name: 'ヒトリゴト', 34 | link: 'https://github.com/yui540/Hitorigoto', 35 | }, 36 | }, 37 | { 38 | color: '#463750', 39 | product: { 40 | name: 'wakaba', 41 | link: 'https://github.com/yui540/wakaba', 42 | }, 43 | }, 44 | { 45 | color: '#e27170', 46 | product: { 47 | name: 'wakaba', 48 | link: 'https://github.com/yui540/wakaba', 49 | }, 50 | }, 51 | { 52 | color: '#e9cdd9', 53 | product: { 54 | name: 'wakaba', 55 | link: 'https://github.com/yui540/wakaba', 56 | }, 57 | }, 58 | { 59 | color: '#81c8c0', 60 | product: { 61 | name: 'toa', 62 | link: 'https://github.com/yui540/toa', 63 | }, 64 | }, 65 | { 66 | color: '#2a2b3d', 67 | product: { 68 | name: 'toa', 69 | link: 'https://github.com/yui540/toa', 70 | }, 71 | }, 72 | { 73 | color: '#1cc6b8', 74 | product: { 75 | name: 'toa', 76 | link: 'https://github.com/yui540/toa', 77 | }, 78 | }, 79 | { 80 | color: '#c16798', 81 | product: { 82 | name: '由比ヶ浜結衣生誕2018非公式サイト', 83 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 84 | }, 85 | }, 86 | { 87 | color: '#e2877e', 88 | product: { 89 | name: '由比ヶ浜結衣生誕2018非公式サイト', 90 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 91 | }, 92 | }, 93 | { 94 | color: '#5f9da3', 95 | product: { 96 | name: '由比ヶ浜結衣生誕2018非公式サイト', 97 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 98 | }, 99 | }, 100 | { 101 | color: '#c5848b', 102 | product: { 103 | name: '由比ヶ浜結衣生誕2018非公式サイト', 104 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 105 | }, 106 | }, 107 | { 108 | color: '#c6e6ef', 109 | product: { 110 | name: '由比ヶ浜結衣生誕2018非公式サイト', 111 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 112 | }, 113 | }, 114 | { 115 | color: '#b46d95', 116 | product: { 117 | name: '由比ヶ浜結衣生誕2018非公式サイト', 118 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 119 | }, 120 | }, 121 | { 122 | color: '#EDC8CF', 123 | product: { 124 | name: '由比ヶ浜結衣生誕2018非公式サイト', 125 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 126 | }, 127 | }, 128 | { 129 | color: '#ADDDF7', 130 | product: { 131 | name: '由比ヶ浜結衣生誕2018非公式サイト', 132 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 133 | }, 134 | }, 135 | { 136 | color: '#EFCEC7', 137 | product: { 138 | name: '由比ヶ浜結衣生誕2018非公式サイト', 139 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 140 | }, 141 | }, 142 | { 143 | color: '#F7E4C6', 144 | product: { 145 | name: '由比ヶ浜結衣生誕2018非公式サイト', 146 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 147 | }, 148 | }, 149 | { 150 | color: '#DBBEB6', 151 | product: { 152 | name: '由比ヶ浜結衣生誕2018非公式サイト', 153 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 154 | }, 155 | }, 156 | { 157 | color: '#9B5B42', 158 | product: { 159 | name: '由比ヶ浜結衣生誕2018非公式サイト', 160 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 161 | }, 162 | }, 163 | { 164 | color: '#C7B3D6', 165 | product: { 166 | name: '由比ヶ浜結衣生誕2018非公式サイト', 167 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 168 | }, 169 | }, 170 | { 171 | color: '#B7D7B6', 172 | product: { 173 | name: '由比ヶ浜結衣生誕2018非公式サイト', 174 | link: 'https://github.com/yui540/HAPPY_BIRTHDAY_YUI', 175 | }, 176 | }, 177 | { 178 | color: '#FCFCF3', 179 | product: { 180 | name: 'DropOut', 181 | link: 'https://github.com/yui540/DropOut', 182 | }, 183 | }, 184 | { 185 | color: '#E4D6CE', 186 | product: { 187 | name: 'DropOut', 188 | link: 'https://github.com/yui540/DropOut', 189 | }, 190 | }, 191 | { 192 | color: '#C2617E', 193 | product: { 194 | name: 'DropOut', 195 | link: 'https://github.com/yui540/DropOut', 196 | }, 197 | }, 198 | { 199 | color: '#E5B8BD', 200 | product: { 201 | name: 'DropOut', 202 | link: 'https://github.com/yui540/DropOut', 203 | }, 204 | }, 205 | { 206 | color: '#4A3F55', 207 | product: { 208 | name: 'DropOut', 209 | link: 'https://github.com/yui540/DropOut', 210 | }, 211 | }, 212 | { 213 | color: '#817487', 214 | product: { 215 | name: 'DropOut', 216 | link: 'https://github.com/yui540/DropOut', 217 | }, 218 | }, 219 | { 220 | color: '#A8CBC6', 221 | product: { 222 | name: 'DropOut', 223 | link: 'https://github.com/yui540/DropOut', 224 | }, 225 | }, 226 | { 227 | color: '#ca7a92', 228 | product: { 229 | name: 'hyper-sana', 230 | link: 'https://github.com/yui540/hyper-sana', 231 | }, 232 | }, 233 | { 234 | color: '#f4d8e4', 235 | product: { 236 | name: 'hyper-sana', 237 | link: 'https://github.com/yui540/hyper-sana', 238 | }, 239 | }, 240 | { 241 | color: '#a3518f', 242 | product: { 243 | name: 'Shuvi', 244 | link: 'https://github.com/yui540/Shuvi', 245 | }, 246 | }, 247 | { 248 | color: '#cd5da0', 249 | product: { 250 | name: 'Shuvi', 251 | link: 'https://github.com/yui540/Shuvi', 252 | }, 253 | }, 254 | { 255 | color: '#c55c66', 256 | product: { 257 | name: 'バーチャルニート公式サイト', 258 | link: 'https://github.com/yui540/virtual-neet', 259 | }, 260 | }, 261 | { 262 | color: '#009298', 263 | product: { 264 | name: '夜空ノ贈リ物', 265 | link: 'https://github.com/yui540/Yozora_No_Okurimono', 266 | }, 267 | }, 268 | { 269 | color: '#3d2213', 270 | product: { 271 | name: '夜空ノ贈リ物', 272 | link: 'https://github.com/yui540/Yozora_No_Okurimono', 273 | }, 274 | }, 275 | { 276 | color: '#3bc6c7', 277 | product: { 278 | name: '夜空ノ贈リ物', 279 | link: 'https://github.com/yui540/Yozora_No_Okurimono', 280 | }, 281 | }, 282 | { 283 | color: '#98d6d4', 284 | product: { 285 | name: '夜空ノ贈リ物', 286 | link: 'https://github.com/yui540/Yozora_No_Okurimono', 287 | }, 288 | }, 289 | { 290 | color: '#2a313e', 291 | product: { 292 | name: 'hyper-akari', 293 | link: 'https://github.com/yui540/hyper-akari', 294 | }, 295 | }, 296 | { 297 | color: '#90bdbd', 298 | product: { 299 | name: 'hyper-akari', 300 | link: 'https://github.com/yui540/hyper-akari', 301 | }, 302 | }, 303 | { 304 | color: '#F8F8F0', 305 | product: { 306 | name: 'hyper-akari', 307 | link: 'https://github.com/yui540/hyper-akari', 308 | }, 309 | }, 310 | { 311 | color: '#cd8c64', 312 | product: { 313 | name: 'ChocolateCake', 314 | link: 'https://github.com/yui540/ChocolateCake', 315 | }, 316 | }, 317 | { 318 | color: '#5d3523', 319 | product: { 320 | name: 'ChocolateCake', 321 | link: 'https://github.com/yui540/ChocolateCake', 322 | }, 323 | }, 324 | { 325 | color: '#566687', 326 | product: { 327 | name: 'unmoral公式サイト', 328 | link: 'https://github.com/yui540/unmoral', 329 | }, 330 | }, 331 | { 332 | color: '#8daacd', 333 | product: { 334 | name: 'unmoral公式サイト', 335 | link: 'https://github.com/yui540/unmoral', 336 | }, 337 | }, 338 | { 339 | color: '#c9d7e6', 340 | product: { 341 | name: 'unmoral公式サイト', 342 | link: 'https://github.com/yui540/unmoral', 343 | }, 344 | }, 345 | { 346 | color: '#d0e3f2', 347 | product: { 348 | name: 'unmoral公式サイト', 349 | link: 'https://github.com/yui540/unmoral', 350 | }, 351 | }, 352 | { 353 | color: '#283c5f', 354 | product: { 355 | name: '臆病な魔女', 356 | link: 'https://github.com/yui540/Cowardly-Witch', 357 | }, 358 | }, 359 | { 360 | color: '#faf7d9', 361 | product: { 362 | name: '臆病な魔女', 363 | link: 'https://github.com/yui540/Cowardly-Witch', 364 | }, 365 | }, 366 | { 367 | color: '#c3ce5f', 368 | product: { 369 | name: '臆病な魔女', 370 | link: 'https://github.com/yui540/Cowardly-Witch', 371 | }, 372 | }, 373 | { 374 | color: '#4aa9a4', 375 | product: { 376 | name: '臆病な魔女', 377 | link: 'https://github.com/yui540/Cowardly-Witch', 378 | }, 379 | }, 380 | { 381 | color: '#c45c66', 382 | product: { 383 | name: '臆病な魔女', 384 | link: 'https://github.com/yui540/Cowardly-Witch', 385 | }, 386 | }, 387 | { 388 | color: '#2089a5', 389 | product: { 390 | name: 'palette - パレット', 391 | link: 'https://github.com/yui540/palette', 392 | }, 393 | }, 394 | { 395 | color: '#c7aa71', 396 | product: { 397 | name: 'palette - パレット', 398 | link: 'https://github.com/yui540/palette', 399 | }, 400 | }, 401 | { 402 | color: '#ad1341', 403 | product: { 404 | name: 'palette - パレット', 405 | link: 'https://github.com/yui540/palette', 406 | }, 407 | }, 408 | { 409 | color: '#5d3523', 410 | product: { 411 | name: 'palette - パレット', 412 | link: 'https://github.com/yui540/palette', 413 | }, 414 | }, 415 | { 416 | color: '#ea8b98', 417 | product: { 418 | name: 'react-message-modal', 419 | link: 'https://github.com/yui540/react-message-modal', 420 | }, 421 | }, 422 | ] 423 | -------------------------------------------------------------------------------- /src/easing.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * ease-in 3 | */ 4 | export const easeInSine: string = 'cubic-bezier(0.47, 0, 0.745, 0.715)' 5 | 6 | export const easeInCubic: string = 'cubic-bezier(0.55, 0.055, 0.675, 0.19)' 7 | 8 | export const easeInQuint: string = 'cubic-bezier(0.755, 0.05, 0.855, 0.06)' 9 | 10 | export const easeInCirc: string = 'cubic-bezier(0.6, 0.04, 0.98, 0.335)' 11 | 12 | export const easeInQuad: string = 'cubic-bezier(0.55, 0.085, 0.68, 0.53)' 13 | 14 | export const easeInQuart: string = 'cubic-bezier(0.895, 0.03, 0.685, 0.22)' 15 | 16 | export const easeInExpo: string = 'cubic-bezier(0.95, 0.05, 0.795, 0.035)' 17 | 18 | export const easeInBack: string = 'cubic-bezier(0.6, -0.28, 0.735, 0.045)' 19 | 20 | /** 21 | * ease-out 22 | */ 23 | export const easeOutSine: string = 'cubic-bezier(0.39, 0.575, 0.565, 1)' 24 | 25 | export const easeOutCubic: string = 'cubic-bezier(0.215, 0.61, 0.355, 1)' 26 | 27 | export const easeOutQuint: string = 'cubic-bezier(0.23, 1, 0.32, 1)' 28 | 29 | export const easeOutCirc: string = 'cubic-bezier(0.075, 0.82, 0.165, 1)' 30 | 31 | export const easeOutQuad: string = 'cubic-bezier(0.25, 0.46, 0.45, 0.94)' 32 | 33 | export const easeOutExpo: string = 'cubic-bezier(0.19, 1, 0.22, 1)' 34 | 35 | export const easeOutBack: string = 'cubic-bezier(0.175, 0.885, 0.32, 1.275)' 36 | 37 | /** 38 | * ease-in-out 39 | */ 40 | export const easeInOutSine: string = 'cubic-bezier(0.445, 0.05, 0.55, 0.95)' 41 | 42 | export const easeInOutCubic: string = 'cubic-bezier(0.645, 0.045, 0.355, 1)' 43 | 44 | export const easeInOutQuint: string = 'cubic-bezier(0.86, 0, 0.07, 1)' 45 | 46 | export const easeInOutCirc: string = 'cubic-bezier(0.785, 0.135, 0.15, 0.86)' 47 | 48 | export const easeInOutQuad: string = 'cubic-bezier(0.455, 0.03, 0.515, 0.955)' 49 | 50 | export const easeInOutQuart: string = 'cubic-bezier(0.77, 0, 0.175, 1)' 51 | 52 | export const easeInOutExpo: string = 'cubic-bezier(1, 0, 0, 1)' 53 | 54 | export const easeInOutBack: string = 'cubic-bezier(0.68, -0.55, 0.265, 1.55)' 55 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as ReactDOM from 'react-dom' 3 | import Top from './components/Top' 4 | 5 | ReactDOM.render(, document.getElementById('root')) 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./public", 4 | "sourceMap": true, 5 | "strictNullChecks": true, 6 | "strictPropertyInitialization": true, 7 | "noImplicitAny": true, 8 | "noImplicitReturns": true, 9 | "module": "commonjs", 10 | "target": "es5", 11 | "jsx": "react" 12 | }, 13 | "include": ["./src/**/*"] 14 | } 15 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mode: process.env.MODE, 3 | entry: './src/index.tsx', 4 | output: { 5 | path: `${__dirname}/public`, 6 | filename: 'index.js', 7 | }, 8 | resolve: { 9 | extensions: ['.ts', '.tsx', '.js', '.json'], 10 | }, 11 | devtool: 'source-map', 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.svg$/, 16 | use: [ 17 | { 18 | loader: 'url-loader', 19 | options: { 20 | limit: 51200, 21 | name: './images/other/[name].[ext]', 22 | }, 23 | }, 24 | ], 25 | }, 26 | { 27 | test: /\.tsx?$/, 28 | loader: 'awesome-typescript-loader', 29 | }, 30 | { 31 | enforce: 'pre', 32 | test: /\.js$/, 33 | loader: 'source-map-loader', 34 | }, 35 | ], 36 | }, 37 | devServer: { 38 | historyApiFallback: true, 39 | contentBase: `${__dirname}/public`, 40 | open: true, 41 | port: 8080, 42 | }, 43 | } 44 | --------------------------------------------------------------------------------