feat: 上传文章

This commit is contained in:
NICE CODE BY DEV 2024-01-28 20:43:39 +08:00
parent 26cb0f4cf8
commit 45469218da
71 changed files with 6493 additions and 12521 deletions

36
.dumi/global.less Normal file
View 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;
}

View File

@ -1,8 +1,8 @@
import { defineConfig } from 'dumi';
export default defineConfig({
title: 'Nice Note',
themeConfig: {
name: 'nicenote',
navs: [
null,
{
@ -11,8 +11,8 @@ export default defineConfig({
},
]
},
favicons: ['https://jzx-h5.oss-cn-hangzhou.aliyuncs.com/logo.ico'],
// logo: 'http://jzx-h5.oss-cn-hangzhou.aliyuncs.com/logo.png',
logo: 'https://i.niupic.com/images/2021/06/07/9krN.png',
favicons: ['https://i.niupic.com/images/2021/06/07/9krN.png'],
outputPath: 'docs-dist',
hash: true,
history: {

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ node_modules
.dumi/tmp-production
.DS_Store
.umi
/docs-dist

3
.npmrc Normal file
View File

@ -0,0 +1,3 @@
registry="https://registry.npmmirror.com"
strict-peer-dependencies=false
ignore-workspace-root-check=true

View File

@ -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;

View File

@ -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 };

View File

@ -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 };

View File

@ -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
}

View File

@ -1,5 +0,0 @@
// @ts-nocheck
import { plugin } from './plugin';
export const __mfsu = 1;

View File

@ -1,4 +0,0 @@
// @ts-nocheck
import 'core-js';
import 'regenerator-runtime/runtime';
export {};

View File

@ -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;
}

View File

@ -1,3 +0,0 @@
// @ts-nocheck
export { history } from './history';
export { plugin } from './plugin';

View File

@ -1 +0,0 @@
{}

View File

@ -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": {}
}

View File

@ -1,6 +0,0 @@
// @ts-nocheck
import React from 'react';
import { dynamic } from 'dumi';
export default {
};

View File

@ -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} />;

View File

@ -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() })();
}
});
}

View File

