feat: draw 分笔画绘制代码完成
This commit is contained in:
parent
577466b645
commit
978dd5ba3e
|
@ -14,10 +14,10 @@
|
|||
</style>
|
||||
</head>
|
||||
<body style="margin: 0">
|
||||
<div id='drawArea'></div>
|
||||
<div id='comment'>
|
||||
|
||||
</div>
|
||||
<div id='drawArea'></div>
|
||||
<script src="./bundle.js"></script>
|
||||
<script src="./bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -29,10 +29,10 @@ import '../src/cnchar/plugin/radical';
|
|||
// import '../npm/idiom/cnchar.idiom.min.js';
|
||||
// import '../npm/xhy/cnchar.xhy.min.js';
|
||||
// import '../npm/radical/cnchar.radical.min.js';
|
||||
import initComment from 'tc-comment';
|
||||
initComment({
|
||||
el: '#app'
|
||||
});
|
||||
// import initComment from 'tc-comment';
|
||||
// initComment({
|
||||
// el: '#comment'
|
||||
// });
|
||||
|
||||
console.log(cnchar);
|
||||
|
||||
|
@ -119,6 +119,33 @@ cnchar.draw('中国', {
|
|||
},
|
||||
});
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
aaa: any;
|
||||
}
|
||||
}
|
||||
|
||||
window.aaa = cnchar.draw('你好九', {
|
||||
type: cnchar.draw.TYPE.ANIMATION,
|
||||
style: {
|
||||
radicalColor: '#44f',
|
||||
backgroundColor: '#ccc'
|
||||
},
|
||||
animation: {
|
||||
animateComplete () {
|
||||
console.log('animateComplete');
|
||||
},
|
||||
loopAnimate: true,
|
||||
autoAnimate: false, // false 时点击出发animate 只能触发一次
|
||||
// stepByStep: false
|
||||
},
|
||||
test: {
|
||||
onTestStatus (d: any) {
|
||||
console.log(d);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// cnchar.draw('你好', {
|
||||
// type: cnchar.draw.TYPE.ANIMATION,
|
||||
// style: {
|
||||
|
|
|
@ -26,4 +26,8 @@ export default class HanziWriter {
|
|||
x: number;
|
||||
y: number;
|
||||
};
|
||||
pauseAnimation(): void;
|
||||
resumeAnimation(): void;
|
||||
animateStroke(strokeNum: number, options: {onComplete(): void}): void;
|
||||
V: any;
|
||||
}
|
|
@ -30,9 +30,8 @@ export declare interface IWriter {
|
|||
text: Array<string>;
|
||||
writers: Array<HanziWriter>;
|
||||
init (): void;
|
||||
animate (complete: IComplete): void;
|
||||
animateStart(): void;
|
||||
loopAnimate(): void;
|
||||
_animateSingle (index: number, complete: IComplete): void;
|
||||
_animateStep (index: number, complete: IComplete): void;
|
||||
startAnimation(): boolean;
|
||||
drawNextStroke(onComplete?: ()=>void): boolean;
|
||||
pauseAnimation(): void;
|
||||
resumeAnimation(): void;
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* @Author: theajack
|
||||
* @Date: 2021-08-05 23:05:21
|
||||
* @LastEditor: theajack
|
||||
* @LastEditTime: 2021-08-06 00:30:19
|
||||
* @Description: Coding something
|
||||
* @FilePath: \cnchar\src\cnchar\plugin\draw\animation-stroke.ts
|
||||
*/
|
||||
|
||||
import {IComplete, IWriter} from 'src/cnchar-types/plugin/draw';
|
||||
import {IDrawOption} from 'src/cnchar-types/plugin/draw/common';
|
||||
import HanziWriter from 'src/cnchar-types/plugin/draw/hanzi-writer';
|
||||
|
||||
const DRAW_MODE = {
|
||||
INITIAL: 0,
|
||||
ANIMATION: 1,
|
||||
STROKE: 2,
|
||||
};
|
||||
|
||||
export class AnimationWriter {
|
||||
writer: IWriter;
|
||||
|
||||
currentCharIndex: number;
|
||||
currentStrokeIndex: number;
|
||||
|
||||
drawMode: number;
|
||||
isPaused: boolean;
|
||||
option: IDrawOption;
|
||||
writers: Array<HanziWriter>;
|
||||
strokeDrawLocked: boolean;
|
||||
|
||||
constructor (writer: IWriter) {
|
||||
this.writer = writer;
|
||||
this.option = writer.option;
|
||||
this.writers = writer.writers;
|
||||
this.isPaused = false;
|
||||
this.drawMode = DRAW_MODE.INITIAL;
|
||||
this.currentCharIndex = 0;
|
||||
this.currentStrokeIndex = 0;
|
||||
this.strokeDrawLocked = false;
|
||||
}
|
||||
|
||||
private _getCurrentCharStrokeNumber () {
|
||||
return this.writers[this.currentCharIndex].V.strokes.length;
|
||||
}
|
||||
|
||||
private _isStepMode () {
|
||||
return this.option.stepByStep;
|
||||
}
|
||||
|
||||
private _animate (complete: IComplete = () => {}) {
|
||||
if (this._isStepMode()) { // 汉字之间连续绘制{
|
||||
if (this.option.showCharacter === false) {
|
||||
this.writers.forEach(writer => {
|
||||
writer.hideCharacter();
|
||||
});
|
||||
}
|
||||
this._animateStep(0, complete);
|
||||
} else { // 汉字一起绘制,笔画最多的绘制完成才算全部绘制完成
|
||||
let index = 0;
|
||||
for (let i = 0; i < this.writers.length; i++) {
|
||||
this._animateSingle(i, () => {
|
||||
index++;
|
||||
if (index === this.writers.length) {
|
||||
complete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawNextStroke (onComplete: ()=>void) {
|
||||
if (this.drawMode === DRAW_MODE.ANIMATION) {
|
||||
console.warn('当前为自动绘制模式');
|
||||
return false;
|
||||
} else if (this.drawMode === DRAW_MODE.INITIAL) {
|
||||
this.drawMode = DRAW_MODE.STROKE;
|
||||
}
|
||||
if (this.strokeDrawLocked) {
|
||||
console.warn('请等待上一步绘制完成');
|
||||
return false;
|
||||
}
|
||||
this.strokeDrawLocked = true;
|
||||
if (this.currentCharIndex === 0 && this.currentStrokeIndex === 0) {
|
||||
this.writers.forEach(writer => {
|
||||
writer.hideCharacter();
|
||||
});
|
||||
}
|
||||
this.writers[this.currentCharIndex].animateStroke(this.currentStrokeIndex, {
|
||||
onComplete: () => {
|
||||
onComplete();
|
||||
this.strokeDrawLocked = false;
|
||||
}
|
||||
});
|
||||
const thisCharStrokeNumber = this._getCurrentCharStrokeNumber();
|
||||
if (this.currentStrokeIndex >= thisCharStrokeNumber - 1) {
|
||||
this.currentStrokeIndex = 0;
|
||||
this.currentCharIndex ++;
|
||||
if (this.currentCharIndex === this.writer.text.length) {
|
||||
this.currentCharIndex = 0;
|
||||
}
|
||||
} else {
|
||||
this.currentStrokeIndex ++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
start () {
|
||||
if (this.drawMode !== DRAW_MODE.INITIAL) {
|
||||
console.warn('当前为手动绘制模式');
|
||||
return false;
|
||||
}
|
||||
this.drawMode = DRAW_MODE.ANIMATION;
|
||||
if (this.option.loopAnimate) {
|
||||
this._loop();
|
||||
} else {
|
||||
this._animate(this.option.animateComplete);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pause () {
|
||||
if (this.isPaused || !this._isStepMode()) return;
|
||||
this.isPaused = true;
|
||||
|
||||
this.writers[this.currentCharIndex].pauseAnimation();
|
||||
}
|
||||
|
||||
resume () {
|
||||
if (!this.isPaused || !this._isStepMode()) return;
|
||||
this.isPaused = false;
|
||||
|
||||
this.writers[this.currentCharIndex].resumeAnimation();
|
||||
}
|
||||
|
||||
private _loop () {
|
||||
const opt = this.option;
|
||||
this._animate(() => {
|
||||
if (opt.animateComplete)
|
||||
opt.animateComplete();
|
||||
setTimeout(() => {
|
||||
this._loop();
|
||||
}, opt.delayBetweenStrokes);
|
||||
});
|
||||
}
|
||||
|
||||
// animate单个汉字
|
||||
private _animateSingle (index: number, complete: IComplete): void {
|
||||
if (index >= this.writers.length) {
|
||||
complete(true);
|
||||
return;
|
||||
}
|
||||
this.writers[index].animateCharacter({
|
||||
onComplete: () => {
|
||||
complete(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
private _animateStep (index: number, complete: IComplete = () => {}): void {
|
||||
this.currentCharIndex = index;
|
||||
this._animateSingle(index, (end: boolean) => {
|
||||
if (!end) {
|
||||
setTimeout(() => {
|
||||
this._animateStep(index + 1, complete);
|
||||
}, this.option.delayBetweenStrokes);
|
||||
} else {
|
||||
complete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ import {TYPE, merge, TEST_STATUS} from './default-option';
|
|||
import {pickCnChar} from './util';
|
||||
import {buildLinesStr} from './line';
|
||||
import {stroke} from './stroke';
|
||||
import {IComplete, IWriter, IWriterOption} from 'cnchar-types/plugin/draw/index';
|
||||
import {IWriter, IWriterOption} from 'cnchar-types/plugin/draw/index';
|
||||
import {
|
||||
TDrawType,
|
||||
IDrawOption,
|
||||
|
@ -18,6 +18,7 @@ import {
|
|||
ITestStatusData
|
||||
} from 'cnchar-types/plugin/draw/common';
|
||||
import {querySelector} from './dom';
|
||||
import {AnimationWriter} from './animation-stroke';
|
||||
|
||||
// export const DEFAULT_WIDTH: number = 60;
|
||||
|
||||
|
@ -36,7 +37,7 @@ export class Writer implements IWriter {
|
|||
type: TDrawType;
|
||||
text: Array<string>;
|
||||
writers: Array<HanziWriter>;
|
||||
animateStart: () => void;
|
||||
animation: AnimationWriter;
|
||||
constructor ({
|
||||
el = 'cnchar-draw',
|
||||
text = '',
|
||||
|
@ -101,23 +102,12 @@ export class Writer implements IWriter {
|
|||
this.el.appendChild(node);
|
||||
});
|
||||
if (this.type === TYPE.ANIMATION) {
|
||||
let isStart = false;
|
||||
this.animateStart = () => {
|
||||
if (isStart) {
|
||||
return;
|
||||
}
|
||||
isStart = true;
|
||||
if (this.option.loopAnimate) {
|
||||
this.loopAnimate();
|
||||
} else {
|
||||
this.animate(this.option.animateComplete);
|
||||
}
|
||||
};
|
||||
this.animation = new AnimationWriter(this);
|
||||
if (this.option.autoAnimate) {
|
||||
this.animateStart();
|
||||
this.startAnimation();
|
||||
} else {
|
||||
const start = () => {
|
||||
this.animateStart();
|
||||
this.startAnimation();
|
||||
this.el.removeEventListener('click', start, false);
|
||||
};
|
||||
this.el.addEventListener('click', start, false);
|
||||
|
@ -148,59 +138,17 @@ export class Writer implements IWriter {
|
|||
}
|
||||
}
|
||||
}
|
||||
animate (complete: IComplete = () => {}) {
|
||||
const opt = this.option;
|
||||
if (opt.stepByStep) { // 汉字之间连续绘制
|
||||
if (opt.showCharacter === false) {
|
||||
this.writers.forEach(writer => {
|
||||
writer.hideCharacter();
|
||||
});
|
||||
}
|
||||
this._animateStep(0, complete);
|
||||
} else { // 汉字一起绘制,笔画最多的绘制完成才算全部绘制完成
|
||||
let index = 0;
|
||||
for (let i = 0; i < this.writers.length; i++) {
|
||||
this._animateSingle(i, () => {
|
||||
index++;
|
||||
if (index === this.writers.length) {
|
||||
complete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
startAnimation () {
|
||||
return this.animation.start();
|
||||
}
|
||||
loopAnimate () {
|
||||
const opt = this.option;
|
||||
this.animate(() => {
|
||||
if (opt.animateComplete)
|
||||
opt.animateComplete();
|
||||
setTimeout(() => {
|
||||
this.loopAnimate();
|
||||
}, opt.delayBetweenStrokes);
|
||||
});
|
||||
drawNextStroke (onComplete: ()=>void = () => {}) {
|
||||
return this.animation.drawNextStroke(onComplete);
|
||||
}
|
||||
// animate单个汉字
|
||||
_animateSingle (index: number, complete: IComplete): void {
|
||||
if (index >= this.writers.length) {
|
||||
complete(true);
|
||||
return;
|
||||
}
|
||||
this.writers[index].animateCharacter({
|
||||
onComplete: () => {
|
||||
complete(false);
|
||||
}
|
||||
});
|
||||
pauseAnimation () {
|
||||
this.animation.pause();
|
||||
}
|
||||
_animateStep (index: number, complete: IComplete = () => {}): void {
|
||||
this._animateSingle(index, (end: boolean) => {
|
||||
if (!end) {
|
||||
setTimeout(() => {
|
||||
this._animateStep(index + 1, complete);
|
||||
}, this.option.delayBetweenStrokes);
|
||||
} else {
|
||||
complete();
|
||||
}
|
||||
});
|
||||
resumeAnimation () {
|
||||
this.animation.resume();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue