feat: 上传文章
36
.dumi/global.less
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#root .dumi-default-doc-layout .dumi-default-features-item {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#root .dumi-default-doc-layout > main {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root .dumi-default-sidebar {
|
||||||
|
overflow-y: hidden;
|
||||||
|
&:hover {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#root .dumi-default-logo {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root .dumi-default-logo img {
|
||||||
|
width: 30px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root .dumi-default-navbar>li {
|
||||||
|
font-size: 14px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root .dumi-default-search-bar-input {
|
||||||
|
width: 200px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root .dumi-default-hero-title>span {
|
||||||
|
font-size: 96px;
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import { defineConfig } from 'dumi';
|
import { defineConfig } from 'dumi';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
title: 'Nice Note',
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
name: 'nicenote',
|
|
||||||
navs: [
|
navs: [
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
@ -11,8 +11,8 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
favicons: ['https://jzx-h5.oss-cn-hangzhou.aliyuncs.com/logo.ico'],
|
logo: 'https://i.niupic.com/images/2021/06/07/9krN.png',
|
||||||
// logo: 'http://jzx-h5.oss-cn-hangzhou.aliyuncs.com/logo.png',
|
favicons: ['https://i.niupic.com/images/2021/06/07/9krN.png'],
|
||||||
outputPath: 'docs-dist',
|
outputPath: 'docs-dist',
|
||||||
hash: true,
|
hash: true,
|
||||||
history: {
|
history: {
|
||||||
|
1
.gitignore
vendored
@ -4,3 +4,4 @@ node_modules
|
|||||||
.dumi/tmp-production
|
.dumi/tmp-production
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.umi
|
.umi
|
||||||
|
/docs-dist
|
||||||
|
3
.npmrc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
registry="https://registry.npmmirror.com"
|
||||||
|
strict-peer-dependencies=false
|
||||||
|
ignore-workspace-root-check=true
|
@ -1,53 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
|
|
||||||
if (window.g_initWebpackHotDevClient) {
|
|
||||||
function tryApplyUpdates(onHotUpdateSuccess?: Function) {
|
|
||||||
// @ts-ignore
|
|
||||||
if (!module.hot) {
|
|
||||||
window.location.reload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isUpdateAvailable() {
|
|
||||||
// @ts-ignore
|
|
||||||
return window.g_getMostRecentCompilationHash() !== __webpack_hash__;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: is update available?
|
|
||||||
// @ts-ignore
|
|
||||||
if (!isUpdateAvailable() || module.hot.status() !== 'idle') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleApplyUpdates(err: Error | null, updatedModules: any) {
|
|
||||||
if (err || !updatedModules || window.g_getHadRuntimeError()) {
|
|
||||||
window.location.reload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
onHotUpdateSuccess?.();
|
|
||||||
|
|
||||||
if (isUpdateAvailable()) {
|
|
||||||
// While we were updating, there was a new update! Do it again.
|
|
||||||
tryApplyUpdates();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
module.hot.check(true).then(
|
|
||||||
function (updatedModules: any) {
|
|
||||||
handleApplyUpdates(null, updatedModules);
|
|
||||||
},
|
|
||||||
function (err: Error) {
|
|
||||||
handleApplyUpdates(err, null);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.g_initWebpackHotDevClient({
|
|
||||||
tryApplyUpdates,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export const __mfsu = 1;
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import { createBrowserHistory, History } from '/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/node_modules/_@umijs_runtime@3.5.41@@umijs/runtime';
|
|
||||||
|
|
||||||
let options = {
|
|
||||||
"basename": "/"
|
|
||||||
};
|
|
||||||
if ((<any>window).routerBase) {
|
|
||||||
options.basename = (<any>window).routerBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove initial history because of ssr
|
|
||||||
let history: History = process.env.__IS_SERVER ? null : createBrowserHistory(options);
|
|
||||||
export const createHistory = (hotReload = false) => {
|
|
||||||
if (!hotReload) {
|
|
||||||
history = createBrowserHistory(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return history;
|
|
||||||
};
|
|
||||||
|
|
||||||
export { history };
|
|
@ -1,8 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import { Plugin } from '/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/node_modules/_@umijs_runtime@3.5.41@@umijs/runtime';
|
|
||||||
|
|
||||||
const plugin = new Plugin({
|
|
||||||
validKeys: ['modifyClientRenderOpts','patchRoutes','rootContainer','render','onRouteChange','__mfsu',],
|
|
||||||
});
|
|
||||||
|
|
||||||
export { plugin };
|
|
297
.umi/core/pluginConfig.d.ts
vendored
@ -1,297 +0,0 @@
|
|||||||
// Created by Umi Plugin
|
|
||||||
|
|
||||||
export interface IConfigFromPlugins {
|
|
||||||
"404"?: boolean
|
|
||||||
routes?: {
|
|
||||||
/**
|
|
||||||
* Any valid URL path
|
|
||||||
*/
|
|
||||||
path?: string
|
|
||||||
/**
|
|
||||||
* A React component to render only when the location matches.
|
|
||||||
*/
|
|
||||||
component?: (string | (() => any))
|
|
||||||
wrappers?: string[]
|
|
||||||
/**
|
|
||||||
* navigate to a new location
|
|
||||||
*/
|
|
||||||
redirect?: string
|
|
||||||
/**
|
|
||||||
* When true, the active class/style will only be applied if the location is matched exactly.
|
|
||||||
*/
|
|
||||||
exact?: boolean
|
|
||||||
routes?: any[]
|
|
||||||
[k: string]: any
|
|
||||||
}[]
|
|
||||||
history?: {
|
|
||||||
type?: ("browser" | "hash" | "memory")
|
|
||||||
options?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
polyfill?: {
|
|
||||||
imports?: string[]
|
|
||||||
}
|
|
||||||
alias?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
analyze?: {
|
|
||||||
analyzerMode?: ("server" | "static" | "disabled")
|
|
||||||
analyzerHost?: string
|
|
||||||
analyzerPort?: any
|
|
||||||
openAnalyzer?: boolean
|
|
||||||
generateStatsFile?: boolean
|
|
||||||
statsFilename?: string
|
|
||||||
logLevel?: ("info" | "warn" | "error" | "silent")
|
|
||||||
defaultSizes?: ("stat" | "parsed" | "gzip")
|
|
||||||
[k: string]: any
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* postcss autoprefixer, default flexbox: no-2009
|
|
||||||
*/
|
|
||||||
autoprefixer?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
base?: string
|
|
||||||
chainWebpack?: (() => any)
|
|
||||||
chunks?: string[]
|
|
||||||
/**
|
|
||||||
* more css-loader options see https://webpack.js.org/loaders/css-loader/#options
|
|
||||||
*/
|
|
||||||
cssLoader?: {
|
|
||||||
url?: (boolean | (() => any))
|
|
||||||
import?: (boolean | (() => any))
|
|
||||||
modules?: (boolean | string | {
|
|
||||||
|
|
||||||
})
|
|
||||||
sourceMap?: boolean
|
|
||||||
importLoaders?: number
|
|
||||||
onlyLocals?: boolean
|
|
||||||
esModule?: boolean
|
|
||||||
localsConvention?: ("asIs" | "camelCase" | "camelCaseOnly" | "dashes" | "dashesOnly")
|
|
||||||
}
|
|
||||||
cssModulesTypescriptLoader?: {
|
|
||||||
mode?: ("emit" | "verify")
|
|
||||||
}
|
|
||||||
cssnano?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
copy?: any[]
|
|
||||||
define?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
devScripts?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* devServer configs
|
|
||||||
*/
|
|
||||||
devServer?: {
|
|
||||||
/**
|
|
||||||
* devServer port, default 8000
|
|
||||||
*/
|
|
||||||
port?: number
|
|
||||||
host?: string
|
|
||||||
https?: ({
|
|
||||||
key?: string
|
|
||||||
cert?: string
|
|
||||||
http2?: boolean
|
|
||||||
[k: string]: any
|
|
||||||
} | boolean)
|
|
||||||
headers?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
writeToDisk?: (boolean | (() => any))
|
|
||||||
[k: string]: any
|
|
||||||
}
|
|
||||||
devtool?: string
|
|
||||||
/**
|
|
||||||
* Code splitting for performance optimization
|
|
||||||
*/
|
|
||||||
dynamicImport?: {
|
|
||||||
/**
|
|
||||||
* loading the component before loaded
|
|
||||||
*/
|
|
||||||
loading?: string
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Code splitting for import statement syntax
|
|
||||||
*/
|
|
||||||
dynamicImportSyntax?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
exportStatic?: {
|
|
||||||
htmlSuffix?: boolean
|
|
||||||
dynamicRoot?: boolean
|
|
||||||
supportWin?: boolean
|
|
||||||
/**
|
|
||||||
* extra render paths only enable in ssr
|
|
||||||
*/
|
|
||||||
extraRoutePaths?: (() => any)
|
|
||||||
}
|
|
||||||
externals?: ({
|
|
||||||
|
|
||||||
} | string | (() => any))
|
|
||||||
extraBabelIncludes?: any[]
|
|
||||||
extraBabelPlugins?: any[]
|
|
||||||
extraBabelPresets?: any[]
|
|
||||||
extraPostCSSPlugins?: any[]
|
|
||||||
/**
|
|
||||||
* fork-ts-checker-webpack-plugin options see https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#options
|
|
||||||
*/
|
|
||||||
forkTSChecker?: {
|
|
||||||
async?: boolean
|
|
||||||
typescript?: (boolean | {
|
|
||||||
|
|
||||||
})
|
|
||||||
eslint?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
issue?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
formatter?: (string | {
|
|
||||||
|
|
||||||
})
|
|
||||||
logger?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
[k: string]: any
|
|
||||||
}
|
|
||||||
fastRefresh?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
hash?: boolean
|
|
||||||
ignoreMomentLocale?: boolean
|
|
||||||
inlineLimit?: number
|
|
||||||
lessLoader?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
manifest?: {
|
|
||||||
fileName?: string
|
|
||||||
publicPath?: ""
|
|
||||||
basePath?: string
|
|
||||||
writeToFileEmit?: boolean
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* open mfsu feature
|
|
||||||
*/
|
|
||||||
mfsu?: {
|
|
||||||
development?: {
|
|
||||||
output?: string
|
|
||||||
}
|
|
||||||
production?: {
|
|
||||||
output?: string
|
|
||||||
}
|
|
||||||
mfName?: string
|
|
||||||
exportAllMembers?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
chunks?: string[]
|
|
||||||
ignoreNodeBuiltInModules?: boolean
|
|
||||||
}
|
|
||||||
mountElementId?: ""
|
|
||||||
mpa?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
nodeModulesTransform?: {
|
|
||||||
type?: ("all" | "none")
|
|
||||||
exclude?: string[]
|
|
||||||
}
|
|
||||||
outputPath?: ""
|
|
||||||
plugins?: string[]
|
|
||||||
postcssLoader?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
presets?: string[]
|
|
||||||
proxy?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
publicPath?: string
|
|
||||||
runtimePublicPath?: boolean
|
|
||||||
ssr?: {
|
|
||||||
/**
|
|
||||||
* force execing Page getInitialProps functions
|
|
||||||
*/
|
|
||||||
forceInitial?: boolean
|
|
||||||
/**
|
|
||||||
* remove window.g_initialProps in html
|
|
||||||
*/
|
|
||||||
removeWindowInitialProps?: boolean
|
|
||||||
/**
|
|
||||||
* disable serve-side render in umi dev mode.
|
|
||||||
*/
|
|
||||||
devServerRender?: boolean
|
|
||||||
mode?: ("stream" | "string")
|
|
||||||
/**
|
|
||||||
* static markup in static site
|
|
||||||
*/
|
|
||||||
staticMarkup?: boolean
|
|
||||||
}
|
|
||||||
singular?: boolean
|
|
||||||
styleLoader?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
targets?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
terserOptions?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
theme?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
runtimeHistory?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
webpack5?: {
|
|
||||||
lazyCompilation?: {
|
|
||||||
entries?: boolean
|
|
||||||
imports?: boolean
|
|
||||||
test?: any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
workerLoader?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
favicon?: string
|
|
||||||
headScripts?: any[]
|
|
||||||
links?: any[]
|
|
||||||
metas?: any[]
|
|
||||||
scripts?: any[]
|
|
||||||
styles?: any[]
|
|
||||||
title?: string
|
|
||||||
mock?: {
|
|
||||||
exclude?: string[]
|
|
||||||
}
|
|
||||||
themeConfig?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
logo?: (string | boolean)
|
|
||||||
mode?: any
|
|
||||||
description?: string
|
|
||||||
locales?: string[][]
|
|
||||||
resolve?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
menus?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
navs?: (any[] | {
|
|
||||||
|
|
||||||
})
|
|
||||||
algolia?: {
|
|
||||||
appId?: string
|
|
||||||
apiKey?: string
|
|
||||||
indexName?: string
|
|
||||||
debug?: boolean
|
|
||||||
}
|
|
||||||
sitemap?: {
|
|
||||||
hostname?: string
|
|
||||||
excludes?: string[]
|
|
||||||
}
|
|
||||||
apiParser?: {
|
|
||||||
|
|
||||||
}
|
|
||||||
[k: string]: any
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import { plugin } from './plugin';
|
|
||||||
|
|
||||||
|
|
||||||
export const __mfsu = 1;
|
|
@ -1,4 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import 'core-js';
|
|
||||||
import 'regenerator-runtime/runtime';
|
|
||||||
export {};
|
|
@ -1,129 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import React from 'react';
|
|
||||||
import { ApplyPluginsType } from '/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/node_modules/_@umijs_runtime@3.5.41@@umijs/runtime';
|
|
||||||
import * as umiExports from './umiExports';
|
|
||||||
import { plugin } from './plugin';
|
|
||||||
|
|
||||||
export function getRoutes() {
|
|
||||||
const routes = [
|
|
||||||
{
|
|
||||||
"path": "/~demos/:uuid",
|
|
||||||
"layout": false,
|
|
||||||
"wrappers": [require('../dumi/layout').default],
|
|
||||||
"component": ((props) => {
|
|
||||||
const React = require('react');
|
|
||||||
const { default: getDemoRenderArgs } = require('/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/node_modules/_@umijs_preset-dumi@1.1.53@@umijs/preset-dumi/lib/plugins/features/demo/getDemoRenderArgs');
|
|
||||||
const { default: Previewer } = require('dumi-theme-default/es/builtins/Previewer.js');
|
|
||||||
const { usePrefersColor, context } = require('dumi/theme');
|
|
||||||
|
|
||||||
|
|
||||||
const { demos } = React.useContext(context);
|
|
||||||
const [renderArgs, setRenderArgs] = React.useState([]);
|
|
||||||
|
|
||||||
// update render args when props changed
|
|
||||||
React.useLayoutEffect(() => {
|
|
||||||
setRenderArgs(getDemoRenderArgs(props, demos));
|
|
||||||
}, [props.match.params.uuid, props.location.query.wrapper, props.location.query.capture]);
|
|
||||||
|
|
||||||
// for listen prefers-color-schema media change in demo single route
|
|
||||||
usePrefersColor();
|
|
||||||
|
|
||||||
switch (renderArgs.length) {
|
|
||||||
case 1:
|
|
||||||
// render demo directly
|
|
||||||
return renderArgs[0];
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
// render demo with previewer
|
|
||||||
return React.createElement(
|
|
||||||
Previewer,
|
|
||||||
renderArgs[0],
|
|
||||||
renderArgs[1],
|
|
||||||
);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return `Demo ${props.match.params.uuid} not found :(`;
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/_demos/:uuid",
|
|
||||||
"redirect": "/~demos/:uuid"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__dumiRoot": true,
|
|
||||||
"layout": false,
|
|
||||||
"path": "/",
|
|
||||||
"wrappers": [require('../dumi/layout').default, require('/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/node_modules/_dumi-theme-default@1.1.24@dumi-theme-default/es/layout.js').default],
|
|
||||||
"routes": [
|
|
||||||
{
|
|
||||||
"path": "/guide",
|
|
||||||
"component": require('/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/new/docs/guide.md').default,
|
|
||||||
"exact": true,
|
|
||||||
"meta": {
|
|
||||||
"filePath": "docs/guide.md",
|
|
||||||
"updatedTime": 1698630719271,
|
|
||||||
"slugs": [],
|
|
||||||
"title": "Guide"
|
|
||||||
},
|
|
||||||
"title": "Guide - nicenote"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/",
|
|
||||||
"component": require('/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/new/docs/index.md').default,
|
|
||||||
"exact": true,
|
|
||||||
"meta": {
|
|
||||||
"filePath": "docs/index.md",
|
|
||||||
"updatedTime": 1698630719273,
|
|
||||||
"title": "A static site based on dumi",
|
|
||||||
"hero": {
|
|
||||||
"title": "Site",
|
|
||||||
"description": "nicenote,nicecode,学习,总结",
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"text": "Hello",
|
|
||||||
"link": "/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "World",
|
|
||||||
"link": "/"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"features": [
|
|
||||||
{
|
|
||||||
"title": "Hello",
|
|
||||||
"emoji": "💎",
|
|
||||||
"description": "Put hello description here"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "World",
|
|
||||||
"emoji": "🌈",
|
|
||||||
"description": "Put world description here"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "!",
|
|
||||||
"emoji": "🚀",
|
|
||||||
"description": "Put ! description here"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"slugs": []
|
|
||||||
},
|
|
||||||
"title": "A static site based on dumi - nicenote"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "nicenote",
|
|
||||||
"component": (props) => props.children
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
// allow user to extend routes
|
|
||||||
plugin.applyPlugins({
|
|
||||||
key: 'patchRoutes',
|
|
||||||
type: ApplyPluginsType.event,
|
|
||||||
args: { routes },
|
|
||||||
});
|
|
||||||
|
|
||||||
return routes;
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
export { history } from './history';
|
|
||||||
export { plugin } from './plugin';
|
|
@ -1 +0,0 @@
|
|||||||
{}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"menus": {
|
|
||||||
"en-US": {
|
|
||||||
"*": [
|
|
||||||
{
|
|
||||||
"path": "/",
|
|
||||||
"title": "A static site based on dumi",
|
|
||||||
"meta": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/guide",
|
|
||||||
"title": "Guide",
|
|
||||||
"meta": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"locales": [
|
|
||||||
{
|
|
||||||
"name": "en-US",
|
|
||||||
"label": "English"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"navs": {},
|
|
||||||
"title": "nicenote",
|
|
||||||
"mode": "doc",
|
|
||||||
"repository": {
|
|
||||||
"url": "",
|
|
||||||
"branch": "master"
|
|
||||||
},
|
|
||||||
"theme": {}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import React from 'react';
|
|
||||||
import { dynamic } from 'dumi';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
};
|
|
@ -1,8 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import React from 'react';
|
|
||||||
import config from '@@/dumi/config';
|
|
||||||
import demos from '@@/dumi/demos';
|
|
||||||
import apis from '@@/dumi/apis';
|
|
||||||
import Layout from '/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/node_modules/_@umijs_preset-dumi@1.1.53@@umijs/preset-dumi/lib/theme/layout';
|
|
||||||
|
|
||||||
export default (props) => <Layout {...props} config={config} demos={demos} apis={apis} />;
|
|
58
.umi/umi.ts
@ -1,58 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import './core/polyfill';
|
|
||||||
import '@@/core/devScripts';
|
|
||||||
import { plugin } from './core/plugin';
|
|
||||||
import './core/pluginRegister';
|
|
||||||
import { createHistory } from './core/history';
|
|
||||||
import { ApplyPluginsType } from '/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/node_modules/_@umijs_runtime@3.5.41@@umijs/runtime';
|
|
||||||
import { renderClient } from '/Users/teddyj/Library/Mobile Documents/com~apple~CloudDocs/Documents/workspace/dev/nicenote/node_modules/_@umijs_renderer-react@3.5.41@@umijs/renderer-react/dist/index.js';
|
|
||||||
import { getRoutes } from './core/routes';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const getClientRender = (args: { hot?: boolean; routes?: any[] } = {}) => plugin.applyPlugins({
|
|
||||||
key: 'render',
|
|
||||||
type: ApplyPluginsType.compose,
|
|
||||||
initialValue: () => {
|
|
||||||
const opts = plugin.applyPlugins({
|
|
||||||
key: 'modifyClientRenderOpts',
|
|
||||||
type: ApplyPluginsType.modify,
|
|
||||||
initialValue: {
|
|
||||||
routes: args.routes || getRoutes(),
|
|
||||||
plugin,
|
|
||||||
history: createHistory(args.hot),
|
|
||||||
isServer: process.env.__IS_SERVER,
|
|
||||||
rootElement: 'root',
|
|
||||||
defaultTitle: ``,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return renderClient(opts);
|
|
||||||
},
|
|
||||||
args,
|
|
||||||
});
|
|
||||||
|
|
||||||
const clientRender = getClientRender();
|
|
||||||
export default clientRender();
|
|
||||||
|
|
||||||
|
|
||||||
window.g_umi = {
|
|
||||||
version: '3.5.41',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// hot module replacement
|
|
||||||
// @ts-ignore
|
|
||||||
if (module.hot) {
|
|
||||||
// @ts-ignore
|
|
||||||
module.hot.accept('./core/routes', () => {
|
|
||||||
const ret = require('./core/routes');
|
|
||||||
if (ret.then) {
|
|
||||||
ret.then(({ getRoutes }) => {
|
|
||||||
getClientRender({ hot: true, routes: getRoutes() })();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
getClientRender({ hot: true, routes: ret.getRoutes() })();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
52
CHANGELOG.md
@ -2,34 +2,30 @@
|
|||||||
|
|
||||||
### 🌟 新功能
|
### 🌟 新功能
|
||||||
|
|
||||||
* 初始化项目 ([466dbeb](https://github.com/j710328466/j710328466.github.io/commit/466dbeb))
|
- 初始化项目 ([466dbeb](https://github.com/j710328466/j710328466.github.io/commit/466dbeb))
|
||||||
* 新增模块 ([9e0b3a9](https://github.com/j710328466/j710328466.github.io/commit/9e0b3a9))
|
- 新增模块 ([9e0b3a9](https://github.com/j710328466/j710328466.github.io/commit/9e0b3a9))
|
||||||
* 新增心跳组件 ([82a59b4](https://github.com/j710328466/j710328466.github.io/commit/82a59b4))
|
- 新增心跳组件 ([82a59b4](https://github.com/j710328466/j710328466.github.io/commit/82a59b4))
|
||||||
* 修改tools,git命令 ([efb8285](https://github.com/j710328466/j710328466.github.io/commit/efb8285))
|
- 修改 tools,git 命令 ([efb8285](https://github.com/j710328466/j710328466.github.io/commit/efb8285))
|
||||||
* **docs:** 新增文章 ([f659605](https://github.com/j710328466/j710328466.github.io/commit/f659605))
|
- **docs:** 新增文章 ([f659605](https://github.com/j710328466/j710328466.github.io/commit/f659605))
|
||||||
* **fea/vue:** 新增vue教程文档 ([d150264](https://github.com/j710328466/j710328466.github.io/commit/d150264))
|
- **fea/vue:** 新增 vue 教程文档 ([d150264](https://github.com/j710328466/j710328466.github.io/commit/d150264))
|
||||||
* **fea:** typescript ([abb3cfe](https://github.com/j710328466/j710328466.github.io/commit/abb3cfe))
|
- **fea:** typescript ([abb3cfe](https://github.com/j710328466/j710328466.github.io/commit/abb3cfe))
|
||||||
* **md:** 新文章 ([41459c4](https://github.com/j710328466/j710328466.github.io/commit/41459c4))
|
- **md:** 新文章 ([41459c4](https://github.com/j710328466/j710328466.github.io/commit/41459c4))
|
||||||
* **package.json:** 添加husky ([95a0051](https://github.com/j710328466/j710328466.github.io/commit/95a0051))
|
- **package.json:** 添加 husky ([95a0051](https://github.com/j710328466/j710328466.github.io/commit/95a0051))
|
||||||
* **resume:** 修改简历 ([9f28c78](https://github.com/j710328466/j710328466.github.io/commit/9f28c78))
|
- **resume:** 修改简历 ([9f28c78](https://github.com/j710328466/j710328466.github.io/commit/9f28c78))
|
||||||
* svg学习笔记 ([63e96b7](https://github.com/j710328466/j710328466.github.io/commit/63e96b7))
|
- svg 学习笔记 ([63e96b7](https://github.com/j710328466/j710328466.github.io/commit/63e96b7))
|
||||||
|
|
||||||
|
|
||||||
### 🐛 Bug 修复
|
### 🐛 Bug 修复
|
||||||
|
|
||||||
* **工具类:** lerna QA ([dbb0c36](https://github.com/j710328466/j710328466.github.io/commit/dbb0c36))
|
- **工具类:** lerna QA ([dbb0c36](https://github.com/j710328466/j710328466.github.io/commit/dbb0c36))
|
||||||
* 设计模式添加 ([79143a6](https://github.com/j710328466/j710328466.github.io/commit/79143a6))
|
- 设计模式添加 ([79143a6](https://github.com/j710328466/j710328466.github.io/commit/79143a6))
|
||||||
* 新增react学习 ([a7ec84e](https://github.com/j710328466/j710328466.github.io/commit/a7ec84e))
|
- 新增 react 学习 ([a7ec84e](https://github.com/j710328466/j710328466.github.io/commit/a7ec84e))
|
||||||
* 修改路径 ([2261dc4](https://github.com/j710328466/j710328466.github.io/commit/2261dc4))
|
- 修改路径 ([2261dc4](https://github.com/j710328466/j710328466.github.io/commit/2261dc4))
|
||||||
* 修改配置 ([bfd5f0f](https://github.com/j710328466/j710328466.github.io/commit/bfd5f0f))
|
- 修改配置 ([bfd5f0f](https://github.com/j710328466/j710328466.github.io/commit/bfd5f0f))
|
||||||
* 修改设计模式 ([6f5630d](https://github.com/j710328466/j710328466.github.io/commit/6f5630d))
|
- 修改设计模式 ([6f5630d](https://github.com/j710328466/j710328466.github.io/commit/6f5630d))
|
||||||
* 修改bug ([83e7ea9](https://github.com/j710328466/j710328466.github.io/commit/83e7ea9))
|
- 修改 bug ([83e7ea9](https://github.com/j710328466/j710328466.github.io/commit/83e7ea9))
|
||||||
* 优化react 设计模式 ([cf4958e](https://github.com/j710328466/j710328466.github.io/commit/cf4958e))
|
- 优化 react 设计模式 ([cf4958e](https://github.com/j710328466/j710328466.github.io/commit/cf4958e))
|
||||||
* **fed/vue:** 新增内容 ([07f15ba](https://github.com/j710328466/j710328466.github.io/commit/07f15ba))
|
- **fed/vue:** 新增内容 ([07f15ba](https://github.com/j710328466/j710328466.github.io/commit/07f15ba))
|
||||||
* **resume:** 新增简历 ([f40ea2e](https://github.com/j710328466/j710328466.github.io/commit/f40ea2e))
|
- **resume:** 新增简历 ([f40ea2e](https://github.com/j710328466/j710328466.github.io/commit/f40ea2e))
|
||||||
* **resume:** 修改简历 ([aa7715c](https://github.com/j710328466/j710328466.github.io/commit/aa7715c))
|
- **resume:** 修改简历 ([aa7715c](https://github.com/j710328466/j710328466.github.io/commit/aa7715c))
|
||||||
* **resume:** 修改简历 ([3e498ff](https://github.com/j710328466/j710328466.github.io/commit/3e498ff))
|
- **resume:** 修改简历 ([3e498ff](https://github.com/j710328466/j710328466.github.io/commit/3e498ff))
|
||||||
* **sd:** sd ([e7d434d](https://github.com/j710328466/j710328466.github.io/commit/e7d434d))
|
- **sd:** sd ([e7d434d](https://github.com/j710328466/j710328466.github.io/commit/e7d434d))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,3 +159,4 @@ class Car implements Alarm, Light {
|
|||||||
1. [Type Search](https://www.typescriptlang.org/dt/search?search=)
|
1. [Type Search](https://www.typescriptlang.org/dt/search?search=)
|
||||||
2. [quick Type:自动生成 Type](https://app.quicktype.io)
|
2. [quick Type:自动生成 Type](https://app.quicktype.io)
|
||||||
3. [ts playground: 线上编写测试代码](https://www.typescriptlang.org/zh/play)
|
3. [ts playground: 线上编写测试代码](https://www.typescriptlang.org/zh/play)
|
||||||
|
4. [tsconfig 参数解释](https://segmentfault.com/a/1190000021749847)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
title: A static site based on dumi
|
title: Nice Note
|
||||||
hero:
|
hero:
|
||||||
title: Nice Note
|
title: Nice Note
|
||||||
description: dev 的学习博客
|
description: dev 的博客
|
||||||
actions:
|
actions:
|
||||||
- text: 开始学习
|
- text: 开始学习
|
||||||
link: /fea/website
|
link: /fea/website
|
||||||
@ -12,6 +12,8 @@ features:
|
|||||||
description: <a href="https://nicecoders.github.io">前端工具合集</a>
|
description: <a href="https://nicecoders.github.io">前端工具合集</a>
|
||||||
---
|
---
|
||||||
|
|
||||||
这是我用来记录我的职业生涯总结的各种乱七八糟的知识点,希望能对你有帮助
|
这里记录了我所有工作中和非工作中的思考和总结
|
||||||
|
|
||||||
|
思维比较发散,想到哪写到哪
|
||||||
|
|
||||||
<embed src="../CHANGELOG.md"></embed>
|
<embed src="../CHANGELOG.md"></embed>
|
||||||
|
@ -17,11 +17,13 @@ group:
|
|||||||
#### 确认网络
|
#### 确认网络
|
||||||
|
|
||||||
- ping [j710328466.github.io](j710328466.github.io)
|
- ping [j710328466.github.io](j710328466.github.io)
|
||||||
|
|
||||||
#### 关闭 iptables 规则
|
#### 关闭 iptables 规则
|
||||||
|
|
||||||
- iptables -L 查看
|
- iptables -L 查看
|
||||||
- iptables -F 关闭
|
- iptables -F 关闭
|
||||||
- iptables -t nat -L
|
- iptables -t nat -L
|
||||||
|
|
||||||
#### 关闭 getenforce
|
#### 关闭 getenforce
|
||||||
|
|
||||||
- setenforce 0
|
- setenforce 0
|
||||||
@ -37,6 +39,9 @@ group:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 安装编译工具和库
|
### 安装编译工具和库
|
||||||
|
|
||||||
|
如果没有再安装
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// 1
|
// 1
|
||||||
wget [http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz](http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz)
|
wget [http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz](http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz)
|
||||||
@ -52,16 +57,30 @@ yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
|
|||||||
- yum -y update
|
- yum -y update
|
||||||
|
|
||||||
### centos 快速安装
|
### centos 快速安装
|
||||||
|
|
||||||
- yum install nginx -y
|
- yum install nginx -y
|
||||||
|
|
||||||
|
## 默认文件位置
|
||||||
|
|
||||||
|
```js
|
||||||
|
/etc/nginx/nginx.conf //yum方式安装后默认配置文件的路径
|
||||||
|
|
||||||
|
/usr/share/nginx/html //nginx网站默认存放目录
|
||||||
|
|
||||||
|
/usr/share/nginx/html/index.html //网站默认主页路径
|
||||||
|
```
|
||||||
|
|
||||||
## 常用命令
|
## 常用命令
|
||||||
|
|
||||||
### 查看 nginx 配置文件路径和安装路径
|
### 查看 nginx 配置文件路径和安装路径
|
||||||
|
|
||||||
> nginx -t
|
> nginx -t
|
||||||
|
|
||||||
### 开始
|
### 开始
|
||||||
|
|
||||||
systemctl start nginx
|
方法 1. systemctl start nginx
|
||||||
|
|
||||||
|
方法 2. systemctl enable --now nginx
|
||||||
|
|
||||||
### 重启
|
### 重启
|
||||||
|
|
||||||
@ -73,10 +92,9 @@ systemctl start nginx
|
|||||||
> killall -9 nginx
|
> killall -9 nginx
|
||||||
|
|
||||||
### 初始目录
|
### 初始目录
|
||||||
|
|
||||||
> /usr/share/nginx/html
|
> /usr/share/nginx/html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 配置文件
|
### 配置文件
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -185,6 +203,7 @@ http {
|
|||||||
## Q&A
|
## Q&A
|
||||||
|
|
||||||
### 1. forbedden 403
|
### 1. forbedden 403
|
||||||
|
|
||||||
> chmod -R 777 /data
|
> chmod -R 777 /data
|
||||||
> chmod -R 777 /data/www
|
> chmod -R 777 /data/www
|
||||||
|
|
||||||
@ -195,5 +214,3 @@ vi /etc/selinux/config
|
|||||||
#SELINUX=enforcing
|
#SELINUX=enforcing
|
||||||
SELINUX=disabled
|
SELINUX=disabled
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "dumi build",
|
"build": "dumi build",
|
||||||
"deploy": "npm run build && gh-pages -d docs-dist",
|
"deploy": "gh-pages -d docs-dist",
|
||||||
"dev": "dumi dev",
|
"dev": "dumi dev",
|
||||||
"prepare": "husky install && dumi setup",
|
"prepare": "husky install && dumi setup",
|
||||||
"start": "npm run dev"
|
"start": "npm run dev"
|
||||||
@ -27,6 +27,7 @@
|
|||||||
"@commitlint/cli": "^17.1.2",
|
"@commitlint/cli": "^17.1.2",
|
||||||
"@commitlint/config-conventional": "^17.1.0",
|
"@commitlint/config-conventional": "^17.1.0",
|
||||||
"dumi": "^2.2.13",
|
"dumi": "^2.2.13",
|
||||||
|
"gh-pages": "^6.1.1",
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.1",
|
||||||
"lint-staged": "^13.0.3",
|
"lint-staged": "^13.0.3",
|
||||||
"prettier": "^2.7.1"
|
"prettier": "^2.7.1"
|
||||||
|
15898
pnpm-lock.yaml
@ -1,94 +0,0 @@
|
|||||||
|
|
||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const clockRef = useRef()
|
|
||||||
|
|
||||||
function clock() {
|
|
||||||
var theCanv = clockRef.current;
|
|
||||||
var theCanvObject = theCanv.getContext('2d');
|
|
||||||
var x = 200;
|
|
||||||
var y = 200;
|
|
||||||
|
|
||||||
startTime();
|
|
||||||
|
|
||||||
function startTime() {
|
|
||||||
|
|
||||||
//分秒刻度和表盘
|
|
||||||
theCanvObject.lineWidth = 1;
|
|
||||||
for (var i = 0; i < 60; i++) {
|
|
||||||
drawArc(150, i*6, (i+1)*6);
|
|
||||||
}
|
|
||||||
drawArc(145, 0, 360, true);
|
|
||||||
|
|
||||||
//时刻度
|
|
||||||
theCanvObject.lineWidth = 2;
|
|
||||||
for (var i = 0; i < 12; i++) {
|
|
||||||
drawArc(150, i*30, (i+1)*30);
|
|
||||||
}
|
|
||||||
drawArc(140, 0, 360, true);
|
|
||||||
|
|
||||||
//针
|
|
||||||
drawHand(getTime().hour,5,60,'#ECFC00');
|
|
||||||
drawHand(getTime().min,4,100,'#00BB3F');
|
|
||||||
drawHand(getTime().sec,3,130,'#D60062');
|
|
||||||
|
|
||||||
setInterval(function () {
|
|
||||||
drawArc(135,0,360,true);
|
|
||||||
drawHand(getTime().hour,5,60,'#ECFC00');
|
|
||||||
drawHand(getTime().min,4,100,'#00BB3F');
|
|
||||||
drawHand(getTime().sec,3,130,'#D60062');
|
|
||||||
},1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawArc(iRadius, iBeginAngle, iEndAngle, ifClear) {
|
|
||||||
var beginRadian = iBeginAngle*Math.PI/180;
|
|
||||||
var endRadian = iEndAngle*Math.PI/180;
|
|
||||||
|
|
||||||
theCanvObject.beginPath(); //创建一个路径
|
|
||||||
theCanvObject.moveTo(x, y); //将路径移到x,y
|
|
||||||
theCanvObject.arc(x, y, iRadius, beginRadian, endRadian, false);
|
|
||||||
//画弧
|
|
||||||
!ifClear && theCanvObject.stroke();
|
|
||||||
|
|
||||||
if (ifClear) {
|
|
||||||
theCanvObject.fillStyle = 'white';
|
|
||||||
theCanvObject.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function drawHand(iAngle, iWidth, iLength, iColor) {
|
|
||||||
|
|
||||||
theCanvObject.save(); //保存的是canvas的属性,不是截图
|
|
||||||
theCanvObject.lineWidth = iWidth;
|
|
||||||
theCanvObject.strokeStyle = iColor;
|
|
||||||
drawArc(iLength, iAngle, iAngle);
|
|
||||||
theCanvObject.restore(); //弹出栈中的状态
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//根据当前时间返回各个针要指的度数
|
|
||||||
function getTime() {
|
|
||||||
|
|
||||||
var jTime = {};
|
|
||||||
var iNow = new Date();
|
|
||||||
jTime.sec = -90 + iNow.getSeconds()*6;
|
|
||||||
jTime.min = -90 + iNow.getMinutes()*6 + iNow.getSeconds()/20;
|
|
||||||
jTime.hour = -90 + iNow.getHours()*30 + iNow.getMinutes()/2;
|
|
||||||
|
|
||||||
return jTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
clock()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<canvas ref={clockRef} width="600" height="600" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const canvasRef = useRef()
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
var c = canvasRef.current,
|
|
||||||
$ = c.getContext('2d'),
|
|
||||||
w = c.width = window.innerWidth / 2,
|
|
||||||
h = c.height = window.innerHeight / 2,
|
|
||||||
particles = []
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 随机获取颜色
|
|
||||||
*
|
|
||||||
* @returns rgb(x,x,x)
|
|
||||||
*/
|
|
||||||
function randomColor() {
|
|
||||||
var r = 100 + Math.floor(Math.random() * 255),
|
|
||||||
g = Math.floor(Math.random() * 150),
|
|
||||||
b = Math.floor(Math.random() * 15)
|
|
||||||
return 'rgb(' + r + ',' + g + ',' + b + ')'
|
|
||||||
}
|
|
||||||
|
|
||||||
function particle() {
|
|
||||||
this.location = {
|
|
||||||
x: w / 2,
|
|
||||||
y: h / 2
|
|
||||||
}
|
|
||||||
this.speed = {
|
|
||||||
x: -1.5 + Math.random() * 3,
|
|
||||||
y: 1 + Math.random() * 5.5
|
|
||||||
}
|
|
||||||
this.life = 50
|
|
||||||
this.radius = 1 + Math.floor(Math.random() * 25)
|
|
||||||
this.color = randomColor()
|
|
||||||
this.opacity = 1
|
|
||||||
this.dead = false
|
|
||||||
this.draw = function () {
|
|
||||||
$.globalCompositeOperation = 'lighter'
|
|
||||||
$.fillStyle = this.color
|
|
||||||
$.beginPath()
|
|
||||||
$.arc(this.location.x, this.location.y, this.radius, 0, Math.PI * 2)
|
|
||||||
$.globalAlpha = this.opacity
|
|
||||||
$.fill()
|
|
||||||
$.closePath()
|
|
||||||
}
|
|
||||||
this.update = function () {
|
|
||||||
if (this.location.x < 0 || this.life == 0 || this.opacity === 0 || this.radius < 1) {
|
|
||||||
this.dead = true
|
|
||||||
}
|
|
||||||
if (!this.dead) {
|
|
||||||
this.location.x += this.speed.x
|
|
||||||
this.location.y -= this.speed.y
|
|
||||||
this.life--
|
|
||||||
this.opacity -= 0.05
|
|
||||||
this.radius--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将火焰置于背景之后
|
|
||||||
function stage() {
|
|
||||||
$.globalCompositeOperation = 'source-over'
|
|
||||||
$.fillStyle = 'rgba(0, 0, 0, 1)'
|
|
||||||
$.fillRect(0, 0, w, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重置画布大小
|
|
||||||
function reset() {
|
|
||||||
w = c.width = window.innerWidth / 2
|
|
||||||
h = c.height = window.innerHeight / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
function loop() {
|
|
||||||
stage()
|
|
||||||
var L = particles.length
|
|
||||||
if (L < 100) {
|
|
||||||
particles.push(new particle())
|
|
||||||
}
|
|
||||||
for (var i = 0; i < L; i++) {
|
|
||||||
var p = particles[i]
|
|
||||||
p.draw()
|
|
||||||
p.update()
|
|
||||||
if (p.dead) {
|
|
||||||
particles[i] = new particle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requestAnimationFrame(loop)
|
|
||||||
}
|
|
||||||
|
|
||||||
function _init() {
|
|
||||||
reset()
|
|
||||||
loop()
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('resize', reset)
|
|
||||||
_init()
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
init()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<canvas ref={canvasRef} width="200" height="200" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
Before Width: | Height: | Size: 166 KiB |
Before Width: | Height: | Size: 150 KiB |
@ -1,118 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
const img1 = require('./img/clipImg1.jpg')
|
|
||||||
const img2 = require('./img/clipImg2.jpg')
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const canvasRef = useRef()
|
|
||||||
const clipImgs1Ref = useRef()
|
|
||||||
const clipImgs2Ref = useRef()
|
|
||||||
|
|
||||||
|
|
||||||
function clipPathMaskRender() {
|
|
||||||
const NUM_CIRCLES = 60
|
|
||||||
const MIN_SIZE = 50
|
|
||||||
const MAX_SIZE = 100
|
|
||||||
|
|
||||||
function getRndInt(min, max) {
|
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min
|
|
||||||
}
|
|
||||||
|
|
||||||
var c = canvasRef && canvasRef.current
|
|
||||||
var ctx = c.getContext('2d')
|
|
||||||
var clipImg1 = clipImgs1Ref && clipImgs1Ref.current
|
|
||||||
var clipImg2 = clipImgs2Ref && clipImgs2Ref.current
|
|
||||||
var t
|
|
||||||
|
|
||||||
class Circle {
|
|
||||||
constructor() {
|
|
||||||
this.x = 0
|
|
||||||
this.y = 0
|
|
||||||
this.size = 0
|
|
||||||
this._needsRandomized = false
|
|
||||||
}
|
|
||||||
|
|
||||||
randomize () {
|
|
||||||
this.x = getRndInt(50, c.width - 50)
|
|
||||||
this.y = getRndInt(50, c.height - 50)
|
|
||||||
this.maxSize = getRndInt(MIN_SIZE, MAX_SIZE)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新
|
|
||||||
update (t, ofs) {
|
|
||||||
// abs 绝对值
|
|
||||||
this.size = Math.abs(Math.round(Math.sin(t + ofs) * this.maxSize))
|
|
||||||
|
|
||||||
if (this.size < 2) {
|
|
||||||
if (this._needsRandomized) {
|
|
||||||
this.randomize()
|
|
||||||
this._needsRandomized = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 画
|
|
||||||
draw () {
|
|
||||||
ctx.moveTo(this.x, this.y)
|
|
||||||
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var circles =[]
|
|
||||||
for (let i = 0; i < NUM_CIRCLES; i++) {
|
|
||||||
var circle = new Circle()
|
|
||||||
circle.randomize()
|
|
||||||
circles.push(circle)
|
|
||||||
}
|
|
||||||
|
|
||||||
function update() {
|
|
||||||
t = 0.001 * Date.now()
|
|
||||||
circles.forEach((circle, idx) => {
|
|
||||||
circle.update(t, idx)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async function render() {
|
|
||||||
await ctx.drawImage(clipImg1, 0, 0)
|
|
||||||
await ctx.save()
|
|
||||||
await ctx.beginPath()
|
|
||||||
|
|
||||||
circles.forEach(function(circle) {
|
|
||||||
circle.draw()
|
|
||||||
})
|
|
||||||
|
|
||||||
ctx.closePath()
|
|
||||||
ctx.clip()
|
|
||||||
|
|
||||||
ctx.drawImage(clipImg2, 0, 0)
|
|
||||||
ctx.restore()
|
|
||||||
}
|
|
||||||
|
|
||||||
function loop() {
|
|
||||||
requestAnimationFrame(loop)
|
|
||||||
update()
|
|
||||||
render()
|
|
||||||
}
|
|
||||||
|
|
||||||
loop()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
clipPathMaskRender()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="clipPathMask demo">
|
|
||||||
<div className="wrap">
|
|
||||||
<h1 className="wrap_tit">Nice Note</h1>
|
|
||||||
<canvas ref={canvasRef} className="wrap_canvas" width="500px" height="500px"></canvas>
|
|
||||||
</div>
|
|
||||||
<div id="clipImgs">
|
|
||||||
<img ref={clipImgs1Ref} id="clipImgs_1" crossOrigin="anonymous" src={img1} />
|
|
||||||
<img ref={clipImgs2Ref} id="clipImgs_2" crossOrigin="anonymous" src={img2} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
.clipPathMask {
|
|
||||||
text-align: center;
|
|
||||||
height: 80vh;
|
|
||||||
color: #fff;
|
|
||||||
background: teal linear-gradient(transparent, #ff0099);
|
|
||||||
.wrap {
|
|
||||||
&_tit {
|
|
||||||
padding: 10px 0;
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
&_canvas {
|
|
||||||
border: 1px solid yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#clipImgs {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const canvasRef = useRef()
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
const theCanvas = canvasRef.current,
|
|
||||||
ctx = theCanvas.getContext('2d'),
|
|
||||||
current_point = {
|
|
||||||
x: null, //当前鼠标x
|
|
||||||
y: null, //当前鼠标y
|
|
||||||
max: 20000,
|
|
||||||
};
|
|
||||||
|
|
||||||
let canvas_width = theCanvas.width,
|
|
||||||
canvas_height = theCanvas.height,
|
|
||||||
random_points = [],
|
|
||||||
all_points = [];
|
|
||||||
|
|
||||||
// theCanvas.style = "position: absolute; top: 0px; left: 0px;";
|
|
||||||
|
|
||||||
|
|
||||||
function draw() {
|
|
||||||
//清屏
|
|
||||||
ctx.clearRect(0, 0, canvas_width, canvas_height);
|
|
||||||
let i,pi,x_dist,y_dist,dist,w;
|
|
||||||
|
|
||||||
//遍历点集合绘制线条,类似于握手问题,两个点只绘制一条线
|
|
||||||
random_points.forEach((p, index) => {
|
|
||||||
p.x += p.xa, //按指定速度移动
|
|
||||||
p.y += p.ya,
|
|
||||||
//小球碰撞则速度取相反数
|
|
||||||
p.xa *= p.x > canvas_width || p.x < 0 ? -1 : 1,
|
|
||||||
p.ya *= p.y > canvas_height || p.y < 0 ? -1 : 1,
|
|
||||||
ctx.fillRect(p.x - 0.5, p.y - 0.5, 1, 1); //绘制点
|
|
||||||
|
|
||||||
for(i = index + 1; i < all_points.length; i++ ) {
|
|
||||||
pi = all_points[i];
|
|
||||||
if(pi.x !== null && pi.y !== null) {
|
|
||||||
x_dist = p.x - pi.x;
|
|
||||||
y_dist = p.y - pi.y;
|
|
||||||
dist = x_dist * x_dist + y_dist * y_dist;
|
|
||||||
//当两点距离小于极限距离时会产生连线,当第二个点是鼠标所产生点时,第一个点在范围内会产生向鼠标点的速度,产生吸附效果
|
|
||||||
dist < pi.max && (pi === current_point && dist >= pi.max / 2 && (p.x -= 0.03 * x_dist, p.y -= 0.03 * y_dist));
|
|
||||||
//根据距离计算连线的透明度,使过度效果流畅
|
|
||||||
w = (pi.max - dist) / pi.max;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.lineWidth = w / 2;
|
|
||||||
ctx.strokeStyle = `rgba(110,110,110,${w + 0.2})`;
|
|
||||||
ctx.moveTo(p.x, p.y);
|
|
||||||
ctx.lineTo(pi.x, pi.y);
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),requestAnimationFrame(draw);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//绑定事件,判断是否添加鼠标这个点
|
|
||||||
window.onmousemove = e => {
|
|
||||||
e = e || window.event;
|
|
||||||
current_point.x = e.clientX;
|
|
||||||
current_point.y = e.clientY;
|
|
||||||
};
|
|
||||||
window.onmouseout = () => {
|
|
||||||
current_point.x = null;
|
|
||||||
current_point.y = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//随机生成100个点
|
|
||||||
for(let i = 0; i < 100; i++ ) {
|
|
||||||
|
|
||||||
let x = Math.random() * canvas_width, //初始坐标
|
|
||||||
y = Math.random() * canvas_height,
|
|
||||||
xa = 2 * Math.random() - 1, //x速度
|
|
||||||
ya = 2 * Math.random() - 1, //y速度
|
|
||||||
max = 6000; //会产生连线的距离的平方
|
|
||||||
|
|
||||||
random_points[i] = {x, y, xa, ya, max};
|
|
||||||
}
|
|
||||||
//将鼠标的点添加至点集合中
|
|
||||||
all_points = [...random_points,current_point];
|
|
||||||
|
|
||||||
//只是背景特效-所以延迟执行
|
|
||||||
setTimeout(draw, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
init()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ position: 'relative' }}>
|
|
||||||
<canvas ref={canvasRef} width="500px" height="300px"></canvas>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 10 KiB |
@ -1,214 +0,0 @@
|
|||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
import img1 from './imgs/1.jpg'
|
|
||||||
import img2 from './imgs/2.jpg'
|
|
||||||
import img3 from './imgs/3.jpg'
|
|
||||||
|
|
||||||
const imgs = [img1, img2, img3]
|
|
||||||
class Particale {
|
|
||||||
constructor(opt) {
|
|
||||||
this.warp = opt.warp; //画布
|
|
||||||
this.ctx = opt.warp && opt.warp.getContext('2d');
|
|
||||||
this.imgsUrl = opt.imgsUrl; //图片地址数组
|
|
||||||
this.imgsObj = []; //图片对象数组
|
|
||||||
this.radius = opt.radius || 10; //粒子半径
|
|
||||||
this.index = 0; //当前图片下标
|
|
||||||
this.initz = 300;
|
|
||||||
this.dots = [];
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
|
|
||||||
//限制小球半径
|
|
||||||
if (this.warp.width > 500 || this.warp.height > 300)
|
|
||||||
this.radius >= 4 ? this.radius = this.radius : this.radius = 4;
|
|
||||||
else
|
|
||||||
this.radius >= 2 ? this.radius = this.radius : this.radius = 2;
|
|
||||||
|
|
||||||
let promiseArr = this.imgsUrl.map(imgUrl => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
var imgObj = new Image();
|
|
||||||
imgObj.onload = () => {
|
|
||||||
this.imgsObj.push(imgObj);
|
|
||||||
resolve();
|
|
||||||
};
|
|
||||||
imgObj.src = imgUrl;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
//图片全部加载完毕开始绘制
|
|
||||||
Promise.all(promiseArr).then(() => {
|
|
||||||
this.picLoop();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
picLoop() {
|
|
||||||
this.dots = [];
|
|
||||||
this.drawPic(); //绘制当前图片
|
|
||||||
this.toParticle(); //得到像素点
|
|
||||||
this.combineAnimate(); //合成图像
|
|
||||||
this.index === this.imgsUrl.length-1 ? this.index = 0 : this.index++; //下标移动到下一张图片
|
|
||||||
}
|
|
||||||
drawPic() {
|
|
||||||
//清除画布
|
|
||||||
this.ctx.clearRect(0, 0, this.warp.width, this.warp.height);
|
|
||||||
let imgObj = this.imgsObj[this.index];
|
|
||||||
|
|
||||||
//限制图片大小
|
|
||||||
if(imgObj.width > imgObj.height) {
|
|
||||||
let ImgScale = imgObj.height / imgObj.width;
|
|
||||||
imgObj.width = this.warp.width * .5;
|
|
||||||
imgObj.height = imgObj.width * ImgScale;
|
|
||||||
} else {
|
|
||||||
let ImgScale = imgObj.width / imgObj.height;
|
|
||||||
imgObj.height = this.warp.height * .7;
|
|
||||||
imgObj.width = imgObj.height * ImgScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//绘制图片到canvas
|
|
||||||
this.ctx.drawImage(imgObj, this.warp.width / 2 - imgObj.width / 2, this.warp.height / 2 - imgObj.height / 2, imgObj.width, imgObj.height);
|
|
||||||
|
|
||||||
}
|
|
||||||
toParticle() {
|
|
||||||
//得到像素
|
|
||||||
let imageData = this.ctx.getImageData(0, 0, this.warp.width, this.warp.height);
|
|
||||||
let data = imageData.data;
|
|
||||||
|
|
||||||
for(let x = 0; x < imageData.width; x += this.radius * 2) {
|
|
||||||
for(let y = 0; y < imageData.height; y += this.radius * 2) {
|
|
||||||
let i = (x + y * this.warp.width) * 4;
|
|
||||||
if(data[i+3] !== 0 && data[i] !== 255 && data[i+1] !== 255 && data[i+2] !== 255) {
|
|
||||||
let dot = {
|
|
||||||
x: x, //图片x轴坐标
|
|
||||||
y: y, // y轴坐标
|
|
||||||
z: 0, // z轴坐标
|
|
||||||
r: data[i], // rgba
|
|
||||||
g: data[i+1], // rgba
|
|
||||||
b: data[i+2], // rgba
|
|
||||||
a: 1, // rgba
|
|
||||||
ix: Math.random() * this.warp.width, //初始化x轴坐标
|
|
||||||
iy: Math.random() * this.warp.height, // y轴坐标
|
|
||||||
iz: Math.random() * this.initz * 2 - this.initz, // z轴坐标
|
|
||||||
ir: 255, // rgba
|
|
||||||
ig: 255, // rgba
|
|
||||||
ib: 255, // rgba
|
|
||||||
ia: 0, // rgba
|
|
||||||
tx: Math.random() * this.warp.width, //目标x轴坐标
|
|
||||||
ty: Math.random() * this.warp.height, // y轴坐标
|
|
||||||
tz: Math.random() * this.initz * 2 - this.initz, // z轴坐标
|
|
||||||
tr: 255, // rgba
|
|
||||||
tg: 255, // rgba
|
|
||||||
tb: 255, // rgba
|
|
||||||
ta: 0, // rgba
|
|
||||||
};
|
|
||||||
this.dots.push(dot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
combineAnimate() {
|
|
||||||
let combined = false;
|
|
||||||
this.ctx.clearRect(0, 0, this.warp.width, this.warp.height);
|
|
||||||
this.dots.map(dot => {
|
|
||||||
if (Math.abs(dot.ix - dot.x) < 0.1 && Math.abs(dot.iy - dot.y) < 0.1 && Math.abs(dot.iz - dot.z) < 0.1) {
|
|
||||||
dot.ix = dot.x;
|
|
||||||
dot.iy = dot.y;
|
|
||||||
dot.iz = dot.z;
|
|
||||||
dot.ir = dot.r;
|
|
||||||
dot.ig = dot.g;
|
|
||||||
dot.ib = dot.b;
|
|
||||||
dot.ia = dot.a;
|
|
||||||
combined = true;
|
|
||||||
} else {
|
|
||||||
dot.ix += (dot.x - dot.ix) * 0.07;
|
|
||||||
dot.iy += (dot.y - dot.iy) * 0.07;
|
|
||||||
dot.iz += (dot.z - dot.iz) * 0.07;
|
|
||||||
dot.ir += (dot.r - dot.ir) * 0.3;
|
|
||||||
dot.ig += (dot.g - dot.ig) * 0.3;
|
|
||||||
dot.ib += (dot.b - dot.ib) * 0.3;
|
|
||||||
dot.ia += (dot.a - dot.ia) * 0.1;
|
|
||||||
combined = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.drowDot(dot);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
if(!combined) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
return this.combineAnimate();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setTimeout(() => {
|
|
||||||
return this.separateAnimate();
|
|
||||||
}, 1500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
separateAnimate() {
|
|
||||||
let separated = false;
|
|
||||||
this.ctx.clearRect(0, 0, this.warp.width, this.warp.height);
|
|
||||||
this.dots.map(dot => {
|
|
||||||
if (Math.abs(dot.ix - dot.tx) < 0.1 && Math.abs(dot.iy - dot.ty) < 0.1 && Math.abs(dot.iz - dot.tz) < 0.1) {
|
|
||||||
dot.ix = dot.tx;
|
|
||||||
dot.iy = dot.ty;
|
|
||||||
dot.iz = dot.tz;
|
|
||||||
dot.ir = dot.tr;
|
|
||||||
dot.ig = dot.tg;
|
|
||||||
dot.ib = dot.tb;
|
|
||||||
dot.ia = dot.ta;
|
|
||||||
separated = true;
|
|
||||||
} else {
|
|
||||||
dot.ix += (dot.tx - dot.ix) * 0.07;
|
|
||||||
dot.iy += (dot.ty - dot.iy) * 0.07;
|
|
||||||
dot.iz += (dot.tz - dot.iz) * 0.07;
|
|
||||||
dot.ir += (dot.tr - dot.ir) * 0.02;
|
|
||||||
dot.ig += (dot.tg - dot.ig) * 0.02;
|
|
||||||
dot.ib += (dot.tb - dot.ib) * 0.02;
|
|
||||||
dot.ia += (dot.ta - dot.ia) * 0.03;
|
|
||||||
separated = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.drowDot(dot);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
if(!separated) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
return this.separateAnimate();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setTimeout(() => {
|
|
||||||
return this.picLoop(); //间接递归,使用尾递归优化
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
drowDot(dot) {
|
|
||||||
let scale = this.initz / (this.initz + dot.iz);
|
|
||||||
this.ctx.save();
|
|
||||||
this.ctx.beginPath();
|
|
||||||
this.ctx.fillStyle = `rgba(${Math.floor(dot.ir)}, ${Math.floor(dot.ig)}, ${Math.floor(dot.ib)}, ${dot.ia})`;
|
|
||||||
this.ctx.arc(this.warp.width / 2 + (dot.ix - this.warp.width / 2) * scale, this.warp.height / 2 + (dot.iy - this.warp.height / 2) * scale, this.radius * scale, 0, Math.PI * 2);
|
|
||||||
this.ctx.fill();
|
|
||||||
this.ctx.closePath();
|
|
||||||
this.ctx.restore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const canvasRef = useRef()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (canvasRef && canvasRef.current) {
|
|
||||||
new Particale({
|
|
||||||
warp: canvasRef && canvasRef.current,
|
|
||||||
imgsUrl: imgs,
|
|
||||||
radius: 1,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<canvas ref={canvasRef} width="500px" height="500px"></canvas>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const canvasRef = useRef()
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
var snake = [41, 40], //snake队列表示蛇身,初始节点存在但不显示
|
|
||||||
direction = 1, //1表示向右,-1表示向左,20表示向下,-20表示向上
|
|
||||||
food = 43, //食物的位置
|
|
||||||
n, //与下次移动的位置有关
|
|
||||||
box = canvasRef.current && canvasRef.current.getContext('2d');
|
|
||||||
//从0到399表示box里[0~19]*[0~19]的所有节点,每20px一个节点
|
|
||||||
|
|
||||||
function draw(seat, color) {
|
|
||||||
box.fillStyle = color;
|
|
||||||
box.fillRect(seat % 20 *20 + 1, ~~(seat / 20) * 20 + 1, 18, 18);
|
|
||||||
//用color填充一个矩形,以前两个参数为x,y坐标,后两个参数为宽和高。
|
|
||||||
}
|
|
||||||
|
|
||||||
document.onkeydown = function(evt) { //当键盘上下左右键摁下的时候改变direction
|
|
||||||
direction = snake[1] - snake[0] == (n = [-1, -20, 1, 20][(evt || event).keyCode - 37] || direction) ? direction : n;
|
|
||||||
console.log([-1, -20, 1, 20][(evt || event).keyCode - 37]);
|
|
||||||
};
|
|
||||||
|
|
||||||
function _move() {
|
|
||||||
snake.unshift(n = snake[0] + direction); //此时的n为下次蛇头出现的位置,n进入队列
|
|
||||||
if(snake.indexOf(n, 1) > 0 || n < 0 || n > 399 || direction == 1 && n % 20 == 0 || direction == -1 && n % 20 == 19) {
|
|
||||||
//if语句判断贪吃蛇是否撞到自己或者墙壁,碰到时返回,结束程序
|
|
||||||
return alert("GAME OVER!");
|
|
||||||
}
|
|
||||||
draw(n, "lime"); //画出蛇头下次出现的位置
|
|
||||||
if(n == food) { //如果吃到食物时,产生一个蛇身以外的随机的点,不会去掉蛇尾
|
|
||||||
while (snake.indexOf(food = ~~(Math.random() * 400)) > 0);
|
|
||||||
draw(food, "yellow");
|
|
||||||
} else { //没有吃到食物时正常移动,蛇尾出队列
|
|
||||||
draw(snake.pop(),"black");
|
|
||||||
}
|
|
||||||
setTimeout(() => _move(), 150); //每隔0.15秒执行函数一次,可以调节蛇的速度
|
|
||||||
}
|
|
||||||
|
|
||||||
box && await _move()
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ background: '#000' }}>
|
|
||||||
<button type="button" onClick={() => init()} >开始</button>
|
|
||||||
<canvas ref={canvasRef} width="400" height="400" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,562 +0,0 @@
|
|||||||
---
|
|
||||||
nav:
|
|
||||||
title: FC
|
|
||||||
path: /funny
|
|
||||||
group:
|
|
||||||
title: canvas
|
|
||||||
order: 4
|
|
||||||
path: /canvas
|
|
||||||
---
|
|
||||||
|
|
||||||
# canvas
|
|
||||||
|
|
||||||
### 粒子背景
|
|
||||||
|
|
||||||
<code src="./demos/ParticleBG/index.jsx" ></code>
|
|
||||||
|
|
||||||
### 粒子图片
|
|
||||||
|
|
||||||
<code src="./demos/ParticleIMG/index.jsx" ></code>
|
|
||||||
|
|
||||||
### 贪吃蛇
|
|
||||||
|
|
||||||
<code src="./demos/Snake/index.jsx" ></code>
|
|
||||||
|
|
||||||
### 液体海报
|
|
||||||
|
|
||||||
<code src="./demos/LiquidPost/index.jsx" ></code>
|
|
||||||
|
|
||||||
### 大转盘(doing)
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
class Global {
|
|
||||||
constructor () {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否为 PC 端,若是则返回 true,否则返回 flase
|
|
||||||
*/
|
|
||||||
IsPC() {
|
|
||||||
let userAgentInfo = navigator.userAgent,
|
|
||||||
flag = true,
|
|
||||||
Agents = ["Android", "iPhone","SymbianOS", "Windows Phone","iPad", "iPod"];
|
|
||||||
|
|
||||||
for (let v = 0; v < Agents.length; v++) {
|
|
||||||
if (userAgentInfo.indexOf(Agents[v]) > 0) {
|
|
||||||
flag = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flag;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓动函数,由快到慢
|
|
||||||
* @param {Num} t 当前时间
|
|
||||||
* @param {Num} b 初始值
|
|
||||||
* @param {Num} c 变化值
|
|
||||||
* @param {Num} d 持续时间
|
|
||||||
*/
|
|
||||||
easeOut(t, b, c, d) {
|
|
||||||
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
|
|
||||||
return -c / 2 * ((--t) * (t - 2) - 1) + b;
|
|
||||||
};
|
|
||||||
|
|
||||||
windowToCanvas(canvas, e) {
|
|
||||||
let bbox = canvas.getBoundingClientRect(),
|
|
||||||
x = this.IsPC() ? e.clientX || event.clientX : e.changedTouches[0].clientX,
|
|
||||||
y = this.IsPC() ? e.clientY || event.clientY : e.changedTouches[0].clientY;
|
|
||||||
|
|
||||||
return {
|
|
||||||
x: x - bbox.left,
|
|
||||||
y: y - bbox.top
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绘制自动换行的文本
|
|
||||||
* @param {Obj} context
|
|
||||||
* @param {Str} t 文本内容
|
|
||||||
* @param {Num} x 坐标
|
|
||||||
* @param {Num} y 坐标
|
|
||||||
* @param {Num} w 文本限制宽度
|
|
||||||
* @param {Num} lineHeight 行高
|
|
||||||
*/
|
|
||||||
drawText(context, t, x, y, w, lineHeight = 20){
|
|
||||||
let chr = t.split(''),
|
|
||||||
temp = '',
|
|
||||||
row = [];
|
|
||||||
|
|
||||||
for (let a = 0; a < chr.length; a++){
|
|
||||||
if ( context.measureText(temp).width < w ) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
row.push(temp);
|
|
||||||
temp = '';
|
|
||||||
}
|
|
||||||
temp += chr[a];
|
|
||||||
};
|
|
||||||
|
|
||||||
row.push(temp);
|
|
||||||
|
|
||||||
for(let b = 0; b < row.length; b++){
|
|
||||||
context.fillText(row[b], x, y + (b + 1) * lineHeight);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定义圆角矩形的方法
|
|
||||||
* @param {Obj} context
|
|
||||||
* @param {Num} cornerX
|
|
||||||
* @param {Num} cornerY
|
|
||||||
* @param {Num} width
|
|
||||||
* @param {Num} height
|
|
||||||
* @param {Num} cornerRadius
|
|
||||||
*/
|
|
||||||
roundedRect(context, cornerX, cornerY, width, height, cornerRadius) {
|
|
||||||
if (width > 0) context.moveTo(cornerX + cornerRadius, cornerY);
|
|
||||||
else context.moveTo(cornerX - cornerRadius, cornerY);
|
|
||||||
|
|
||||||
context.arcTo(cornerX + width, cornerY,
|
|
||||||
cornerX + width, cornerY + height,
|
|
||||||
cornerRadius);
|
|
||||||
|
|
||||||
context.arcTo(cornerX + width, cornerY + height,
|
|
||||||
cornerX, cornerY + height,
|
|
||||||
cornerRadius);
|
|
||||||
|
|
||||||
context.arcTo(cornerX, cornerY + height,
|
|
||||||
cornerX, cornerY,
|
|
||||||
cornerRadius);
|
|
||||||
|
|
||||||
if (width > 0) {
|
|
||||||
context.arcTo(cornerX, cornerY,
|
|
||||||
cornerX + cornerRadius, cornerY,
|
|
||||||
cornerRadius);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
context.arcTo(cornerX, cornerY,
|
|
||||||
cornerX - cornerRadius, cornerY,
|
|
||||||
cornerRadius);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RouletteWheel extends Global{
|
|
||||||
constructor(params) {
|
|
||||||
super()
|
|
||||||
this.width = params.width
|
|
||||||
this.height = params.height
|
|
||||||
|
|
||||||
this.centerX = params.centerX
|
|
||||||
this.centerY = params.centerY
|
|
||||||
this.outsideRadius = params.outsideRadius
|
|
||||||
|
|
||||||
this.evenColor = params.evenColor
|
|
||||||
this.oddColor = params.oddColor
|
|
||||||
this.loseColor = params.odd
|
|
||||||
this.textColor = params.textColor
|
|
||||||
|
|
||||||
this.awards = params.awards || []
|
|
||||||
|
|
||||||
this.startRadian = params.startRadian || 0
|
|
||||||
this.duration = params.duration || 4000
|
|
||||||
this.velocity = params.velocity || 10
|
|
||||||
|
|
||||||
// 回调函数
|
|
||||||
this.finish = params.finish
|
|
||||||
}
|
|
||||||
|
|
||||||
initCanvas() {
|
|
||||||
let canvas = this.canvas
|
|
||||||
canvas.width = this.width;
|
|
||||||
canvas.height = this.height;
|
|
||||||
let ctx = canvas.getContext('2d')
|
|
||||||
|
|
||||||
for (let i = 0; i < this.awards.length; i++) {
|
|
||||||
// const award = awards[i]
|
|
||||||
let _startR = this.startRadian + this.awardRadian * i
|
|
||||||
let _endR = _startR + this.awardRadian
|
|
||||||
|
|
||||||
if (i % 2 === 0) ctx.fillStyle = "#FF6766"
|
|
||||||
else ctx.fillStyle = "#FD5757"
|
|
||||||
|
|
||||||
ctx.beginPath(); //开始绘制路径
|
|
||||||
ctx.moveTo(250, 250); //将当前位置移动到新的目标点
|
|
||||||
ctx.arc(250, 250, this.radius, _startR, _endR);
|
|
||||||
ctx.closePath(); //绘制路径
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.beginPath(); //开始绘制路径
|
|
||||||
ctx.moveTo(250, 250); //将当前位置移动到新的目标点
|
|
||||||
ctx.arc(250, 250, 250, Math.PI / 2, Math.PI);
|
|
||||||
ctx.closePath(); //绘制路径
|
|
||||||
ctx.fillStyle = "#ccc"; //填充背景颜色
|
|
||||||
ctx.fill();
|
|
||||||
ctx.beginPath(); //开始绘制路径
|
|
||||||
ctx.moveTo(250, 250); //将当前位置移动到新的目标点
|
|
||||||
ctx.arc(250, 250, 250, Math.PI, Math.PI * 1.5);
|
|
||||||
ctx.closePath(); //绘制路径
|
|
||||||
ctx.fillStyle = "#ddd"; //填充背景颜色
|
|
||||||
ctx.fill();
|
|
||||||
ctx.beginPath(); //开始绘制路径
|
|
||||||
ctx.moveTo(250, 250); //将当前位置移动到新的目标点
|
|
||||||
ctx.arc(250, 250, 250, Math.PI * 1.5, Math.PI * 2);
|
|
||||||
ctx.closePath(); //绘制路径
|
|
||||||
ctx.fillStyle = "#aaa"; //填充背景颜色
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const canvasRef = useRef()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let rw = new RouletteWheel({
|
|
||||||
canvas: canvasRef.current,
|
|
||||||
width: '500',
|
|
||||||
height: '500',
|
|
||||||
awards: [ // 转盘内的奖品个数以及内容
|
|
||||||
'大保健', '话费10元', '话费20元', '话费30元', '保时捷911', '周大福土豪金项链',
|
|
||||||
// 'iphone 20', '火星7日游'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<canvas ref={canvasRef} width="200" height="200" ></code>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 火焰
|
|
||||||
|
|
||||||
<code src="./demos/Fire/index.jsx" ></code>
|
|
||||||
|
|
||||||
### 星空
|
|
||||||
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 星空初始化
|
|
||||||
*/
|
|
||||||
class NightSky {
|
|
||||||
constructor(opt) {
|
|
||||||
this.opt = {
|
|
||||||
width: 500,
|
|
||||||
height: 500,
|
|
||||||
num: 120,
|
|
||||||
canvas: null,
|
|
||||||
...opt
|
|
||||||
}
|
|
||||||
this.opt.canvas.width = this.opt.width
|
|
||||||
this.opt.canvas.height = this.opt.height
|
|
||||||
this.ctx = this.opt.canvas && this.opt.canvas.getContext('2d')
|
|
||||||
this.opt.canvas.style.backgroundColor = '#000'
|
|
||||||
this.starList = []
|
|
||||||
this.draw = this.draw
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this.drawStar()
|
|
||||||
this.animate()
|
|
||||||
}
|
|
||||||
|
|
||||||
drawStar() {
|
|
||||||
let { width, height, num } = this.opt
|
|
||||||
|
|
||||||
for (let i = 0; i < num; i++) {
|
|
||||||
this.starList[i] = new Star({
|
|
||||||
maxRadius: 3,
|
|
||||||
ctx: this.ctx,
|
|
||||||
width,
|
|
||||||
height
|
|
||||||
})
|
|
||||||
this.starList[i].draw()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
animate() {
|
|
||||||
let ctx = this.ctx
|
|
||||||
let starList = this.starList
|
|
||||||
let { width, height } = this.opt
|
|
||||||
|
|
||||||
function _move() {
|
|
||||||
ctx.clearRect(0, 0, width, height)
|
|
||||||
for (const i in starList) {
|
|
||||||
starList[i].move()
|
|
||||||
}
|
|
||||||
window.requestAnimationFrame(_move)
|
|
||||||
}
|
|
||||||
|
|
||||||
window.requestAnimationFrame(_move)
|
|
||||||
}
|
|
||||||
|
|
||||||
draw(val) {
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Star {
|
|
||||||
constructor(opt) {
|
|
||||||
let { width, height, maxRadius = 2, ctx, speed = 0.5 } = opt
|
|
||||||
this.x = Math.random() * width
|
|
||||||
this.y = Math.random() * height
|
|
||||||
this.height = height
|
|
||||||
this.width = width
|
|
||||||
this.speed = speed
|
|
||||||
this.maxRadius = maxRadius
|
|
||||||
this.ctx = ctx
|
|
||||||
this.r = Math.random() * maxRadius
|
|
||||||
var alpha = (Math.floor(Math.random() * 10) + 1) / 10
|
|
||||||
this.color = `rgba(255, 255, 255, ${alpha})`
|
|
||||||
}
|
|
||||||
|
|
||||||
draw() {
|
|
||||||
this.ctx.fillStyle = this.color
|
|
||||||
this.ctx.shadowBlur = this.r * 2
|
|
||||||
this.ctx.beginPath()
|
|
||||||
this.ctx.arc(this.x, this.y, this.r * Math.random(), 0, 2 * Math.PI, false)
|
|
||||||
this.ctx.closePath()
|
|
||||||
this.ctx.fill()
|
|
||||||
}
|
|
||||||
|
|
||||||
move() {
|
|
||||||
this.y -= this.speed
|
|
||||||
if (this.y <= -10) {
|
|
||||||
this.y = this.height + 10
|
|
||||||
}
|
|
||||||
this.draw()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const canvasRef = useRef()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let nightSky = new NightSky({
|
|
||||||
canvas: canvasRef.current,
|
|
||||||
width: 500,
|
|
||||||
height: 300
|
|
||||||
})
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<canvas ref={canvasRef} width="200" height="200" ></code>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 移动(doing)
|
|
||||||
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
class Move {
|
|
||||||
constructor(opt) {
|
|
||||||
const option = {
|
|
||||||
canvas: null,
|
|
||||||
width: document.documentElement.clientWidth, // 宽度
|
|
||||||
height: document.documentElement.clientHeight, // 高度
|
|
||||||
bgColor: '#000',
|
|
||||||
para: {
|
|
||||||
num: 100,
|
|
||||||
color: false, // 颜色 如果是false 则是随机渐变颜色
|
|
||||||
r: 0.9, // 圆每次增加的半径
|
|
||||||
o: 0.09, // 判断圆消失的条件,数值越大,消失的越快
|
|
||||||
},
|
|
||||||
...opt
|
|
||||||
}
|
|
||||||
const { canvas, width, height, bgColor } = option
|
|
||||||
this.option = option
|
|
||||||
this.round_arr = []
|
|
||||||
this.ctx = canvas.getContext('2d')
|
|
||||||
|
|
||||||
canvas.width = width
|
|
||||||
canvas.height = height
|
|
||||||
canvas.style.backgroundColor = bgColor
|
|
||||||
|
|
||||||
this.init(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
init(opt) {
|
|
||||||
let tempSum = 0
|
|
||||||
window.onmousemove = function (event) {
|
|
||||||
|
|
||||||
let mouseX = event.clientX;
|
|
||||||
let mouseY = event.clientY;
|
|
||||||
|
|
||||||
if (tempSum < 5) {
|
|
||||||
tempSum++
|
|
||||||
} else {
|
|
||||||
opt.round_arr.push({
|
|
||||||
mouseX,
|
|
||||||
mouseY,
|
|
||||||
r: opt.option.para.r, // 设置半径每次增大的数值
|
|
||||||
o: 1, // 判断圆消失的条件,数值越大,消失得越快
|
|
||||||
})
|
|
||||||
tempSum = 0
|
|
||||||
opt.animate()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
animate() {
|
|
||||||
let { para, width, height } = this.option
|
|
||||||
let color = 0, color2
|
|
||||||
let ctx = this.ctx
|
|
||||||
let round_arr = this.round_arr
|
|
||||||
|
|
||||||
if (!para.color) {
|
|
||||||
color += Math.random();
|
|
||||||
color2 = 'hsl(' + color + ',100%,80%)';
|
|
||||||
}
|
|
||||||
|
|
||||||
function _move() {
|
|
||||||
|
|
||||||
ctx.clearRect(0, 0, width, height);
|
|
||||||
|
|
||||||
for (var i = 0; i < round_arr.length; i++) {
|
|
||||||
|
|
||||||
ctx.fillStyle = color2;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc( round_arr[i].mouseX ,round_arr[i].mouseY, round_arr[i].r, 0, Math.PI * 2);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.fill();
|
|
||||||
round_arr[i].r += para.r;
|
|
||||||
round_arr[i].o -= para.o;
|
|
||||||
|
|
||||||
if( round_arr[i].o <= 0){
|
|
||||||
round_arr.splice(i,1);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.requestAnimationFrame(_move);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const canvasRef = useRef()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let rw = new Move({
|
|
||||||
canvas: canvasRef.current,
|
|
||||||
width: 500,
|
|
||||||
height: 300
|
|
||||||
})
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<canvas ref={canvasRef} width="200" height="200" ></code>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 棒棒糖
|
|
||||||
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
import React, { useRef, useEffect } from 'react';
|
|
||||||
|
|
||||||
class Lollipop {
|
|
||||||
constructor(opt) {
|
|
||||||
this.opt = {
|
|
||||||
canvas: null, // 画布
|
|
||||||
width: document.documentElement.clientWidth, // 宽度
|
|
||||||
height: document.documentElement.clientHeight, // 高度
|
|
||||||
bgColor: '#000',
|
|
||||||
...opt
|
|
||||||
}
|
|
||||||
this.ctx = this.opt.canvas.getContext('2d')
|
|
||||||
|
|
||||||
// 初始化画布
|
|
||||||
this.opt.canvas.width = this.opt.width
|
|
||||||
this.opt.canvas.height = this.opt.height
|
|
||||||
this.opt.canvas.style.backgroundColor = this.opt.bgColor
|
|
||||||
|
|
||||||
this.render()
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
this._drawCircle(this.ctx)
|
|
||||||
this._drawStick(this.ctx)
|
|
||||||
this._drawHalfCircle(this.ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 画圆
|
|
||||||
* @param {*} ctx
|
|
||||||
*/
|
|
||||||
_drawCircle(ctx) {
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.arc(300, 300, 50, 0, Math.PI * 2, true)
|
|
||||||
ctx.closePath()
|
|
||||||
ctx.fillStyle = '#fff'
|
|
||||||
ctx.shadowBlur = 15
|
|
||||||
ctx.shadowColor = '#fff'
|
|
||||||
ctx.fill()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 棍子
|
|
||||||
* @param {*} ctx
|
|
||||||
*/
|
|
||||||
_drawStick(ctx) {
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.moveTo(340, 340)
|
|
||||||
ctx.lineTo(450, 450)
|
|
||||||
ctx.lineWidth = 8
|
|
||||||
ctx.lineCap = 'round'
|
|
||||||
ctx.strokeStyle = '#fff'
|
|
||||||
ctx.stroke()
|
|
||||||
ctx.closePath()
|
|
||||||
}
|
|
||||||
|
|
||||||
_drawHalfCircle(ctx) {
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.arc(300, 300, 30, 0, Math.PI * 0.6, false)
|
|
||||||
ctx.shadowBlur = 5
|
|
||||||
ctx.lineWidth = 5
|
|
||||||
ctx.lineCap = 'round'
|
|
||||||
ctx.strokeStyle = '#ccc'
|
|
||||||
ctx.stroke()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const canvasRef = useRef()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
new Lollipop({
|
|
||||||
canvas: canvasRef.current,
|
|
||||||
width: 500,
|
|
||||||
height: 800
|
|
||||||
})
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<canvas ref={canvasRef} width="200" height="200" ></code>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 时钟
|
|
||||||
|
|
||||||
<code src="./demos/Clock/index.jsx" ></code>
|
|
@ -1,106 +0,0 @@
|
|||||||
@property --rotate {
|
|
||||||
syntax: "<angle>";
|
|
||||||
initial-value: 132deg;
|
|
||||||
inherits: false;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cont {
|
|
||||||
position: relative;
|
|
||||||
min-height: 400px;
|
|
||||||
height: 500px;
|
|
||||||
background: #212534;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
padding-top: 2rem;
|
|
||||||
padding-bottom: 2rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background: #191c29;
|
|
||||||
width: 200px;
|
|
||||||
height: 300px;
|
|
||||||
padding: 3px;
|
|
||||||
position: relative;
|
|
||||||
border-radius: 6px;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 1.5em;
|
|
||||||
cursor: pointer;
|
|
||||||
font-family: cursive;
|
|
||||||
&_heart {
|
|
||||||
font-size: 150px;
|
|
||||||
color: #e00;
|
|
||||||
animation: beat .25s infinite alternate;
|
|
||||||
transform-origin: center;
|
|
||||||
}
|
|
||||||
:global :local{
|
|
||||||
/* Heart beat animation */
|
|
||||||
@keyframes beat {
|
|
||||||
to { transform: scale(1.4); }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.card:hover {
|
|
||||||
color: rgb(88 199 250 / 100%);
|
|
||||||
transition: color 1s;
|
|
||||||
}
|
|
||||||
.card:hover:before, .card:hover:after {
|
|
||||||
animation: none;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.card::before{
|
|
||||||
content: "";
|
|
||||||
width: 104%;
|
|
||||||
height: 102%;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-image: linear-gradient(
|
|
||||||
var(--rotate)
|
|
||||||
, #5ddcff, #3c67e3 43%, #4e00c2);
|
|
||||||
position: absolute;
|
|
||||||
z-index: -1;
|
|
||||||
top: -1%;
|
|
||||||
left: -2%;
|
|
||||||
animation: spin 2.5s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card::after {
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
top: 20px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: -1;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0 auto;
|
|
||||||
transform: scale(0.8);
|
|
||||||
filter: blur(30px);
|
|
||||||
background-image: linear-gradient(
|
|
||||||
var(--rotate)
|
|
||||||
, #5ddcff, #3c67e3 43%, #4e00c2);
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity .5s;
|
|
||||||
animation: spin 2.5s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
import './index.less';
|
|
||||||
|
|
||||||
|
|
||||||
export default function () {
|
|
||||||
return (
|
|
||||||
<div className="cont">
|
|
||||||
<div className="card">
|
|
||||||
{/* <div className={styles.card_heart}>♥</div> */}
|
|
||||||
{/* <h1 className={styles.card_title}>hello! motherfucker!</h1> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
|
|
||||||
.textMask {
|
|
||||||
position: relative;
|
|
||||||
height: 300px;
|
|
||||||
width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
.bg {
|
|
||||||
height: 300px;
|
|
||||||
width: 100%;
|
|
||||||
background-image: url('https://images4.alphacoders.com/284/284838.jpg');
|
|
||||||
background-size: 100% 100%;
|
|
||||||
background-position: center;
|
|
||||||
transform: rotateY(180deg);
|
|
||||||
transition: all 2.5s ease-in-out;
|
|
||||||
}
|
|
||||||
.text {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
width: 100%;
|
|
||||||
background-image: url('https://images4.alphacoders.com/284/284838.jpg');
|
|
||||||
background-size: 100% 100%;
|
|
||||||
background-position: center;
|
|
||||||
font-size: 50px;
|
|
||||||
color: transparent;
|
|
||||||
text-transform: uppercase;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 200px;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
background-clip: text;
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
transition: all 2.5s ease-in-out;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
.text {
|
|
||||||
background-size: 80% 80%;
|
|
||||||
}
|
|
||||||
.bg {
|
|
||||||
background-size: 150% 150%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="demo textMask">
|
|
||||||
<div className="bg"></div>
|
|
||||||
<div className="text">
|
|
||||||
Text Mask
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
.box {
|
|
||||||
width: 500px;
|
|
||||||
height: 500px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
background: #ccc;
|
|
||||||
}
|
|
||||||
.ball {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
position: absolute;
|
|
||||||
background: red;
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
const ballRef = useRef(null)
|
|
||||||
|
|
||||||
function fun(v) {
|
|
||||||
let Vx = Math.random()*v;
|
|
||||||
let Vy = Math.sqrt(v*v - Vx*Vx);
|
|
||||||
let startX = Math.random()*490;
|
|
||||||
let startY = Math.random()*490;
|
|
||||||
const ball = ballRef.current;
|
|
||||||
Math.random() > 0.5 && (Vx *= -1);
|
|
||||||
Math.random() > 0.5 && (Vy *= -1);
|
|
||||||
ball.style.left = startX + 'px';
|
|
||||||
ball.style.top = startY + 'px';
|
|
||||||
function animate(){
|
|
||||||
if(startX >= 490 || startX <= 0)
|
|
||||||
Vx = -Vx;
|
|
||||||
startX += Vx;
|
|
||||||
if(startY >= 490 || startY <= 0)
|
|
||||||
Vy = -Vy;
|
|
||||||
startY += Vy;
|
|
||||||
ball.style.left = startX + 'px';
|
|
||||||
ball.style.top = startY + 'px';
|
|
||||||
window.requestAnimationFrame(animate);
|
|
||||||
}
|
|
||||||
window.requestAnimationFrame(animate);
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="box">
|
|
||||||
<button onClick={() => fun(5)} type="button">开始</button>
|
|
||||||
<div className="ball" ref={ballRef}></div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
Before Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 684 KiB |
Before Width: | Height: | Size: 1.9 MiB |
@ -1,157 +0,0 @@
|
|||||||
@keyframes ani {
|
|
||||||
from {
|
|
||||||
mask-position: 0 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
mask-position: 100% 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes ani2 {
|
|
||||||
from {
|
|
||||||
mask-position: 100% 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
mask-position: 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttonMask {
|
|
||||||
button {
|
|
||||||
width: 101%;
|
|
||||||
height: 100%;
|
|
||||||
font-family: 'Righteous', cursive;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 20px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.mas {
|
|
||||||
margin-top: 12px;
|
|
||||||
position: absolute;
|
|
||||||
color: #000;
|
|
||||||
text-align: center;
|
|
||||||
width: 101%;
|
|
||||||
font-family: 'Righteous' sans-serif;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 20px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.btn {
|
|
||||||
position: relative;
|
|
||||||
width: 100px;
|
|
||||||
height: 50px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-top: 6vh;
|
|
||||||
overflow: hidden;
|
|
||||||
border: 1px solid ;
|
|
||||||
font-family: 'Righteous' sans-serif;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 20px;
|
|
||||||
text-align: center;
|
|
||||||
transition: .5s;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
}
|
|
||||||
.button-container-1 {
|
|
||||||
button {
|
|
||||||
background: #000;
|
|
||||||
mask: url('./img/button1.png');
|
|
||||||
mask-size: 2300% 100%;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
-webkit-animation: ani2 .7s steps(22) forwards;
|
|
||||||
animation: ani2 .7s steps(22) forwards;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
-webkit-animation: ani .7s steps(22) forwards;
|
|
||||||
animation: ani .7s steps(22) forwards;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.button-container-2 {
|
|
||||||
button {
|
|
||||||
background: #000;
|
|
||||||
mask: url('./img/button2.png');
|
|
||||||
mask-size: 3000% 100%;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
-webkit-animation: ani2 .7s steps(29) forwards;
|
|
||||||
animation: ani2 .7s steps(29) forwards;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
-webkit-animation: ani .7s steps(29) forwards;
|
|
||||||
animation: ani .7s steps(29) forwards;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.button-container-3 {
|
|
||||||
button {
|
|
||||||
background: #000;
|
|
||||||
mask: url('./img/button3.png');
|
|
||||||
mask-size: 7100% 100%;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
-webkit-animation: ani2 0.7s steps(70) forwards;
|
|
||||||
animation: ani2 0.7s steps(70) forwards;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
-webkit-animation: ani 0.7s steps(70) forwards;
|
|
||||||
animation: ani 0.7s steps(70) forwards;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.button-container-4 {
|
|
||||||
position: relative;
|
|
||||||
height: 45px;
|
|
||||||
width: 200px;
|
|
||||||
background: #fff;
|
|
||||||
color: #6cf;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 45px;
|
|
||||||
-webkit-box-sizing:border-box;
|
|
||||||
box-sizing:border-box;
|
|
||||||
margin: 40px auto;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.button-container-4::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
width: 0;
|
|
||||||
height: 1px;
|
|
||||||
right: -2px;
|
|
||||||
top: -2px;
|
|
||||||
background-color: #6cf;
|
|
||||||
z-index: -1;
|
|
||||||
transition: width .4s linear, height .4s linear;
|
|
||||||
}
|
|
||||||
.button-container-4::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
width: 0;
|
|
||||||
height: 1px;
|
|
||||||
left: -2px;
|
|
||||||
bottom: -2px;
|
|
||||||
background-color: #6cf;
|
|
||||||
z-index: -1;
|
|
||||||
transition: width .4s linear, height .4s linear;
|
|
||||||
}
|
|
||||||
.button-container-4:hover {
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
transition: width .4s linear, height .4s linear;
|
|
||||||
width: 201px;
|
|
||||||
height: 46px;
|
|
||||||
}
|
|
||||||
&::after {
|
|
||||||
content: "";
|
|
||||||
transition: width .4s linear, height .4s linear;
|
|
||||||
width: 201px;
|
|
||||||
height: 46px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="buttonMask">
|
|
||||||
<div className="btn button-container-1">
|
|
||||||
<span className="mas">MASK1</span>
|
|
||||||
<button type="button" name="Hover">MASK1</button>
|
|
||||||
</div>
|
|
||||||
<div className="btn button-container-2">
|
|
||||||
<span className="mas">MASK2</span>
|
|
||||||
<button type="button" name="Hover">MASK2</button>
|
|
||||||
</div>
|
|
||||||
<div className="btn button-container-3">
|
|
||||||
<span className="mas">MASK2</span>
|
|
||||||
<button type="button" name="Hover">MASK3</button>
|
|
||||||
</div>
|
|
||||||
<div className="button-container-4">
|
|
||||||
描边动画
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
Before Width: | Height: | Size: 329 KiB |
@ -1,47 +0,0 @@
|
|||||||
.svgMask {
|
|
||||||
position: relative;
|
|
||||||
.rang {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 250px;
|
|
||||||
z-index: 10;
|
|
||||||
svg {
|
|
||||||
width: 100%;
|
|
||||||
height: inherit;
|
|
||||||
text {
|
|
||||||
text-anchor: middle;
|
|
||||||
}
|
|
||||||
.svgDemo {
|
|
||||||
&_rect {
|
|
||||||
fill: darken( #fff, 60%);
|
|
||||||
}
|
|
||||||
&_tit {
|
|
||||||
letter-spacing: -2px;
|
|
||||||
font-size: 6em;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
&_subtit {
|
|
||||||
letter-spacing: 8px;
|
|
||||||
font-size: 1.2em;
|
|
||||||
font-weight: 300;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.down {
|
|
||||||
fill: #000;
|
|
||||||
mask: url(#svgDemo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.intro {
|
|
||||||
position: relative;
|
|
||||||
background: url('./img/amazon_view.jpg');
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class="svgMask">
|
|
||||||
<div class="rang">
|
|
||||||
<svg>
|
|
||||||
<defs>
|
|
||||||
<mask id="svgDemo" class="svgDemo" width="100%" heigth="100%" x="0" y="0">
|
|
||||||
<rect class="svgDemo_rect" x="0" y="0" width="100%" height="100%" />
|
|
||||||
|
|
||||||
<text class="svgDemo_tit" x="50%" y="0" dy="1.58em">SVG + CSS</text>
|
|
||||||
<text class="svgDemo_subtit" x="50%" y="0" dy="9.8em">welcome!</text>
|
|
||||||
</mask>
|
|
||||||
</defs>
|
|
||||||
<rect class="down" x="0" y="0" width="100%" height="100%" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="intro">嗨,你好吗?</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg width="45px" height="26px" viewBox="0 0 45 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
|
|
||||||
<title>Group</title>
|
|
||||||
<desc>Created with Sketch.</desc>
|
|
||||||
<defs></defs>
|
|
||||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
||||||
<g id="block/navigation_primary_white" transform="translate(-165.000000, -12.000000)" fill="#303233">
|
|
||||||
<g id="Group">
|
|
||||||
<g transform="translate(165.000000, 12.000000)">
|
|
||||||
<g id="systemicon/black/djilogo">
|
|
||||||
<path d="M17.9822999,14.0172253 L21.3322723,0 L28.6674466,0 L24.8560701,15.9459198 C24.1224248,19.0236511 21.8345765,19.7624088 19.7179972,19.7624088 L2.81348162,19.7624088 C0.951249717,19.7624088 -0.609344073,18.9712479 0.235498266,15.4180531 L1.75902636,9.05809025 C2.52845917,5.83081808 4.92750466,5.09206033 6.6619238,5.09206033 L18.464154,5.09206033 L17.5119489,9.06831527 L11.4868555,9.06831527 C10.6023912,9.06831527 10.1167027,9.26131253 9.87002406,10.2927615 L8.89609083,14.354651 C8.54971825,15.8117164 9.05969116,15.9114104 10.1243714,15.9114104 L15.6458826,15.9114104 C16.6568816,15.9114104 17.5451803,15.8487821 17.9822999,14.0172253 Z M37.8744387,5.0897597 L45,5.0897597 L41.5477774,19.7626645 L34.422216,19.7626645 L37.8744387,5.0897597 Z M29.1385644,5.0897597 L36.2641257,5.0897597 L32.9461065,18.8807564 C31.5618943,24.6604494 27.6955583,25.9973709 25.077953,25.9973709 L15.0817171,25.9973709 L16.2767664,21.0254545 C16.2767664,21.0254545 21.5937772,21.0510171 21.7829401,21.0280108 C23.684794,20.869523 25.5777009,19.9441586 26.2333804,17.1974624 L29.1385644,5.0897597 Z" id="LOGO"></path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.9 KiB |
@ -1,51 +0,0 @@
|
|||||||
|
|
||||||
@keyframes move {
|
|
||||||
0% {
|
|
||||||
background-position: 0 0;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
background-position: 100% 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.realMask {
|
|
||||||
position: relative;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
z-index: 1;
|
|
||||||
height: 500px;
|
|
||||||
overflow: hidden;
|
|
||||||
&_bg {
|
|
||||||
background-image: url('https://sp-webfront.skypixel.com/skypixel/v2/public/website/assets/1535027674204-f6eca6369ec03e70262b58b0e25cda7b.jpg');
|
|
||||||
background-size: cover;
|
|
||||||
position: absolute;
|
|
||||||
top: -20px;
|
|
||||||
left: -20px;
|
|
||||||
right: -20px;
|
|
||||||
bottom: -20px;
|
|
||||||
filter: blur(15px);
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
&_mask {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
width: 200px;
|
|
||||||
height: 80px;
|
|
||||||
animation: move 88s infinite;
|
|
||||||
background-image: url(https://sp-webfront.skypixel.com/skypixel/v2/public/website/assets/1535027674204-f6eca6369ec03e70262b58b0e25cda7b.jpg);
|
|
||||||
background-size: cover;
|
|
||||||
mask-image: url('./img/dji.svg');
|
|
||||||
mask-size: cover;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
&_slogan {
|
|
||||||
color: white;
|
|
||||||
margin-top: 24px;
|
|
||||||
font-size: 36px;
|
|
||||||
font-weight: 300;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="realMask">
|
|
||||||
<div className="realMask_bg"></div>
|
|
||||||
<div className="realMask_mask"></div>
|
|
||||||
<div className="realMask_slogan">NiceNote</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
@keyframes Gradient {
|
|
||||||
0%{background-position:50% 0%}
|
|
||||||
50%{background-position:50% 100%}
|
|
||||||
100%{background-position:50% 0%}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gradientMask {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
font-size: 50px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
font-weight: bold;
|
|
||||||
background: linear-gradient(0deg, #e55d87, #5fc3e4);
|
|
||||||
background-size: 400% 400%;
|
|
||||||
animation: Gradient 4s linear infinite;
|
|
||||||
svg {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
text {
|
|
||||||
text-anchor: middle;
|
|
||||||
}
|
|
||||||
svg mask rect {
|
|
||||||
fill: #eee;
|
|
||||||
}
|
|
||||||
svg > rect {
|
|
||||||
fill: #eee;
|
|
||||||
mask: url(#gradientMask_svg__mask);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="gradientMask">
|
|
||||||
<svg
|
|
||||||
className="gradientMask_svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="100%"
|
|
||||||
height="100%"
|
|
||||||
>
|
|
||||||
<defs>
|
|
||||||
<mask id="gradientMask_svg__mask" x="0" y="0" width="100%" height="100%">
|
|
||||||
<rect x="0" y="0" width="100%" height="100%" />
|
|
||||||
<text x="50%" y="1em">Hello</text>
|
|
||||||
<text x="50%" y="2em">Motal</text>
|
|
||||||
</mask>
|
|
||||||
</defs>
|
|
||||||
<rect x="0" y="0" width="100%" height="100%" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
Before Width: | Height: | Size: 329 KiB |
@ -1,47 +0,0 @@
|
|||||||
.svgBgMask {
|
|
||||||
position: relative;
|
|
||||||
font-weight: 700;
|
|
||||||
h1, h2 {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.picture {
|
|
||||||
img {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
will-change: transform;
|
|
||||||
width: 100%;
|
|
||||||
height: 100vh;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
svg {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.article {
|
|
||||||
padding-top: 100px;
|
|
||||||
background-color: #222;
|
|
||||||
text-align: center;
|
|
||||||
color: #fff;
|
|
||||||
h1 {
|
|
||||||
margin: 0;
|
|
||||||
letter-spacing: 3pt;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 50px;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
margin-top: 100px;
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 60px 100px;
|
|
||||||
h2 {
|
|
||||||
margin-top: 35px;
|
|
||||||
font-size: 1.1em;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
const img = require('./img/amazon_view.jpg')
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="svgBgMask">
|
|
||||||
<div className="picture">
|
|
||||||
<img src={img} alt="" />
|
|
||||||
<svg width="100%" height="1280">
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="gradient" gradientTransform="rotate(76)">
|
|
||||||
<stop offset="18%" stop-color="#1a237e" />
|
|
||||||
<stop offset="80%" stop-color="#00e5ff" />
|
|
||||||
</linearGradient>
|
|
||||||
<mask id="mask">
|
|
||||||
<rect width="100%" height="100%" fill="#fff" />
|
|
||||||
<text x="10%" y="25%" font-size="50px" font-weight="300">hello</text>
|
|
||||||
<text x="10%" y="50%" font-size="100px" letter-spacing="8">My Friend</text>
|
|
||||||
</mask>
|
|
||||||
</defs>
|
|
||||||
<rect width="100%" height="100%" fill="url(#gradient)" fill-opacity="0.8" mask="url(#mask)" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="article">
|
|
||||||
<h1>You Are The Best</h1>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<img src="https://s.cdpn.io/387787/scalable.svg" alt="" width="60" height="60" />
|
|
||||||
<h2>bread</h2>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<img src="https://s.cdpn.io/387787/customizable.svg" alt="" width="60" height="60" />
|
|
||||||
<h2>hand</h2>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<img src="https://s.cdpn.io/387787/accessible.svg" alt="" width="60" height="60" />
|
|
||||||
<h2>heart</h2>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
|
|
||||||
@keyframes typing {
|
|
||||||
from { width: 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes blink-caret {
|
|
||||||
50% {
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cssPrint {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: black;
|
|
||||||
&_h1 {
|
|
||||||
display: inline-block;
|
|
||||||
color: lime;
|
|
||||||
font: bold 200% Consolas;
|
|
||||||
/*font: bold 200% "Source Code Pro";*/
|
|
||||||
/*必须使用等宽字体*/
|
|
||||||
border-right: .1em solid currentColor;
|
|
||||||
width: 28ch;
|
|
||||||
margin: 2em 1em;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
animation: typing 3s steps(20, end),
|
|
||||||
blink-caret .5s step-end infinite alternate;
|
|
||||||
/*step-end每个关键帧在end处跳转,infinite无限循环播放,alternate来回播放,normal顺序播放*/
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="cssPrint">
|
|
||||||
<h1 className="cssPrint_h1">
|
|
||||||
This is Nice Note WebSite By Json!
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
|
|
||||||
.ribbon {
|
|
||||||
display:inline-block;
|
|
||||||
height: 300px;
|
|
||||||
background-color: #000;
|
|
||||||
&::before, &::after {
|
|
||||||
margin-top:.5em;
|
|
||||||
content: "";
|
|
||||||
float:left;
|
|
||||||
border:1.5em solid #fff;
|
|
||||||
}
|
|
||||||
&::before {
|
|
||||||
border-left-color: transparent;
|
|
||||||
}
|
|
||||||
&::after {
|
|
||||||
border-right-color: transparent;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
float: left;
|
|
||||||
height: 3.5em;
|
|
||||||
color: #000;
|
|
||||||
text-decoration:none;
|
|
||||||
overflow: hidden;
|
|
||||||
&:hover span {
|
|
||||||
margin-top: 0;
|
|
||||||
background-color: #FFD204;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
position: relative;
|
|
||||||
background: #fff;
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 3em;
|
|
||||||
margin-top: .5em;
|
|
||||||
padding: 0 1em;
|
|
||||||
transition: background .2s, margin-top .2s;
|
|
||||||
&:before {
|
|
||||||
content: "";
|
|
||||||
position:absolute;
|
|
||||||
top:3em;
|
|
||||||
left:0;
|
|
||||||
border-right:0.5em solid #9B8651;
|
|
||||||
border-bottom:0.5em solid #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='ribbon'>
|
|
||||||
<a href='#'><span>首页</span></a>
|
|
||||||
<a href='#'><span>关于我</span></a>
|
|
||||||
<a href='#'><span>服务</span></a>
|
|
||||||
<a href='#'><span>介绍</span></a>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
.wraper {
|
|
||||||
width: 260px;
|
|
||||||
height: 260px;
|
|
||||||
margin: 128px auto;
|
|
||||||
perspective: 1000px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cube {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
/*transform: rotateX(-30deg) rotateY(-45deg);*/
|
|
||||||
animation: spin 5s ease-in-out infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
from {
|
|
||||||
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotateX(360deg) rotateY(360deg) rotateZ(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cube>div {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
background-color: rgba(0, 0, 0, .8);
|
|
||||||
text-align: center;
|
|
||||||
line-height: 260px;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 48px;
|
|
||||||
border: 2px solid #fff;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.front {
|
|
||||||
transform: translateZ(130px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.end {
|
|
||||||
transform: rotateY(180deg) translateZ(130px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top {
|
|
||||||
transform: rotateX(90deg) translateZ(130px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
transform: rotateX(-90deg) translateZ(130px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
transform: rotateY(-90deg) translateZ(130px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
transform: rotateY(90deg) translateZ(130px);
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
import React, { useRef, useEffect, FC } from 'react';
|
|
||||||
import './index.less'
|
|
||||||
|
|
||||||
export default (): any => {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手动控制动画
|
|
||||||
*/
|
|
||||||
function init() {
|
|
||||||
setTimeout(function () {
|
|
||||||
var cube = document.querySelector(".cube"),
|
|
||||||
downX, downY, moveX, moveY, tempX, tempY, degX = 0, degY = 0;
|
|
||||||
|
|
||||||
window.onmousedown = function (e) {
|
|
||||||
e = e || event;
|
|
||||||
downX = e.clientX; //获取鼠标点下去时的坐标
|
|
||||||
downY = e.clientY;
|
|
||||||
console.log('can');
|
|
||||||
|
|
||||||
window.onmousemove = function (e) {
|
|
||||||
e = e || event;
|
|
||||||
moveX = e.clientX - downX; //算出鼠标移动的距离
|
|
||||||
moveY = e.clientY - downY;
|
|
||||||
//根据一定比例将变化反应在盒子上,改变比例5可以调节拖动的速度
|
|
||||||
tempX = degX + moveX / 5;
|
|
||||||
tempY = degY - moveY / 5;
|
|
||||||
cube.style.transform = "rotatex(" + tempY + "deg) rotatey(" + tempX + "deg)";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
window.onmouseup = function (e) {
|
|
||||||
e = e || event;
|
|
||||||
degX += moveX / 5; //鼠标松开时将拖动期间改变的最终结果保存
|
|
||||||
degY += - moveY / 5;
|
|
||||||
window.onmousemove = null; //取消监听
|
|
||||||
};
|
|
||||||
|
|
||||||
// !function () {
|
|
||||||
// var n = 1000;
|
|
||||||
// var wraper = document.querySelector('.wraper');
|
|
||||||
// wraper.style.perspective = n + 'px';
|
|
||||||
// window.onmousewheel = function (e) {
|
|
||||||
// e = e || event;
|
|
||||||
// if (e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
|
|
||||||
// if (e.wheelDelta > 0) { //当滑轮向上滚动时减小景深
|
|
||||||
// wraper.style.perspective = n - 50 + 'px';
|
|
||||||
// if (n > 350) {
|
|
||||||
// n = n - 50;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (e.wheelDelta < 0) { //当滑轮向下滚动时增加景深
|
|
||||||
// wraper.style.perspective = n + 50 + 'px';
|
|
||||||
// n += 50;
|
|
||||||
// }
|
|
||||||
// } else if (e.detail) { //Firefox滑轮事件
|
|
||||||
// if (e.detail > 0) {
|
|
||||||
// wraper.style.perspective = n - 50 + 'px';
|
|
||||||
// if (n > 350) {
|
|
||||||
// n = n - 50;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (e.detail < 0) {
|
|
||||||
// wraper.style.perspective = n + 50 + 'px';
|
|
||||||
// n += 50;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// }();
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="wraper">
|
|
||||||
<div className="cube">
|
|
||||||
<div className="front">Front</div>
|
|
||||||
<div className="end">End</div>
|
|
||||||
<div className="left">Left</div>
|
|
||||||
<div className="right">Right</div>
|
|
||||||
<div className="top">Top</div>
|
|
||||||
<div className="bottom">Bottom</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
---
|
|
||||||
nav:
|
|
||||||
title: FC
|
|
||||||
path: /funny
|
|
||||||
group:
|
|
||||||
title: css
|
|
||||||
order: 3
|
|
||||||
path: /css
|
|
||||||
---
|
|
||||||
|
|
||||||
# css
|
|
||||||
|
|
||||||
|
|
||||||
### 心跳卡片
|
|
||||||
|
|
||||||
<a href="https://codepen.io/gayane-gasparyan/pen/jOmaBQK">参考</a>
|
|
||||||
<code src="./demos/HeartBeat/index.tsx" ></code>
|
|
||||||
|
|
||||||
### 小球动画
|
|
||||||
|
|
||||||
<code src="./demos/demo10/index.tsx" ></code>
|
|
||||||
|
|
||||||
### 3D 方块
|
|
||||||
|
|
||||||
<code src="./demos/demo9/index.tsx" ></code>
|
|
||||||
|
|
||||||
### 3D 导航条
|
|
||||||
|
|
||||||
<code src="./demos/demo8/index.tsx" ></code>
|
|
||||||
|
|
||||||
### 键盘打字效果
|
|
||||||
|
|
||||||
<code src="./demos/demo7/index.tsx" ></code>
|
|
||||||
|
|
||||||
### 镂空文字背景
|
|
||||||
|
|
||||||
<code src="./demos/demo1/index.tsx" ></code>
|
|
||||||
|
|
||||||
### 按钮合集
|
|
||||||
|
|
||||||
<code src="./demos/demo2/index.tsx" ></code>
|
|
||||||
|
|
||||||
### Svg 蒙版
|
|
||||||
|
|
||||||
<code src="./demos/demo3/index.tsx" ></code>
|
|
||||||
|
|
||||||
### 毛玻璃蒙版
|
|
||||||
|
|
||||||
<code src="./demos/demo4/index.tsx" ></code>
|
|
||||||
|
|
||||||
### 渐变文字
|
|
||||||
|
|
||||||
<code src="./demos/demo5/index.tsx" ></code>
|
|
||||||
|
|
||||||
### 渐变文字
|
|
||||||
|
|
||||||
<code src="./demos/demo6/index.tsx" ></code>
|
|
36
src/index.md
@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
nav:
|
|
||||||
title: FC
|
|
||||||
path: /funny
|
|
||||||
group:
|
|
||||||
title: 说明
|
|
||||||
order: 4
|
|
||||||
path: /code
|
|
||||||
---
|
|
||||||
|
|
||||||
# 说明
|
|
||||||
|
|
||||||
funny code 的缩写,就是记录一些有意思的酷炫 code
|
|
||||||
|
|
||||||
## 迪士尼动画12原则
|
|
||||||
|
|
||||||
1. 挤压与拉伸
|
|
||||||
2. 预备动作
|
|
||||||
3. 表情与呈像方式
|
|
||||||
4. 逐帧画法与关键帧画法
|
|
||||||
5. 动作的惯性跟随和重叠
|
|
||||||
6. 慢入与慢出
|
|
||||||
7. 弧形运动轨迹
|
|
||||||
8. 次要动作
|
|
||||||
9. 节奏
|
|
||||||
10. 夸张
|
|
||||||
11. 熟练的手绘技法
|
|
||||||
12. 吸引力
|
|
||||||
|
|
||||||
## 提升页面性能技巧
|
|
||||||
|
|
||||||
页面渲染顺序:js - css - layout(重排) - paint(重绘) - composite
|
|
||||||
|
|
||||||
* translate 替换为 left\top\right\bottom
|
|
||||||
* scale 替换为 width\height
|
|
||||||
* opacity 替换为 display\visibility
|
|