feat: draw ts 改造
This commit is contained in:
parent
19d5f2ae40
commit
3f4a143038
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,9 @@
|
|||
import cnchar from '../src/main/index';
|
||||
// import cnchar from '../src/main/index';
|
||||
import cnchar from '../src/main/ts/index';
|
||||
import '../src/plugin/order';
|
||||
import '../src/plugin/trad';
|
||||
import '../src/plugin/poly';
|
||||
import '../src/plugin/draw';
|
||||
import '../src/plugin/draw/ts';
|
||||
import '../src/plugin/idiom';
|
||||
import '../src/plugin/xhy';
|
||||
import '../src/plugin/radical';
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import './extend';
|
||||
|
||||
declare type spellArg = 'array' | 'low' | 'up' | 'first' | 'poly' | 'tone' | 'simple' | 'trad';
|
||||
declare type strokeArg = 'letter' | 'shape' | 'count' | 'name' | 'detail' | 'array' | 'order' | 'simple' | 'trad';
|
||||
declare type spellToWordArg = 'poly' | 'alltone' | 'array' | 'simple' | 'trad';
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {CnCharInterface} from './types';
|
||||
import {ICnChar} from './types';
|
||||
|
||||
let _cnchar: CnCharInterface;
|
||||
let _cnchar: ICnChar;
|
||||
const toneCodes: Array<number> = [];
|
||||
|
||||
export function initToneCodes (__cnchar: CnCharInterface): void {
|
||||
export function initToneCodes (__cnchar: ICnChar): void {
|
||||
_cnchar = __cnchar;
|
||||
'aoeiuvn'.split('').forEach(item => {
|
||||
const code = item.charCodeAt(0);
|
||||
|
|
|
@ -5,6 +5,7 @@ import infoDict from './dict/info-dict.json';
|
|||
import {mapJson} from './util';
|
||||
import {transformTone, spell, arg, shapeSpell, stroke} from './tool';
|
||||
import {Json, ITransformReturn} from './types/common';
|
||||
import {ISetIntoJson} from './types/tool';
|
||||
|
||||
const strokeDict = originStrokeDict as Json<string>;
|
||||
// 设置多音字默认拼音
|
||||
|
@ -16,24 +17,18 @@ export function setSpellDefault (word: string | Json<string>, spell?: string): v
|
|||
isSpell: true
|
||||
});
|
||||
}
|
||||
|
||||
export function setIntoJson ({
|
||||
export const setIntoJson: ISetIntoJson = ({
|
||||
target,
|
||||
key,
|
||||
value,
|
||||
isSpell = false
|
||||
} : {
|
||||
target: Json<string>,
|
||||
key: string | Json<string>,
|
||||
value?: string,
|
||||
isSpell: boolean
|
||||
}): void {
|
||||
isSpell = false,
|
||||
}): void => {
|
||||
mapJson(key, value, (k, v) => {
|
||||
if (k && v) {
|
||||
target[k] = isSpell ? shapeSpell(v) : v;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function setIntoSpellBase (
|
||||
dict: Json<string>,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import {ICnChar} from './types/index';
|
||||
|
||||
declare const cnchar: ICnChar;
|
||||
|
||||
export default cnchar;
|
|
@ -9,7 +9,7 @@ import {setSpellDefault, setIntoJson, setSpell, setStrokeCount} from './config';
|
|||
import {initSpellToWord, spellToWord, spellInfo} from './spellToWord';
|
||||
import {initStrokeToWord, strokeToWord} from './strokeToWord';
|
||||
import {compareSpell, sortSpell, compareStroke, sortStroke, initSort} from './sort';
|
||||
import {CnCharInterface, SpellArg, StrokeArg} from './types';
|
||||
import {ICnChar, SpellArg, StrokeArg} from './types';
|
||||
import {IPlugin} from './types/common';
|
||||
|
||||
function _spell (...args: Array<string>): string | Array<string> {
|
||||
|
@ -28,7 +28,7 @@ function initStrProto () {
|
|||
};
|
||||
}
|
||||
|
||||
const cnchar: CnCharInterface = {
|
||||
const cnchar: ICnChar = {
|
||||
version,
|
||||
spell: _spell,
|
||||
stroke: _stroke,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "cnchar",
|
||||
"version": "2.2.8",
|
||||
"lockfileVersion": 1
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "cnchar",
|
||||
"version": "2.2.8",
|
||||
"description": "功能全面、多端支持的汉字拼音笔画js库,支持多音字、繁体字、火星文",
|
||||
"main": "index.js",
|
||||
"scripts": {},
|
||||
"unpkg": "cnchar.min.js",
|
||||
"jsdelivr": "cnchar.min.js",
|
||||
"typings": "index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/theajack/cnchar.git"
|
||||
},
|
||||
"keywords": [
|
||||
"汉字拼音",
|
||||
"汉字笔画数",
|
||||
"汉字笔画顺序",
|
||||
"繁体字",
|
||||
"火星文",
|
||||
"js库",
|
||||
"theajack"
|
||||
],
|
||||
"author": "theajack",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/theajack/cnchar/issues"
|
||||
},
|
||||
"homepage": "https://www.theajack.com/cnchar/"
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import {initToneCodes, getCharCode} from './compareSpell';
|
||||
import {CnCharInterface, CompareType, SortSpellArg} from './types';
|
||||
import {ICnChar, CompareType, SortSpellArg, SpellArg} from './types';
|
||||
|
||||
let _cnchar: CnCharInterface;
|
||||
let _cnchar: ICnChar;
|
||||
|
||||
const arg:{
|
||||
[prop in SortSpellArg]: SortSpellArg
|
||||
|
@ -10,7 +10,7 @@ const arg:{
|
|||
'desc': 'desc',
|
||||
};
|
||||
|
||||
export function initSort (__cnchar: CnCharInterface) {
|
||||
export function initSort (__cnchar: ICnChar) {
|
||||
_cnchar = __cnchar;
|
||||
initToneCodes(__cnchar);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ const TYPE:{
|
|||
};
|
||||
|
||||
function pretreat (spell: string, tone: boolean): string {
|
||||
const arr: Array<spellArg> = ['low'];
|
||||
const arr: Array<SpellArg> = ['low'];
|
||||
if (tone) {arr.push('tone');}
|
||||
if (_cnchar.isCnChar(spell)) {
|
||||
return _cnchar.spell(spell, ...arr) as string;
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
import originDict from './dict/spell-dict-jian.json';
|
||||
import {initial as initialDict} from './dict/info-dict.json';
|
||||
import {CnCharInterface, CncharToolInterface, ToneType, TypeValueObject, SpellToWordArg} from './types/index';
|
||||
import {SpellInfoInterface, Json, spellInfoReturnInterface} from './types/common';
|
||||
import {ICnChar, ToneType, TypeValueObject, SpellToWordArg} from './types/index';
|
||||
import {ICncharTool} from './types/tool';
|
||||
import {ISpellInfo, Json, ISpellInfoReturn} from './types/common';
|
||||
|
||||
const dict = originDict as Json<string>;
|
||||
|
||||
const arg: {
|
||||
[prop in SpellToWordArg]: SpellToWordArg
|
||||
} = {simple: 'simple', trad: 'trad', poly: 'poly', alltone: 'alltone', array: 'array'};
|
||||
let _: CncharToolInterface;// 工具方法
|
||||
let _: ICncharTool;// 工具方法
|
||||
|
||||
|
||||
// 获取拼音信息 spell,tone,index,initial,final
|
||||
export const spellInfo = ((spell: string): spellInfoReturnInterface => {
|
||||
export const spellInfo = ((spell: string): ISpellInfoReturn => {
|
||||
spell = spell.toLowerCase();
|
||||
const info = _.removeTone(spell, false);
|
||||
if (info.index === -1) {
|
||||
|
@ -37,9 +38,9 @@ export const spellInfo = ((spell: string): spellInfoReturnInterface => {
|
|||
initial,
|
||||
final,
|
||||
};
|
||||
}) as unknown as SpellInfoInterface;
|
||||
}) as unknown as ISpellInfo;
|
||||
|
||||
export function initSpellToWord (cnchar: CnCharInterface): void {
|
||||
export function initSpellToWord (cnchar: ICnChar): void {
|
||||
_ = cnchar._;
|
||||
spellInfo.tones = _.tones.split('');
|
||||
spellInfo.initials = initialDict;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import dict from './dict/stroke-count-jian.json';
|
||||
import {Json} from './types/common';
|
||||
import {CnCharInterface, CncharToolInterface, StrokeToWordArg, TypeValueObject} from './types/index';
|
||||
import {ICnChar, StrokeToWordArg, TypeValueObject} from './types/index';
|
||||
import {ICncharTool} from './types/tool';
|
||||
const arg: {
|
||||
[prop in StrokeToWordArg]: StrokeToWordArg
|
||||
} = {simple: 'simple', trad: 'trad', array: 'array'};
|
||||
let _: CncharToolInterface;// 工具方法
|
||||
let _: ICncharTool;// 工具方法
|
||||
|
||||
export function initStrokeToWord (cnchar: CnCharInterface): void {
|
||||
export function initStrokeToWord (cnchar: ICnChar): void {
|
||||
cnchar.strokeToWord = strokeToWord;
|
||||
cnchar.type.strokeToWord = arg as TypeValueObject;
|
||||
_ = cnchar._;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import {spellInfo} from './spellToWord';
|
||||
import {_warn, isCnChar, has} from './util';
|
||||
import defultDict from './dict/spell-default.json';
|
||||
import {AllArgs, CnCharInterface, TypeProp, ToneType, SpellArg, StrokeArg, TypeValueObject} from './types/index';
|
||||
import {AllArgs, ICnChar, TypeProp, ToneType, SpellArg, StrokeArg, TypeValueObject} from './types/index';
|
||||
import {Json, ITransformReturn} from './types/common';
|
||||
import {TSpellArg, IDealUpLowFirst, IRemoveTone, IFunc, ICheckArgs, ITransformTone} from './types/tool';
|
||||
|
||||
const defDict = defultDict as Json<string>;
|
||||
|
||||
export const tones: string = 'āáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜ*ńňǹ'; // * 表示n的一声
|
||||
|
||||
const noTones: string = 'aoeiuün';
|
||||
|
||||
export const arg: {
|
||||
[prop in SpellArg]: SpellArg
|
||||
} = {
|
||||
export const arg: TSpellArg = {
|
||||
array: 'array',
|
||||
low: 'low',
|
||||
up: 'up',
|
||||
|
@ -22,8 +22,8 @@ export const arg: {
|
|||
trad: 'trad',
|
||||
};
|
||||
|
||||
let _cnchar: CnCharInterface;
|
||||
export function initCnchar (cnchar: CnCharInterface): void {
|
||||
let _cnchar: ICnChar;
|
||||
export function initCnchar (cnchar: ICnChar): void {
|
||||
_cnchar = cnchar;
|
||||
}
|
||||
|
||||
|
@ -95,10 +95,10 @@ export function spell (dict: Json<string>, originArgs: Array<string>): string |
|
|||
return result;
|
||||
}
|
||||
|
||||
export function dealUpLowFirst (
|
||||
export const dealUpLowFirst: IDealUpLowFirst = (
|
||||
res: Array<Array<string>> | Array<string>,
|
||||
args: Array<SpellArg>
|
||||
): void {
|
||||
): void => {
|
||||
if (_cnchar._.poly) {
|
||||
dealResCase(res, low);
|
||||
// 当启用了 多音词时 需要强制默认小写
|
||||
|
@ -112,7 +112,7 @@ export function dealUpLowFirst (
|
|||
} else if (!has(args, arg.low)) {
|
||||
dealResCase(res, upFirst);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function dealResCase (
|
||||
res: Array<Array<string>> | Array<string>,
|
||||
|
@ -175,9 +175,9 @@ function getSpell (
|
|||
|
||||
// tone=false : 根据有音调的拼音获得无音调的拼音和音调
|
||||
// tone=true : 返回原拼音
|
||||
export function removeTone (spell: string, tone: boolean): {
|
||||
export const removeTone: IRemoveTone = (spell: string, tone: boolean): {
|
||||
spell: string, tone?: ToneType, index?: number
|
||||
} {
|
||||
} => {
|
||||
if (tone) {
|
||||
return {spell};
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ export function removeTone (spell: string, tone: boolean): {
|
|||
}
|
||||
}
|
||||
return {spell, tone: 0, index: -1};
|
||||
}
|
||||
};
|
||||
|
||||
function setTone (spell: string, index: number, tone: ToneType): string {
|
||||
if (tone === 0) { // 轻声
|
||||
|
@ -233,13 +233,13 @@ export function stroke (
|
|||
}
|
||||
return strokes;
|
||||
}
|
||||
export function sumStroke (strs: Array<number>): number {
|
||||
export const sumStroke: IFunc<number, Array<number>> = (strs: Array<number>): number => {
|
||||
let sum: number = 0;
|
||||
strs.forEach(function (c) {
|
||||
sum += c;
|
||||
});
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
// spell 所有参数 ["array", "low", "up", "first", "poly", "tone", "simple"]
|
||||
// simple 禁用繁体字
|
||||
|
@ -247,11 +247,11 @@ export function sumStroke (strs: Array<number>): number {
|
|||
// stroke 所有参数 ["letter", "shape", "count", "name", "detail", "array", "order", "simple"]
|
||||
//
|
||||
let _hasCheck: boolean = false;
|
||||
export function checkArgs (
|
||||
export const checkArgs: ICheckArgs = (
|
||||
type: TypeProp,
|
||||
args: Array<AllArgs>,
|
||||
jumpNext?: boolean
|
||||
): void {
|
||||
): void => {
|
||||
if (!_cnchar.check) {
|
||||
return;
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ export function checkArgs (
|
|||
warnArgs(useless, '无效', type, args);
|
||||
warnArgs(ignore, '被忽略', type, args);
|
||||
warnArgs(redunt, '冗余', type, args);
|
||||
}
|
||||
};
|
||||
function warnArgs (
|
||||
arr: Array<AllArgs>,
|
||||
txt: string,
|
||||
|
@ -366,11 +366,11 @@ export function shapeSpell (spell: string): string {
|
|||
// lv2 => {spell:'lü', tone: 2, index: 2, isTrans: true}
|
||||
// lǘ => {spell:'lü', tone: 2, index: 2, isTrans: false}
|
||||
// needTone = true: lv2 => {spell:'lǘ', tone: 2, index: 2, isTrans: true}
|
||||
export function transformTone (
|
||||
export const transformTone: ITransformTone = (
|
||||
spell: string,
|
||||
needTone: boolean = false,
|
||||
type: 'low' | 'up' = 'low'
|
||||
): ITransformReturn {
|
||||
): ITransformReturn => {
|
||||
if (spell.indexOf('v') !== -1) {
|
||||
spell = spell.replace('v', 'ü');
|
||||
}
|
||||
|
@ -402,4 +402,4 @@ export function transformTone (
|
|||
spell = spell.toUpperCase();
|
||||
}
|
||||
return {spell, tone, index, isTrans};
|
||||
}
|
||||
};
|
|
@ -1,10 +1,10 @@
|
|||
import {CnCharInterface, ToneType} from '.';
|
||||
import {ICnChar, ToneType} from '.';
|
||||
|
||||
export declare interface Json<T = any> {
|
||||
[prop: string]: T
|
||||
}
|
||||
|
||||
export declare interface spellInfoReturnInterface {
|
||||
export declare interface ISpellInfoReturn {
|
||||
spell: string;
|
||||
initial: string;
|
||||
final: string;
|
||||
|
@ -12,8 +12,8 @@ export declare interface spellInfoReturnInterface {
|
|||
index: number;
|
||||
}
|
||||
|
||||
export declare interface SpellInfoInterface extends Function {
|
||||
(spell: string): spellInfoReturnInterface;
|
||||
export declare interface ISpellInfo extends Function {
|
||||
(spell: string): ISpellInfoReturn;
|
||||
tones: Array<string>,
|
||||
initials: Array<string>
|
||||
}
|
||||
|
@ -26,13 +26,20 @@ export declare interface ITransformReturn {
|
|||
}
|
||||
|
||||
export declare interface IPlugin {
|
||||
(cnchar: CnCharInterface): void;
|
||||
init?(cnchar: CnCharInterface): void;
|
||||
(cnchar: ICnChar): void;
|
||||
init?(cnchar: ICnChar): void;
|
||||
}
|
||||
export declare interface ConvertInterface {
|
||||
simpleToSpark(sentence: string): string;
|
||||
simpleToTrad(sentence: string): string;
|
||||
sparkToSimple(sentence: string): string;
|
||||
sparkToTrad(sentence: string): string;
|
||||
tradToSimple(sentence: string): string;
|
||||
tradToSpark(sentence: string): string;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
cnchar: CnCharInterface,
|
||||
CnChar: CnCharInterface,
|
||||
cnchar: ICnChar,
|
||||
CnChar: ICnChar,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,4 @@
|
|||
import './extend';
|
||||
import {has, _throw, _warn, isCnChar, mapJson} from '../util';
|
||||
import {
|
||||
arg, removeTone, tones, checkArgs, transformTone,
|
||||
sumStroke, dealUpLowFirst
|
||||
} from '../tool';
|
||||
import {ConvertInterface} from '../../../plugin/trad/index';
|
||||
import {Json} from './common';
|
||||
import {setIntoJson} from '../config';
|
||||
|
||||
import {ICncharTool} from './tool';
|
||||
|
||||
export declare type SpellArg = 'array' | 'low' | 'up' | 'first' | 'poly' | 'tone' | 'simple' | 'trad';
|
||||
export declare type StrokeArg = 'letter' | 'shape' | 'count' | 'name' | 'detail' | 'array' | 'order' | 'simple' | 'trad';
|
||||
|
@ -26,7 +17,7 @@ export declare type ToneType = 0 | 1 | 2 | 3 | 4;
|
|||
export declare type CompareType = 'more' | 'less' | 'even' | 'error';
|
||||
|
||||
|
||||
export declare interface spellInfoReturnInterface {
|
||||
export declare interface ISpellInfoReturn {
|
||||
spell: string;
|
||||
initial: string;
|
||||
final: string;
|
||||
|
@ -34,43 +25,22 @@ export declare interface spellInfoReturnInterface {
|
|||
index: number;
|
||||
}
|
||||
|
||||
export declare interface CncharToolInterface {
|
||||
arg: typeof arg,
|
||||
has: typeof has,
|
||||
_throw: typeof _throw,
|
||||
tones: typeof tones,
|
||||
setIntoJson: typeof setIntoJson,
|
||||
_warn: typeof _warn,
|
||||
dealUpLowFirst: typeof dealUpLowFirst,
|
||||
removeTone: typeof removeTone,
|
||||
sumStroke: typeof sumStroke,
|
||||
isCnChar: typeof isCnChar,
|
||||
checkArgs: typeof checkArgs,
|
||||
transformTone: typeof transformTone,
|
||||
convert?: ConvertInterface, //
|
||||
dict: {
|
||||
getTradOrders?(): Json<string>;
|
||||
getTradCount?(): Json<string>;
|
||||
},
|
||||
mapJson: typeof mapJson,
|
||||
poly?: boolean,
|
||||
}
|
||||
|
||||
export declare type TypeProp = 'spell' | 'stroke' | 'spellToWord' | 'strokeToWord' | 'orderToWord' | 'idiom' | 'xhy' | 'radical';
|
||||
|
||||
export declare type TypeValueObject = {
|
||||
[prop in AllArgs]?: AllArgs;
|
||||
};
|
||||
|
||||
export declare interface CnCharInterface {
|
||||
[x: string]: any;
|
||||
spell(sentence: string, ...args: Array<SpellArg>): string | Array<any>;
|
||||
stroke(sentence: string, ...args: Array<StrokeArg>): number | Array<any>;
|
||||
declare interface ISpell {(sentence: string, ...args: Array<SpellArg>): string | Array<any>;}
|
||||
declare interface IStroke {(sentence: string, ...args: Array<StrokeArg>): number | Array<any>;}
|
||||
export declare interface ICnChar {
|
||||
spell: ISpell;
|
||||
stroke: IStroke;
|
||||
use(...plugins: Array<Function>): void;
|
||||
spellToWord(spell: string, ...args: Array<SpellToWordArg>): string | Array<string>;
|
||||
strokeToWord(stroke: number, ...args: Array<StrokeToWordArg>): string | Array<string>;
|
||||
spellInfo: {
|
||||
(spell: string): spellInfoReturnInterface;
|
||||
(spell: string): ISpellInfoReturn;
|
||||
tones: Array<string>;
|
||||
initials: Array<string>;
|
||||
};
|
||||
|
@ -101,9 +71,13 @@ export declare interface CnCharInterface {
|
|||
setStrokeCount(json: {[key: string]: number}): void;
|
||||
shapeSpell(spell: string): string;
|
||||
|
||||
_: CncharToolInterface;
|
||||
_: ICncharTool;
|
||||
_origin: {
|
||||
spell: ISpell;
|
||||
stroke: IStroke;
|
||||
};
|
||||
}
|
||||
|
||||
declare const cnchar: CnCharInterface;
|
||||
declare const cnchar: ICnChar;
|
||||
|
||||
export default cnchar;
|
|
@ -0,0 +1,77 @@
|
|||
import {Json, ConvertInterface, ITransformReturn} from './common';
|
||||
import {AllArgs, SpellArg, ToneType, TypeProp} from '.';
|
||||
|
||||
export declare interface ISetIntoJson {
|
||||
(option: {
|
||||
target: Json<string>,
|
||||
key: string | Json<string>,
|
||||
value?: string,
|
||||
isSpell: boolean
|
||||
}): void
|
||||
}
|
||||
|
||||
export declare type TSpellArg = {
|
||||
[prop in SpellArg]: SpellArg
|
||||
}
|
||||
|
||||
export declare interface IHas {(args: Array<AllArgs>, name: AllArgs): boolean;}
|
||||
|
||||
export declare interface IFunc<T = void, A = string> {(arg: A): T;}
|
||||
|
||||
export declare interface IDealUpLowFirst {
|
||||
(
|
||||
res: Array<Array<string>> | Array<string>,
|
||||
args: Array<SpellArg>
|
||||
): void;
|
||||
}
|
||||
|
||||
export declare interface IRemoveTone {
|
||||
(spell: string, tone: boolean): {spell: string, tone?: ToneType, index?: number};
|
||||
}
|
||||
|
||||
export declare interface IMapJson {
|
||||
(
|
||||
key: Json | string,
|
||||
value: undefined | any,
|
||||
cb: (key: string, value: any) => void
|
||||
): void;
|
||||
}
|
||||
|
||||
export declare interface ICheckArgs {
|
||||
(
|
||||
type: TypeProp,
|
||||
args: Array<AllArgs>,
|
||||
jumpNext?: boolean
|
||||
): void;
|
||||
}
|
||||
|
||||
export declare interface ITransformTone {
|
||||
(
|
||||
spell: string,
|
||||
needTone?: boolean,
|
||||
type?: 'low' | 'up'
|
||||
): ITransformReturn;
|
||||
}
|
||||
|
||||
export declare interface ICncharTool {
|
||||
arg: TSpellArg;
|
||||
has: IHas;
|
||||
_throw: IFunc<never>;
|
||||
tones: string;
|
||||
setIntoJson: ISetIntoJson;
|
||||
_warn: IFunc;
|
||||
dealUpLowFirst: IDealUpLowFirst;
|
||||
removeTone: IRemoveTone;
|
||||
sumStroke: IFunc<number, Array<number>>;
|
||||
isCnChar: IFunc<boolean>;
|
||||
checkArgs: ICheckArgs;
|
||||
transformTone: ITransformTone;
|
||||
convert?: ConvertInterface;
|
||||
dict: {
|
||||
getTradOrders?(): Json<string>;
|
||||
getTradCount?(): Json<string>;
|
||||
};
|
||||
mapJson: IMapJson;
|
||||
poly?: boolean;
|
||||
}
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
import infoDict from './dict/info-dict.json';
|
||||
import {AllArgs} from './types';
|
||||
import {Json} from './types/common';
|
||||
import {IHas, IFunc, IMapJson} from './types/tool';
|
||||
|
||||
export function mapJson (
|
||||
export const mapJson: IMapJson = (
|
||||
key: Json | string,
|
||||
value: undefined | any,
|
||||
cb: (key: string, value: any) => void
|
||||
): void {
|
||||
): void => {
|
||||
if (typeof key === 'object') {
|
||||
for (const k in key) {
|
||||
cb(k, key[k]);
|
||||
|
@ -14,16 +15,16 @@ export function mapJson (
|
|||
return;
|
||||
}
|
||||
cb(key, value);
|
||||
}
|
||||
};
|
||||
|
||||
export function isCnChar (word: string): boolean {
|
||||
export const isCnChar: IFunc<boolean> = (word: string): boolean => {
|
||||
const unicode: number = word.charCodeAt(0);
|
||||
return unicode >= 19968 && unicode <= 40869;
|
||||
}
|
||||
};
|
||||
|
||||
export function has (args: Array<AllArgs>, name: AllArgs): boolean {
|
||||
export const has: IHas = (args: Array<AllArgs>, name: AllArgs): boolean => {
|
||||
return args.indexOf(name) !== -1;
|
||||
}
|
||||
};
|
||||
|
||||
export function isPolyWord (word: string): boolean {
|
||||
if (word === '') {
|
||||
|
@ -38,11 +39,12 @@ export function isPolyWord (word: string): boolean {
|
|||
return infoDict.polyWord.indexOf(word) !== -1;
|
||||
}
|
||||
|
||||
export function _throw (err: string): never {
|
||||
export const _throw: IFunc<never> = (err: string): never => {
|
||||
throw new Error('CnChar Error:' + err);
|
||||
}
|
||||
export function _warn (err: string): void {
|
||||
console.warn('CnChar Warning:' + err);
|
||||
}
|
||||
};
|
||||
|
||||
export const _warn: IFunc<void> = (info: string): void => {
|
||||
console.warn('CnChar Warning:' + info);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ function merge (type, args) {
|
|||
const json = {};
|
||||
for (const key in args) {
|
||||
const arg = args[key];
|
||||
debugger;
|
||||
for (const k in arg) {
|
||||
if (!isUd(arg[k])) {
|
||||
json[k] = arg[k];
|
||||
|
|
|
@ -32,15 +32,15 @@ declare interface DrawOption {
|
|||
clear?: boolean; // 绘制前是否清空容器 默认为true
|
||||
style?: { // 样式类
|
||||
backgroundColor?: string, // 默认为#fff
|
||||
showOutline?: boolean;//: true,
|
||||
showCharacter?: boolean;//: true,
|
||||
currentColor?: string;//: '#b44', // 仅在stroke模式下有效
|
||||
length?: number;//: 60,
|
||||
padding?: number;//: 5, // 数值, 默认 20。 画布的汉字和边缘之间的填充
|
||||
outlineColor?: string;//: '#ddd', // 十六进制字符, 默认 '#DDD'。
|
||||
strokeColor?: string;//: '#555', // 十六进制字符, 默认 '#555'。绘制每个笔划的颜色。
|
||||
radicalColor?: string;//: null, // 十六进制字符, 默认 null。 如果存在偏旁部首数据,则在笔划中绘制偏旁部首的颜色。 如果没有设置,激光将绘制与其他笔划相同的颜色。
|
||||
strokeFadeDuration?: number; //400
|
||||
showOutline?: boolean;// : true,
|
||||
showCharacter?: boolean;// : true,
|
||||
currentColor?: string;// : '#b44', // 仅在stroke模式下有效
|
||||
length?: number;// : 60,
|
||||
padding?: number;// : 5, // 数值, 默认 20。 画布的汉字和边缘之间的填充
|
||||
outlineColor?: string;// : '#ddd', // 十六进制字符, 默认 '#DDD'。
|
||||
strokeColor?: string;// : '#555', // 十六进制字符, 默认 '#555'。绘制每个笔划的颜色。
|
||||
radicalColor?: string;// : null, // 十六进制字符, 默认 null。 如果存在偏旁部首数据,则在笔划中绘制偏旁部首的颜色。 如果没有设置,激光将绘制与其他笔划相同的颜色。
|
||||
strokeFadeDuration?: number; // 400
|
||||
},
|
||||
line?: { // 背景线条类
|
||||
lineStraight?: boolean;// : true,
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
import {IDrawOption, IDrawClassOption, TDrawType, TTestStatusType} from './types/common';
|
||||
import {Json} from 'cnchar/types/common';
|
||||
|
||||
export const TYPE = {
|
||||
export const TYPE: Json<TDrawType> = {
|
||||
NORMAL: 'normal',
|
||||
ANIMATION: 'animation',
|
||||
STROKE: 'stroke',
|
||||
TEST: 'test'
|
||||
};
|
||||
|
||||
export const TEST_STATUS = {
|
||||
export const TEST_STATUS: Json<TTestStatusType> = {
|
||||
MISTAKE: 'mistake',
|
||||
CORRECT: 'correct',
|
||||
COMPLETE: 'complete'
|
||||
};
|
||||
|
||||
const DrawOption = {
|
||||
export const DrawOption: IDrawOption = {
|
||||
showOutline: true,
|
||||
showCharacter: true,
|
||||
currentColor: '#b44',
|
||||
|
@ -64,9 +66,8 @@ function isUd (v: any): boolean {
|
|||
return typeof v === 'undefined';
|
||||
}
|
||||
|
||||
// 使用npm link配置本地开发目录
|
||||
export function merge (type, args) {
|
||||
const json = {};
|
||||
export function merge (type: TDrawType, args: IDrawClassOption): IDrawOption {
|
||||
const json: IDrawOption = {};
|
||||
for (const key in args) {
|
||||
const arg = args[key];
|
||||
for (const k in arg) {
|
||||
|
@ -83,7 +84,7 @@ export function merge (type, args) {
|
|||
return json;
|
||||
}
|
||||
|
||||
function checkTypeDefault (type, args, json) {
|
||||
function checkTypeDefault (type: IDrawOption, args: IDrawClassOption, json: IDrawOption): void {
|
||||
if (type === TYPE.ANIMATION) {
|
||||
if (!args.animation || isUd(args.animation.showCharacter)) {
|
||||
json.showCharacter = false;
|
||||
|
@ -93,7 +94,7 @@ function checkTypeDefault (type, args, json) {
|
|||
}
|
||||
}
|
||||
|
||||
function check (json, attrs) {
|
||||
function check (json: IDrawOption, attrs?: Array<string>): IDrawOption {
|
||||
attrs = attrs || Object.keys(DrawOption);
|
||||
attrs.forEach(attr => {
|
||||
if (isUd(json[attr])) {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import HanziWriter from './types/hanzi-writer';
|
||||
|
||||
export default HanziWriter;
|
|
@ -1,100 +1,8 @@
|
|||
declare type DrawType = 'normal' | 'animation' | 'stroke' | 'test';
|
||||
declare type TestStatusType = 'mistake' | 'correct' | 'complete';
|
||||
declare class Writer {
|
||||
constructor();
|
||||
option: object;
|
||||
el: HTMLElement;
|
||||
type: DrawType;
|
||||
text: Array<string>;
|
||||
writer: Array<object>;
|
||||
animateStart():void;
|
||||
}
|
||||
|
||||
declare interface TestStatus {
|
||||
index: number,
|
||||
status: TestStatusType,
|
||||
data: {
|
||||
character: string;
|
||||
totalMistakes: number;// 到目前为止在测验期间犯的总错误。
|
||||
strokeNum?: number;// 当前笔画数。
|
||||
mistakesOnStroke?: number;// 到目前为止用户绘制此笔划所犯的错误数。
|
||||
strokesRemaining?: number;// 测验完成前剩余的笔画数。
|
||||
drawnPath?: {
|
||||
pathString: string;
|
||||
points: Array<{x:number;y:number}>
|
||||
};// 对象包含用户绘制的 pathString ,用于评分的分数。
|
||||
}
|
||||
}
|
||||
|
||||
declare interface DrawOption {
|
||||
el?: string | HTMLElement; // 绘制的容器,支持选择器或dom,若是不填,会在body后append一个dom作为容器
|
||||
type?: DrawType; // 绘制模式,默认为normal
|
||||
clear?: boolean; // 绘制前是否清空容器 默认为true
|
||||
style?: { // 样式类
|
||||
backgroundColor?: string, // 默认为#fff
|
||||
showOutline?: boolean;// : true,
|
||||
showCharacter?: boolean;// : true,
|
||||
currentColor?: string;// : '#b44', // 仅在stroke模式下有效
|
||||
length?: number;// : 60,
|
||||
padding?: number;// : 5, // 数值, 默认 20。 画布的汉字和边缘之间的填充
|
||||
outlineColor?: string;// : '#ddd', // 十六进制字符, 默认 '#DDD'。
|
||||
strokeColor?: string;// : '#555', // 十六进制字符, 默认 '#555'。绘制每个笔划的颜色。
|
||||
radicalColor?: string;// : null, // 十六进制字符, 默认 null。 如果存在偏旁部首数据,则在笔划中绘制偏旁部首的颜色。 如果没有设置,激光将绘制与其他笔划相同的颜色。
|
||||
strokeFadeDuration?: number; // 400
|
||||
},
|
||||
line?: { // 背景线条类
|
||||
lineStraight?: boolean;// : true,
|
||||
lineCross?: boolean;// : true,
|
||||
lineWidth?: number;// : 1,
|
||||
lineColor?: string;// : '#ddd',
|
||||
lineDash?: boolean;// : true,
|
||||
border?: boolean;// : true,
|
||||
borderWidth?: number;// : 1,
|
||||
borderColor?: string;// : '#ccc',
|
||||
borderDash?: boolean;// : false,
|
||||
},
|
||||
animation?: {
|
||||
strokeAnimationSpeed?: number;// : 1, // 数值, 默认 1。 绘制每个笔划的速度必须大于0。增加此数字可以更快地绘制笔划,减少绘制笔划的速度更慢。
|
||||
delayBetweenStrokes?: number;// : 1000, // 数值, 默认 1000。 动画进行中每个笔画之间的间隔时间(以毫秒为单位)。
|
||||
delayBetweenLoops?: number;// : 200, // 数值, 默认 2000。 循环动画时每个动画循环之间的时间(以毫秒为单位)。
|
||||
autoAnimate?: boolean;// : true,
|
||||
animateComplete?: Function;// : () => {},
|
||||
stepByStep?: boolean;// : true,
|
||||
loopAnimate?: boolean;// : false,
|
||||
},
|
||||
test?: {
|
||||
strokeHighlightSpeed?: number;// : 20, // 数值, 默认 20。 在测验中给出提示时突出显示每个笔划的速度必须大于0。增加此数字以突出显示更快,减少以突出显示更慢。
|
||||
highlightColor?: number;// : '#aaf', // 十六进制字符, 默认 '#AAF'。 用于在测验中突出显示的颜色。
|
||||
drawingColor?: number;// : '#333', // 十六进制字符, 默认 '#333'。 测验期间绘制的线条颜色。
|
||||
drawingWidth?: number;// : 4, // 数值, 默认 4。 进行测验时绘制的线条宽度。
|
||||
showHintAfterMisses?: number;// : 3, // 整数, 默认 3 中风高亮提示之前的未命中数被给予用户。 设置为 false 以禁用。 创建测验时也可以设置此项。
|
||||
highlightOnComplete?: number;// : true, // 布尔值, 默认 true。 控制当用户完成绘制整个字符时,测验是否会短暂突出显示字符。 创建测验时也可以设置此项。
|
||||
highlightCompleteColor?: number;// : null, // 十六进制字符, 默认 null。 在测验中突出显示字符时使用的颜色。 如果未设置,则将使用highlightColor。 仅当highlightOnComplete为true时才相关。
|
||||
onTestStatus?(args: TestStatus):void;// : null, // ({index, status, data})=>{}
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Draw {
|
||||
(text:string, option?:DrawOption):Writer;
|
||||
TYPE: {
|
||||
ANIMATION: 'animation',
|
||||
NORMAL: 'normal',
|
||||
STROKE: 'stroke',
|
||||
TEST: 'test'
|
||||
},
|
||||
TEST_STATUS: {
|
||||
MISTAKE: 'mistake',
|
||||
CORRECT: 'correct',
|
||||
COMPLETE: 'complete'
|
||||
}
|
||||
}
|
||||
|
||||
declare const draw: Draw;
|
||||
|
||||
import {IDraw} from './types/common';
|
||||
declare const draw: IDraw;
|
||||
declare module 'cnchar' {
|
||||
interface CnCharStatic {
|
||||
draw: Draw;
|
||||
draw: IDraw;
|
||||
}
|
||||
}
|
||||
|
||||
export default draw;
|
|
@ -1,9 +1,11 @@
|
|||
// powerd by hanzi-writer v2.2.2
|
||||
require('./promise-polyfill');
|
||||
const draw = require('./writer');
|
||||
import {ICnChar} from 'cnchar/types';
|
||||
import './promise-polyfill';
|
||||
import {IDraw} from './types/common';
|
||||
import draw from './writer';
|
||||
|
||||
|
||||
function main (cnchar) {
|
||||
export default function main (cnchar: ICnChar & {draw?: IDraw}): void {
|
||||
if (cnchar.plugins.indexOf('draw') !== -1) {
|
||||
return;
|
||||
}
|
||||
|
@ -11,7 +13,7 @@ function main (cnchar) {
|
|||
cnchar.draw = draw;
|
||||
}
|
||||
|
||||
function init (cnchar) {
|
||||
function init (cnchar?: ICnChar): void {
|
||||
if (typeof window === 'object') {
|
||||
window.CncharDraw = draw;
|
||||
}
|
||||
|
@ -25,5 +27,3 @@ function init (cnchar) {
|
|||
draw.init = init;
|
||||
|
||||
init();
|
||||
|
||||
module.exports = draw;
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
import {IBuildLineStr} from './types/common';
|
||||
|
||||
function buildLinesStr ({
|
||||
export function buildLinesStr ({
|
||||
width,
|
||||
lineStraight,
|
||||
lineCross,
|
||||
|
@ -11,7 +11,10 @@ function buildLinesStr ({
|
|||
borderWidth,
|
||||
borderColor,
|
||||
borderDash,
|
||||
}) {
|
||||
}: IBuildLineStr): {
|
||||
lineHTML: string,
|
||||
border: string
|
||||
} {
|
||||
let str = '';
|
||||
let attr = '';
|
||||
if (lineDash) {
|
||||
|
@ -35,5 +38,3 @@ function buildLinesStr ({
|
|||
}
|
||||
return {lineHTML: str, border: _border};
|
||||
}
|
||||
|
||||
module.exports = {buildLinesStr};
|
|
@ -1,8 +1,10 @@
|
|||
const HanziWriter = require('./hanzi-writer');
|
||||
import HanziWriter from './hanzi-writer';
|
||||
import {Writer} from './writer';
|
||||
import {ICloneSvg, IDrawOption} from './types/common';
|
||||
|
||||
function stroke (writer, cloneSvg) {
|
||||
export function stroke (writer: Writer, cloneSvg: ICloneSvg): void {
|
||||
writer.text.forEach((s) => {
|
||||
const target = document.createElement('div');
|
||||
const target: HTMLElement = document.createElement('div');
|
||||
writer.el.appendChild(target);
|
||||
HanziWriter.loadCharacterData(s).then(function (charData) {
|
||||
for (var i = 0; i < charData.strokes.length; i++) {
|
||||
|
@ -21,13 +23,29 @@ function stroke (writer, cloneSvg) {
|
|||
}
|
||||
|
||||
|
||||
function renderFanningStrokes ({option, target, strokes, radStrokes, cloneSvg, current, width}) {
|
||||
function renderFanningStrokes ({
|
||||
option,
|
||||
target,
|
||||
strokes,
|
||||
radStrokes,
|
||||
cloneSvg,
|
||||
current,
|
||||
width
|
||||
}: {
|
||||
option: IDrawOption;
|
||||
target: HTMLElement,
|
||||
strokes: Array<string>;
|
||||
radStrokes: Array<number>;
|
||||
cloneSvg: ICloneSvg,
|
||||
current: number;
|
||||
width: number;
|
||||
}): void {
|
||||
const radicalColor = (radStrokes.length > 0 && option.radicalColor) ? option.radicalColor : null;
|
||||
var svg = cloneSvg(option);
|
||||
const svg = cloneSvg(option);
|
||||
target.appendChild(svg);
|
||||
var group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
const group: SVGGElement = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
|
||||
var transformData = HanziWriter.getScalingTransform(width, width, option.padding);
|
||||
const transformData = HanziWriter.getScalingTransform(width, width, option.padding);
|
||||
group.setAttributeNS(null, 'transform', transformData.transform);
|
||||
svg.appendChild(group);
|
||||
for (let i = 0; i <= current; i++) {
|
||||
|
@ -46,12 +64,10 @@ function renderFanningStrokes ({option, target, strokes, radStrokes, cloneSvg, c
|
|||
}
|
||||
}
|
||||
|
||||
function renderPath (strokePath, group, color) {
|
||||
var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
function renderPath (strokePath: string, group: SVGGElement, color: string): void {
|
||||
const path: SVGPathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
path.setAttributeNS(null, 'd', strokePath);
|
||||
// style the character paths
|
||||
path.style.fill = color;
|
||||
group.appendChild(path);
|
||||
}
|
||||
|
||||
module.exports = {stroke};
|
|
@ -0,0 +1,118 @@
|
|||
import {IWriter} from './index';
|
||||
import {Json} from 'cnchar/types/common';
|
||||
import {ICnChar} from 'cnchar/types';
|
||||
|
||||
export declare type TDrawType = 'normal' | 'animation' | 'stroke' | 'test';
|
||||
export declare type TTestStatusType = 'mistake' | 'correct' | 'complete';
|
||||
|
||||
export declare interface ITestStatusData {
|
||||
character: string;
|
||||
totalMistakes: number;// 到目前为止在测验期间犯的总错误。
|
||||
strokeNum?: number;// 当前笔画数。
|
||||
mistakesOnStroke?: number;// 到目前为止用户绘制此笔划所犯的错误数。
|
||||
strokesRemaining?: number;// 测验完成前剩余的笔画数。
|
||||
drawnPath?: {
|
||||
pathString: string;
|
||||
points: Array<{x:number;y:number}>;
|
||||
};// 对象包含用户绘制的 pathString ,用于评分的分数。
|
||||
}
|
||||
|
||||
declare interface ITestStatus {
|
||||
index: number;
|
||||
status: TTestStatusType;
|
||||
data: ITestStatusData;
|
||||
}
|
||||
|
||||
export declare interface IDrawStyleOption { // 样式类
|
||||
backgroundColor?: string, // 默认为#fff
|
||||
showOutline?: boolean;// : true,
|
||||
showCharacter?: boolean;// : true,
|
||||
currentColor?: string;// : '#b44', // 仅在stroke模式下有效
|
||||
length?: number;// : 60,
|
||||
padding?: number;// : 5, // 数值, 默认 20。 画布的汉字和边缘之间的填充
|
||||
outlineColor?: string;// : '#ddd', // 十六进制字符, 默认 '#DDD'。
|
||||
strokeColor?: string;// : '#555', // 十六进制字符, 默认 '#555'。绘制每个笔划的颜色。
|
||||
radicalColor?: string;// : null, // 十六进制字符, 默认 null。 如果存在偏旁部首数据,则在笔划中绘制偏旁部首的颜色。 如果没有设置,激光将绘制与其他笔划相同的颜色。
|
||||
strokeFadeDuration?: number; // 400
|
||||
}
|
||||
|
||||
export declare interface IDrawLineOption { // 背景线条类
|
||||
lineStraight?: boolean;// : true,
|
||||
lineCross?: boolean;// : true,
|
||||
lineWidth?: number;// : 1,
|
||||
lineColor?: string;// : '#ddd',
|
||||
lineDash?: boolean;// : true,
|
||||
border?: boolean;// : true,
|
||||
borderWidth?: number;// : 1,
|
||||
borderColor?: string;// : '#ccc',
|
||||
borderDash?: boolean;// : false,
|
||||
}
|
||||
|
||||
export declare interface IDrawAnimationOption {
|
||||
strokeAnimationSpeed?: number;// : 1, // 数值, 默认 1。 绘制每个笔划的速度必须大于0。增加此数字可以更快地绘制笔划,减少绘制笔划的速度更慢。
|
||||
delayBetweenStrokes?: number;// : 1000, // 数值, 默认 1000。 动画进行中每个笔画之间的间隔时间(以毫秒为单位)。
|
||||
delayBetweenLoops?: number;// : 200, // 数值, 默认 2000。 循环动画时每个动画循环之间的时间(以毫秒为单位)。
|
||||
autoAnimate?: boolean;// : true,
|
||||
animateComplete?: Function;// : () => {},
|
||||
stepByStep?: boolean;// : true,
|
||||
loopAnimate?: boolean;// : false,
|
||||
showCharacter?: boolean;// : true,
|
||||
}
|
||||
export declare interface IDrawTestOption {
|
||||
strokeHighlightSpeed?: number;// : 20, // 数值, 默认 20。 在测验中给出提示时突出显示每个笔划的速度必须大于0。增加此数字以突出显示更快,减少以突出显示更慢。
|
||||
highlightColor?: string;// : '#aaf', // 十六进制字符, 默认 '#AAF'。 用于在测验中突出显示的颜色。
|
||||
drawingColor?: string;// : '#333', // 十六进制字符, 默认 '#333'。 测验期间绘制的线条颜色。
|
||||
drawingWidth?: number;// : 4, // 数值, 默认 4。 进行测验时绘制的线条宽度。
|
||||
showHintAfterMisses?: number;// : 3, // 整数, 默认 3 中风高亮提示之前的未命中数被给予用户。 设置为 false 以禁用。 创建测验时也可以设置此项。
|
||||
highlightOnComplete?: boolean;// : true, // 布尔值, 默认 true。 控制当用户完成绘制整个字符时,测验是否会短暂突出显示字符。 创建测验时也可以设置此项。
|
||||
highlightCompleteColor?: number;// : null, // 十六进制字符, 默认 null。 在测验中突出显示字符时使用的颜色。 如果未设置,则将使用highlightColor。 仅当highlightOnComplete为true时才相关。
|
||||
onTestStatus?(args: ITestStatus):void;// : null, // ({index, status, data})=>{}
|
||||
}
|
||||
|
||||
export declare interface IDrawClassOption {
|
||||
el?: string | HTMLElement; // 绘制的容器,支持选择器或dom,若是不填,会在body后append一个dom作为容器
|
||||
type?: TDrawType; // 绘制模式,默认为normal
|
||||
clear?: boolean; // 绘制前是否清空容器 默认为true
|
||||
style?: IDrawStyleOption;
|
||||
line?: IDrawLineOption;
|
||||
animation?: IDrawAnimationOption;
|
||||
test?: IDrawTestOption;
|
||||
}
|
||||
|
||||
export declare interface IDrawStrokeOption {
|
||||
|
||||
}
|
||||
|
||||
export declare interface IDrawOption extends IDrawStyleOption, IDrawLineOption, IDrawAnimationOption, IDrawTestOption {
|
||||
clear?: boolean;
|
||||
width?: number;
|
||||
height?: number;
|
||||
text?: string;
|
||||
}
|
||||
|
||||
export declare interface IBuildLineStr extends IDrawLineOption {
|
||||
width: number;
|
||||
}
|
||||
|
||||
export declare interface ICloneSvg{
|
||||
(option: IDrawOption): Node;
|
||||
}
|
||||
|
||||
export declare interface IDraw {
|
||||
(text: string, options: IDrawOption): IWriter;
|
||||
TYPE: Json<TDrawType>;
|
||||
TEST_STATUS: Json<TTestStatusType>;
|
||||
init?(cnchar?: ICnChar): void;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
CncharDraw: IDraw,
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'cnchar' {
|
||||
interface ICnChar {
|
||||
draw: IDraw;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import {IDrawOption, ITestStatusData} from './common';
|
||||
|
||||
declare type TDrawType = 'normal' | 'animation' | 'stroke' | 'test';
|
||||
|
||||
declare interface ICharData {
|
||||
strokes: Array<string>;
|
||||
radStrokes: Array<number>;
|
||||
medians: Array<Array<Array<number>>>;
|
||||
}
|
||||
|
||||
export default class HanziWriter {
|
||||
quiz(options: {
|
||||
onMistake (strokeData: ITestStatusData): void;
|
||||
onCorrectStroke (strokeData: ITestStatusData): void;
|
||||
onComplete (strokeData: ITestStatusData): void;
|
||||
}): void;
|
||||
hideCharacter(): void;
|
||||
animateCharacter(option: {
|
||||
onComplete(): void;
|
||||
}): void;
|
||||
static create(node: Node, text: string, option: IDrawOption): HanziWriter;
|
||||
static loadCharacterData(str: string): Promise<ICharData>;
|
||||
static getScalingTransform(width: number, height: number, padding: number);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
import {
|
||||
IDrawAnimationOption,
|
||||
IDrawLineOption,
|
||||
IDrawStyleOption,
|
||||
IDrawTestOption,
|
||||
IDrawStrokeOption,
|
||||
IDrawOption,
|
||||
TDrawType,
|
||||
} from './common';
|
||||
import HanziWriter from './hanzi-writer';
|
||||
|
||||
export declare interface IWriterOption {
|
||||
el?: string | HTMLElement;
|
||||
text?: string;
|
||||
clear?: boolean;
|
||||
type?: TDrawType;
|
||||
style?: IDrawStyleOption,
|
||||
line?: IDrawLineOption,
|
||||
animation?: IDrawAnimationOption,
|
||||
stroke?: IDrawStrokeOption,
|
||||
test?: IDrawTestOption,
|
||||
}
|
||||
export declare interface IWriter {
|
||||
option: IDrawOption;
|
||||
el: HTMLElement;
|
||||
type: TDrawType;
|
||||
text: Array<string>;
|
||||
writers: Array<HanziWriter>;
|
||||
init (): void;
|
||||
animate (complete: Function): void;
|
||||
animateStart(): void;
|
||||
loopAnimate(): void;
|
||||
_animateSingle (index: number, complete: Function): void;
|
||||
_animateStep (index: number, complete: Function): void;
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
function isCnChar (word) {
|
||||
export function isCnChar (word: string): boolean {
|
||||
const unicode = word.charCodeAt(0);
|
||||
return unicode >= 19968 && unicode <= 40869;
|
||||
}
|
||||
|
||||
function pickCnChar (text) {
|
||||
export function pickCnChar (text: string): string {
|
||||
let v = '';
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
if (isCnChar(text[i])) {
|
||||
|
@ -13,7 +12,3 @@ function pickCnChar (text) {
|
|||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isCnChar, pickCnChar
|
||||
};
|
|
@ -1,8 +1,21 @@
|
|||
const HanziWriter = require('./hanzi-writer');
|
||||
const {TYPE, merge, TEST_STATUS} = require('./default-option');
|
||||
const {pickCnChar} = require('./util');
|
||||
const {buildLinesStr} = require('./line');
|
||||
const {stroke} = require('./stroke');
|
||||
import HanziWriter from './hanzi-writer';
|
||||
import {TYPE, merge, TEST_STATUS} from './default-option';
|
||||
import {pickCnChar} from './util';
|
||||
import {buildLinesStr} from './line';
|
||||
import {stroke} from './stroke';
|
||||
import {IWriter, IWriterOption} from './types/index';
|
||||
import {
|
||||
TDrawType,
|
||||
IDrawOption,
|
||||
IDrawStyleOption,
|
||||
IDrawAnimationOption,
|
||||
IDrawLineOption,
|
||||
IDrawTestOption,
|
||||
IDrawStrokeOption,
|
||||
IBuildLineStr,
|
||||
ICloneSvg,
|
||||
IDraw
|
||||
} from './types/common';
|
||||
|
||||
const document = (typeof window === 'object') ? (window.document || null) : null;
|
||||
|
||||
|
@ -13,7 +26,13 @@ const svg = (() => {
|
|||
return document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
})();
|
||||
|
||||
class Writer {
|
||||
export class Writer implements IWriter {
|
||||
option: IDrawOption;
|
||||
el: HTMLElement;
|
||||
type: TDrawType;
|
||||
text: Array<string>;
|
||||
writers: Array<HanziWriter>;
|
||||
animateStart: () => void;
|
||||
constructor ({
|
||||
el = 'cnchar-draw',
|
||||
text = '',
|
||||
|
@ -24,18 +43,28 @@ class Writer {
|
|||
animation = {},
|
||||
stroke = {},
|
||||
test = {},
|
||||
}) {
|
||||
}: IWriterOption) {
|
||||
this.type = type;
|
||||
this.writers = [];
|
||||
this.text = text.split('');
|
||||
const opts = {style, line};
|
||||
const opts: {
|
||||
style: IDrawStyleOption;
|
||||
line: IDrawLineOption;
|
||||
animation?: IDrawAnimationOption;
|
||||
test?: IDrawTestOption;
|
||||
stroke?: IDrawStrokeOption;
|
||||
} = {style, line};
|
||||
switch (type) {
|
||||
case TYPE.ANIMATION: opts.animation = animation; break;
|
||||
case TYPE.STROKE: opts.stroke = stroke; break;
|
||||
case TYPE.TEST: opts.test = test; break;
|
||||
}
|
||||
this.option = merge(type, opts);
|
||||
this.el = typeof el === 'string' ? document.querySelector(el) : el;
|
||||
if (typeof el === 'string') {
|
||||
this.el = document.querySelector(el) || document.body;
|
||||
} else {
|
||||
this.el = el;
|
||||
}
|
||||
if (this.el && clear) {
|
||||
this.el.innerHTML = '';
|
||||
}
|
||||
|
@ -45,12 +74,12 @@ class Writer {
|
|||
}
|
||||
this.init();
|
||||
}
|
||||
init () {
|
||||
const {lineHTML, border} = buildLinesStr(this.option);
|
||||
const cloneSvg = (option) => {
|
||||
const node = svg.cloneNode();
|
||||
node.setAttribute('width', this.option.width);
|
||||
node.setAttribute('height', this.option.height);
|
||||
init (): void {
|
||||
const {lineHTML, border} = buildLinesStr(this.option as IBuildLineStr);
|
||||
const cloneSvg: ICloneSvg = (option: IDrawOption) => {
|
||||
const node = svg.cloneNode() as HTMLElement;
|
||||
node.setAttribute('width', this.option.width.toString());
|
||||
node.setAttribute('height', this.option.height.toString());
|
||||
if (border) {
|
||||
node.style.border = border;
|
||||
}
|
||||
|
@ -93,10 +122,10 @@ class Writer {
|
|||
this.el.addEventListener('click', start, false);
|
||||
}
|
||||
} else if (this.type === TYPE.TEST) {
|
||||
let opt = () => {return {};};
|
||||
let opt: Function;
|
||||
const fn = this.option.onTestStatus;
|
||||
if (typeof fn === 'function') {
|
||||
opt = (index) => {
|
||||
opt = (index: number) => {
|
||||
return {
|
||||
onMistake (strokeData) {
|
||||
fn({index, status: TEST_STATUS.MISTAKE, data: strokeData});
|
||||
|
@ -109,6 +138,8 @@ class Writer {
|
|||
}
|
||||
};
|
||||
};
|
||||
} else {
|
||||
opt = () => {return {};};
|
||||
}
|
||||
this.writers.forEach((writer, index) => {
|
||||
writer.quiz(opt(index));
|
||||
|
@ -116,7 +147,7 @@ class Writer {
|
|||
}
|
||||
}
|
||||
}
|
||||
animate (complete) {
|
||||
animate (complete: Function) {
|
||||
const opt = this.option;
|
||||
if (opt.stepByStep) { // 汉字之间连续绘制
|
||||
if (opt.showCharacter === false) {
|
||||
|
@ -147,18 +178,18 @@ class Writer {
|
|||
});
|
||||
}
|
||||
// animate单个汉字
|
||||
_animateSingle (i, complete) {
|
||||
if (i >= this.writers.length) {
|
||||
_animateSingle (index: number, complete: Function): void {
|
||||
if (index >= this.writers.length) {
|
||||
complete(true);
|
||||
return;
|
||||
}
|
||||
this.writers[i].animateCharacter({
|
||||
this.writers[index].animateCharacter({
|
||||
onComplete: () => {
|
||||
complete(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
_animateStep (index, complete) {
|
||||
_animateStep (index: number, complete: Function): void {
|
||||
this._animateSingle(index, (end) => {
|
||||
if (!end) {
|
||||
setTimeout(() => {
|
||||
|
@ -171,8 +202,7 @@ class Writer {
|
|||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function draw (text = '', options = {}) {
|
||||
const draw: IDraw = (text: string = '', options: IDrawOption = {}): IWriter => {
|
||||
if (typeof window === 'undefined') {
|
||||
console.error('Draw 方法仅支持在浏览器环境下使用');
|
||||
return null;
|
||||
|
@ -184,7 +214,9 @@ function draw (text = '', options = {}) {
|
|||
options.text = text;
|
||||
return new Writer(options);
|
||||
};
|
||||
|
||||
draw.TYPE = TYPE;
|
||||
draw.TEST_STATUS = TEST_STATUS;
|
||||
draw.init = null;
|
||||
|
||||
module.exports = draw;
|
||||
export default draw;
|
Loading…
Reference in New Issue