mirror of
				https://ghproxy.com/https://github.com/StreakingMan/solvable-sheep-game
				synced 2025-11-04 15:16:06 +08:00 
			
		
		
		
	feat: 生成二维码
This commit is contained in:
		
							parent
							
								
									f6681cabb0
								
							
						
					
					
						commit
						f36c99b385
					
				| 
						 | 
				
			
			@ -13,6 +13,7 @@
 | 
			
		|||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "classnames": "^2.3.2",
 | 
			
		||||
        "clipboard": "^2.0.11",
 | 
			
		||||
        "hydrogen-js-sdk": "^2.3.10",
 | 
			
		||||
        "qrcode.react": "^3.1.0",
 | 
			
		||||
        "react": "^18.2.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ import React, {
 | 
			
		|||
} from 'react';
 | 
			
		||||
 | 
			
		||||
import './App.scss';
 | 
			
		||||
import { GithubIcon } from './components/GithubIcon';
 | 
			
		||||
import { PersonalInfo } from './components/PersonalInfo';
 | 
			
		||||
import {
 | 
			
		||||
    parsePathCustomThemeId,
 | 
			
		||||
    parsePathThemeName,
 | 
			
		||||
| 
						 | 
				
			
			@ -475,7 +475,7 @@ const App: FC = () => {
 | 
			
		|||
        <>
 | 
			
		||||
            <h2>{curTheme.title}</h2>
 | 
			
		||||
            <p>
 | 
			
		||||
                <GithubIcon />
 | 
			
		||||
                <PersonalInfo />
 | 
			
		||||
            </p>
 | 
			
		||||
            <h3 className="flex-container flex-center">
 | 
			
		||||
                主题:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
.dialog {
 | 
			
		||||
    text-align: left;
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
 | 
			
		||||
    &Wrapper {
 | 
			
		||||
        z-index: 10;
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +16,7 @@
 | 
			
		|||
        transition: 0.3s;
 | 
			
		||||
        padding: 16px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        flex-flow: column nowrap !important;
 | 
			
		||||
 | 
			
		||||
        @media screen and (min-width: 1024px) {
 | 
			
		||||
            margin: 36px 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -49,9 +50,11 @@
 | 
			
		|||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
 | 
			
		||||
        &Empty::before {
 | 
			
		||||
            content: '+';
 | 
			
		||||
            color: #999;
 | 
			
		||||
            font-size: 2em;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +95,7 @@
 | 
			
		|||
        background-color: #f9f9f9;
 | 
			
		||||
        font-size: 1.5em;
 | 
			
		||||
        color: #999;
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
 | 
			
		||||
        span {
 | 
			
		||||
            transform: rotate(45deg);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,8 +3,10 @@ import style from './ConfigDialog.module.scss';
 | 
			
		|||
import classNames from 'classnames';
 | 
			
		||||
import { Icon, Sound, Theme } from '../themes/interface';
 | 
			
		||||
import { defaultSounds } from '../themes/default';
 | 
			
		||||
import { QRCodeSVG } from 'qrcode.react';
 | 
			
		||||
import { QRCodeCanvas } from 'qrcode.react';
 | 
			
		||||
import Bmob from 'hydrogen-js-sdk';
 | 
			
		||||
import { captureElement } from '../utils';
 | 
			
		||||
import { copy } from 'clipboard';
 | 
			
		||||
 | 
			
		||||
const STORAGEKEY = 'customTheme';
 | 
			
		||||
let storageTheme: Theme<any>;
 | 
			
		||||
| 
						 | 
				
			
			@ -254,7 +256,6 @@ export const ConfigDialog: FC<{
 | 
			
		|||
    // 生成二维码和链接
 | 
			
		||||
    const onGenQrLinkClick = () => {
 | 
			
		||||
        setConfigError('');
 | 
			
		||||
        setGenLink('');
 | 
			
		||||
        generateTheme()
 | 
			
		||||
            .then((theme) => {
 | 
			
		||||
                const stringify = JSON.stringify(theme);
 | 
			
		||||
| 
						 | 
				
			
			@ -274,6 +275,7 @@ export const ConfigDialog: FC<{
 | 
			
		|||
            })
 | 
			
		||||
            .catch((e) => {
 | 
			
		||||
                setConfigError(e);
 | 
			
		||||
                setGenLink('');
 | 
			
		||||
            });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -405,7 +407,23 @@ export const ConfigDialog: FC<{
 | 
			
		|||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div className="flex-spacer" />
 | 
			
		||||
            {genLink && <textarea value={genLink} />}
 | 
			
		||||
            {genLink && (
 | 
			
		||||
                <div className="flex-container flex-column">
 | 
			
		||||
                    <QRCodeCanvas id="qrCode" value={genLink} size={300} />
 | 
			
		||||
                    <button
 | 
			
		||||
                        onClick={() =>
 | 
			
		||||
                            captureElement('qrCode', customThemeInfo.title)
 | 
			
		||||
                        }
 | 
			
		||||
                        className="primary"
 | 
			
		||||
                    >
 | 
			
		||||
                        下载二维码
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <div>{genLink}</div>
 | 
			
		||||
                    <button onClick={() => copy(genLink)} className="primary">
 | 
			
		||||
                        复制链接
 | 
			
		||||
                    </button>
 | 
			
		||||
                </div>
 | 
			
		||||
            )}
 | 
			
		||||
            {configError && <div className={style.error}>{configError}</div>}
 | 
			
		||||
            <div className="flex-container">
 | 
			
		||||
                <button className="flex-grow" onClick={onPreviewClick}>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,28 +0,0 @@
 | 
			
		|||
import React, { FC } from 'react';
 | 
			
		||||
 | 
			
		||||
export const GithubIcon: FC = () => {
 | 
			
		||||
    return (
 | 
			
		||||
        <a
 | 
			
		||||
            href="https://github.com/StreakingMan/solvable-sheep-game"
 | 
			
		||||
            target="_blank"
 | 
			
		||||
            rel="noreferrer"
 | 
			
		||||
        >
 | 
			
		||||
            点个✨不迷路 @StreakingMan
 | 
			
		||||
            <svg
 | 
			
		||||
                height="24"
 | 
			
		||||
                aria-hidden="true"
 | 
			
		||||
                viewBox="0 0 16 16"
 | 
			
		||||
                version="1.1"
 | 
			
		||||
                width="24"
 | 
			
		||||
                data-view-component="true"
 | 
			
		||||
                className="octicon octicon-mark-github v-align-middle"
 | 
			
		||||
                fill="currentColor"
 | 
			
		||||
            >
 | 
			
		||||
                <path
 | 
			
		||||
                    fillRule="evenodd"
 | 
			
		||||
                    d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
 | 
			
		||||
                />
 | 
			
		||||
            </svg>
 | 
			
		||||
        </a>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										46
									
								
								src/components/PersonalInfo.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/components/PersonalInfo.tsx
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										32
									
								
								src/utils.ts
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								src/utils.ts
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -31,3 +31,35 @@ export const parsePathCustomThemeId: (url: string) => string = (url) => {
 | 
			
		|||
    const params = urlObj.searchParams;
 | 
			
		||||
    return params.get('customTheme') || '';
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 截图
 | 
			
		||||
export const captureElement = (id: string, filename: string) => {
 | 
			
		||||
    const canvas = document.createElement('canvas');
 | 
			
		||||
    const ctx = canvas.getContext('2d');
 | 
			
		||||
    if (!ctx) return;
 | 
			
		||||
    const element = document.getElementById(id);
 | 
			
		||||
    if (!element) return;
 | 
			
		||||
    console.log(element);
 | 
			
		||||
    canvas.width = element.clientWidth;
 | 
			
		||||
    canvas.height = element.clientHeight;
 | 
			
		||||
    console.log(element.clientWidth);
 | 
			
		||||
    // @ts-ignore
 | 
			
		||||
    ctx.drawImage(element, 0, 0, element.clientWidth, element.clientHeight);
 | 
			
		||||
    canvas.toBlob(
 | 
			
		||||
        function (blob) {
 | 
			
		||||
            if (!blob) return;
 | 
			
		||||
            const eleLink = document.createElement('a');
 | 
			
		||||
            eleLink.download = filename;
 | 
			
		||||
            eleLink.style.display = 'none';
 | 
			
		||||
            // 字符内容转变成blob地址
 | 
			
		||||
            eleLink.href = URL.createObjectURL(blob);
 | 
			
		||||
            // 触发点击
 | 
			
		||||
            document.body.appendChild(eleLink);
 | 
			
		||||
            eleLink.click();
 | 
			
		||||
            // 然后移除
 | 
			
		||||
            document.body.removeChild(eleLink);
 | 
			
		||||
        },
 | 
			
		||||
        'image/png',
 | 
			
		||||
        1
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										31
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								yarn.lock
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1316,6 +1316,15 @@ cli-truncate@^3.1.0:
 | 
			
		|||
    slice-ansi "^5.0.0"
 | 
			
		||||
    string-width "^5.0.0"
 | 
			
		||||
 | 
			
		||||
clipboard@^2.0.11:
 | 
			
		||||
  version "2.0.11"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.11.tgz#62180360b97dd668b6b3a84ec226975762a70be5"
 | 
			
		||||
  integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    good-listener "^1.2.2"
 | 
			
		||||
    select "^1.1.2"
 | 
			
		||||
    tiny-emitter "^2.0.0"
 | 
			
		||||
 | 
			
		||||
cliui@^2.1.0:
 | 
			
		||||
  version "2.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
 | 
			
		||||
| 
						 | 
				
			
			@ -1814,6 +1823,11 @@ define-property@^2.0.2:
 | 
			
		|||
    is-descriptor "^1.0.2"
 | 
			
		||||
    isobject "^3.0.1"
 | 
			
		||||
 | 
			
		||||
delegate@^3.1.2:
 | 
			
		||||
  version "3.2.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
 | 
			
		||||
  integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
 | 
			
		||||
 | 
			
		||||
des.js@^1.0.0:
 | 
			
		||||
  version "1.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
 | 
			
		||||
| 
						 | 
				
			
			@ -2830,6 +2844,13 @@ globjoin@^0.1.4:
 | 
			
		|||
  resolved "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
 | 
			
		||||
  integrity sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==
 | 
			
		||||
 | 
			
		||||
good-listener@^1.2.2:
 | 
			
		||||
  version "1.2.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
 | 
			
		||||
  integrity sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    delegate "^3.1.2"
 | 
			
		||||
 | 
			
		||||
graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0:
 | 
			
		||||
  version "4.2.10"
 | 
			
		||||
  resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
 | 
			
		||||
| 
						 | 
				
			
			@ -4903,6 +4924,11 @@ scheduler@^0.23.0:
 | 
			
		|||
  dependencies:
 | 
			
		||||
    loose-envify "^1.1.0"
 | 
			
		||||
 | 
			
		||||
select@^1.1.2:
 | 
			
		||||
  version "1.1.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
 | 
			
		||||
  integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==
 | 
			
		||||
 | 
			
		||||
"semver@2 || 3 || 4 || 5":
 | 
			
		||||
  version "5.7.1"
 | 
			
		||||
  resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
 | 
			
		||||
| 
						 | 
				
			
			@ -5526,6 +5552,11 @@ timers-browserify@^2.0.4:
 | 
			
		|||
  dependencies:
 | 
			
		||||
    setimmediate "^1.0.4"
 | 
			
		||||
 | 
			
		||||
tiny-emitter@^2.0.0:
 | 
			
		||||
  version "2.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
 | 
			
		||||
  integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
 | 
			
		||||
 | 
			
		||||
to-arraybuffer@^1.0.0:
 | 
			
		||||
  version "1.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user