@ray-js/lamp-bead-strip 1.0.1-beta-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +131 -0
- package/lib/components/index.js +58 -0
- package/lib/components/index.json +4 -0
- package/lib/components/index.rjs +151 -0
- package/lib/components/index.tyml +11 -0
- package/lib/components/index.tyss +9 -0
- package/lib/components/mode/index.js +52 -0
- package/lib/components/mode/mode1.js +29 -0
- package/lib/components/mode/mode10.js +45 -0
- package/lib/components/mode/mode11.js +45 -0
- package/lib/components/mode/mode12.js +80 -0
- package/lib/components/mode/mode13.js +35 -0
- package/lib/components/mode/mode14.js +115 -0
- package/lib/components/mode/mode15.js +32 -0
- package/lib/components/mode/mode16.js +55 -0
- package/lib/components/mode/mode2.js +65 -0
- package/lib/components/mode/mode3.js +30 -0
- package/lib/components/mode/mode4.js +33 -0
- package/lib/components/mode/mode5.js +52 -0
- package/lib/components/mode/mode6.js +63 -0
- package/lib/components/mode/mode7.js +69 -0
- package/lib/components/mode/mode8.js +27 -0
- package/lib/components/mode/mode9.js +28 -0
- package/lib/components/utils.js +187 -0
- package/lib/index.config.js +11 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +20 -0
- package/lib/props.d.ts +67 -0
- package/lib/props.js +18 -0
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +21 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
English | [简体中文](./README-zh_CN.md)
|
|
2
|
+
|
|
3
|
+
# @ray-js/lamp-bead-strip
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@ray-js/lamp-bead-strip) [](https://www.npmjs.com/package/@ray-js/lamp-bead-strip)
|
|
6
|
+
|
|
7
|
+
> Animated LED strip
|
|
8
|
+
|
|
9
|
+
Directly using `canvas` to draw animation effects, and internally preventing duplicate rendering, achieving simultaneous rendering of multiple animations on low-end machine pages without stuttering.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
$ npm install @ray-js/lamp-bead-strip
|
|
15
|
+
# or
|
|
16
|
+
$ yarn add @ray-js/lamp-bead-strip
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Develop
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
# watch compile component code
|
|
23
|
+
yarn watch
|
|
24
|
+
# watch compile demo
|
|
25
|
+
yarn start:tuya
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
### Basic usage
|
|
31
|
+
|
|
32
|
+
`colors`and `canvasId`are mandatory, otherwise the animation cannot run`canvasId`must ensure page uniqueness. When we input different animation modes`mode`, the component will automatically play the animation.
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import LampBeadStrip from '@ray-js/lamp-bead-strip';
|
|
36
|
+
export default () => (
|
|
37
|
+
<LampBeadStrip
|
|
38
|
+
canvasId="diy-scene"
|
|
39
|
+
speed={80}
|
|
40
|
+
mode={10}
|
|
41
|
+
colors={['rgb(255,0,0)', 'rgb(0,255,0)', 'rgb(0,0,255)']}
|
|
42
|
+
contentValue={{ segmented: 1 }}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Pauses
|
|
48
|
+
|
|
49
|
+
`ready`allows you to set whether the animation of the component plays or pauses.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import LampBeadStrip from '@ray-js/lamp-bead-strip';
|
|
53
|
+
export default () => (
|
|
54
|
+
<LampBeadStrip
|
|
55
|
+
canvasId="diy-scene1"
|
|
56
|
+
mode={2}
|
|
57
|
+
ready={false}
|
|
58
|
+
colors={['rgb(255,0,0)', 'rgb(0,255,0)', 'rgb(0,0,255)']}
|
|
59
|
+
contentValue={{ segmented: 1, direction: 1 }}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Customize Scaling Size
|
|
65
|
+
|
|
66
|
+
Since the components are drawn through canvas, the internal dimensions are fixed. The component internally handles screen scaling logic, which is controlled through the`scale`property. If you want to modify the size of a component, you can customize the`scale`property to achieve your goal. The following use case expects the component size to be`1.1`times larger than before.
|
|
67
|
+
|
|
68
|
+
> It should be noted that the component only sets the scale once during initialization, so if the scale property is changed or set after initialization, it will be invalid
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import LampBeadStrip from '@ray-js/lamp-bead-strip';
|
|
72
|
+
import { getSystemInfoSync } from '@ray-js/ray';
|
|
73
|
+
|
|
74
|
+
const { windowWidth = 375 } = getSystemInfoSync();
|
|
75
|
+
export default () => {
|
|
76
|
+
const scale = (windowWidth / 375) * 1.1;
|
|
77
|
+
return (
|
|
78
|
+
<LampBeadStrip
|
|
79
|
+
containerStyle={`height: ${48 * 1.1}rpx;width:${570 * 1.1}rpx;`}
|
|
80
|
+
mode={16}
|
|
81
|
+
canvasId="template2"
|
|
82
|
+
scale={scale}
|
|
83
|
+
colors={['rgb(255,0,0)', 'rgb(0,255,0)', 'rgb(0,0,255)']}
|
|
84
|
+
contentValue={{ expand: 1 }}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Set the light off color
|
|
91
|
+
|
|
92
|
+
`closeColor` can set the color of lights that do not have color in the animation, that is, the color of the light beads that turn off the lights in the device. This way, the light strip component can adapt to multiple background colors, preventing the node color that turns off the lights from being the same as the background color.
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
import LampBeadStrip from '@ray-js/lamp-bead-strip';
|
|
96
|
+
|
|
97
|
+
export default () => {
|
|
98
|
+
return (
|
|
99
|
+
<LampBeadStrip
|
|
100
|
+
mode={16}
|
|
101
|
+
canvasId="template3"
|
|
102
|
+
closeColor="rgba(255,255,255,.6)"
|
|
103
|
+
colors={['rgb(255,0,0)', 'rgb(0,255,0)', 'rgb(0,0,255)']}
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
};
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Animation Mode
|
|
110
|
+
|
|
111
|
+
> Phase 1: 6, 1. Gradient, 2. Jump, 3. Breath, 4. Blink, 10. Flowing Water, 11. Rainbow
|
|
112
|
+
> Phase 2 10, 5 shooting stars, 6 accumulation, 7 falling, 8 chasing light, 9 drifting, 12 flashing, 13 rebounding, 14 shuttling, 15 chaotic flashing, 16 opening and closing
|
|
113
|
+
|
|
114
|
+
| Animation mode value | description | Contains control types contentValue |
|
|
115
|
+
| -------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------ |
|
|
116
|
+
| 1 | (Phase 1)Gradient | segmented(intact 0/subsection 1) |
|
|
117
|
+
| 2 | (Phase 1)Jump | segmented(intact 0/subsection 1) |
|
|
118
|
+
| 3 | (Phase 1)Breath | segmented(intact 0/subsection 1) |
|
|
119
|
+
| 4 | (Phase 1)Blink | segmented(intact 0/subsection 1) |
|
|
120
|
+
| 10 | (Phase 1)Flowing Water | direction(Clockwise 0/anti-clockwise 1) |
|
|
121
|
+
| 11 | (Phase 1)Rainbow | direction(Clockwise 0/anti-clockwise 1) |
|
|
122
|
+
| 5 | (Phase 2)shooting stars | direction(Clockwise 0/anti-clockwise 1) expand(shooting-stars 0/meteor-shower 1/Colorful-meteor 2) |
|
|
123
|
+
| 6 | (Phase 2)accumulation | direction(Clockwise 0/anti-clockwise 1) segmented(intact 0/subsection 1) |
|
|
124
|
+
| 7 | (Phase 2)falling | direction(Clockwise 0/anti-clockwise 1) segmented(intact 0/subsection 1) |
|
|
125
|
+
| 8 | (Phase 2)chasing light | direction(Clockwise 0/anti-clockwise 1) |
|
|
126
|
+
| 9 | (Phase 2)drifting | direction(Clockwise 0/anti-clockwise 1) |
|
|
127
|
+
| 12 | (Phase 2)flashing | segmented(intact 0/subsection 1) |
|
|
128
|
+
| 13 | (Phase 2)rebounding | expand(rebound 0/Colorful rebound 1) |
|
|
129
|
+
| 14 | (Phase 2)shuttling | - |
|
|
130
|
+
| 15 | (Phase 2)chaotic flashing | - |
|
|
131
|
+
| 16 | (Phase 2)opening and closing | expand(Same Time 0/staggered 1) |
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: mjh
|
|
3
|
+
* @Date: 2024-09-02 11:42:04
|
|
4
|
+
* @LastEditors: mjh
|
|
5
|
+
* @LastEditTime: 2024-10-16 17:37:37
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
import Render from './index.rjs';
|
|
9
|
+
// eslint-disable-next-line no-undef
|
|
10
|
+
Component({
|
|
11
|
+
properties: {
|
|
12
|
+
/** {
|
|
13
|
+
scale: Number,
|
|
14
|
+
mode: String,
|
|
15
|
+
ready: Boolean,
|
|
16
|
+
colors: Array,
|
|
17
|
+
canvasId: String,
|
|
18
|
+
contentValue: Object,
|
|
19
|
+
containerStyle: String,
|
|
20
|
+
canvasStyle: String,
|
|
21
|
+
closeColor: String
|
|
22
|
+
} */
|
|
23
|
+
prop: Object
|
|
24
|
+
},
|
|
25
|
+
data() {
|
|
26
|
+
return {
|
|
27
|
+
pre: {},
|
|
28
|
+
isReady: false
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
lifetimes: {
|
|
32
|
+
attached() {
|
|
33
|
+
this.render = new Render(this);
|
|
34
|
+
},
|
|
35
|
+
ready() {
|
|
36
|
+
if (!this.render) {
|
|
37
|
+
this.render = new Render(this);
|
|
38
|
+
}
|
|
39
|
+
this.pre = this.data.prop;
|
|
40
|
+
this.render.renderLight(this.data.prop);
|
|
41
|
+
this.isReady = true;
|
|
42
|
+
},
|
|
43
|
+
detached() {
|
|
44
|
+
this.render.stopLight();
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
observers: {
|
|
48
|
+
prop(res) {
|
|
49
|
+
// canvas元素加载完成后再渲染
|
|
50
|
+
if (!this.isReady || JSON.stringify(res) === JSON.stringify(this.pre || {})) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this.render.renderLight(res);
|
|
54
|
+
this.pre = res;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
methods: {}
|
|
58
|
+
});
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: mjh
|
|
3
|
+
* @Date: 2024-09-02 11:42:04
|
|
4
|
+
* @LastEditors: mjh
|
|
5
|
+
* @LastEditTime: 2024-10-21 14:31:04
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { topList } from './utils'
|
|
10
|
+
import modeOption from './mode/index'
|
|
11
|
+
export default Render({
|
|
12
|
+
ctx: null,
|
|
13
|
+
offset: 0,
|
|
14
|
+
scale: 1,
|
|
15
|
+
timer: null,
|
|
16
|
+
colors: [],
|
|
17
|
+
contentValue: {},
|
|
18
|
+
speed: 50,
|
|
19
|
+
ready: true,
|
|
20
|
+
mode: null,
|
|
21
|
+
animationStore: null,
|
|
22
|
+
closeRgb: null,
|
|
23
|
+
/**
|
|
24
|
+
* @name: 渲染灯带动画
|
|
25
|
+
* @desc:
|
|
26
|
+
* @param {*} props
|
|
27
|
+
* @return {*}
|
|
28
|
+
*/
|
|
29
|
+
async renderLight(props) {
|
|
30
|
+
this.scale = props.scale || 1;
|
|
31
|
+
if (!props.canvasId) {
|
|
32
|
+
console.log('canvasId 是必传项!');
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
// 初始化记录和缩放 canvas
|
|
36
|
+
if(!this.ctx) {
|
|
37
|
+
const canvas5 = await getCanvasById('ray-lamp-bead-strip-canvasId-' + props.canvasId);
|
|
38
|
+
this.ctx = canvas5.getContext('2d');
|
|
39
|
+
this.ctx.scale(this.scale, this.scale);
|
|
40
|
+
}
|
|
41
|
+
this.ready = props.ready ?? true
|
|
42
|
+
// 只有关键属性变化才重置动画
|
|
43
|
+
const isSameContent = `${props.closeColor}${props.mode}${props.colors.length}${props.contentValue.expand}${props.contentValue.segmented}` === `${this.closeRgb}${this.mode}${this.colors.length}${this.contentValue.expand}${this.contentValue.segmented}`
|
|
44
|
+
this.closeRgb = props.closeColor;
|
|
45
|
+
this.mode = props.mode;
|
|
46
|
+
this.colors = props.colors;
|
|
47
|
+
this.contentValue = props.contentValue || {};
|
|
48
|
+
this.speed = props.speed || 50;
|
|
49
|
+
// 获取对应模式的动画方法
|
|
50
|
+
const currFun = modeOption[this.mode];
|
|
51
|
+
const isSafe = this.errorCheck(currFun, props)
|
|
52
|
+
if(!isSafe) return
|
|
53
|
+
this.animationStore = modeOption[this.mode](props.colors, props.contentValue, this.closeRgb)
|
|
54
|
+
this.startLight(!isSameContent)
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* @name: 开始动画
|
|
58
|
+
* @desc:
|
|
59
|
+
* @param {*} init 是否重置动画
|
|
60
|
+
* @return {*}
|
|
61
|
+
*/
|
|
62
|
+
startLight(init) {
|
|
63
|
+
// 重置动画
|
|
64
|
+
if (init) {
|
|
65
|
+
this.offset = 0
|
|
66
|
+
}
|
|
67
|
+
this.stopLight();
|
|
68
|
+
this.draw();
|
|
69
|
+
// 动画更新时间
|
|
70
|
+
const speed = this.speed < 30 ? 200 + (30 - this.speed) * 5 : 6000 / this.speed;
|
|
71
|
+
if(!this.ready) return
|
|
72
|
+
this.timer = setInterval(() => {
|
|
73
|
+
this.draw();
|
|
74
|
+
},speed);
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* @name: 暂停动画
|
|
78
|
+
* @desc:
|
|
79
|
+
* @return {*}
|
|
80
|
+
*/
|
|
81
|
+
async stopLight() {
|
|
82
|
+
if (!this.timer) return;
|
|
83
|
+
clearInterval(this.timer);
|
|
84
|
+
this.timer = null;
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* @name: 绘制动画
|
|
88
|
+
* @desc:
|
|
89
|
+
* @return {*}
|
|
90
|
+
*/
|
|
91
|
+
draw() {
|
|
92
|
+
const { colorList, length } = this.animationStore
|
|
93
|
+
this.drawPoint(colorList[this.offset]);
|
|
94
|
+
this.offset += 1;
|
|
95
|
+
if(this.offset === length) this.offset = 0
|
|
96
|
+
},
|
|
97
|
+
/**
|
|
98
|
+
* @name: 绘制点
|
|
99
|
+
* @desc:
|
|
100
|
+
* @param {*} colorList 颜色列表
|
|
101
|
+
* @return {*}
|
|
102
|
+
*/
|
|
103
|
+
drawPoint(colorList) {
|
|
104
|
+
if(!colorList) return;
|
|
105
|
+
this.ctx.globalCompositeOperation = 'destination-over';
|
|
106
|
+
// clear canvas
|
|
107
|
+
this.ctx.clearRect(0, 0, this.ctx.canvas.clientWidth, this.ctx.canvas.clientHeight);
|
|
108
|
+
let startTop = (8.75 + 4.5)
|
|
109
|
+
colorList.forEach((_, index) => {
|
|
110
|
+
const color = colorList[index]
|
|
111
|
+
const topMid = topList[index]
|
|
112
|
+
startTop -= topMid
|
|
113
|
+
//开始绘制
|
|
114
|
+
this.ctx.beginPath();
|
|
115
|
+
this.ctx.arc(
|
|
116
|
+
(4.5 + 14.45 * index),
|
|
117
|
+
startTop,
|
|
118
|
+
4.5,
|
|
119
|
+
0,
|
|
120
|
+
2*Math.PI);
|
|
121
|
+
this.ctx.fillStyle = color;
|
|
122
|
+
this.ctx.fill();
|
|
123
|
+
})
|
|
124
|
+
},
|
|
125
|
+
/**
|
|
126
|
+
* @name: 异常错误检测
|
|
127
|
+
* @desc:
|
|
128
|
+
* @param {*} currFun 动画方法
|
|
129
|
+
* @param {*} props 入参
|
|
130
|
+
* @return {*}
|
|
131
|
+
*/
|
|
132
|
+
errorCheck(currFun, props) {
|
|
133
|
+
if (!currFun) {
|
|
134
|
+
console.error('错误的动画mode类型!');
|
|
135
|
+
return false
|
|
136
|
+
}
|
|
137
|
+
if (!props.colors?.length) {
|
|
138
|
+
console.error('未传入颜色列表!');
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
if (props.colors.some(item => typeof item === 'string' ? !item.startsWith('rgb(') : true)) {
|
|
142
|
+
console.error('颜色必须是rgb!');
|
|
143
|
+
return false
|
|
144
|
+
}
|
|
145
|
+
if (props.speed > 100 || props.speed < 1) {
|
|
146
|
+
console.error('错误的speed值,其范围为1~100!');
|
|
147
|
+
return false
|
|
148
|
+
}
|
|
149
|
+
return true
|
|
150
|
+
}
|
|
151
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<view
|
|
2
|
+
class="ray-lamp-bead-strip {{prop.className}}"
|
|
3
|
+
style="{{prop.containerStyle}}"
|
|
4
|
+
>
|
|
5
|
+
<canvas
|
|
6
|
+
type="2d"
|
|
7
|
+
class="ray-lamp-bead-strip-canvas"
|
|
8
|
+
canvas-id="ray-lamp-bead-strip-canvasId-{{prop.canvasId}}"
|
|
9
|
+
style="{{prop.canvasStyle}}"
|
|
10
|
+
></canvas>
|
|
11
|
+
</view>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** 一期 */
|
|
2
|
+
import mode1 from './mode1';
|
|
3
|
+
import mode2 from './mode2';
|
|
4
|
+
import mode3 from './mode3';
|
|
5
|
+
import mode4 from './mode4';
|
|
6
|
+
import mode10 from './mode10';
|
|
7
|
+
import mode11 from './mode11';
|
|
8
|
+
/** 二期 */
|
|
9
|
+
import mode5 from './mode5';
|
|
10
|
+
import mode6 from './mode6';
|
|
11
|
+
import mode7 from './mode7';
|
|
12
|
+
import mode8 from './mode8';
|
|
13
|
+
import mode9 from './mode9';
|
|
14
|
+
import mode12 from './mode12';
|
|
15
|
+
import mode13 from './mode13';
|
|
16
|
+
import mode14 from './mode14';
|
|
17
|
+
import mode15 from './mode15';
|
|
18
|
+
import mode16 from './mode16';
|
|
19
|
+
export default {
|
|
20
|
+
/** 渐变 */
|
|
21
|
+
1: mode1,
|
|
22
|
+
/** 跳变 */
|
|
23
|
+
2: mode2,
|
|
24
|
+
/** 呼吸 */
|
|
25
|
+
3: mode3,
|
|
26
|
+
/** 闪烁 */
|
|
27
|
+
4: mode4,
|
|
28
|
+
/** 流水 */
|
|
29
|
+
10: mode10,
|
|
30
|
+
/** 彩虹 */
|
|
31
|
+
11: mode11,
|
|
32
|
+
/** 流星 */
|
|
33
|
+
5: mode5,
|
|
34
|
+
/** 堆积 */
|
|
35
|
+
6: mode6,
|
|
36
|
+
/** 飘落 */
|
|
37
|
+
7: mode7,
|
|
38
|
+
/** 追光 */
|
|
39
|
+
8: mode8,
|
|
40
|
+
/** 飘动 */
|
|
41
|
+
9: mode9,
|
|
42
|
+
/** 闪现 */
|
|
43
|
+
12: mode12,
|
|
44
|
+
/** 反弹 */
|
|
45
|
+
13: mode13,
|
|
46
|
+
/** 穿梭 */
|
|
47
|
+
14: mode14,
|
|
48
|
+
/** 乱闪 */
|
|
49
|
+
15: mode15,
|
|
50
|
+
/** 开合 */
|
|
51
|
+
16: mode16
|
|
52
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { generateGradientColors, getListByIndex, arrayFill } from '../utils';
|
|
2
|
+
|
|
3
|
+
/** 渐变 */
|
|
4
|
+
const mode = (colors, option) => {
|
|
5
|
+
const {
|
|
6
|
+
segmented
|
|
7
|
+
} = option || {};
|
|
8
|
+
let allColor = [];
|
|
9
|
+
colors.forEach((element, index) => {
|
|
10
|
+
const afterColor = colors[index + 1] || colors[0];
|
|
11
|
+
const colorList = generateGradientColors([element, afterColor], 10);
|
|
12
|
+
allColor = [...allColor, ...colorList];
|
|
13
|
+
});
|
|
14
|
+
if (!segmented) {
|
|
15
|
+
const colorList = allColor.map(item => arrayFill(20, item));
|
|
16
|
+
return {
|
|
17
|
+
colorList,
|
|
18
|
+
length: colorList.length
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const colorList = allColor.map((_, index) => {
|
|
22
|
+
return [...arrayFill(4, allColor[index]), ...arrayFill(4, getListByIndex(allColor, index + 10)), ...arrayFill(4, getListByIndex(allColor, index + 20)), ...arrayFill(4, getListByIndex(allColor, index + 30)), ...arrayFill(4, getListByIndex(allColor, index + 40))];
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
colorList,
|
|
26
|
+
length: colorList.length
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export default mode;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: mjh
|
|
3
|
+
* @Date: 2024-10-21 14:23:12
|
|
4
|
+
* @LastEditors: mjh
|
|
5
|
+
* @LastEditTime: 2024-10-21 14:24:06
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
import { arrayFill } from '../utils';
|
|
9
|
+
|
|
10
|
+
/** 流水 */
|
|
11
|
+
const mode = (colors, option) => {
|
|
12
|
+
const {
|
|
13
|
+
direction
|
|
14
|
+
} = option || {};
|
|
15
|
+
let numList = [];
|
|
16
|
+
switch (colors.length) {
|
|
17
|
+
case 2:
|
|
18
|
+
numList = arrayFill(colors.length, 15);
|
|
19
|
+
break;
|
|
20
|
+
case 3:
|
|
21
|
+
numList = arrayFill(colors.length, 10);
|
|
22
|
+
break;
|
|
23
|
+
case 4:
|
|
24
|
+
case 5:
|
|
25
|
+
numList = arrayFill(colors.length, 6);
|
|
26
|
+
break;
|
|
27
|
+
case 6:
|
|
28
|
+
case 7:
|
|
29
|
+
case 8:
|
|
30
|
+
numList = arrayFill(colors.length, 5);
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
const allColor = numList.map((item, index) => arrayFill(item, colors[index])).flat(1);
|
|
36
|
+
const colorList = allColor.map((_, index) => {
|
|
37
|
+
const list = [...allColor.slice(index), ...allColor.slice(0, index)];
|
|
38
|
+
return direction ? list : list.reverse();
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
colorList,
|
|
42
|
+
length: colorList.length
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export default mode;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: mjh
|
|
3
|
+
* @Date: 2024-10-21 14:23:12
|
|
4
|
+
* @LastEditors: mjh
|
|
5
|
+
* @LastEditTime: 2024-10-21 14:24:33
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
import { arrayFill } from '../utils';
|
|
9
|
+
|
|
10
|
+
/** 彩虹 */
|
|
11
|
+
const mode = (colors, option) => {
|
|
12
|
+
const {
|
|
13
|
+
direction
|
|
14
|
+
} = option || {};
|
|
15
|
+
let colorList = colors;
|
|
16
|
+
switch (colors.length) {
|
|
17
|
+
case 2:
|
|
18
|
+
case 4:
|
|
19
|
+
case 6:
|
|
20
|
+
case 8:
|
|
21
|
+
colorList = arrayFill(5, colors).flat(1);
|
|
22
|
+
break;
|
|
23
|
+
case 3:
|
|
24
|
+
case 7:
|
|
25
|
+
colorList = arrayFill(10, colors).flat(1);
|
|
26
|
+
break;
|
|
27
|
+
case 5:
|
|
28
|
+
colorList = arrayFill(2, colors).flat(1);
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
const allColor = colorList.map(item => arrayFill(4, item)).flat(1);
|
|
34
|
+
const colorAnimation = allColor.map((_, index) => {
|
|
35
|
+
const endIndex = index + 20;
|
|
36
|
+
const endColor = endIndex > allColor.length - 1 ? allColor.slice(0, endIndex - allColor.length + 1) : [];
|
|
37
|
+
const list = [...allColor.slice(index, index + 20), ...endColor];
|
|
38
|
+
return direction ? list : list.reverse();
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
colorList: colorAnimation,
|
|
42
|
+
length: colorAnimation.length
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export default mode;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: mjh
|
|
3
|
+
* @Date: 2024-10-21 14:23:12
|
|
4
|
+
* @LastEditors: mjh
|
|
5
|
+
* @LastEditTime: 2024-10-21 14:27:13
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
import { arrayFill, splitArray } from '../utils';
|
|
9
|
+
|
|
10
|
+
/** 闪现 */
|
|
11
|
+
const mode = (colors, option, closeRgb) => {
|
|
12
|
+
const {
|
|
13
|
+
segmented
|
|
14
|
+
} = option || {};
|
|
15
|
+
const closeColors = arrayFill(4, closeRgb);
|
|
16
|
+
// 全段
|
|
17
|
+
if (!segmented) {
|
|
18
|
+
const colorAnimation = colors.map(item => {
|
|
19
|
+
let partCheckList = arrayFill(5, false);
|
|
20
|
+
const partColors = arrayFill(4, item);
|
|
21
|
+
const fillColors = arrayFill(6, '').map((_, index) => {
|
|
22
|
+
if (index) {
|
|
23
|
+
const currIndexList = [];
|
|
24
|
+
partCheckList.forEach((check, ind) => {
|
|
25
|
+
!check && currIndexList.push(ind);
|
|
26
|
+
});
|
|
27
|
+
const checkIndex = Math.ceil(Math.random() * (currIndexList.length - 1));
|
|
28
|
+
partCheckList[currIndexList[checkIndex]] = true;
|
|
29
|
+
}
|
|
30
|
+
const list = partCheckList.map(part => part ? partColors : closeColors).flat(1);
|
|
31
|
+
return arrayFill(2, list);
|
|
32
|
+
}).flat(1);
|
|
33
|
+
fillColors.push(...arrayFill(3, arrayFill(20, item)));
|
|
34
|
+
return fillColors;
|
|
35
|
+
}).flat(1);
|
|
36
|
+
return {
|
|
37
|
+
colorList: colorAnimation,
|
|
38
|
+
length: colorAnimation.length
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
// 分段
|
|
42
|
+
let colorList = colors;
|
|
43
|
+
switch (colors.length) {
|
|
44
|
+
case 2:
|
|
45
|
+
case 3:
|
|
46
|
+
case 4:
|
|
47
|
+
case 6:
|
|
48
|
+
case 7:
|
|
49
|
+
case 8:
|
|
50
|
+
colorList = arrayFill(5, colors).flat(1);
|
|
51
|
+
break;
|
|
52
|
+
case 5:
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
const splitColorList = splitArray(colorList, 5);
|
|
58
|
+
const colorAnimation = splitColorList.map(colorItemList => {
|
|
59
|
+
let partCheckList = arrayFill(5, false);
|
|
60
|
+
const fillColors = arrayFill(6, '').map((_, index) => {
|
|
61
|
+
if (index) {
|
|
62
|
+
const currIndexList = [];
|
|
63
|
+
partCheckList.forEach((item, ind) => {
|
|
64
|
+
!item && currIndexList.push(ind);
|
|
65
|
+
});
|
|
66
|
+
const checkIndex = Math.ceil(Math.random() * (currIndexList.length - 1));
|
|
67
|
+
partCheckList[currIndexList[checkIndex]] = true;
|
|
68
|
+
}
|
|
69
|
+
const list = partCheckList.map((item, indexs) => item ? arrayFill(4, colorItemList[indexs]) : closeColors).flat(1);
|
|
70
|
+
return arrayFill(3, list);
|
|
71
|
+
}).flat(1);
|
|
72
|
+
fillColors.push(...arrayFill(4, fillColors[fillColors.length - 1]));
|
|
73
|
+
return fillColors;
|
|
74
|
+
}).flat(1);
|
|
75
|
+
return {
|
|
76
|
+
colorList: colorAnimation,
|
|
77
|
+
length: colorAnimation.length
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
export default mode;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: mjh
|
|
3
|
+
* @Date: 2024-10-21 14:23:12
|
|
4
|
+
* @LastEditors: mjh
|
|
5
|
+
* @LastEditTime: 2024-10-21 14:27:45
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
import { arrayFill, generateGradientColors } from '../utils';
|
|
9
|
+
|
|
10
|
+
/** 反弹 */
|
|
11
|
+
const mode = (colors, option, closeRgb) => {
|
|
12
|
+
const {
|
|
13
|
+
expand
|
|
14
|
+
} = option || {};
|
|
15
|
+
const closeColors = arrayFill(20, closeRgb);
|
|
16
|
+
const colorList = colors % 2 === 0 ? colors : arrayFill(2, colors).flat(1);
|
|
17
|
+
let direction = 'right';
|
|
18
|
+
let isFirst = true;
|
|
19
|
+
const colorAnimation = colorList.map((item, index) => {
|
|
20
|
+
const currColors = !expand ? arrayFill(5, item) : generateGradientColors([item, colorList[index + 1] || colorList[0]], 5);
|
|
21
|
+
const colorRoadList = arrayFill(isFirst ? 16 : 15, '').map((_, ind) => {
|
|
22
|
+
const currList = [...closeColors];
|
|
23
|
+
currList.splice(isFirst ? ind : ind + 1, 5, ...currColors);
|
|
24
|
+
return direction === 'right' ? currList : currList.reverse();
|
|
25
|
+
});
|
|
26
|
+
isFirst = false;
|
|
27
|
+
direction = direction === 'right' ? 'left' : 'right';
|
|
28
|
+
return colorRoadList;
|
|
29
|
+
}).flat(1);
|
|
30
|
+
return {
|
|
31
|
+
colorList: colorAnimation,
|
|
32
|
+
length: colorAnimation.length
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export default mode;
|