feat: add figure

This commit is contained in:
Tristan 2019-09-13 10:24:50 +08:00
parent dca6098f0c
commit 4adb4c35f8
28 changed files with 231 additions and 83 deletions

View File

@ -27,6 +27,7 @@
},
"homepage": "https://works.yangerxiao.com/chinese-colors/",
"dependencies": {
"@ungap/url-search-params": "^0.1.2",
"color-convert": "^2.0.1",
"html2canvas": "^1.0.0-rc.3",
"pinyin": "^2.9.0",

BIN
public/figure/fanchuan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
public/figure/hengshan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
public/figure/jinyu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
public/figure/lvzhu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

BIN
public/figure/moon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
public/figure/pomo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
public/figure/pomodian.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
public/figure/qunshan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
public/figure/qunshan2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
public/figure/yuweng.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
public/figure/zhuzi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

View File

@ -8,7 +8,7 @@ import Preview from './components/Preview';
import ColorParam from './components/ColorParam';
import InfoModal from './components/InfoModal';
import IconInfo from './components/IconInfo';
import IconScreenshoot from './components/IconScreenshoot';
import IconScreenshot from './components/IconScreenshot';
import Header from './components/Header';
import ColorSet from './components/ColorSet';
import { useModal, useColor, usePreview } from './hooks';
@ -117,7 +117,7 @@ const App = () => {
figure={currColor.figure}
/>
)}
<IconScreenshoot showPreview={showPreview} />
<IconScreenshot showPreview={showPreview} />
{!modalVisible && <IconInfo showInfoModal={showModal} />}
{modalVisible && <InfoModal bgColor={currColor.hex} closeModal={closeModal} />}
</>

View File

