feat: 新增模块

This commit is contained in:
haishan 2021-08-25 20:10:25 +08:00
parent 2261dc4140
commit 9e0b3a92f8
42 changed files with 2533 additions and 16 deletions

10
docs/fea/Q&A/index.md Normal file
View File

@ -0,0 +1,10 @@
---
nav:
title: 前端
path: /fea
group:
title: 💊 Q&A
order: 100
---
## 问题合集

View File

@ -3,7 +3,7 @@ nav:
title: 前端
path: /fea
group:
title: canvas
title: 💊 canvas
order: 1
---

View File

@ -3,7 +3,7 @@ nav:
title: 前端
path: /fea
group:
title: canvas
title: 💊 canvas
order: 2
---

View File

@ -3,12 +3,16 @@ nav:
title: 前端
path: /fea
group:
title: canvas
title: 💊 canvas
order: 6
---
## 动画案例
### 液体海报
<code src="./demos/demo1/index.jsx" />
### 大转盘doing
```jsx

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

View File

@ -0,0 +1,118 @@
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

@ -0,0 +1,18 @@
.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

@ -3,7 +3,7 @@ nav:
title: 前端
path: /fea
group:
title: canvas
title: 💊 canvas
order: 4
---

View File

@ -0,0 +1,42 @@
.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

@ -0,0 +1,17 @@
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>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@ -0,0 +1,103 @@
@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: 20;
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;
}
}
}
}

View File

@ -0,0 +1,25 @@
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">MASK2</button>
</div>
</div>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 KiB

View File

@ -0,0 +1,47 @@
.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

@ -0,0 +1,27 @@
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

@ -0,0 +1,18 @@
<?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>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,50 @@
@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;
&_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

@ -0,0 +1,16 @@
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

@ -0,0 +1,32 @@
@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

@ -0,0 +1,28 @@
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.

After

Width:  |  Height:  |  Size: 329 KiB

View File

@ -0,0 +1,47 @@
.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

@ -0,0 +1,50 @@
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>
)
}

34
docs/fea/css/index.md Normal file
View File

@ -0,0 +1,34 @@
---
nav:
title: 前端
path: /fea
group:
title: 💊 css
order: 3
---
## 💊 css
### 镂空文字背景
<code src="./demos/demo1/index.tsx" />
### 涂鸦按钮
<code src="./demos/demo2/index.tsx" />
### Svg 蒙版
<code src="./demos/demo3/index.tsx" />
### 毛玻璃蒙版
<code src="./demos/demo4/index.tsx" />
### 渐变文字
<code src="./demos/demo5/index.tsx" />
### 渐变文字
<code src="./demos/demo6/index.tsx" />

1701
docs/fea/norms.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,12 +3,14 @@ nav:
title: 前端
path: /fea
group:
title: 设计模式
title: 💊 设计模式
order: 4
---
## 适配器模式
将一个类的接口转化为另外一个接口,以满足用户需求,使类之间接口不兼容问题通过适配器得以解决。
```js
import react from 'react';

View File

@ -3,7 +3,7 @@ nav:
title: 前端
path: /fea
group:
title: 设计模式
title: 💊 设计模式
order: 3
---

View File

@ -0,0 +1,40 @@
---
nav:
title: 前端
path: /fea
group:
title: 💊 设计模式
order: 3
---
## 装饰器模式
- 动态地给某个对象添加一些额外的职责,,是一种实现继承的替代方案
- 在不改变原对象的基础上,通过对其进行包装扩展,使原有对象可以满足用户的更复杂需求,而不会影响从这个类中派生的其他对象
```js
class Cellphone {
create() {
console.log('生成一个手机')
}
}
class Decorator {
constructor(cellphone) {
this.cellphone = cellphone
}
create() {
this.cellphone.create()
this.createShell(cellphone)
}
createShell() {
console.log('生成手机壳')
}
}
// 测试代码
let cellphone = new Cellphone()
cellphone.create()
console.log('------------')
let dec = new Decorator(cellphone)
dec.create()
```

View File

@ -3,12 +3,62 @@ nav:
title: 前端
path: /fea
group:
title: 设计模式
title: 💊 设计模式
order: 6
---
## 发布订阅者模式
定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使它们能够自动更新自己,当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。
### 简单版
```js
// 主题 保存状态,状态变化之后触发所有观察者对象
class Subject {
constructor() {
this.state = 0
this.observers = []
}
getState() {
return this.state
}
setState(state) {
this.state = state
this.notifyAllObservers()
}
notifyAllObservers() {
this.observers.forEach(observer => {
observer.update()
})
}
attach(observer) {
this.observers.push(observer)
}
}
// 观察者
class Observer {
constructor(name, subject) {
this.name = name
this.subject = subject
this.subject.attach(this)
}
update() {
console.log(`${this.name} update, state: ${this.subject.getState()}`)
}
}
// 测试
let s = new Subject()
let o1 = new Observer('o1', s)
let o2 = new Observer('02', s)
s.setState(12)
```
### 复杂版
```js
/**
* 发布订阅者模式

View File

@ -3,16 +3,15 @@ nav:
title: 前端
path: /fea
group:
title: 设计模式
title: 💊 设计模式
order: 1
---
## 工厂模式
可以简单理解为批量生产
工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。
```js
// ------------------- 工厂模式 -------------------
class User {
constructor(type) {
if (new.target === User) {

View File

@ -3,12 +3,16 @@ nav:
title: 前端
path: /fea
group:
title: 设计模式
title: 💊 设计模式
order: 5
---
## 代理模式
是为一个对象提供一个代用品或占位符,以便控制对它的访问
### ES5 版
```js
/**
* 代理模式
@ -28,4 +32,34 @@ export default class ProxyPro {
})
}
}
```
### ES6 版
```js
let Flower = function() {}
let xiaoming = {
sendFlower: function(target) {
let flower = new Flower()
target.receiveFlower(flower)
}
}
let B = {
receiveFlower: function(flower) {
A.listenGoodMood(function() {
A.receiveFlower(flower)
})
}
}
let A = {
receiveFlower: function(flower) {
console.log('收到花'+ flower)
},
listenGoodMood: function(fn) {
setTimeout(function() {
fn()
}, 1000)
}
}
xiaoming.sendFlower(B)
```

View File

@ -3,12 +3,14 @@ nav:
title: 前端
path: /fea
group:
title: 设计模式
title: 💊 设计模式
order: 2
---
## 单例模式
一个类只有一个实例,并提供一个访问它的全局访问点。
```js
// ------------------- 单例模式 -------------------
export default class Singleton {

View File

@ -3,7 +3,7 @@ nav:
title: 前端
path: /fea
group:
title: 设计模式
title: 💊 设计模式
order: 7
---
@ -37,5 +37,5 @@ class CalculateMoney {
let calculateMoney = new CalculateMoney('', 10000)
// console.log(calculateMoney);
// => 4000000
```

View File

@ -1,7 +1,7 @@
---
hero:
title: niceNote
desc: Json's 学习笔记
desc: 💊 Json's 学习笔记
actions:
- text: 开始学习
link: /fea
@ -19,3 +19,4 @@ footer: Open-source MIT Licensed | Copyright © 2020<br />Powered by Json
---
嗨~

@ -1 +0,0 @@
Subproject commit 421af564f3cf2953a822fe25ecdea03536a58950

1
temp/javascript Submodule

@ -0,0 +1 @@
Subproject commit f5c14cae2ff58000cead98290b8ec4b54dda2f14

@ -0,0 +1 @@
Subproject commit 4548296affb227c29ead868309e48667f8280c55

@ -0,0 +1 @@
Subproject commit b16a2837446cfad928def157b769c46b3095aea7