本项目用于存放一些 es6 小工具
随机打散数组,并返回指数量与指定条件的数组。
语法:
randomList(list, count, filter)
parameters
name | type | detail |
---|---|---|
list | Array | 目标数组 |
count | Number | 返回的数组的个数 |
filter | Function | 过滤条件函数 |
return: [keys, vals]
具体参见:
// 引用模块
import randomList from `./modules/randomList`;
// 调用如下
let [keys, vals] = randomList([1, 2, 3, 4, 5], 2, (num) => num>5);
创建双向链表的类(构造函数)。Chain 已弃用不再维护。已经升级至 Chain_v2
语法:
new Chain(Array)
将传入的数组转化为一个链表。
return: {shift, unshift, pop, push, insertAfter, insertAfter, pointerAt, setPointer, prev, next, curr, first, last, remove, add, clone, splice, slice, concat, length, HEAD, TAIL, POINTER, chain}
name | type | detail |
---|---|---|
shift | Function | 删除链表第一个节点,并返回这个节点。参见数组的 shift |
unshift | Function | 向链表头部插入一个或多个节点节点。chain.unshift(node1[, node2, node3, ...]); 参见数组的 unshift |
pop | Function | 删除链表最后一个,并返回这个节点。参见数组的 pop |
push | Function | 向链表尾部插入一个或多个节点。chain.push(node1[, node2, node3, ...]); 参考数组的 push |
at | Function | 返回指定索引的节点,并将 POINTER 指向当前位置 |
pointerAt | Function | 返回指定 POINTER 地址的节点 |
setPointer | Function | 设置 POINTER 地址 |
prev | Function | 返回当前节点,并把 POINTER 指向上一个节点 |
next | Function | 返回当前节点,并把 POINTER 指向上一个节点 |
curr | Function | 返回当前节点 |
first | Function | 返回头节点 |
last | Function | 返回尾节点 |
remove | Function | 删除指定索引范围的节点,返回一个Chain实例。用法:chain.remove(start[, end]) |
insertAfter | Function | 向指定索引后插入节点。 用法:chain.insertAfter(index, node1[, node2, node3, ...]) |
insertBefore | Function | 向指定索引前插入节点。用法:chain.insertBefore(index, node1[, node2, node3, ...]) |
slice | Function | 克隆索引范围的节点,返回一个Chain实例。用法:chain.slice(start[, end]) |
splice | Function | 删除索引范围的节点,并在 start 处批量插入指定节点,返回一个 Chain 实例。用法:chain.splice(start[, deleteCount, item1, item2, ...]) |
concat | Function | 合并两个链表。用法:chainA.concat(chainB) |
clone | Function | 返回一个克隆链表 |
length | Number | 链表长度 |
HEAD | Number | 头指针 |
TAIL | Number | 尾指针 |
POINTER | Number | 当前位置指针 |
chain | Array | 存储链表结构的数组 |
Chain的实例同时是一个迭代器。如下:
import Chain from './modules/Chain';
let chain = new Chain([1, 2, 3, 4, 5, 6, 7]);
for(let it of chain) {
console.log(it.data)
}
上面代码输出的结果是:1, 2, 3, 4, 5, 6, 7
利用 next/prev 来做迭代,如下:
let chain = new Chain([1, 2, 3, 4, 5, 6, 7, 8]), item, i = 0;
chain.setPointer(3);
while(item = chain.prev()) {
console.log(item.data);
}
上面的结果是:4, 3, 2, 1
说明:由于最开始的结构设计不合理,导致 concat 的算法复杂度太高,不符合链表的表现。我决定重新设计一个 v2 版本
重新设计改写的 Chain
类,一个纯粹的链表类。API 与 Chain
几乎一样。
语法:
new Chain(Array)
将传入的数组转化为一个链表。
return: {shift, unshift, pop, push, insertAfter, insertAfter, prev, next, curr, first, last, remove, add, clone, reverse, slice, splice, concat, reverse, length, *setPointer, *setHead, *setTail, *HEAD, *TAIL, *POINTER, [Symbol.iterator]}
name | type | syntax | detail |
---|---|---|---|
shift | Function | chain.shift() | 删除链表第一个节点,并返回这个节点。 |
unshift | Function | chain.unshift(node1[, node2, node3, ...]) | 向链表头部插入一个或多个节点节点。 |
pop | Function | chain.pop() | 删除链表最后一个,并返回这个节点。 |
push | Function | chain.push(node1[, node2, node3, ...]) | 向链表尾部插入一个或多个节点。 参考数组的 push |
at | Function | chain.at(index) | 返回指定索引的节点,并将 POINTER 指向当前位置 |
prev | Function | chain.prev() | 返回当前节点,并把 POINTER 指向上一个节点 |
next | Function | chain.next() | 返回当前节点,并把 POINTER 指向上一个节点 |
curr | Function | chain.curr() | 返回当前节点 |
first | Function | chain.first() | 返回头节点 |
last | Function | chain.last() | 返回尾节点 |
indexOf | Function | chain.indexOf(value, fromIndex) | 返回 value 的索引位置,如果没有返回 -1 |
sort | Function | chain.sort(compare) | 链表排序 |
remove | Function | chain.remove(start[, end]) | 删除指定索引范围的节点,返回一个Chain实例。 |
insertAfter | Function | chain.insertAfter(index, node1[, node2, node3, ...]) | 向指定索引后插入节点。 |
insertBefore | Function | chain.insertBefore(index, node1[, node2, node3, ...]) | 向指定索引前插入节点。 |
insertChainAfter | Function | chainA.insertChainAfter(index, chainB) | 向指定索引后插入链表。 |
insertChainBefore | Function | chainA.insertChainBefore(index, chainB) | 向指定索引前插入链表。 |
slice | Function | chain.slice(start[, end]) | 克隆索引范围的节点,返回一个Chain实例。 |
splice | Function | chain.splice(start[, deleteCount, item1, item2, ...]) | 删除索引范围的节点,并在 start 处批量插入指定节点,返回一个 Chain 实例。 |
reverse | Function | chain.reverse() | 链表快速反转 |
concat | Function | chainA.concat(chainB) | 合并两个链表。 |
clone | Function | chain.clone() | 返回一个克隆链表 |
length | Number | chain.length | 链表长度 |
* setPointer |
Function | chain.setPointer(node = chain.HEAD) | 设置 POINTER 指针 |
* setHead |
Function | chain.setHead(node) | 设置头指针 |
* setTail |
Function | chain.setTail(node) | 设置尾指针 |
* HEAD |
Object | - | 头指针 |
* TAIL |
Object | - | 尾指针 |
* POINTER |
Object | - | 当前位置指针 |
* NEXT |
String | - | 前驱别名。勿调用! |
* PREV |
String | - | 后驱别名。勿调用! |
[Symbol.iterator] | Symbol | - | 迭代接口 |
注意加 *
的属性表示内部调用
Chain的实例同时是一个迭代器。如下:
import Chain from './modules/Chain';
let chain = new Chain([1, 2, 3, 4, 5, 6, 7]);
for(let it of chain) {
console.log(it.data)
}
上面代码输出的结果是:1, 2, 3, 4, 5, 6, 7
利用 next/prev 来做迭代,如下:
let chain = new Chain([1, 2, 3, 4, 5, 6, 7, 8]), item, i = 0;
chain.setPointer(3);
while(item = chain.prev()) {
console.log(item.data);
}
上面的结果是:4, 3, 2, 1
可以跟数组一样操作合并:
let chain = new Chain([1, 2, 3, 4, 5]);
let chain2 = new Chain(["a", "b", "c", "d", "e"]);
chain.concat(chain2);
for(let data of chain) {
console.log(data);
}
输出结果:1, 2, 3, 4, 5, a, b, c, d, e
统一管理 setTimeout/setInterval 的小库,可以与渲染引擎(如 createjs/PIXI 等)结合使用,也可以单独使用。
默认情况(非游戏开发):
import timer from './modules/timer';
let intervalID = timer.setInterval(() => console.log("++1s++"), 1000);
timer.setTimeout(() => timer.clearInterval(intervalID), 5000);
结合 createjs:
import timer from './modules/timer';
// 统一 ticker
createjs.Ticker.addEventListener("tick", function(e) {
e.paused || timer.update(e.delta);
});
// 计时
let intervalID = timer.setInterval(() => console.log("++1s++"), 1000);
// 5s 后暂停
timer.setTimeout(() => timer.pause(intervaID), 5000);
// 10s 后继续
timer.setTimeout(() => timer.resume(intervaID), 10000);
timer 的 APIs 如下:
name | type | syntax | detail |
---|---|---|---|
setTimeout | Function | let setTimeoutID = timer.setTimeout(fun, delay[, id]) | 替代原生setTimeout,第三个参数表示指定一个有意义的setTimeoutID |
clearTimeout | Function | timer.clearTimeout(setTimeoutID) | 清除timer.setTimeout |
setInterval | Function | let setIntervalID = timer.setInterval(fun, delay[, id]) | 替代原生setInterval,第三个参数表示指定一个有意义的setIntervalID |
clearInterval | Function | timer.clearInterval(setIntervalID) | 清除timer.clearInterval |
delete | Function | timer.delete(setTimeoutID/setIntervalID) | 相当于clearTimeout & clearInterval |
pause | Function | timer.pause(setTimeoutID/setIntervalID) | 暂停指定ID的计时,如果没指定ID表示暂停所有计时 |
resume | Function | timer.resume(setTimeoutID/setIntervalID) | 恢复指定ID的计时,如果没指定ID表示恢复所有计时 |
play | Function | timer.play(setTimeoutID/setIntervalID) | 同 resume |
pauseAll | Function | timer.pauseAll() | 暂停所有计时 |
playAll | Function | timer.playAll() | 恢复所有计时 |
clean | Function | timer.clean() | 清空所有计时 |
set | Function | timer.set(id, {fn, delay}) | 重置timer的回调函数与delay |
reset | Function | timer.reset(id) | 调用reset后,指定ID的计时会被置零 |
resetAll | Function | timer.resetAll() | 调用resetAll后,所有计时会被置零 |
useRAF | Boolean | timer.useRAF = true / false | true 表示启用自身RAF,false 反之。与第三方ticker结合时,timer 会自动切换 |
事件管理类。语法如下:
let event = new Event();
event实例的API如下:
name | type | syntac | deltail |
---|---|---|---|
on | Function | event.on(eventName, fn) | 监听一个自定义事件 |
off | Function | event.off(eventName, fn) | 移除监听事件,event.off(eventName) 表示删除这个事件的所有监听 |
once | Function | event.once(eventName, fn) | 监听一次自定义事件 |
clean | Function | event.clean() | 清空所有事件 |
dispatch | Function | event.dispatch(eventName, args) | 触发一个自定义事件 |
用法如下:
let event = new Events();
event.on("haha", function() {
console.log("haha");
});
setTimeout(() => event.dispatch("haha"));
计算两点间的角度。用法如下:
export p2angle from './modules/p2angle';
p2angle.set(0, 0);
let radian = p2angel.get(100, 100);
console.log("点(100, 100) 到 原点(0, 0) 的弧度是:" + radian);
let degree = p2angel.getDegree(100, 100);
console.log("点(100, 100) 到 原点(0, 0) 的角度是:" + degree);
p2angle的API如下:
name | type | detail |
---|---|---|
set | Function | 设置一个原点 |
get | Function | 获取当前点到原点的弧度值 |
getDegree | Function | 获取当前点到原点的角度值 |
注意,这里的角度的取值请参考下图:
「波动算法」,用于随机分割数值。通过「波动算法」可以指定分割后的随机数偏离「平均值」的距离,详细可以参考:波动均分算法。
这里提供了两个「波动均分算法」:
- exhaustWave
- quickWave
语法如下:
exhaustWave(n, crest, trough); 返回值:分割的结果数组
n ----- 表示要分割的份数; crest ------- 波峰值(即距离平均值的正向尺寸); trough ------- 波谷值(即距离平均值的负向尺寸),默认取 crest 的值;
用法如下:
// 将 100 分割成 5分,波动为 10
var average = 100 / 5;
// 分配结果
var res = exhaustWave(5, 10).map(rnd => rnd + average)
exhaustWave 一般不推荐使用,因为效率低下,并且只适用到整数分割
quickWave(n, crest, trough, isInteger); 返回值:分割的结果数组
n ----- 表示要分割的份数; crest ------- 波峰值(即距离平均值的正向尺寸); trough ------- 波谷值(即距离平均值的负向尺寸),默认取 crest 的值; isInteger ------ 是否分割为整数,默认取 true
用法如下:
// 将 100 分割成 5分,波动为 10
var average = 100 / 5;
// 分配结果
var res = quickWave(5, 10, 10, false).map(rnd => rnd + average)
快速分配是推荐的算法,效率高可以分割实数