@ -3,7 +3,12 @@
"name": "红",
"hex": "#ffb3a7",
"colors": [
{ "hex": "#ffb3a7", "name": "粉红", "intro": "即浅红色。别称:妃色、杨妃色、湘妃色、妃红色" },
{
"hex": "#ffb3a7",
"name": "粉红",
"intro": "即浅红色。别称:妃色、杨妃色、湘妃色、妃红色",
"figure": "flower.moon.png?o=0.8"
},
{
"hex": "#ed5736",
"name": "妃色",
@ -22,7 +27,8 @@
{
"hex": "#db5a6b",
"name": "海棠红",
"intro": "淡紫红色、较桃红色深一些,是非常妩媚娇艳的颜色。"
"intro": "淡紫红色、较桃红色深一些,是非常妩媚娇艳的颜色。",
"figure": "flower.moon.png?o=0.6"
},
{ "hex": "#f20c00", "name": "石榴红", "intro": "石榴花的颜色,高色度和纯度的红色。" },
{ "hex": "#c93756", "name": "樱桃色", "intro": "鲜红色" },
@ -53,7 +59,7 @@
{ "hex": "#cb3a56", "name": "茜色", "intro": "茜草染的色彩,呈深红色" },
{ "hex": "#ff2d51", "name": "火红", "intro": "火焰的红色,赤色" },
{ "hex": "#c91f37", "name": "赫赤", "intro": "深红,火红。泛指赤色、火红色。" },
{ "hex": "#ef7a82", "name": "嫣红", "intro": "鲜艳的红色" },
{ "hex": "#ef7a82", "name": "嫣红", "intro": "鲜艳的红色", "figure": "jinyu.png?o=0.8" },
{
"hex": "#ff0097",
"name": "洋红",
@ -209,9 +215,15 @@
{
"hex": "#177cb0",
"name": "靛青",
"intro": "也叫\"蓝靛\"。用蓼蓝叶泡水调和与石灰沉淀所得的蓝色染料。呈深蓝绿色发音dian四声有些地方将蓝墨水称为\"靛水\"或者\"兰靛水\""
"intro": "也叫\"蓝靛\"。用蓼蓝叶泡水调和与石灰沉淀所得的蓝色染料。呈深蓝绿色发音dian四声有些地方将蓝墨水称为\"靛水\"或者\"兰靛水\"",
"figure": "hehua.caise.png"
},
{
"hex": "#065279",
"name": "靛蓝",
"intro": "由植物(例如靛蓝或菘蓝属植物)得到的蓝色染料",
"figure": "moon.png"
},
{ "hex": "#065279", "name": "靛蓝", "intro": "由植物(例如靛蓝或菘蓝属植物)得到的蓝色染料" },
{ "hex": "#3eede7", "name": "碧蓝", "intro": "青蓝色" },
{ "hex": "#70f3ff", "name": "蔚蓝", "intro": "类似晴朗天空的颜色的一种蓝色" },
{
@ -243,19 +255,34 @@
{ "hex": "#b0a4e3", "name": "雪青", "intro": "浅蓝紫色" },
{ "hex": "#cca4e3", "name": "丁香色", "intro": "紫丁香的颜色,浅浅的紫色,很娇柔淡雅的色彩" },
{ "hex": "#edd1d8", "name": "藕色", "intro": "浅灰而略带红的颜色" },
{ "hex": "#e4c6d0", "name": "藕荷色", "intro": "浅紫而略带红的颜色" }
{
"hex": "#e4c6d0",
"name": "藕荷色",
"intro": "浅紫而略带红的颜色",
"figure": "jinyu.png?o=0.8"
}
]
},
{
"name": "苍",
"hex": "#75878a",
"colors": [
{ "hex": "#75878a", "name": "苍色", "intro": "即各种颜色掺入黑色后的颜色,如" },
{
"hex": "#75878a",
"name": "苍色",
"intro": "即各种颜色掺入黑色后的颜色",
"figure": "qunshan.png?width=100%"
},
{ "hex": "#519a73", "name": "苍翠", "intro": "" },
{ "hex": "#a29b7c", "name": "苍黄", "intro": "" },
{ "hex": "#a29b7c", "name": "苍黄", "intro": "", "figure": "guilinshanshui.png" },
{ "hex": "#7397ab", "name": "苍青", "intro": "" },
{ "hex": "#395260", "name": "苍黑", "intro": "" },
{ "hex": "#d1d9e0", "name": "苍白", "intro": "准确的说是掺入不同灰度级别的灰色" }
{
"hex": "#d1d9e0",
"name": "苍白",
"intro": "准确的说是掺入不同灰度级别的灰色",
"figure": "fanchuan.png"
}
]
},
{
@ -267,11 +294,12 @@
{ "hex": "#d4f2e7", "name": "水绿", "intro": "" },
{ "hex": "#d2f0f4", "name": "水蓝", "intro": "" },
{ "hex": "#d3e0f3", "name": "淡青", "intro": "" },
{ "hex": "#30dff3", "name": "湖蓝", "intro": "" },
{ "hex": "#30dff3", "name": "湖蓝", "intro": "", "figure": "moon.png" },
{
"hex": "#25f8cb",
"name": "湖绿",
"intro": "皆是浅色。深色淡色,颜色深的或浅的,不再一一列出。"
"intro": "皆是浅色。深色淡色,颜色深的或浅的,不再一一列出。",
"figure": "hehua.caise.png"
}
]
},
@ -279,15 +307,40 @@
"name": "灰白",
"hex": "#f0f0f4",
"colors": [
{ "hex": "#ffffff", "name": "精白", "intro": "纯白,洁白,净白,粉白。" },
{ "hex": "#fffbf0", "name": "象牙白", "intro": "乳白色" },
{ "hex": "#f2fdff", "name": "雪白", "intro": "如雪般洁白" },
{
"hex": "#ffffff",
"name": "精白",
"intro": "纯白,洁白,净白,粉白。",
"figure": "meihua.shuimo.png"
},
{ "hex": "#fffbf0", "name": "象牙白", "intro": "乳白色", "figure": "pomo.png" },
{ "hex": "#f2fdff", "name": "雪白", "intro": "如雪般洁白", "figure": "meihua.pink.png" },
{ "hex": "#d6ecf0", "name": "月白", "intro": "淡蓝色" },
{ "hex": "#f2ecde", "name": "缟", "intro": "白色" },
{ "hex": "#e0f0e9", "name": "素", "intro": "白色,无色" },
{ "hex": "#f3f9f1", "name": "荼白", "intro": "如荼之白色" },
{ "hex": "#e9f1f6", "name": "霜色", "intro": "白霜的颜色。" },
{ "hex": "#c2ccd0", "name": "花白", "intro": "白色和黑色混杂的。斑白的夹杂有灰色的白" },
{ "hex": "#f2ecde", "name": "缟", "intro": "白色", "figure": "meihua.pink.png" },
{
"hex": "#e0f0e9",
"name": "素",
"intro": "白色,无色",
"figure": "qunshan.png?width=100%"
},
{
"hex": "#f3f9f1",
"name": "荼白",
"intro": "如荼之白色",
"figure": "qunshan2.png?width=100%"
},
{
"hex": "#e9f1f6",
"name": "霜色",
"intro": "白霜的颜色。",
"figure": "qunshan2.png?width=100%"
},
{
"hex": "#c2ccd0",
"name": "花白",
"intro": "白色和黑色混杂的。斑白的夹杂有灰色的白",
"figure": "flower.moon.png"
},
{
"hex": "#fcefe8",
"name": "鱼肚白",
@ -310,14 +363,15 @@
{ "hex": "#622a1d", "name": "玄色", "intro": "赤黑色,黑中带红的颜色,又泛指黑色" },
{ "hex": "#3d3b4f", "name": "玄青", "intro": "深黑色" },
{ "hex": "#725e82", "name": "乌色", "intro": "暗而呈黑的颜色" },
{ "hex": "#392f41", "name": "乌黑", "intro": "深黑;漆黑" },
{ "hex": "#161823", "name": "漆黑", "intro": "非常黑的" },
{ "hex": "#392f41", "name": "乌黑", "intro": "深黑;漆黑", "figure": "moon.png" },
{ "hex": "#161823", "name": "漆黑", "intro": "非常黑的", "figure": "flower.moon.png?o=0.6" },
{ "hex": "#50616d", "name": "墨色", "intro": "即黑色" },
{ "hex": "#758a99", "name": "墨灰", "intro": "即黑灰" },
{
"hex": "#000000",
"name": "黑色",
"intro": "亮度最低的非彩色的或消色差的物体的颜色;最暗的灰色;与白色截然不同的消色差的颜色;被认为特别属于那些既不能反射、又不能透过能使人感觉到的微小入射光的物体,任何亮度很低的物体颜色。"
"intro": "亮度最低的非彩色的或消色差的物体的颜色;最暗的灰色;与白色截然不同的消色差的颜色;被认为特别属于那些既不能反射、又不能透过能使人感觉到的微小入射光的物体,任何亮度很低的物体颜色。",
"figure": "moon.png"
},
{ "hex": "#493131", "name": "缁色", "intro": "帛黑色" },
{ "hex": "#312520", "name": "煤黑", "intro": "别称:象牙黑。都是黑,不过有冷暖之分。" },

View File

@ -4,11 +4,11 @@ const Wrapper = styled.div`
font-size: 0.2rem;
position: relative; /* so that children can be absolutely positioned */
padding: 0;
width: 5em;
height: 5em;
width: 4em;
height: 4em;
background-color: rgba(242, 233, 225, 0.6);
border-radius: 50%;
line-height: 5em;
line-height: 4em;
&:after {
border: none;
@ -25,8 +25,8 @@ const Wrapper = styled.div`
}
> span {
position: absolute;
line-height: 5em;
width: 5em;
line-height: 4em;
width: 4em;
text-align: center;
font-weight: 800;
display: block;
@ -36,10 +36,10 @@ const Wrapper = styled.div`
.left-half-clipper {
/* a round circle */
border-radius: 50%;
width: 5em;
height: 5em;
width: 4em;
height: 4em;
position: absolute; /* needed for clipping */
clip: rect(0, 5em, 5em, 2.5em); /* clips the whole left half*/
clip: rect(0, 4em, 4em, 2em); /* clips the whole left half*/
}
/* when p>50, don't clip left half*/
&.over50 .left-half-clipper {
@ -51,9 +51,9 @@ const Wrapper = styled.div`
to escape the outer clipping path.*/
transition: all 0.5s;
position: absolute; /*needed for clipping*/
clip: rect(0, 2.5em, 5em, 0);
width: 5em;
height: 5em;
clip: rect(0, 2em, 4em, 0);
width: 4em;
height: 4em;
border-radius: 50%;
border: 1.5em solid ${({ color }) => color}; /*The border is 0.35 but making it larger removes visual artifacts */
box-sizing: border-box;
@ -62,11 +62,11 @@ const Wrapper = styled.div`
&.over50 .first50-bar {
/*Progress bar for the first 50%, filling the whole right half*/
position: absolute; /*needed for clipping*/
clip: rect(0, 5em, 5em, 2.5em);
clip: rect(0, 4em, 4em, 2em);
background-color: ${({ color }) => color};
border-radius: 50%;
width: 5em;
height: 5em;
width: 4em;
height: 4em;
}
&:not(.over50) .first50-bar {
display: none;

View File

@ -49,6 +49,9 @@ const Wrapper = styled.li.attrs(({ color }) => ({
.cmyk {
display: flex;
justify-content: space-between;
.circle:not(:last-child) {
margin-bottom: 0.2rem;
}
}
}
.line2 {

View File

@ -6,6 +6,7 @@ const Wrapper = styled.section`
display: flex;
flex-direction: column;
align-self: center;
margin-right: 0.5rem;
.item {
border-top: 1px solid rgba(255, 255, 255, 0.6);
padding: 1rem 0.2rem 0.6rem 0.2rem;

View File

@ -1,16 +1,7 @@
import React from 'react';
import React, { useRef } from 'react';
import html2canvas from 'html2canvas';
import styled, { keyframes } from 'styled-components';
const Float = keyframes`
0%,40%,80%{
transform:translateX(-50%) translateY(0%);
}
20%,60%,100%{
transform:translateX(-50%) translateY(2%);
}
`;
import styled from 'styled-components';
function saveAs(uri, filename) {
var link = document.createElement('a');
@ -36,7 +27,7 @@ const Wrapper = styled.button`
position: absolute;
bottom: 10vh;
left: 50%;
/* transform: translateX(-50%); */
transform: translateX(-50%);
border: none;
border-radius: 0.3rem;
padding: 0.6rem 0.8rem;
@ -44,32 +35,64 @@ const Wrapper = styled.button`
color: #eee;
background: #1f2f2d;
box-shadow: 0px 5px 9px rgba(0, 0, 0, 0.5);
animation: ${Float} 3s infinite forwards;
&.tip {
visibility: hidden;
&:after {
content: '长按图片保存';
display: block;
position: absolute;
color: #fff;
background: rgba(0, 0, 0, 0.5);
padding: 0.4rem 0.6rem;
border-radius: 0.2rem;
font-size: 0.8rem;
top: -120%;
left: 50%;
visibility: visible;
transform: translateX(-50%);
width: 100%;
}
}
`;
const generateImage = (ele, name, isWeixin = false) => {
html2canvas(ele, {
onclone: document => {
let tmp = document.querySelector('#PREVIEW');
tmp.classList.add('starting');
const Download = ({ name }) => {
tmp.style.height = window.innerHeight + 'px';
}
}).then(function(canvas) {
console.log(canvas);
if (isWeixin) {
console.log('weixin');
let img = document.createElement('img');
img.classList.add('downloadImg');
img.src = canvas.toDataURL('image/png');
ele.classList.add('img');
ele.appendChild(img);
} else {
saveAs(canvas.toDataURL(), `${name}-${new Date().getTime()}.png`);
}
ele.classList.remove('starting');
});
};
const Download = ({ name, isWeixin = false, ...rest }) => {
const btn = useRef(null);
const handleDownloadClick = () => {
// startScreenshoot();
let ele = document.querySelector('#PREVIEW');
ele.classList.add('starting');
ele.style.height = window.innerHeight + 'px';
html2canvas(ele, {
// width: window.screen.availWidth,
// height: window.screen.availHeight,
// width: window.innerWidth,
// height: window.screen.availHeight
// onclone: cloned => {
// cloned.querySelector('aside').remove();
// cloned.querySelector('button').remove();
// return cloned;
// }
}).then(function(canvas) {
console.log(canvas);
saveAs(canvas.toDataURL(), `${name}-${new Date().getTime()}.png`);
ele.classList.remove('starting');
});
generateImage(ele, name, isWeixin);
if (isWeixin) {
btn.current.classList.add('tip');
}
};
return <Wrapper onClick={handleDownloadClick}>保存</Wrapper>;
return (
<Wrapper ref={btn} onClick={handleDownloadClick} {...rest}>
生成壁纸
</Wrapper>
);
};
export default Download;

View File

@ -11,15 +11,16 @@ const Wrapper = styled.aside`
justify-content: center;
align-items: center;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
z-index: 999;
.icon {
width: 1.8rem;
height: 1.8rem;
}
`;
const IconClose = ({ closePreview }) => {
const IconClose = ({ closePreview, ...rest }) => {
return (
<Wrapper onClick={closePreview}>
<Wrapper onClick={closePreview} {...rest}>
<svg
t="1568280236953"
className="icon"

View File

@ -2,6 +2,8 @@
import React from 'react';
import styled from 'styled-components';
import GitHubButton from 'react-github-btn';
import Logo from '../assets/img/logo.png';
const Wrapper = styled.section`
position: fixed;
top: 0;
@ -31,6 +33,14 @@ const Wrapper = styled.section`
background-color: ${({ bgColor }) => {
return bgColor;
}};
text-align: center;
> h1 {
margin-bottom: 1rem;
img {
width: 4rem;
}
}
> h2 {
text-transform: uppercase;
font-size: 1.4rem;
@ -64,6 +74,9 @@ export default function InfoModal({ closeModal, bgColor }) {
<Wrapper bgColor={bgColor}>
<div className="mask" onClick={closeModal}></div>
<div className="info">
<h1>
<img className="logo" src={Logo} alt="logo" />
</h1>
<h2>chinese colors</h2>
<p>
<span>

View File

@ -1,9 +1,24 @@
import React from 'react';
import styled from 'styled-components';
import styled, { keyframes } from 'styled-components';
import URLSearchParams from '@ungap/url-search-params';
import Download from './DownloadBtn';
import IconClose from './IconClose';
import BodyBg from '../assets/img/bg.texture.png';
const FadeIn = keyframes`
from {
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
to {
opacity: 1;
-webkit-transform: scale(0.96) translate3d(0, 0, 0);
transform: scale(0.96) translate3d(0, 0, 0);
}
`;
const isWeixin = navigator.userAgent.toLowerCase().indexOf('micromessenger') > -1;
const Wrapper = styled.section`
position: fixed;
left: 0;
@ -15,16 +30,30 @@ const Wrapper = styled.section`
background-image: url(${BodyBg});
width: 100%;
height: 100%;
/* box-shadow: 0 0 20px rgba(0, 0, 0, 0.4); */
animation: ${FadeIn} 1s;
animation-fill-mode: both;
&.starting {
aside,
button {
animation: none;
transform: initial;
}
&.img {
.downloadImg {
width: 100%;
height: 100%;
}
hgroup,
.figure {
display: none;
}
}
hgroup {
position: absolute;
left: 1rem;
top: 1rem;
left: 0;
top: 0;
z-index: 99;
margin-left: 1rem;
margin-top: 1rem;
display: flex;
align-items: flex-end;
> h1 {
@ -32,33 +61,51 @@ const Wrapper = styled.section`
'Microsoft YaHei';
font-size: 6rem;
width: 6rem;
opacity: 0.6;
opacity: 0.7;
padding-top: 0.4rem;
border-top: 0.6rem solid ${({ bgColor }) => bgColor};
}
> h2 {
font-size: 2.8rem;
font-size: 2.4rem;
text-transform: capitalize;
transform-origin: left;
transform: rotate(90deg);
opacity: 0.3;
color: rgba(255, 255, 235, 0.4);
margin-bottom: 2.6rem;
margin-left: 1rem;
font-weight: bold;
white-space: nowrap;
}
}
.figure {
position: absolute;
bottom: 0;
right: 0;
}
`;
const Preview = ({ name, pinyin, color, closePreview }) => {
const Preview = ({ name, pinyin, color, figure = '', closePreview }) => {
console.log('ffff', figure);
const params = new URLSearchParams(figure.split('?')[1] || '');
const figureW = params.get('width') || '23rem';
const figureO = +(params.get('o') || 1);
return (
<Wrapper id="PREVIEW" bgColor={color}>
<IconClose closePreview={closePreview} />
<IconClose closePreview={closePreview} data-html2canvas-ignore />
<hgroup>
<h1>{name}</h1>
<h2>{pinyin}</h2>
</hgroup>
<Download name={name} />
{figure && (
<img
className="figure"
style={{ width: figureW, opacity: figureO }}
src={`figure/${figure}`}
alt="figure"
/>
)}
<Download name={name} isWeixin={isWeixin} data-html2canvas-ignore />
</Wrapper>
);
};

View File

@ -1008,6 +1008,11 @@
resolved "https://registry.npm.taobao.org/@types/semver/download/@types/semver-6.0.2.tgz?cache=0&sync_timestamp=1567707471864&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fsemver%2Fdownload%2F%40types%2Fsemver-6.0.2.tgz#5e8b09f0e4af53034b1d0fb9977a277847836205"
integrity sha1-XosJ8OSvUwNLHQ+5l3oneEeDYgU=
"@ungap/url-search-params@^0.1.2":
version "0.1.2"
resolved "https://registry.npm.taobao.org/@ungap/url-search-params/download/@ungap/url-search-params-0.1.2.tgz#8ba8c0527543fe675d1c29ae0a2daca842e8ee4f"
integrity sha1-i6jAUnVD/mddHCmuCi2sqELo7k8=
"@voxpelli/semver-set@^1.0.1":
version "1.0.1"
resolved "https://registry.npm.taobao.org/@voxpelli/semver-set/download/@voxpelli/semver-set-1.0.1.tgz#2b74dd95e1b0f5a5b1f10d0d9d6efe4143496b5f"