@ -2,34 +2,30 @@
### 🌟 新功能
* 初始化项目 ([466dbeb](https://github.com/j710328466/j710328466.github.io/commit/466dbeb))
* 新增模块 ([9e0b3a9](https://github.com/j710328466/j710328466.github.io/commit/9e0b3a9))
* 新增心跳组件 ([82a59b4](https://github.com/j710328466/j710328466.github.io/commit/82a59b4))
* 修改toolsgit命令 ([efb8285](https://github.com/j710328466/j710328466.github.io/commit/efb8285))
* **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** typescript ([abb3cfe](https://github.com/j710328466/j710328466.github.io/commit/abb3cfe))
* **md** 新文章 ([41459c4](https://github.com/j710328466/j710328466.github.io/commit/41459c4))
* **package.json** 添加husky ([95a0051](https://github.com/j710328466/j710328466.github.io/commit/95a0051))
* **resume** 修改简历 ([9f28c78](https://github.com/j710328466/j710328466.github.io/commit/9f28c78))
* svg学习笔记 ([63e96b7](https://github.com/j710328466/j710328466.github.io/commit/63e96b7))
- 初始化项目 ([466dbeb](https://github.com/j710328466/j710328466.github.io/commit/466dbeb))
- 新增模块 ([9e0b3a9](https://github.com/j710328466/j710328466.github.io/commit/9e0b3a9))
- 新增心跳组件 ([82a59b4](https://github.com/j710328466/j710328466.github.io/commit/82a59b4))
- 修改 toolsgit 命令 ([efb8285](https://github.com/j710328466/j710328466.github.io/commit/efb8285))
- **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** typescript ([abb3cfe](https://github.com/j710328466/j710328466.github.io/commit/abb3cfe))
- **md** 新文章 ([41459c4](https://github.com/j710328466/j710328466.github.io/commit/41459c4))
- **package.json** 添加 husky ([95a0051](https://github.com/j710328466/j710328466.github.io/commit/95a0051))
- **resume** 修改简历 ([9f28c78](https://github.com/j710328466/j710328466.github.io/commit/9f28c78))
- svg 学习笔记 ([63e96b7](https://github.com/j710328466/j710328466.github.io/commit/63e96b7))
### 🐛 Bug 修复
* **工具类:** lerna QA ([dbb0c36](https://github.com/j710328466/j710328466.github.io/commit/dbb0c36))
* 设计模式添加 ([79143a6](https://github.com/j710328466/j710328466.github.io/commit/79143a6))
* 新增react学习 ([a7ec84e](https://github.com/j710328466/j710328466.github.io/commit/a7ec84e))
* 修改路径 ([2261dc4](https://github.com/j710328466/j710328466.github.io/commit/2261dc4))
* 修改配置 ([bfd5f0f](https://github.com/j710328466/j710328466.github.io/commit/bfd5f0f))
* 修改设计模式 ([6f5630d](https://github.com/j710328466/j710328466.github.io/commit/6f5630d))
* 修改bug ([83e7ea9](https://github.com/j710328466/j710328466.github.io/commit/83e7ea9))
* 优化react 设计模式 ([cf4958e](https://github.com/j710328466/j710328466.github.io/commit/cf4958e))
* **fed/vue** 新增内容 ([07f15ba](https://github.com/j710328466/j710328466.github.io/commit/07f15ba))
* **resume** 新增简历 ([f40ea2e](https://github.com/j710328466/j710328466.github.io/commit/f40ea2e))
* **resume** 修改简历 ([aa7715c](https://github.com/j710328466/j710328466.github.io/commit/aa7715c))
* **resume** 修改简历 ([3e498ff](https://github.com/j710328466/j710328466.github.io/commit/3e498ff))
* **sd** sd ([e7d434d](https://github.com/j710328466/j710328466.github.io/commit/e7d434d))
- **工具类:** lerna QA ([dbb0c36](https://github.com/j710328466/j710328466.github.io/commit/dbb0c36))
- 设计模式添加 ([79143a6](https://github.com/j710328466/j710328466.github.io/commit/79143a6))
- 新增 react 学习 ([a7ec84e](https://github.com/j710328466/j710328466.github.io/commit/a7ec84e))
- 修改路径 ([2261dc4](https://github.com/j710328466/j710328466.github.io/commit/2261dc4))
- 修改配置 ([bfd5f0f](https://github.com/j710328466/j710328466.github.io/commit/bfd5f0f))
- 修改设计模式 ([6f5630d](https://github.com/j710328466/j710328466.github.io/commit/6f5630d))
- 修改 bug ([83e7ea9](https://github.com/j710328466/j710328466.github.io/commit/83e7ea9))
- 优化 react 设计模式 ([cf4958e](https://github.com/j710328466/j710328466.github.io/commit/cf4958e))
- **fed/vue** 新增内容 ([07f15ba](https://github.com/j710328466/j710328466.github.io/commit/07f15ba))
- **resume** 新增简历 ([f40ea2e](https://github.com/j710328466/j710328466.github.io/commit/f40ea2e))
- **resume** 修改简历 ([aa7715c](https://github.com/j710328466/j710328466.github.io/commit/aa7715c))
- **resume** 修改简历 ([3e498ff](https://github.com/j710328466/j710328466.github.io/commit/3e498ff))
- **sd** sd ([e7d434d](https://github.com/j710328466/j710328466.github.io/commit/e7d434d))

View File

@ -159,3 +159,4 @@ class Car implements Alarm, Light {
1. [Type Search](https://www.typescriptlang.org/dt/search?search=)
2. [quick Type自动生成 Type](https://app.quicktype.io)
3. [ts playground: 线上编写测试代码](https://www.typescriptlang.org/zh/play)
4. [tsconfig 参数解释](https://segmentfault.com/a/1190000021749847)

View File

@ -1,8 +1,8 @@
---
title: A static site based on dumi
title: Nice Note
hero:
title: NiceNote
description: dev 的学习博客
title: Nice Note
description: dev 的博客
actions:
- text: 开始学习
link: /fea/website
@ -12,6 +12,8 @@ features:
description: <a href="https://nicecoders.github.io">前端工具合集</a>
---
这是我用来记录我的职业生涯总结的各种乱七八糟的知识点,希望能对你有帮助
这里记录了我所有工作中和非工作中的思考和总结
思维比较发散,想到哪写到哪
<embed src="../CHANGELOG.md"></embed>

View File

@ -17,11 +17,13 @@ group:
#### 确认网络
- ping [j710328466.github.io](j710328466.github.io)
#### 关闭 iptables 规则
- iptables -L 查看
- iptables -F 关闭
- iptables -t nat -L
#### 关闭 getenforce
- setenforce 0
@ -37,6 +39,9 @@ group:
```
### 安装编译工具和库
如果没有再安装
```js
// 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)
@ -52,16 +57,30 @@ yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel
- yum -y update
### centos 快速安装
- yum install nginx -y
## 默认文件位置
```js
/etc/nginx/nginx.conf //yum方式安装后默认配置文件的路径
/usr/share/nginx/html //nginx网站默认存放目录
/usr/share/nginx/html/index.html //网站默认主页路径
```
## 常用命令
### 查看 nginx 配置文件路径和安装路径
> nginx -t
### 开始
systemctl start nginx
方法 1. systemctl start nginx
方法 2. systemctl enable --now nginx
### 重启
@ -73,10 +92,9 @@ systemctl start nginx
> killall -9 nginx
### 初始目录
> /usr/share/nginx/html
### 配置文件
```
@ -185,6 +203,7 @@ http {
## Q&A
### 1. forbedden 403
> chmod -R 777 /data
> chmod -R 777 /data/www
@ -195,5 +214,3 @@ vi /etc/selinux/config
#SELINUX=enforcing
SELINUX=disabled
```

View File

@ -5,7 +5,7 @@
"license": "MIT",
"scripts": {
"build": "dumi build",
"deploy": "npm run build && gh-pages -d docs-dist",
"deploy": "gh-pages -d docs-dist",
"dev": "dumi dev",
"prepare": "husky install && dumi setup",
"start": "npm run dev"
@ -27,6 +27,7 @@
"@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.1.0",
"dumi": "^2.2.13",
"gh-pages": "^6.1.1",
"husky": "^8.0.1",
"lint-staged": "^13.0.3",
"prettier": "^2.7.1"

File diff suppressed because it is too large Load Diff

View File

@ -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); //xy
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>
)
}

View File

@ -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>
)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

View File

@ -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>
)
}

View File

@ -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;
}
}

View File

@ -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>
)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@ -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>
)
}

View File

@ -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-120-20
food = 43, //
n, //
box = canvasRef.current && canvasRef.current.getContext('2d');
//0399box[0~19]*[0~19]20px
function draw(seat, color) {
box.fillStyle = color;
box.fillRect(seat % 20 *20 + 1, ~~(seat / 20) * 20 + 1, 18, 18);
//colorxy
}
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); //nn
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>
)
}

View File

@ -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>

View File

@ -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;
}

View File

@ -1,13 +0,0 @@
import './index.less';
export default function () {
return (
<div className="cont">
<div className="card">
{/* <div className={styles.card_heart}>&#x2665;</div> */}
{/* <h1 className={styles.card_title}>hello! motherfucker!</h1> */}
</div>
</div>
);
}

View File

@ -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%;
}
}
}

View File

@ -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>
)
}

View File

@ -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;
}

View File

@ -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>
)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 684 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

View File

@ -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;
}
}
}

View File

@ -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>
)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 KiB

View File

@ -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;
}
}

View File

@ -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>
)
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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>
)
}

View File

@ -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);
}
}

View File

@ -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>
)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 KiB

View File

@ -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;
}
}
}
}
}

View File

@ -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>
)
}

View File

@ -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顺序播放*/
}
}

View File

@ -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>
)
}

View File

@ -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;
}
}
}

View File

@ -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>
)
}

View File

@ -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);
}

View File

@ -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>
)
}

View File

@ -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>

View File

@ -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