├── .editorconfig ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── config ├── config.ts ├── postcssPlugins.ts └── router.ts ├── images └── index.png ├── package.json ├── src ├── app.tsx ├── assets │ └── public │ │ ├── fiveStars.png │ │ └── upload.png ├── components │ └── Loading │ │ ├── index.less │ │ └── index.tsx ├── layouts │ └── index.tsx ├── pages │ ├── document.ejs │ └── index │ │ ├── components │ │ ├── ImageModal.tsx │ │ └── index.less │ │ ├── img.ts │ │ ├── index.less │ │ └── index.tsx ├── styles │ ├── global.less │ ├── index.less │ └── reset.less └── utils │ ├── api.ts │ ├── dev.ts │ ├── file.ts │ └── props.ts ├── tsconfig.json └── typings.d.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: github pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-20.04 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | submodules: recursive 15 | fetch-depth: 0 16 | 17 | - name: Build 18 | uses: actions/setup-node@master 19 | - run: npm install 20 | - run: npm run build 21 | 22 | - name: Deploy 23 | uses: peaceiris/actions-gh-pages@v3 24 | with: 25 | github_token: ${{ secrets.ACCESS_TOKEN }} 26 | publish_dir: './dist' 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | 16 | # umi 17 | /src/.umi 18 | /src/.umi-production 19 | /src/.umi-test 20 | /.env.local 21 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.md 2 | **/*.svg 3 | **/*.ejs 4 | **/*.html 5 | package.json 6 | .umi 7 | .umi-production 8 | .umi-test 9 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 120, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 [Sharida] 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 | ## 国庆专属 生成渐变红旗头像 2 | 3 | ### 特性 4 | 5 | - 纯前端实现 6 | - `React` + `TypeScript` 7 | - `canvas` 绘图 8 | - `cropperjs` 裁切头像 9 | 10 | ### 在线体验 11 | 12 | 在线体验:[渐变红旗头像生成](https://findmio.github.io/Five-star-red-flag-Avatar) 13 | 14 | 15 | ### 界面 16 | 17 | image 18 | 19 | -------------------------------------------------------------------------------- /config/config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | import routes from './router'; // 路由 3 | import extraPostCSSPlugins from './postcssPlugins'; // 额外的 postcss 配置 4 | 5 | const path = '/Five-star-red-flag-Avatar/'; 6 | 7 | export default defineConfig({ 8 | routes, 9 | extraPostCSSPlugins, 10 | alias: { 11 | config: '/config', 12 | }, 13 | 14 | publicPath: process.env.NODE_ENV === 'production' ? path : '/', 15 | base: path, 16 | 17 | fastRefresh: {}, 18 | extraBabelPlugins: [['import', { libraryName: 'antd-mobile', libraryDirectory: 'es/components', style: false }]], 19 | dynamicImport: { 20 | loading: '@/components/Loading', 21 | }, 22 | 23 | targets: { 24 | ios: 10, 25 | chrome: 79, 26 | ie: false, 27 | firefox: false, 28 | safari: false, 29 | edge: false, 30 | }, 31 | 32 | // 优化项 33 | mfsu: {}, 34 | mock: false, 35 | antd: false, 36 | hash: true, 37 | ignoreMomentLocale: true, 38 | nodeModulesTransform: { 39 | type: 'none', 40 | exclude: [], 41 | }, 42 | }); 43 | -------------------------------------------------------------------------------- /config/postcssPlugins.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | require('postcss-px-to-viewport')({ 3 | viewportWidth: 375, // 视窗的宽度,对应的是我们设计稿的宽度,一般是375 4 | unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除) 5 | viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw 6 | selectorBlackList: [], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名 7 | minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值 8 | mediaQuery: false, // 允许在媒体查询中转换`px` 9 | }), 10 | // require('autoprefixer'), 11 | ] -------------------------------------------------------------------------------- /config/router.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | path: '/', 4 | component: '@/layouts', 5 | routes: [ 6 | { path: '/', component: '@/pages/index', title: '渐变红旗头像生成' }, 7 | ], 8 | }, 9 | ]; 10 | -------------------------------------------------------------------------------- /images/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/findmio/Five-star-red-flag-Avatar/8bb49ea481c598d1e11343458f67907445ada4d1/images/index.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "umi dev", 5 | "build": "umi build", 6 | "deploy": "npm run build && gh-pages -d dist", 7 | "postinstall": "umi generate tmp", 8 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 9 | "test": "umi-test", 10 | "test:coverage": "umi-test --coverage" 11 | }, 12 | "gitHooks": { 13 | "pre-commit": "lint-staged" 14 | }, 15 | "lint-staged": { 16 | "*.{js,jsx,less,md,json}": [ 17 | "prettier --write" 18 | ], 19 | "*.ts?(x)": [ 20 | "prettier --parser=typescript --write" 21 | ] 22 | }, 23 | "dependencies": { 24 | "@ant-design/pro-layout": "^6.5.0", 25 | "ahooks": "^3.5.0", 26 | "antd-mobile": "^5.15.1", 27 | "axios": "^0.21.4", 28 | "cropperjs": "^1.5.12", 29 | "dayjs": "^1.10.7", 30 | "lodash": "^4.17.21", 31 | "qs": "^6.10.1", 32 | "react": "17.x", 33 | "react-dom": "17.x", 34 | "react-query": "^3.24.4", 35 | "umi": "^3.5.19" 36 | }, 37 | "devDependencies": { 38 | "@types/lodash": "^4.14.175", 39 | "@types/qs": "^6.9.7", 40 | "@types/react": "^17.0.0", 41 | "@types/react-dom": "^17.0.0", 42 | "@umijs/preset-react": "1.x", 43 | "@umijs/test": "^3.5.19", 44 | "autoprefixer": "^10.3.5", 45 | "babel-plugin-import": "^1.13.3", 46 | "gh-pages": "^3.2.3", 47 | "lint-staged": "^10.0.7", 48 | "postcss-px-to-viewport": "^1.1.1", 49 | "prettier": "^2.2.0", 50 | "typescript": "^4.1.2", 51 | "yorkie": "^2.0.0" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/app.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { QueryClient, QueryClientProvider } from 'react-query'; 3 | import 'antd-mobile/es/global'; 4 | import '@/styles/index.less'; 5 | 6 | export function onRouteChange(props: { matchedRoutes: any }) { 7 | const { matchedRoutes } = props; 8 | if (matchedRoutes.length) { 9 | } 10 | } 11 | 12 | const queryClient = new QueryClient({ 13 | defaultOptions: { 14 | queries: { 15 | refetchOnWindowFocus: false, // 窗口获得焦点时重新获取数据 16 | }, 17 | }, 18 | }); 19 | 20 | /** 21 | * react-dom 渲染时的根组件 22 | */ 23 | export function rootContainer(container: any) { 24 | const App = () => {container}; 25 | return React.createElement(App, null, container); 26 | } 27 | -------------------------------------------------------------------------------- /src/assets/public/fiveStars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/findmio/Five-star-red-flag-Avatar/8bb49ea481c598d1e11343458f67907445ada4d1/src/assets/public/fiveStars.png -------------------------------------------------------------------------------- /src/assets/public/upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/findmio/Five-star-red-flag-Avatar/8bb49ea481c598d1e11343458f67907445ada4d1/src/assets/public/upload.png -------------------------------------------------------------------------------- /src/components/Loading/index.less: -------------------------------------------------------------------------------- 1 | .page { 2 | position: fixed; 3 | z-index: 999; 4 | background-color: #fff; 5 | width: 100vw; 6 | height: 100vh; 7 | overflow: hidden; 8 | display: flex; 9 | align-items: center; 10 | justify-content: center; 11 | } 12 | 13 | .lds-spinner, 14 | .lds-spinner div, 15 | .lds-spinner div:after { 16 | box-sizing: border-box; 17 | } 18 | 19 | .lds-spinner { 20 | color: black; 21 | display: inline-block; 22 | position: relative; 23 | width: 80px; 24 | height: 80px; 25 | transform: scale(0.6); 26 | } 27 | 28 | .lds-spinner div { 29 | transform-origin: 40px 40px; 30 | animation: lds-spinner 1.2s linear infinite; 31 | } 32 | 33 | .lds-spinner div:after { 34 | content: ' '; 35 | display: block; 36 | position: absolute; 37 | top: 3.2px; 38 | left: 36.8px; 39 | width: 4.4px; 40 | height: 12.6px; 41 | border-radius: 20%; 42 | background: currentColor; 43 | } 44 | 45 | .lds-spinner div:nth-child(1) { 46 | transform: rotate(0deg); 47 | animation-delay: -1.1s; 48 | } 49 | 50 | .lds-spinner div:nth-child(2) { 51 | transform: rotate(30deg); 52 | animation-delay: -1s; 53 | } 54 | 55 | .lds-spinner div:nth-child(3) { 56 | transform: rotate(60deg); 57 | animation-delay: -0.9s; 58 | } 59 | 60 | .lds-spinner div:nth-child(4) { 61 | transform: rotate(90deg); 62 | animation-delay: -0.8s; 63 | } 64 | 65 | .lds-spinner div:nth-child(5) { 66 | transform: rotate(120deg); 67 | animation-delay: -0.7s; 68 | } 69 | 70 | .lds-spinner div:nth-child(6) { 71 | transform: rotate(150deg); 72 | animation-delay: -0.6s; 73 | } 74 | 75 | .lds-spinner div:nth-child(7) { 76 | transform: rotate(180deg); 77 | animation-delay: -0.5s; 78 | } 79 | 80 | .lds-spinner div:nth-child(8) { 81 | transform: rotate(210deg); 82 | animation-delay: -0.4s; 83 | } 84 | 85 | .lds-spinner div:nth-child(9) { 86 | transform: rotate(240deg); 87 | animation-delay: -0.3s; 88 | } 89 | 90 | .lds-spinner div:nth-child(10) { 91 | transform: rotate(270deg); 92 | animation-delay: -0.2s; 93 | } 94 | 95 | .lds-spinner div:nth-child(11) { 96 | transform: rotate(300deg); 97 | animation-delay: -0.1s; 98 | } 99 | 100 | .lds-spinner div:nth-child(12) { 101 | transform: rotate(330deg); 102 | animation-delay: 0s; 103 | } 104 | 105 | @keyframes lds-spinner { 106 | 0% { 107 | opacity: 1; 108 | } 109 | 110 | 100% { 111 | opacity: 0; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/components/Loading/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './index.less'; 3 | 4 | 5 | const Loading = () => { 6 | return ( 7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | ); 24 | }; 25 | export default Loading; -------------------------------------------------------------------------------- /src/layouts/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Layout: React.FC = (props) => { 4 | const { children } = props; 5 | 6 | return <>{children}; 7 | }; 8 | export default Layout; 9 | -------------------------------------------------------------------------------- /src/pages/document.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 |   14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /src/pages/index/components/ImageModal.tsx: -------------------------------------------------------------------------------- 1 | import Cropper from 'cropperjs'; 2 | import React, { useEffect, useRef } from 'react'; 3 | import styles from './index.less'; 4 | import { Dialog } from 'antd-mobile'; 5 | import { getDataUrl } from '@/utils/file'; 6 | import 'cropperjs/dist/cropper.css'; 7 | 8 | interface Props { 9 | imageModalVisible: boolean; 10 | onClose(visible: boolean): void; 11 | onConfirm(data: string): void; 12 | imgData: string; 13 | } 14 | 15 | interface CProps { 16 | url: string; 17 | store: any; 18 | } 19 | 20 | const Content: React.FC = (props) => { 21 | const { url, store } = props; 22 | const imageRef = useRef(null); 23 | 24 | useEffect(() => { 25 | if (imageRef.current) { 26 | store.current = new Cropper(imageRef.current, { 27 | aspectRatio: 1, 28 | autoCropArea: 1, 29 | viewMode: 1, 30 | movable: false, 31 | zoomable: false, 32 | }); 33 | } 34 | }, [url]); 35 | 36 | return ( 37 |
38 | 图片 39 |
40 | ); 41 | }; 42 | 43 | const ImageModal: React.FC = (props) => { 44 | const { imageModalVisible, onClose, imgData, onConfirm } = props; 45 | const cropperRef = useRef(null); 46 | 47 | const handleConfirm = () => { 48 | cropperRef.current.getCroppedCanvas().toBlob(async (blob: Blob) => { 49 | const data = await getDataUrl(blob); 50 | onConfirm(data); 51 | }); 52 | }; 53 | 54 | return ( 55 | { 59 | switch (values.key) { 60 | case 'cancel': 61 | onClose(false); 62 | break; 63 | case 'confirm': 64 | handleConfirm(); 65 | break; 66 | } 67 | }} 68 | content={} 69 | actions={[ 70 | [ 71 | { 72 | key: 'cancel', 73 | text: '取消', 74 | }, 75 | { 76 | key: 'confirm', 77 | text: '确认', 78 | bold: true, 79 | }, 80 | ], 81 | ]} 82 | /> 83 | ); 84 | }; 85 | export default ImageModal; 86 | -------------------------------------------------------------------------------- /src/pages/index/components/index.less: -------------------------------------------------------------------------------- 1 | .image { 2 | width: 250px; 3 | min-height: 250px; 4 | img { 5 | width: 250px; 6 | min-height: 250px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/pages/index/img.ts: -------------------------------------------------------------------------------- 1 | export default 'data:image/jpeg;base64,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' -------------------------------------------------------------------------------- /src/pages/index/index.less: -------------------------------------------------------------------------------- 1 | .page { 2 | min-height: 100vh; 3 | width: 100vw; 4 | padding: 12px; 5 | overflow-x: hidden; 6 | .avatar { 7 | display: flex; 8 | justify-content: space-evenly; 9 | img { 10 | width: 200px; 11 | height: 200px; 12 | object-fit: cover; 13 | } 14 | .avatarRight { 15 | margin-left: 8px; 16 | display: flex; 17 | flex-direction: column; 18 | align-items: center; 19 | justify-content: space-evenly; 20 | } 21 | .avatarRightItem { 22 | display: flex; 23 | flex-direction: column; 24 | align-items: center; 25 | position: relative; 26 | background-color: #fff; 27 | div { 28 | margin-top: 6px; 29 | font-size: var(--adm-font-size-main); 30 | color: #666; 31 | } 32 | .input { 33 | position: absolute; 34 | overflow: hidden; 35 | opacity: 0; 36 | left: 0; 37 | top: 0; 38 | bottom: 0; 39 | right: 0; 40 | } 41 | } 42 | } 43 | .sliders { 44 | margin-top: 20px; 45 | .download { 46 | display: flex; 47 | align-items: center; 48 | justify-content: center; 49 | padding: 12px 0; 50 | background-color: #1677FF; 51 | color: #fff; 52 | border-radius: 4px; 53 | 54 | &:link { 55 | text-decoration: none; 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/pages/index/index.tsx: -------------------------------------------------------------------------------- 1 | import ImageModal from './components/ImageModal'; 2 | import imgPlaceholder from './img'; 3 | import React, { useRef, useState, useEffect } from 'react'; 4 | import styles from './index.less'; 5 | import { Button, Form, Image, ImageViewer, Slider } from 'antd-mobile'; 6 | import { getDataUrl, dataURLtoBlob } from '@/utils/file'; 7 | import { isEmpty } from 'lodash'; 8 | import { PicturesOutline, RedoOutline } from 'antd-mobile-icons'; 9 | import { useDebounceFn } from 'ahooks'; 10 | import fiveStars from '@/assets/public/fiveStars.png'; 11 | 12 | const size = 500; 13 | const scale = 369 / 303; 14 | 15 | const initialValues = { 16 | starSize: 126, 17 | gradualChangeSize: 520, 18 | gradualChangePosition: -76, 19 | gradualChangeSection: 4, 20 | }; 21 | 22 | export default function IndexPage() { 23 | const [form] = Form.useForm(); 24 | const canvasRef = useRef(null); 25 | const inputRef = useRef(null); 26 | const imageRef = useRef(null); 27 | const fiveStarsRef = useRef(null); 28 | 29 | const [imgData, setImgData] = useState(imgPlaceholder); 30 | const [imageModalVisible, setImageModalVisible] = useState(false); 31 | const [generateImg, setGenerateImg] = useState(''); 32 | const [imageViewerVisible, setImageViewerVisible] = useState(false); 33 | 34 | useEffect(() => { 35 | generate(); 36 | }, []); 37 | 38 | const { run: sliderChange } = useDebounceFn( 39 | () => { 40 | generate(); 41 | }, 42 | { 43 | wait: 300, 44 | }, 45 | ); 46 | 47 | const generate = async (baseImg: string = imgData) => { 48 | const { starSize, gradualChangeSize, gradualChangePosition, gradualChangeSection } = form.getFieldsValue(); 49 | 50 | if (!canvasRef.current || !imageRef.current || !fiveStarsRef.current) { 51 | return; 52 | } 53 | const ctx = canvasRef.current.getContext('2d'); 54 | ctx!.clearRect(0, 0, size, size); 55 | 56 | imageRef.current.src = baseImg; 57 | imageRef.current.onload = () => { 58 | ctx!.drawImage(imageRef.current!, 0, 0, size, size); 59 | // 填充渐变 60 | const radgrad = ctx!.createRadialGradient( 61 | 0, 62 | gradualChangePosition, 63 | 0, 64 | 0, 65 | gradualChangePosition + 100, 66 | (gradualChangeSize * 1.414) / 1.5, 67 | ); 68 | radgrad.addColorStop(0, '#d80203'); 69 | radgrad.addColorStop(gradualChangeSection / 10, 'rgba(216,2,3,0.8)'); 70 | radgrad.addColorStop(1, 'rgba(255, 255, 255, 0)'); 71 | ctx!.fillStyle = radgrad; 72 | ctx!.fillRect(0, 0, size, size); 73 | 74 | fiveStarsRef.current!.src = fiveStars; 75 | fiveStarsRef.current!.onload = () => { 76 | // 填充星星 77 | ctx!.drawImage( 78 | fiveStarsRef.current!, 79 | 0, 80 | 0, 81 | fiveStarsRef.current!.width, 82 | fiveStarsRef.current!.height, 83 | 20, 84 | 20, 85 | starSize * scale, 86 | starSize, 87 | ); 88 | setGenerateImg(canvasRef.current!.toDataURL('image/png', 1)); 89 | }; 90 | }; 91 | }; 92 | 93 | const getFile = async () => { 94 | if (!isEmpty(inputRef.current?.files)) { 95 | const file = inputRef.current!.files![0]; 96 | inputRef.current!.value = ''; 97 | const base64 = await getDataUrl(file); 98 | setImgData(base64); 99 | setImageModalVisible(true); 100 | } 101 | }; 102 | 103 | const handleReset = () => { 104 | form.resetFields(); 105 | generate(); 106 | }; 107 | 108 | const onConfirm = (data: string) => { 109 | setImgData(data); 110 | generate(data); 111 | setImageModalVisible(false); 112 | }; 113 | 114 | const downloadFile = () => { 115 | window.location.href = generateImg; 116 | }; 117 | 118 | const imageModalProps = { 119 | imageModalVisible, 120 | onClose: setImageModalVisible, 121 | imgData, 122 | onConfirm, 123 | }; 124 | 125 | return ( 126 |
127 |
128 | { 131 | setImageViewerVisible(true); 132 | }} 133 | /> 134 |
135 |
136 | 137 |
更换图片
138 | getFile()} 140 | ref={inputRef} 141 | className={styles.input} 142 | type="file" 143 | accept="image/png, image/jpeg" 144 | /> 145 |
146 |
147 | 148 |
重置参数
149 |
150 |
151 |
152 | 153 |
154 |
158 | 下载 159 | 160 | } 161 | initialValues={initialValues} 162 | > 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 |
176 |
177 | 178 | 179 | 180 | { 184 | setImageViewerVisible(false); 185 | }} 186 | /> 187 | 188 | 189 | 190 | 199 | 210 |
211 | ); 212 | } 213 | -------------------------------------------------------------------------------- /src/styles/global.less: -------------------------------------------------------------------------------- 1 | .page { 2 | min-height: 100vh; 3 | width: 100vw; 4 | overflow-y: auto; 5 | } 6 | -------------------------------------------------------------------------------- /src/styles/index.less: -------------------------------------------------------------------------------- 1 | @import url('./reset.less'); 2 | @import url('./global.less'); -------------------------------------------------------------------------------- /src/styles/reset.less: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | div, 4 | span, 5 | applet, 6 | object, 7 | iframe, 8 | h1, 9 | h2, 10 | h3, 11 | h4, 12 | h5, 13 | h6, 14 | p, 15 | blockquote, 16 | pre, 17 | a, 18 | abbr, 19 | acronym, 20 | address, 21 | big, 22 | cite, 23 | code, 24 | del, 25 | dfn, 26 | em, 27 | img, 28 | ins, 29 | kbd, 30 | q, 31 | s, 32 | samp, 33 | small, 34 | strike, 35 | strong, 36 | sub, 37 | sup, 38 | tt, 39 | var, 40 | b, 41 | u, 42 | i, 43 | center, 44 | dl, 45 | dt, 46 | dd, 47 | ol, 48 | ul, 49 | li, 50 | fieldset, 51 | form, 52 | label, 53 | legend, 54 | table, 55 | caption, 56 | tbody, 57 | tfoot, 58 | thead, 59 | tr, 60 | th, 61 | td, 62 | article, 63 | aside, 64 | canvas, 65 | details, 66 | embed, 67 | figure, 68 | figcaption, 69 | footer, 70 | header, 71 | hgroup, 72 | menu, 73 | nav, 74 | output, 75 | ruby, 76 | section, 77 | summary, 78 | time, 79 | mark, 80 | audio, 81 | video { 82 | margin: 0; 83 | padding: 0; 84 | border: 0; 85 | font-size: 100%; 86 | font: inherit; 87 | vertical-align: baseline; 88 | box-sizing: border-box; 89 | } 90 | article, 91 | aside, 92 | details, 93 | figcaption, 94 | figure, 95 | footer, 96 | header, 97 | hgroup, 98 | menu, 99 | nav, 100 | section { 101 | display: block; 102 | } 103 | body { 104 | line-height: 1; 105 | } 106 | ol, 107 | ul { 108 | list-style: none; 109 | } 110 | blockquote, 111 | q { 112 | quotes: none; 113 | } 114 | blockquote:before, 115 | blockquote:after, 116 | q:before, 117 | q:after { 118 | content: ''; 119 | content: none; 120 | } 121 | table { 122 | border-collapse: collapse; 123 | border-spacing: 0; 124 | } 125 | -------------------------------------------------------------------------------- /src/utils/api.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | } 3 | -------------------------------------------------------------------------------- /src/utils/dev.ts: -------------------------------------------------------------------------------- 1 | const { NODE_ENV } = process.env; 2 | 3 | /** 4 | * 判断是否为开发环境 5 | * @returns {Boolean} true | false 6 | */ 7 | export const isDev = NODE_ENV === 'development'; -------------------------------------------------------------------------------- /src/utils/file.ts: -------------------------------------------------------------------------------- 1 | export async function getDataUrl(file: File | Blob): Promise { 2 | return new Promise(resolve => { 3 | const reader = new FileReader(); 4 | 5 | reader.readAsDataURL(file); 6 | 7 | reader.onload = () => { 8 | resolve(reader.result as string) 9 | } 10 | }) 11 | } 12 | 13 | 14 | export function dataURLtoBlob(base64Str: string) { 15 | var bstr = atob(base64Str), n = bstr.length, u8arr = new Uint8Array(n); 16 | while (n--) { 17 | u8arr[n] = bstr.charCodeAt(n); 18 | } 19 | return new Blob([u8arr], { type: 'image/png' }); 20 | } -------------------------------------------------------------------------------- /src/utils/props.ts: -------------------------------------------------------------------------------- 1 | import { assign, assignWith, isUndefined } from 'lodash'; 2 | 3 | export function mergeProps(defaultProps: D, props: P): P & D { 4 | function customizer(objValue: any, srcValue: any) { 5 | return isUndefined(srcValue) ? objValue : srcValue 6 | } 7 | return assignWith(assign({}, defaultProps), props, customizer) 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "resolveJsonModule": true, 7 | "importHelpers": true, 8 | "jsx": "react-jsx", 9 | "esModuleInterop": true, 10 | "sourceMap": true, 11 | "baseUrl": "./", 12 | "strict": true, 13 | "paths": { 14 | "@/*": ["src/*"], 15 | "@@/*": ["src/.umi/*"] 16 | }, 17 | "allowSyntheticDefaultImports": true 18 | }, 19 | "include": [ 20 | "mock/**/*", 21 | "src/**/*", 22 | "config/**/*", 23 | ".umirc.ts", 24 | "typings.d.ts" 25 | ], 26 | "exclude": [ 27 | "node_modules", 28 | "lib", 29 | "es", 30 | "dist", 31 | "typings", 32 | "**/__test__", 33 | "test", 34 | "docs", 35 | "tests" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | declare module '*.png'; 4 | declare module '*.svg' { 5 | export function ReactComponent( 6 | props: React.SVGProps, 7 | ): React.ReactElement; 8 | const url: string; 9 | export default url; 10 | } 11 | --------------------------------------------------------------------------------