1 | import {window} from "./browser";
|
2 | import { ObjectInterface } from "./types";
|
3 |
|
4 | declare var jQuery: any;
|
5 |
|
6 | export function toArray(nodes: NodeList): HTMLElement[] {
|
7 |
|
8 |
|
9 | const el = [];
|
10 | for (let i = 0, len = nodes.length;
|
11 | i < len; i++) {
|
12 | el.push(nodes[i]);
|
13 | }
|
14 | return el;
|
15 | }
|
16 |
|
17 | export function $(param, multi = false) {
|
18 | let el;
|
19 |
|
20 | if (typeof param === "string") {
|
21 |
|
22 | const match = param.match(/^<([a-z]+)\s*([^>]*)>/);
|
23 |
|
24 |
|
25 | if (match) {
|
26 | const dummy = document.createElement("div");
|
27 |
|
28 | dummy.innerHTML = param;
|
29 | el = toArray(dummy.childNodes);
|
30 | } else {
|
31 | el = toArray(document.querySelectorAll(param));
|
32 | }
|
33 | if (!multi) {
|
34 | el = el.length >= 1 ? el[0] : undefined;
|
35 | }
|
36 | } else if (param === window) {
|
37 | el = param;
|
38 | } else if (param.nodeName &&
|
39 | (param.nodeType === 1 || param.nodeType === 9)) {
|
40 | el = param;
|
41 | } else if (("jQuery" in window && param instanceof jQuery) ||
|
42 | param.constructor.prototype.jquery) {
|
43 | el = multi ? param.toArray() : param.get(0);
|
44 | } else if (Array.isArray(param)) {
|
45 | el = param.map(v => $(v));
|
46 | if (!multi) {
|
47 | el = el.length >= 1 ? el[0] : undefined;
|
48 | }
|
49 | }
|
50 | return el;
|
51 | }
|
52 |
|
53 | let raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame;
|
54 | let caf = window.cancelAnimationFrame || window.webkitCancelAnimationFrame;
|
55 | if (raf && !caf) {
|
56 | const keyInfo = {};
|
57 | const oldraf = raf;
|
58 | raf = (callback: FrameRequestCallback) => {
|
59 | function wrapCallback(timestamp) {
|
60 | if (keyInfo[key]) {
|
61 | callback(timestamp);
|
62 | }
|
63 | }
|
64 | const key = oldraf(wrapCallback);
|
65 | keyInfo[key] = true;
|
66 | return key;
|
67 | };
|
68 | caf = (key: number) => {
|
69 | delete keyInfo[key];
|
70 | };
|
71 | } else if (!(raf && caf)) {
|
72 | raf = (callback: FrameRequestCallback) => {
|
73 | return window.setTimeout(() => {
|
74 | callback(window.performance && window.performance.now && window.performance.now() || new Date().getTime());
|
75 | }, 16);
|
76 | };
|
77 | caf = window.clearTimeout;
|
78 | }
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | export function requestAnimationFrame(fp) {
|
86 | return raf(fp);
|
87 | }
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 | export function cancelAnimationFrame(key) {
|
95 | caf(key);
|
96 | }
|
97 |
|
98 | export function map<T, U>(obj: ObjectInterface<T>, callback: (value: T, key: string) => U): ObjectInterface<U> {
|
99 | const tranformed: ObjectInterface<U> = {};
|
100 |
|
101 | for (const k in obj) {
|
102 | k && (tranformed[k] = callback(obj[k], k));
|
103 | }
|
104 | return tranformed;
|
105 | }
|
106 |
|
107 | export function filter<T>(obj: ObjectInterface<T>, callback: (value: T, key: string) => boolean): ObjectInterface<T> {
|
108 | const filtered: ObjectInterface<T> = {};
|
109 |
|
110 | for (const k in obj) {
|
111 | k && callback(obj[k], k) && (filtered[k] = obj[k]);
|
112 | }
|
113 | return filtered;
|
114 | }
|
115 | export function every<T>(obj: ObjectInterface<T>, callback: (value: T, key: string) => boolean) {
|
116 | for (const k in obj) {
|
117 | if (k && !callback(obj[k], k)) {
|
118 | return false;
|
119 | }
|
120 | }
|
121 | return true;
|
122 | }
|
123 | export function equal(target: ObjectInterface, base: ObjectInterface): boolean {
|
124 | return every(target, (v, k) => v === base[k]);
|
125 | }
|
126 |
|
127 | const roundNumFunc = {};
|
128 |
|
129 | export function roundNumber(num: number, roundUnit: number) {
|
130 |
|
131 | if (!roundNumFunc[roundUnit]) {
|
132 | roundNumFunc[roundUnit] = getRoundFunc(roundUnit);
|
133 | }
|
134 |
|
135 | return roundNumFunc[roundUnit](num);
|
136 | }
|
137 |
|
138 | export function roundNumbers(num: ObjectInterface<number>, roundUnit: ObjectInterface<number> | number) {
|
139 | if (!num || !roundUnit) {
|
140 | return num;
|
141 | }
|
142 | const isNumber = typeof roundUnit === "number";
|
143 | return map(num, (value, key) => roundNumber(value, isNumber ? roundUnit : roundUnit[key]));
|
144 | }
|
145 |
|
146 | export function getDecimalPlace(val: number): number {
|
147 | if (!isFinite(val)) {
|
148 | return 0;
|
149 | }
|
150 |
|
151 | const v = (val + "");
|
152 |
|
153 | if (v.indexOf("e") >= 0) {
|
154 |
|
155 |
|
156 | let p = 0;
|
157 | let e = 1;
|
158 |
|
159 | while (Math.round(val * e) / e !== val) {
|
160 | e *= 10;
|
161 | p++;
|
162 | }
|
163 |
|
164 | return p;
|
165 | }
|
166 |
|
167 |
|
168 |
|
169 | return v.indexOf(".") >= 0 ? (v.length - v.indexOf(".") - 1) : 0;
|
170 | }
|
171 |
|
172 | export function inversePow(n: number) {
|
173 |
|
174 |
|
175 | return 1 / Math.pow(10, n);
|
176 | }
|
177 |
|
178 | export function getRoundFunc(v: number) {
|
179 | const p = v < 1 ? Math.pow(10, getDecimalPlace(v)) : 1;
|
180 |
|
181 | return (n: number) => {
|
182 | if (v === 0) {
|
183 | return 0;
|
184 | }
|
185 |
|
186 | return Math.round(Math.round(n / v) * v * p) / p;
|
187 | };
|
188 | }
|