mirror of
https://github.com/pissang/claygl.git
synced 2026-02-01 17:27:08 +00:00
wip: update core module to typescript
This commit is contained in:
parent
49e1f145d3
commit
872b465cde
@ -11,8 +11,9 @@ module.exports = {
|
||||
'no-array-constructor': 2,
|
||||
'no-label-var': 2,
|
||||
'no-undef-init': 2,
|
||||
'no-unused-vars': 0,
|
||||
'@typescript-eslint/no-unused-vars': [1, { vars: 'local', args: 'none' }]
|
||||
'no-dupe-class-members': 0,
|
||||
'@typescript-eslint/no-unused-vars': [1, { vars: 'local', args: 'none' }],
|
||||
'@typescript-eslint/no-dupe-class-members': 2
|
||||
},
|
||||
globals: {
|
||||
console: true,
|
||||
|
||||
@ -184,7 +184,7 @@ const Geometry = GeometryBase.extend(
|
||||
let normals = attributes.normal.value;
|
||||
|
||||
if (!normals || normals.length !== positions.length) {
|
||||
normals = attributes.normal.value = new vendor.Float32Array(positions.length);
|
||||
normals = attributes.normal.value = new Float32Array(positions.length);
|
||||
} else {
|
||||
// Reset
|
||||
for (let i = 0; i < normals.length; i++) {
|
||||
@ -433,7 +433,7 @@ const Geometry = GeometryBase.extend(
|
||||
}
|
||||
|
||||
if (this.indices.length > 0xffff) {
|
||||
this.indices = new vendor.Uint32Array(this.indices);
|
||||
this.indices = new Uint32Array(this.indices);
|
||||
}
|
||||
|
||||
const attributes = this.attributes;
|
||||
|
||||
@ -7,11 +7,11 @@ import vendor from './core/vendor';
|
||||
function getArrayCtorByType(type) {
|
||||
return (
|
||||
{
|
||||
byte: vendor.Int8Array,
|
||||
ubyte: vendor.Uint8Array,
|
||||
short: vendor.Int16Array,
|
||||
ushort: vendor.Uint16Array
|
||||
}[type] || vendor.Float32Array
|
||||
byte: Int8Array,
|
||||
ubyte: Uint8Array,
|
||||
short: Int16Array,
|
||||
ushort: Uint16Array
|
||||
}[type] || Float32Array
|
||||
);
|
||||
}
|
||||
|
||||
@ -393,7 +393,7 @@ const GeometryBase = Base.extend(
|
||||
*/
|
||||
initIndicesFromArray: function (array) {
|
||||
let value;
|
||||
const ArrayConstructor = this.vertexCount > 0xffff ? vendor.Uint32Array : vendor.Uint16Array;
|
||||
const ArrayConstructor = this.vertexCount > 0xffff ? Uint32Array : Uint16Array;
|
||||
// Convert 2d array to flat
|
||||
if (array[0] && array[0].length) {
|
||||
let n = 0;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import Base from './core/Base';
|
||||
import util from './core/util';
|
||||
import colorUtil from './core/color';
|
||||
import * as util from './core/util';
|
||||
import * as colorUtil from './core/color';
|
||||
const parseColor = colorUtil.parseToFloat;
|
||||
|
||||
const programKeyCache = {};
|
||||
|
||||
@ -3,7 +3,7 @@ import Node from './Node';
|
||||
import Light from './Light';
|
||||
import Camera from './Camera';
|
||||
import BoundingBox from './math/BoundingBox';
|
||||
import util from './core/util';
|
||||
import * as util from './core/util';
|
||||
import mat4 from './glmatrix/mat4';
|
||||
import LRUCache from './core/LRU';
|
||||
import Matrix4 from './math/Matrix4';
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
* http://www.nvidia.com/object/using_sas.html
|
||||
* https://github.com/KhronosGroup/collada2json/issues/45
|
||||
*/
|
||||
import util from './core/util';
|
||||
import * as util from './core/util';
|
||||
import vendor from './core/vendor';
|
||||
|
||||
const uniformRegex =
|
||||
@ -263,7 +263,7 @@ function parseDeclarations(type, line) {
|
||||
|
||||
continue;
|
||||
} else if (token === ')') {
|
||||
declarations[currentDeclaration].value = new vendor.Float32Array(declarationValue);
|
||||
declarations[currentDeclaration].value = new Float32Array(declarationValue);
|
||||
declarationValue = null;
|
||||
opType = TYPE_NORMAL;
|
||||
continue;
|
||||
|
||||
@ -3,7 +3,7 @@ import Material from './Material';
|
||||
|
||||
import Shader from './Shader';
|
||||
import standardEssl from './shader/source/standard.glsl.js';
|
||||
import util from './core/util';
|
||||
import * as util from './core/util';
|
||||
|
||||
// Import standard shader
|
||||
Shader.import(standardEssl);
|
||||
@ -82,7 +82,7 @@ const StandardMaterial = Material.extend(
|
||||
},
|
||||
function (option) {
|
||||
// PENDING
|
||||
util.extend(this, option);
|
||||
Object.assign(this, option);
|
||||
// Extend after shader is created.
|
||||
util.defaults(
|
||||
this,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import Texture from './Texture';
|
||||
import glenum from './core/glenum';
|
||||
import util from './core/util';
|
||||
import * as util from './core/util';
|
||||
import mathUtil from './math/util';
|
||||
import vendor from './core/vendor';
|
||||
const isPowerOfTwo = mathUtil.isPowerOfTwo;
|
||||
|
||||
@ -35,12 +35,12 @@ import AmbientSHLight from './light/AmbientSH';
|
||||
import ShadowMapPass from './prePass/ShadowMap';
|
||||
import RayPicking from './picking/RayPicking';
|
||||
import LRUCache from './core/LRU';
|
||||
import util from './core/util';
|
||||
import * as util from './core/util';
|
||||
import shUtil from './util/sh';
|
||||
import textureUtil from './util/texture';
|
||||
import vendor from './core/vendor';
|
||||
|
||||
import colorUtil from './core/color';
|
||||
import * as colorUtil from './core/color';
|
||||
const parseColor = colorUtil.parseToFloat;
|
||||
|
||||
import shaderLibrary from './shader/builtin';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import notifier from '../core/mixin/notifier';
|
||||
import notifier from '../core/otifierr
|
||||
import vendor from '../core/vendor';
|
||||
import util from '../core/util';
|
||||
import * as util from '../core/util';
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@ -52,7 +52,7 @@ Task.prototype.isSettled = function () {
|
||||
return this._fullfilled || this._rejected;
|
||||
};
|
||||
|
||||
util.extend(Task.prototype, notifier);
|
||||
Object.assign(Task.prototype, notifier);
|
||||
|
||||
function makeRequestTask(url, responseType) {
|
||||
const task = new Task();
|
||||
@ -116,6 +116,6 @@ Task.makeTask = function () {
|
||||
return new Task();
|
||||
};
|
||||
|
||||
util.extend(Task.prototype, notifier);
|
||||
Object.assign(Task.prototype, notifier);
|
||||
|
||||
export default Task;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import util from '../core/util';
|
||||
import * as util from '../core/util';
|
||||
import Task from './Task';
|
||||
|
||||
/**
|
||||
|
||||
@ -46,10 +46,9 @@ import glenum$26 from './core/glenum';
|
||||
import GLInfo$27 from './core/GLInfo';
|
||||
import LinkedList$28 from './core/LinkedList';
|
||||
import LRU$29 from './core/LRU';
|
||||
import extend$30 from './core/mixin/extend';
|
||||
import notifier$31 from './core/mixin/notifier';
|
||||
import notifier$31 from './core/notifier
|
||||
import request$32 from './core/request';
|
||||
import util$33 from './core/util';
|
||||
import * as util$33 from './core/util';
|
||||
import vendor$34 from './core/vendor';
|
||||
import createCompositor$35 from './createCompositor';
|
||||
import GBuffer$36 from './deferred/GBuffer';
|
||||
@ -87,7 +86,7 @@ import Matrix4$67 from './math/Matrix4';
|
||||
import Plane$68 from './math/Plane';
|
||||
import Quaternion$69 from './math/Quaternion';
|
||||
import Ray$70 from './math/Ray';
|
||||
import util$71 from './math/util';
|
||||
import * as util$71 from './math/util';
|
||||
import Value$72 from './math/Value';
|
||||
import Vector2$73 from './math/Vector2';
|
||||
import Vector3$74 from './math/Vector3';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import Texture2D from '../Texture2D';
|
||||
import glenum from '../core/glenum';
|
||||
import util from '../core/util';
|
||||
import * as util from '../core/util';
|
||||
|
||||
const TexturePool = function () {
|
||||
this._pool = {};
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import extendMixin from './mixin/extend';
|
||||
import notifierMixin from './mixin/notifier';
|
||||
import util from './util';
|
||||
import * as util from './util';
|
||||
|
||||
/**
|
||||
* Base class of all objects
|
||||
@ -9,20 +6,12 @@ import util from './util';
|
||||
* @alias clay.core.Base
|
||||
* @mixes clay.core.mixin.notifier
|
||||
*/
|
||||
const Base = function () {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.__uid__ = util.genGUID();
|
||||
};
|
||||
|
||||
Base.__initializers__ = [
|
||||
function (opts) {
|
||||
util.extend(this, opts);
|
||||
class Base {
|
||||
__uid__: number;
|
||||
constructor() {
|
||||
this.__uid__ = util.genGUID();
|
||||
}
|
||||
];
|
||||
|
||||
util.extend(Base, extendMixin);
|
||||
util.extend(Base.prototype, notifierMixin);
|
||||
}
|
||||
|
||||
export default Base;
|
||||
|
||||
@ -1,109 +1,103 @@
|
||||
// @ts-nocheck
|
||||
import util from './util';
|
||||
import * as util from './util';
|
||||
|
||||
const DIRTY_PREFIX = '__dt__';
|
||||
|
||||
const Cache = function () {
|
||||
this._contextId = 0;
|
||||
class Cache<D extends Record<string, any> = Record<string, any>> {
|
||||
private _contextId = 0;
|
||||
private _caches: D[] = [];
|
||||
private _context = {} as D;
|
||||
|
||||
this._caches = [];
|
||||
constructor() {}
|
||||
|
||||
this._context = {};
|
||||
};
|
||||
|
||||
Cache.prototype = {
|
||||
use: function (contextId, documentSchema) {
|
||||
use(contextId: number, documentSchema?: () => D) {
|
||||
const caches = this._caches;
|
||||
if (!caches[contextId]) {
|
||||
caches[contextId] = {};
|
||||
caches[contextId] = {} as D;
|
||||
|
||||
if (documentSchema) {
|
||||
caches[contextId] = documentSchema();
|
||||
}
|
||||
}
|
||||
this._contextId = contextId;
|
||||
|
||||
this._context = caches[contextId];
|
||||
},
|
||||
}
|
||||
|
||||
put: function (key, value) {
|
||||
put<T extends keyof D>(key: T, value: D[T]) {
|
||||
this._context[key] = value;
|
||||
},
|
||||
}
|
||||
|
||||
get: function (key) {
|
||||
get<T extends keyof D>(key: T): D[T] {
|
||||
return this._context[key];
|
||||
},
|
||||
}
|
||||
|
||||
dirty: function (field) {
|
||||
dirty(field: string) {
|
||||
field = field || '';
|
||||
const key = DIRTY_PREFIX + field;
|
||||
this.put(key, true);
|
||||
},
|
||||
this.put(key, true as any);
|
||||
}
|
||||
|
||||
dirtyAll: function (field) {
|
||||
dirtyAll(field: string) {
|
||||
field = field || '';
|
||||
const key = DIRTY_PREFIX + field;
|
||||
const caches = this._caches;
|
||||
for (let i = 0; i < caches.length; i++) {
|
||||
if (caches[i]) {
|
||||
caches[i][key] = true;
|
||||
(caches[i] as any)[key] = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
fresh: function (field) {
|
||||
fresh(field: string) {
|
||||
field = field || '';
|
||||
const key = DIRTY_PREFIX + field;
|
||||
this.put(key, false);
|
||||
},
|
||||
this.put(key, false as any);
|
||||
}
|
||||
|
||||
freshAll: function (field) {
|
||||
freshAll(field: string) {
|
||||
field = field || '';
|
||||
const key = DIRTY_PREFIX + field;
|
||||
const caches = this._caches;
|
||||
for (let i = 0; i < caches.length; i++) {
|
||||
if (caches[i]) {
|
||||
caches[i][key] = false;
|
||||
(caches[i] as any)[key] = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
isDirty: function (field) {
|
||||
isDirty(field: string) {
|
||||
field = field || '';
|
||||
const key = DIRTY_PREFIX + field;
|
||||
const context = this._context;
|
||||
return !util.hasOwn(context, key) || context[key] === true;
|
||||
},
|
||||
}
|
||||
|
||||
deleteContext: function (contextId) {
|
||||
deleteContext(contextId: number) {
|
||||
delete this._caches[contextId];
|
||||
this._context = {};
|
||||
},
|
||||
this._context = {} as D;
|
||||
}
|
||||
|
||||
delete: function (key) {
|
||||
delete(key: string) {
|
||||
delete this._context[key];
|
||||
},
|
||||
}
|
||||
|
||||
clearAll: function () {
|
||||
this._caches = {};
|
||||
},
|
||||
clearAll() {
|
||||
this._caches = [];
|
||||
}
|
||||
|
||||
getContext: function () {
|
||||
getContext() {
|
||||
return this._context;
|
||||
},
|
||||
}
|
||||
|
||||
eachContext: function (cb, context) {
|
||||
eachContext(cb: (key: string) => void) {
|
||||
const keys = Object.keys(this._caches);
|
||||
keys.forEach(function (key) {
|
||||
cb && cb.call(context, key);
|
||||
cb(key);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
miss: function (key) {
|
||||
miss(key: string) {
|
||||
return !util.hasOwn(this._context, key);
|
||||
}
|
||||
};
|
||||
|
||||
Cache.prototype.constructor = Cache;
|
||||
}
|
||||
|
||||
export default Cache;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
const EXTENSION_LIST = [
|
||||
'OES_texture_float',
|
||||
'OES_texture_half_float',
|
||||
@ -20,46 +19,52 @@ const EXTENSION_LIST = [
|
||||
'EXT_frag_depth',
|
||||
'EXT_sRGB',
|
||||
'ANGLE_instanced_arrays'
|
||||
];
|
||||
] as const;
|
||||
|
||||
const PARAMETER_NAMES = ['MAX_TEXTURE_SIZE', 'MAX_CUBE_MAP_TEXTURE_SIZE'];
|
||||
|
||||
function GLInfo(_gl) {
|
||||
const extensions = {};
|
||||
const parameters = {};
|
||||
/* global WebGLRenderingContext */
|
||||
class GLInfo {
|
||||
private _extensions: Record<string, any> = {};
|
||||
private _parameters: Record<string, any> = {};
|
||||
gl: WebGLRenderingContext;
|
||||
|
||||
// Get webgl extension
|
||||
for (let i = 0; i < EXTENSION_LIST.length; i++) {
|
||||
const extName = EXTENSION_LIST[i];
|
||||
createExtension(extName);
|
||||
}
|
||||
// Get parameters
|
||||
for (let i = 0; i < PARAMETER_NAMES.length; i++) {
|
||||
const name = PARAMETER_NAMES[i];
|
||||
parameters[name] = _gl.getParameter(_gl[name]);
|
||||
}
|
||||
|
||||
this.getExtension = function (name) {
|
||||
if (!(name in extensions)) {
|
||||
createExtension(name);
|
||||
constructor(gl: WebGLRenderingContext) {
|
||||
this.gl = gl;
|
||||
// Get webgl extension
|
||||
for (let i = 0; i < EXTENSION_LIST.length; i++) {
|
||||
const extName = EXTENSION_LIST[i];
|
||||
this._createExtension(extName);
|
||||
}
|
||||
return extensions[name];
|
||||
};
|
||||
// Get parameters
|
||||
for (let i = 0; i < PARAMETER_NAMES.length; i++) {
|
||||
const name = PARAMETER_NAMES[i];
|
||||
this._parameters[name] = gl.getParameter((gl as any)[name]);
|
||||
}
|
||||
}
|
||||
|
||||
this.getParameter = function (name) {
|
||||
return parameters[name];
|
||||
};
|
||||
getExtension(name: string) {
|
||||
if (!(name in this._extensions)) {
|
||||
this._createExtension(name);
|
||||
}
|
||||
return this._extensions[name];
|
||||
}
|
||||
|
||||
function createExtension(name) {
|
||||
if (_gl.getExtension) {
|
||||
let ext = _gl.getExtension(name);
|
||||
getParameter(name: string) {
|
||||
return this._parameters[name];
|
||||
}
|
||||
|
||||
private _createExtension(name: string) {
|
||||
const gl = this.gl;
|
||||
if (gl.getExtension) {
|
||||
let ext = gl.getExtension(name);
|
||||
if (!ext) {
|
||||
ext = _gl.getExtension('MOZ_' + name);
|
||||
ext = gl.getExtension('MOZ_' + name);
|
||||
}
|
||||
if (!ext) {
|
||||
ext = _gl.getExtension('WEBKIT_' + name);
|
||||
ext = gl.getExtension('WEBKIT_' + name);
|
||||
}
|
||||
extensions[name] = ext;
|
||||
this._extensions[name] = ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
144
src/core/LRU.ts
144
src/core/LRU.ts
@ -1,82 +1,92 @@
|
||||
// @ts-nocheck
|
||||
import LinkedList from './LinkedList';
|
||||
import util from './util';
|
||||
import LinkedList, { Entry } from './LinkedList';
|
||||
import * as util from './util';
|
||||
|
||||
interface LRUEntry<T> extends Entry<T> {
|
||||
key: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* LRU Cache
|
||||
* @constructor
|
||||
* @alias clay.core.LRU
|
||||
*/
|
||||
const LRU = function (maxSize) {
|
||||
this._list = new LinkedList();
|
||||
class LRU<T> {
|
||||
private _list = new LinkedList<T>();
|
||||
private _map: Record<string, LRUEntry<T>> = {};
|
||||
private _maxSize: number;
|
||||
|
||||
this._map = {};
|
||||
|
||||
this._maxSize = maxSize || 10;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set cache max size
|
||||
* @param {number} size
|
||||
*/
|
||||
LRU.prototype.setMaxSize = function (size) {
|
||||
this._maxSize = size;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @param {} value
|
||||
*/
|
||||
LRU.prototype.put = function (key, value) {
|
||||
if (!util.hasOwn(this._map, key)) {
|
||||
const len = this._list.length();
|
||||
if (len >= this._maxSize && len > 0) {
|
||||
// Remove the least recently used
|
||||
const leastUsedEntry = this._list.head;
|
||||
this._list.remove(leastUsedEntry);
|
||||
delete this._map[leastUsedEntry.key];
|
||||
}
|
||||
|
||||
const entry = this._list.insert(value);
|
||||
entry.key = key;
|
||||
this._map[key] = entry;
|
||||
constructor(maxSize: number) {
|
||||
this._maxSize = maxSize || 10;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @return {}
|
||||
*/
|
||||
LRU.prototype.get = function (key) {
|
||||
const entry = this._map[key];
|
||||
if (util.hasOwn(this._map, key)) {
|
||||
// Put the latest used entry in the tail
|
||||
if (entry !== this._list.tail) {
|
||||
/**
|
||||
* Set cache max size
|
||||
* @param size
|
||||
*/
|
||||
setMaxSize(size: number) {
|
||||
this._maxSize = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a value and return removed.
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
put(key: string, value: T) {
|
||||
if (!util.hasOwn(this._map, key)) {
|
||||
const len = this._list.length();
|
||||
let removed;
|
||||
if (len >= this._maxSize && len > 0) {
|
||||
// Remove the least recently used
|
||||
const leastUsedEntry = this._list.head as LRUEntry<T>;
|
||||
if (leastUsedEntry) {
|
||||
removed = leastUsedEntry.value;
|
||||
this._list.remove(leastUsedEntry);
|
||||
delete this._map[leastUsedEntry.key];
|
||||
}
|
||||
}
|
||||
|
||||
const entry = this._list.insert(value) as LRUEntry<T>;
|
||||
entry.key = key;
|
||||
this._map[key] = entry;
|
||||
return removed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
get(key: string): T | undefined {
|
||||
const entry = this._map[key];
|
||||
if (util.hasOwn(this._map, key)) {
|
||||
// Put the latest used entry in the tail
|
||||
if (entry !== this._list.tail) {
|
||||
this._list.remove(entry);
|
||||
this._list.insertEntry(entry);
|
||||
}
|
||||
|
||||
return entry.value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
*/
|
||||
remove(key: string) {
|
||||
const entry = this._map[key];
|
||||
if (typeof entry !== 'undefined') {
|
||||
delete this._map[key];
|
||||
this._list.remove(entry);
|
||||
this._list.insertEntry(entry);
|
||||
}
|
||||
|
||||
return entry.value;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
*/
|
||||
LRU.prototype.remove = function (key) {
|
||||
const entry = this._map[key];
|
||||
if (typeof entry !== 'undefined') {
|
||||
delete this._map[key];
|
||||
this._list.remove(entry);
|
||||
/**
|
||||
* Clear the cache
|
||||
*/
|
||||
clear() {
|
||||
this._list.clear();
|
||||
this._map = {};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the cache
|
||||
*/
|
||||
LRU.prototype.clear = function () {
|
||||
this._list.clear();
|
||||
this._map = {};
|
||||
};
|
||||
}
|
||||
|
||||
export default LRU;
|
||||
|
||||
@ -1,52 +1,70 @@
|
||||
// @ts-nocheck
|
||||
/**
|
||||
* Simple double linked list. Compared with array, it has O(1) remove operation.
|
||||
* @constructor
|
||||
* @alias clay.core.LinkedList
|
||||
*/
|
||||
const LinkedList = function () {
|
||||
/**
|
||||
* @type {clay.core.LinkedList.Entry}
|
||||
*/
|
||||
this.head = null;
|
||||
|
||||
export class Entry<T> {
|
||||
value: T;
|
||||
next?: Entry<T>;
|
||||
prev?: Entry<T>;
|
||||
constructor(val: T) {
|
||||
/**
|
||||
* @type {}
|
||||
*/
|
||||
this.value = val;
|
||||
}
|
||||
}
|
||||
class LinkedList<T> {
|
||||
head?: Entry<T>;
|
||||
tail?: Entry<T>;
|
||||
|
||||
private _length = 0;
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* @type {clay.core.LinkedList.Entry}
|
||||
* Insert a new value at the tail
|
||||
*/
|
||||
this.tail = null;
|
||||
|
||||
this._length = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Insert a new value at the tail
|
||||
* @param {} val
|
||||
* @return {clay.core.LinkedList.Entry}
|
||||
*/
|
||||
LinkedList.prototype.insert = function (val) {
|
||||
const entry = new LinkedList.Entry(val);
|
||||
this.insertEntry(entry);
|
||||
return entry;
|
||||
};
|
||||
|
||||
/**
|
||||
* Insert a new value at idx
|
||||
* @param {number} idx
|
||||
* @param {} val
|
||||
* @return {clay.core.LinkedList.Entry}
|
||||
*/
|
||||
LinkedList.prototype.insertAt = function (idx, val) {
|
||||
if (idx < 0) {
|
||||
return;
|
||||
insert(val: T) {
|
||||
const entry = new Entry(val);
|
||||
this.insertEntry(entry);
|
||||
return entry;
|
||||
}
|
||||
let next = this.head;
|
||||
let cursor = 0;
|
||||
while (next && cursor != idx) {
|
||||
next = next.next;
|
||||
cursor++;
|
||||
|
||||
/**
|
||||
* Insert a new value at idx
|
||||
* @param idx
|
||||
* @param val
|
||||
*/
|
||||
insertAt(idx: number, val: T) {
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
let next = this.head;
|
||||
let cursor = 0;
|
||||
while (next && cursor != idx) {
|
||||
next = next.next;
|
||||
cursor++;
|
||||
}
|
||||
if (next) {
|
||||
const entry = new Entry(val);
|
||||
const prev = next.prev;
|
||||
if (!prev) {
|
||||
//next is head
|
||||
this.head = entry;
|
||||
} else {
|
||||
prev.next = entry;
|
||||
entry.prev = prev;
|
||||
}
|
||||
entry.next = next;
|
||||
next.prev = entry;
|
||||
} else {
|
||||
this.insert(val);
|
||||
}
|
||||
}
|
||||
if (next) {
|
||||
const entry = new LinkedList.Entry(val);
|
||||
|
||||
insertBeforeEntry(val: T, next: Entry<T>) {
|
||||
const entry = new Entry(val);
|
||||
const prev = next.prev;
|
||||
if (!prev) {
|
||||
//next is head
|
||||
@ -57,197 +75,155 @@ LinkedList.prototype.insertAt = function (idx, val) {
|
||||
}
|
||||
entry.next = next;
|
||||
next.prev = entry;
|
||||
} else {
|
||||
this.insert(val);
|
||||
}
|
||||
};
|
||||
|
||||
LinkedList.prototype.insertBeforeEntry = function (val, next) {
|
||||
const entry = new LinkedList.Entry(val);
|
||||
const prev = next.prev;
|
||||
if (!prev) {
|
||||
//next is head
|
||||
this.head = entry;
|
||||
} else {
|
||||
prev.next = entry;
|
||||
entry.prev = prev;
|
||||
this._length++;
|
||||
}
|
||||
entry.next = next;
|
||||
next.prev = entry;
|
||||
|
||||
this._length++;
|
||||
};
|
||||
|
||||
/**
|
||||
* Insert an entry at the tail
|
||||
* @param {clay.core.LinkedList.Entry} entry
|
||||
*/
|
||||
LinkedList.prototype.insertEntry = function (entry) {
|
||||
if (!this.head) {
|
||||
this.head = this.tail = entry;
|
||||
} else {
|
||||
this.tail.next = entry;
|
||||
entry.prev = this.tail;
|
||||
this.tail = entry;
|
||||
}
|
||||
this._length++;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove entry.
|
||||
* @param {clay.core.LinkedList.Entry} entry
|
||||
*/
|
||||
LinkedList.prototype.remove = function (entry) {
|
||||
const prev = entry.prev;
|
||||
const next = entry.next;
|
||||
if (prev) {
|
||||
prev.next = next;
|
||||
} else {
|
||||
// Is head
|
||||
this.head = next;
|
||||
}
|
||||
if (next) {
|
||||
next.prev = prev;
|
||||
} else {
|
||||
// Is tail
|
||||
this.tail = prev;
|
||||
}
|
||||
entry.next = entry.prev = null;
|
||||
this._length--;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove entry at index.
|
||||
* @param {number} idx
|
||||
* @return {}
|
||||
*/
|
||||
LinkedList.prototype.removeAt = function (idx) {
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
let curr = this.head;
|
||||
let cursor = 0;
|
||||
while (curr && cursor != idx) {
|
||||
curr = curr.next;
|
||||
cursor++;
|
||||
}
|
||||
if (curr) {
|
||||
this.remove(curr);
|
||||
return curr.value;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Get head value
|
||||
* @return {}
|
||||
*/
|
||||
LinkedList.prototype.getHead = function () {
|
||||
if (this.head) {
|
||||
return this.head.value;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Get tail value
|
||||
* @return {}
|
||||
*/
|
||||
LinkedList.prototype.getTail = function () {
|
||||
if (this.tail) {
|
||||
return this.tail.value;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Get value at idx
|
||||
* @param {number} idx
|
||||
* @return {}
|
||||
*/
|
||||
LinkedList.prototype.getAt = function (idx) {
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
let curr = this.head;
|
||||
let cursor = 0;
|
||||
while (curr && cursor != idx) {
|
||||
curr = curr.next;
|
||||
cursor++;
|
||||
}
|
||||
return curr.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {} value
|
||||
* @return {number}
|
||||
*/
|
||||
LinkedList.prototype.indexOf = function (value) {
|
||||
let curr = this.head;
|
||||
let cursor = 0;
|
||||
while (curr) {
|
||||
if (curr.value === value) {
|
||||
return cursor;
|
||||
}
|
||||
curr = curr.next;
|
||||
cursor++;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
LinkedList.prototype.length = function () {
|
||||
return this._length;
|
||||
};
|
||||
|
||||
/**
|
||||
* If list is empty
|
||||
*/
|
||||
LinkedList.prototype.isEmpty = function () {
|
||||
return this._length === 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Function} cb
|
||||
* @param {} context
|
||||
*/
|
||||
LinkedList.prototype.forEach = function (cb, context) {
|
||||
let curr = this.head;
|
||||
let idx = 0;
|
||||
const haveContext = typeof context != 'undefined';
|
||||
while (curr) {
|
||||
if (haveContext) {
|
||||
cb.call(context, curr.value, idx);
|
||||
/**
|
||||
* Insert an entry at the tail
|
||||
* @param entry
|
||||
*/
|
||||
insertEntry(entry: Entry<T>) {
|
||||
if (!this.head) {
|
||||
this.head = this.tail = entry;
|
||||
} else {
|
||||
cb(curr.value, idx);
|
||||
this.tail!.next = entry;
|
||||
entry.prev = this.tail;
|
||||
this.tail = entry;
|
||||
}
|
||||
curr = curr.next;
|
||||
idx++;
|
||||
this._length++;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the list
|
||||
*/
|
||||
LinkedList.prototype.clear = function () {
|
||||
this.tail = this.head = null;
|
||||
this._length = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {} val
|
||||
*/
|
||||
LinkedList.Entry = function (val) {
|
||||
/**
|
||||
* @type {}
|
||||
*/
|
||||
this.value = val;
|
||||
|
||||
/**
|
||||
* @type {clay.core.LinkedList.Entry}
|
||||
* Remove entry.
|
||||
* @param entry
|
||||
*/
|
||||
this.next = null;
|
||||
remove(entry: Entry<T>) {
|
||||
const prev = entry.prev;
|
||||
const next = entry.next;
|
||||
if (prev) {
|
||||
prev.next = next;
|
||||
} else {
|
||||
// Is head
|
||||
this.head = next;
|
||||
}
|
||||
if (next) {
|
||||
next.prev = prev;
|
||||
} else {
|
||||
// Is tail
|
||||
this.tail = prev;
|
||||
}
|
||||
entry.next = entry.prev = undefined;
|
||||
this._length--;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {clay.core.LinkedList.Entry}
|
||||
* Remove entry at index.
|
||||
* @param idx
|
||||
* @return
|
||||
*/
|
||||
this.prev = null;
|
||||
};
|
||||
removeAt(idx: number) {
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
let curr = this.head;
|
||||
let cursor = 0;
|
||||
while (curr && cursor != idx) {
|
||||
curr = curr.next;
|
||||
cursor++;
|
||||
}
|
||||
if (curr) {
|
||||
this.remove(curr);
|
||||
return curr.value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get head value
|
||||
* @return {}
|
||||
*/
|
||||
getHead() {
|
||||
if (this.head) {
|
||||
return this.head.value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get tail value
|
||||
* @return {}
|
||||
*/
|
||||
getTail() {
|
||||
if (this.tail) {
|
||||
return this.tail.value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get value at idx
|
||||
* @param idx
|
||||
* @return
|
||||
*/
|
||||
getAt(idx: number): T | undefined {
|
||||
if (idx < 0) {
|
||||
return;
|
||||
}
|
||||
let curr = this.head;
|
||||
let cursor = 0;
|
||||
while (curr && cursor != idx) {
|
||||
curr = curr.next;
|
||||
cursor++;
|
||||
}
|
||||
return curr && curr.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
*/
|
||||
indexOf(value: T): number {
|
||||
let curr = this.head;
|
||||
let cursor = 0;
|
||||
while (curr) {
|
||||
if (curr.value === value) {
|
||||
return cursor;
|
||||
}
|
||||
curr = curr.next;
|
||||
cursor++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Length of list
|
||||
*/
|
||||
length(): number {
|
||||
return this._length;
|
||||
}
|
||||
|
||||
/**
|
||||
* If list is empty
|
||||
*/
|
||||
isEmpty() {
|
||||
return this._length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cb
|
||||
* @param context
|
||||
*/
|
||||
forEach(cb: (value: T, idx: number) => void) {
|
||||
let curr = this.head;
|
||||
let idx = 0;
|
||||
while (curr) {
|
||||
cb(curr.value, idx);
|
||||
curr = curr.next;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list
|
||||
*/
|
||||
clear() {
|
||||
this.tail = this.head = undefined;
|
||||
this._length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
export default LinkedList;
|
||||
|
||||
@ -1,28 +1,29 @@
|
||||
// @ts-nocheck
|
||||
import util from '../util';
|
||||
import * as util from './util';
|
||||
|
||||
function Handler(action, context) {
|
||||
this.action = action;
|
||||
this.context = context;
|
||||
class Handler {
|
||||
action: Function;
|
||||
context: any;
|
||||
constructor(action: Function, context: any) {
|
||||
this.action = action;
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @mixin
|
||||
* @alias clay.core.mixin.notifier
|
||||
*/
|
||||
const notifier = {
|
||||
class Notifier {
|
||||
private _handlers?: Record<string, Handler[]>;
|
||||
/**
|
||||
* Trigger event
|
||||
* @param {string} name
|
||||
*/
|
||||
trigger: function (name) {
|
||||
if (!this.__handlers__) {
|
||||
return;
|
||||
}
|
||||
if (!util.hasOwn(this.__handlers__, name)) {
|
||||
trigger(name: string) {
|
||||
if (!util.hasOwn(this._handlers, name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hdls = this.__handlers__[name];
|
||||
const hdls = this._handlers![name];
|
||||
const l = hdls.length;
|
||||
const args = arguments;
|
||||
let i = -1;
|
||||
@ -59,7 +60,7 @@ const notifier = {
|
||||
}
|
||||
return;
|
||||
}
|
||||
},
|
||||
}
|
||||
/**
|
||||
* Register event handler
|
||||
* @param {string} name
|
||||
@ -67,11 +68,11 @@ const notifier = {
|
||||
* @param {Object} [context]
|
||||
* @chainable
|
||||
*/
|
||||
on: function (name, action, context) {
|
||||
on(name: string, action: Function, context: any) {
|
||||
if (!name || !action) {
|
||||
return;
|
||||
}
|
||||
const handlers = this.__handlers__ || (this.__handlers__ = {});
|
||||
const handlers = this._handlers || (this._handlers = {});
|
||||
if (!handlers[name]) {
|
||||
handlers[name] = [];
|
||||
} else {
|
||||
@ -83,7 +84,7 @@ const notifier = {
|
||||
handlers[name].push(handler);
|
||||
|
||||
return this;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Register event, event will only be triggered once and then removed
|
||||
@ -92,17 +93,17 @@ const notifier = {
|
||||
* @param {Object} [context]
|
||||
* @chainable
|
||||
*/
|
||||
once: function (name, action, context) {
|
||||
once(name: string, action: Function, context: any) {
|
||||
if (!name || !action) {
|
||||
return;
|
||||
}
|
||||
const self = this;
|
||||
function wrapper() {
|
||||
self.off(name, wrapper);
|
||||
action.apply(this, arguments);
|
||||
action.apply(self, arguments);
|
||||
}
|
||||
return this.on(name, wrapper, context);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of once('before' + name)
|
||||
@ -111,13 +112,13 @@ const notifier = {
|
||||
* @param {Object} [context]
|
||||
* @chainable
|
||||
*/
|
||||
before: function (name, action, context) {
|
||||
before(name: string, action: Function, context: any) {
|
||||
if (!name || !action) {
|
||||
return;
|
||||
}
|
||||
name = 'before' + name;
|
||||
return this.on(name, action, context);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of once('after' + name)
|
||||
@ -126,13 +127,13 @@ const notifier = {
|
||||
* @param {Object} [context]
|
||||
* @chainable
|
||||
*/
|
||||
after: function (name, action, context) {
|
||||
after(name: string, action: Function, context: any) {
|
||||
if (!name || !action) {
|
||||
return;
|
||||
}
|
||||
name = 'after' + name;
|
||||
return this.on(name, action, context);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of on('success')
|
||||
@ -140,9 +141,9 @@ const notifier = {
|
||||
* @param {Object} [context]
|
||||
* @chainable
|
||||
*/
|
||||
success: function (action, context) {
|
||||
success(action: Function, context: any) {
|
||||
return this.once('success', action, context);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of on('error')
|
||||
@ -150,9 +151,9 @@ const notifier = {
|
||||
* @param {Object} [context]
|
||||
* @chainable
|
||||
*/
|
||||
error: function (action, context) {
|
||||
error(action: Function, context: any) {
|
||||
return this.once('error', action, context);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove event listener
|
||||
@ -160,8 +161,8 @@ const notifier = {
|
||||
* @param {Object} [context]
|
||||
* @chainable
|
||||
*/
|
||||
off: function (name, action) {
|
||||
const handlers = this.__handlers__ || (this.__handlers__ = {});
|
||||
off(name: string, action: Function) {
|
||||
const handlers = this._handlers || (this._handlers = {});
|
||||
|
||||
if (!action) {
|
||||
handlers[name] = [];
|
||||
@ -179,7 +180,7 @@ const notifier = {
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* If registered the event handler
|
||||
@ -187,8 +188,8 @@ const notifier = {
|
||||
* @param {Function} action
|
||||
* @return {boolean}
|
||||
*/
|
||||
has: function (name, action) {
|
||||
const handlers = this.__handlers__;
|
||||
has(name: string, action: Function) {
|
||||
const handlers = this._handlers;
|
||||
|
||||
if (!handlers || !handlers[name]) {
|
||||
return false;
|
||||
@ -200,6 +201,6 @@ const notifier = {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default notifier;
|
||||
export default Notifier;
|
||||
@ -1,12 +1,9 @@
|
||||
// @ts-nocheck
|
||||
/**
|
||||
* @namespace clay.core.color
|
||||
*/
|
||||
import LRU from '../core/LRU';
|
||||
|
||||
const colorUtil = {};
|
||||
|
||||
const kCSSColorTable = {
|
||||
const kCSSColorTable: Record<string, number[]> = {
|
||||
transparent: [0, 0, 0, 0],
|
||||
aliceblue: [240, 248, 255, 1],
|
||||
antiquewhite: [250, 235, 215, 1],
|
||||
@ -157,24 +154,24 @@ const kCSSColorTable = {
|
||||
yellowgreen: [154, 205, 50, 1]
|
||||
};
|
||||
|
||||
function clampCssByte(i) {
|
||||
function clampCssByte(i: number) {
|
||||
// Clamp to integer 0 .. 255.
|
||||
i = Math.round(i); // Seems to be what Chrome does (vs truncation).
|
||||
return i < 0 ? 0 : i > 255 ? 255 : i;
|
||||
}
|
||||
|
||||
function clampCssAngle(i) {
|
||||
function clampCssAngle(i: number) {
|
||||
// Clamp to integer 0 .. 360.
|
||||
i = Math.round(i); // Seems to be what Chrome does (vs truncation).
|
||||
return i < 0 ? 0 : i > 360 ? 360 : i;
|
||||
}
|
||||
|
||||
function clampCssFloat(f) {
|
||||
function clampCssFloat(f: number) {
|
||||
// Clamp to float 0.0 .. 1.0.
|
||||
return f < 0 ? 0 : f > 1 ? 1 : f;
|
||||
}
|
||||
|
||||
function parseCssInt(str) {
|
||||
function parseCssInt(str: string) {
|
||||
// int or percentage.
|
||||
if (str.length && str.charAt(str.length - 1) === '%') {
|
||||
return clampCssByte((parseFloat(str) / 100) * 255);
|
||||
@ -182,15 +179,15 @@ function parseCssInt(str) {
|
||||
return clampCssByte(parseInt(str, 10));
|
||||
}
|
||||
|
||||
function parseCssFloat(str) {
|
||||
function parseCssFloat(str: string | number) {
|
||||
// float or percentage.
|
||||
if (str.length && str.charAt(str.length - 1) === '%') {
|
||||
return clampCssFloat(parseFloat(str) / 100);
|
||||
if ((str as string).length && (str as string).charAt((str as string).length - 1) === '%') {
|
||||
return clampCssFloat(parseFloat(str as string) / 100);
|
||||
}
|
||||
return clampCssFloat(parseFloat(str));
|
||||
return clampCssFloat(parseFloat(str as string));
|
||||
}
|
||||
|
||||
function cssHueToRgb(m1, m2, h) {
|
||||
function cssHueToRgb(m1: number, m2: number, h: number) {
|
||||
if (h < 0) {
|
||||
h += 1;
|
||||
} else if (h > 1) {
|
||||
@ -209,18 +206,18 @@ function cssHueToRgb(m1, m2, h) {
|
||||
return m1;
|
||||
}
|
||||
|
||||
function lerpNumber(a, b, p) {
|
||||
function lerpNumber(a: number, b: number, p: number) {
|
||||
return a + (b - a) * p;
|
||||
}
|
||||
|
||||
function setRgba(out, r, g, b, a) {
|
||||
function setRgba(out: number[], r: number, g: number, b: number, a: number) {
|
||||
out[0] = r;
|
||||
out[1] = g;
|
||||
out[2] = b;
|
||||
out[3] = a;
|
||||
return out;
|
||||
}
|
||||
function copyRgba(out, a) {
|
||||
function copyRgba(out: number[], a: number[]) {
|
||||
out[0] = a[0];
|
||||
out[1] = a[1];
|
||||
out[2] = a[2];
|
||||
@ -228,10 +225,10 @@ function copyRgba(out, a) {
|
||||
return out;
|
||||
}
|
||||
|
||||
const colorCache = new LRU(20);
|
||||
let lastRemovedArr = null;
|
||||
const colorCache = new LRU<number[]>(20);
|
||||
let lastRemovedArr: number[] | undefined;
|
||||
|
||||
function putToCache(colorStr, rgbaArr) {
|
||||
function putToCache(colorStr: string, rgbaArr: number[]) {
|
||||
// Reuse removed array
|
||||
if (lastRemovedArr) {
|
||||
copyRgba(lastRemovedArr, rgbaArr);
|
||||
@ -240,12 +237,11 @@ function putToCache(colorStr, rgbaArr) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @name clay.core.color.parse
|
||||
* @param {string} colorStr
|
||||
* @param {Array.<number>} out
|
||||
* @return {Array.<number>}
|
||||
* @param colorStr
|
||||
* @param out
|
||||
* @return
|
||||
*/
|
||||
colorUtil.parse = function (colorStr, rgbaArr) {
|
||||
export function parse(colorStr: string, rgbaArr?: number[]) {
|
||||
if (!colorStr) {
|
||||
return;
|
||||
}
|
||||
@ -301,8 +297,8 @@ colorUtil.parse = function (colorStr, rgbaArr) {
|
||||
const op = str.indexOf('('),
|
||||
ep = str.indexOf(')');
|
||||
if (op !== -1 && ep + 1 === str.length) {
|
||||
const fname = str.substr(0, op);
|
||||
const params = str.substr(op + 1, ep - (op + 1)).split(',');
|
||||
const fname = str.slice(0, op);
|
||||
const params = str.slice(op + 1, ep - (op + 1)).split(',');
|
||||
let alpha = 1; // To allow case fallthrough.
|
||||
switch (fname) {
|
||||
case 'rgba':
|
||||
@ -310,7 +306,7 @@ colorUtil.parse = function (colorStr, rgbaArr) {
|
||||
setRgba(rgbaArr, 0, 0, 0, 1);
|
||||
return;
|
||||
}
|
||||
alpha = parseCssFloat(params.pop()); // jshint ignore:line
|
||||
alpha = parseCssFloat(params.pop()!); // jshint ignore:line
|
||||
// Fall through.
|
||||
case 'rgb':
|
||||
if (params.length !== 3) {
|
||||
@ -331,7 +327,7 @@ colorUtil.parse = function (colorStr, rgbaArr) {
|
||||
setRgba(rgbaArr, 0, 0, 0, 1);
|
||||
return;
|
||||
}
|
||||
params[3] = parseCssFloat(params[3]);
|
||||
params[3] = parseCssFloat(params[3]) as any;
|
||||
hsla2rgba(params, rgbaArr);
|
||||
putToCache(colorStr, rgbaArr);
|
||||
return rgbaArr;
|
||||
@ -350,10 +346,10 @@ colorUtil.parse = function (colorStr, rgbaArr) {
|
||||
|
||||
setRgba(rgbaArr, 0, 0, 0, 1);
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
colorUtil.parseToFloat = function (colorStr, rgbaArr) {
|
||||
rgbaArr = colorUtil.parse(colorStr, rgbaArr);
|
||||
export function parseToFloat(colorStr: string, rgbaArr?: number[]) {
|
||||
rgbaArr = parse(colorStr, rgbaArr);
|
||||
if (!rgbaArr) {
|
||||
return;
|
||||
}
|
||||
@ -361,20 +357,19 @@ colorUtil.parseToFloat = function (colorStr, rgbaArr) {
|
||||
rgbaArr[1] /= 255;
|
||||
rgbaArr[2] /= 255;
|
||||
return rgbaArr;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @name clay.core.color.hsla2rgba
|
||||
* @param {Array.<number>} hsla
|
||||
* @param {Array.<number>} rgba
|
||||
* @return {Array.<number>} rgba
|
||||
* @param hsla
|
||||
* @param rgba
|
||||
* @return rgba
|
||||
*/
|
||||
function hsla2rgba(hsla, rgba) {
|
||||
const h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360; // 0 .. 1
|
||||
export function hsla2rgba(hsla: (number | string)[], rgba?: number[]) {
|
||||
const h = (((parseFloat(hsla[0] as any) % 360) + 360) % 360) / 360; // 0 .. 1
|
||||
// NOTE(deanm): According to the CSS spec s/l should only be
|
||||
// percentages, but we don't bother and let float or percentage.
|
||||
const s = parseCssFloat(hsla[1]);
|
||||
const l = parseCssFloat(hsla[2]);
|
||||
const s = parseCssFloat(hsla[1] as any);
|
||||
const l = parseCssFloat(hsla[2] as any);
|
||||
const m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
|
||||
const m1 = l * 2 - m2;
|
||||
|
||||
@ -388,18 +383,17 @@ function hsla2rgba(hsla, rgba) {
|
||||
);
|
||||
|
||||
if (hsla.length === 4) {
|
||||
rgba[3] = hsla[3];
|
||||
rgba[3] = +hsla[3];
|
||||
}
|
||||
|
||||
return rgba;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name clay.core.color.rgba2hsla
|
||||
* @param {Array.<number>} rgba
|
||||
* @return {Array.<number>} hsla
|
||||
* @param rgba
|
||||
* @return hsla
|
||||
*/
|
||||
function rgba2hsla(rgba) {
|
||||
export function rgba2hsla(rgba: number[]) {
|
||||
if (!rgba) {
|
||||
return;
|
||||
}
|
||||
@ -439,16 +433,16 @@ function rgba2hsla(rgba) {
|
||||
H = 2 / 3 + deltaG - deltaR;
|
||||
}
|
||||
|
||||
if (H < 0) {
|
||||
if (H && H < 0) {
|
||||
H += 1;
|
||||
}
|
||||
|
||||
if (H > 1) {
|
||||
if (H && H > 1) {
|
||||
H -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
const hsla = [H * 360, S, L];
|
||||
const hsla = [(H as number) * 360, S, L];
|
||||
|
||||
if (rgba[3] != null) {
|
||||
hsla.push(rgba[3]);
|
||||
@ -458,13 +452,12 @@ function rgba2hsla(rgba) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @name clay.core.color.lift
|
||||
* @param {string} color
|
||||
* @param {number} level
|
||||
* @return {string}
|
||||
* @param color
|
||||
* @param level
|
||||
* @return
|
||||
*/
|
||||
colorUtil.lift = function (color, level) {
|
||||
const colorArr = colorUtil.parse(color);
|
||||
export function lift(color: string, level: number): string | undefined {
|
||||
const colorArr = parse(color);
|
||||
if (colorArr) {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (level < 0) {
|
||||
@ -473,33 +466,31 @@ colorUtil.lift = function (color, level) {
|
||||
colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;
|
||||
}
|
||||
}
|
||||
return colorUtil.stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
|
||||
return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @name clay.core.color.toHex
|
||||
* @param {string} color
|
||||
* @return {string}
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
colorUtil.toHex = function (color) {
|
||||
const colorArr = colorUtil.parse(color);
|
||||
export function toHex(color: string): string | undefined {
|
||||
const colorArr = parse(color);
|
||||
if (colorArr) {
|
||||
return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + +colorArr[2])
|
||||
.toString(16)
|
||||
.slice(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Map value to color. Faster than lerp methods because color is represented by rgba array.
|
||||
* @name clay.core.color
|
||||
* @param {number} normalizedValue A float between 0 and 1.
|
||||
* @param {Array.<Array.<number>>} colors List of rgba color array
|
||||
* @param {Array.<number>} [out] Mapped gba color array
|
||||
* @return {Array.<number>} will be null/undefined if input illegal.
|
||||
* @param normalizedValue A float between 0 and 1.
|
||||
* @param colors List of rgba color array
|
||||
* @param out Mapped gba color array
|
||||
* @return will be null/undefined if input illegal.
|
||||
*/
|
||||
colorUtil.fastLerp = function (normalizedValue, colors, out) {
|
||||
export function fastLerp(normalizedValue: number, colors: number[][], out?: number[]) {
|
||||
if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1)) {
|
||||
return;
|
||||
}
|
||||
@ -518,9 +509,7 @@ colorUtil.fastLerp = function (normalizedValue, colors, out) {
|
||||
out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
colorUtil.fastMapToColor = colorUtil.fastLerp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} normalizedValue A float between 0 and 1.
|
||||
@ -529,7 +518,7 @@ colorUtil.fastMapToColor = colorUtil.fastLerp;
|
||||
* @return {(string|Object)} Result color. If fullOutput,
|
||||
* return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},
|
||||
*/
|
||||
colorUtil.lerp = function (normalizedValue, colors, fullOutput) {
|
||||
export function lerp(normalizedValue: number, colors: string[]) {
|
||||
if (!(colors && colors.length) || !(normalizedValue >= 0 && normalizedValue <= 1)) {
|
||||
return;
|
||||
}
|
||||
@ -537,11 +526,14 @@ colorUtil.lerp = function (normalizedValue, colors, fullOutput) {
|
||||
const value = normalizedValue * (colors.length - 1);
|
||||
const leftIndex = Math.floor(value);
|
||||
const rightIndex = Math.ceil(value);
|
||||
const leftColor = colorUtil.parse(colors[leftIndex]);
|
||||
const rightColor = colorUtil.parse(colors[rightIndex]);
|
||||
const leftColor = parse(colors[leftIndex]);
|
||||
const rightColor = parse(colors[rightIndex]);
|
||||
if (!leftColor || !rightColor) {
|
||||
return;
|
||||
}
|
||||
const dv = value - leftIndex;
|
||||
|
||||
const color = colorUtil.stringify(
|
||||
return stringify(
|
||||
[
|
||||
clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)),
|
||||
clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)),
|
||||
@ -550,71 +542,55 @@ colorUtil.lerp = function (normalizedValue, colors, fullOutput) {
|
||||
],
|
||||
'rgba'
|
||||
);
|
||||
|
||||
return fullOutput
|
||||
? {
|
||||
color: color,
|
||||
leftIndex: leftIndex,
|
||||
rightIndex: rightIndex,
|
||||
value: value
|
||||
}
|
||||
: color;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
colorUtil.mapToColor = colorUtil.lerp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name clay.core.color
|
||||
* @param {string} color
|
||||
* @param {number=} h 0 ~ 360, ignore when null.
|
||||
* @param {number=} s 0 ~ 1, ignore when null.
|
||||
* @param {number=} l 0 ~ 1, ignore when null.
|
||||
* @return {string} Color string in rgba format.
|
||||
* @param color
|
||||
* @param h 0 ~ 360, ignore when null.
|
||||
* @param s 0 ~ 1, ignore when null.
|
||||
* @param l 0 ~ 1, ignore when null.
|
||||
* @return Color string in rgba format.
|
||||
*/
|
||||
colorUtil.modifyHSL = function (color, h, s, l) {
|
||||
color = colorUtil.parse(color);
|
||||
export function modifyHSL(color: string, h: number, s: number, l: number): string | undefined {
|
||||
let colorArr = parse(color);
|
||||
|
||||
if (color) {
|
||||
color = rgba2hsla(color);
|
||||
h != null && (color[0] = clampCssAngle(h));
|
||||
s != null && (color[1] = parseCssFloat(s));
|
||||
l != null && (color[2] = parseCssFloat(l));
|
||||
if (colorArr) {
|
||||
colorArr = rgba2hsla(colorArr)!;
|
||||
h != null && (colorArr[0] = clampCssAngle(h));
|
||||
s != null && (colorArr[1] = parseCssFloat(s));
|
||||
l != null && (colorArr[2] = parseCssFloat(l));
|
||||
|
||||
return colorUtil.stringify(hsla2rgba(color), 'rgba');
|
||||
return stringify(hsla2rgba(colorArr), 'rgba');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} color
|
||||
* @param {number=} alpha 0 ~ 1
|
||||
* @return {string} Color string in rgba format.
|
||||
*/
|
||||
colorUtil.modifyAlpha = function (color, alpha) {
|
||||
color = colorUtil.parse(color);
|
||||
export function modifyAlpha(color: string, alpha: number) {
|
||||
const colorArr = parse(color);
|
||||
|
||||
if (color && alpha != null) {
|
||||
color[3] = clampCssFloat(alpha);
|
||||
return colorUtil.stringify(color, 'rgba');
|
||||
if (colorArr && alpha != null) {
|
||||
colorArr[3] = clampCssFloat(alpha);
|
||||
return stringify(colorArr, 'rgba');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array.<number>} arrColor like [12,33,44,0.4]
|
||||
* @param {string} type 'rgba', 'hsva', ...
|
||||
* @return {string} Result color. (If input illegal, return undefined).
|
||||
* @param colorArr like [12,33,44,0.4]
|
||||
* @param type 'rgba', 'hsva', ...
|
||||
* @return Result color. (If input illegal, return undefined).
|
||||
*/
|
||||
colorUtil.stringify = function (arrColor, type) {
|
||||
if (!arrColor || !arrColor.length) {
|
||||
export function stringify(colorArr: number[], type: 'rgba' | 'hsva' | 'hsla' | 'rgb') {
|
||||
if (!colorArr || !colorArr.length) {
|
||||
return;
|
||||
}
|
||||
let colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
|
||||
let colorStr = colorArr[0] + ',' + colorArr[1] + ',' + colorArr[2];
|
||||
if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
|
||||
colorStr += ',' + arrColor[3];
|
||||
colorStr += ',' + colorArr[3];
|
||||
}
|
||||
return type + '(' + colorStr + ')';
|
||||
};
|
||||
|
||||
export default colorUtil;
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
/**
|
||||
* @namespace clay.core.glenum
|
||||
* @see http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14
|
||||
@ -418,4 +417,4 @@ export default {
|
||||
CONTEXT_LOST_WEBGL: 0x9242,
|
||||
UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243,
|
||||
BROWSER_DEFAULT_WEBGL: 0x9244
|
||||
};
|
||||
} as const;
|
||||
|
||||
@ -1,106 +0,0 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import util from '../util';
|
||||
|
||||
/**
|
||||
* Extend a sub class from base class
|
||||
* @param {object|Function} makeDefaultOpt default option of this sub class, method of the sub can use this.xxx to access this option
|
||||
* @param {Function} [initialize] Initialize after the sub class is instantiated
|
||||
* @param {Object} [proto] Prototype methods/properties of the sub class
|
||||
* @memberOf clay.core.mixin.extend
|
||||
* @return {Function}
|
||||
*/
|
||||
function derive(makeDefaultOpt, initialize /*optional*/, proto /*optional*/) {
|
||||
if (typeof initialize == 'object') {
|
||||
proto = initialize;
|
||||
initialize = null;
|
||||
}
|
||||
|
||||
const _super = this;
|
||||
|
||||
let propList;
|
||||
if (!(makeDefaultOpt instanceof Function)) {
|
||||
// Optimize the property iterate if it have been fixed
|
||||
propList = [];
|
||||
for (const propName in makeDefaultOpt) {
|
||||
if (util.hasOwn(makeDefaultOpt, propName)) {
|
||||
propList.push(propName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sub = function (options) {
|
||||
// call super constructor
|
||||
_super.apply(this, arguments);
|
||||
|
||||
if (makeDefaultOpt instanceof Function) {
|
||||
// Invoke makeDefaultOpt each time if it is a function, So we can make sure each
|
||||
// property in the object will not be shared by mutiple instances
|
||||
extend(this, makeDefaultOpt.call(this, options));
|
||||
} else {
|
||||
extendWithPropList(this, makeDefaultOpt, propList);
|
||||
}
|
||||
|
||||
if (this.constructor === sub) {
|
||||
// Initialize function will be called in the order of inherit
|
||||
const initializers = sub.__initializers__;
|
||||
for (let i = 0; i < initializers.length; i++) {
|
||||
initializers[i].apply(this, arguments);
|
||||
}
|
||||
}
|
||||
};
|
||||
// save super constructor
|
||||
sub.__super__ = _super;
|
||||
// Initialize function will be called after all the super constructor is called
|
||||
if (!_super.__initializers__) {
|
||||
sub.__initializers__ = [];
|
||||
} else {
|
||||
sub.__initializers__ = _super.__initializers__.slice();
|
||||
}
|
||||
if (initialize) {
|
||||
sub.__initializers__.push(initialize);
|
||||
}
|
||||
|
||||
const Ctor = function () {};
|
||||
Ctor.prototype = _super.prototype;
|
||||
sub.prototype = new Ctor();
|
||||
sub.prototype.constructor = sub;
|
||||
extend(sub.prototype, proto);
|
||||
|
||||
// extend the derive method as a static method;
|
||||
sub.extend = _super.extend;
|
||||
|
||||
// DEPCRATED
|
||||
sub.derive = _super.extend;
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
function extend(target, source) {
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
for (const name in source) {
|
||||
if (util.hasOwn(source, name)) {
|
||||
target[name] = source[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extendWithPropList(target, source, propList) {
|
||||
for (let i = 0; i < propList.length; i++) {
|
||||
const propName = propList[i];
|
||||
target[propName] = source[propName];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @alias clay.core.mixin.extend
|
||||
* @mixin
|
||||
*/
|
||||
export default {
|
||||
extend: derive,
|
||||
|
||||
// DEPCRATED
|
||||
derive: derive
|
||||
};
|
||||
@ -1,5 +1,10 @@
|
||||
// @ts-nocheck
|
||||
function get(options) {
|
||||
function get(options: {
|
||||
url: string;
|
||||
responseType?: XMLHttpRequest['responseType'];
|
||||
onprogress?: (percent: number, loaded: number, total: number) => void;
|
||||
onload?: (data: any) => void;
|
||||
onerror?: () => void;
|
||||
}) {
|
||||
/* global XMLHttpRequest */
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
@ -10,18 +15,19 @@ function get(options) {
|
||||
// arraybuffer, blob, document, json, text
|
||||
xhr.responseType = options.responseType || 'text';
|
||||
|
||||
if (options.onprogress) {
|
||||
const onprogress = options.onprogress;
|
||||
if (onprogress) {
|
||||
//https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest
|
||||
xhr.onprogress = function (e) {
|
||||
if (e.lengthComputable) {
|
||||
const percent = e.loaded / e.total;
|
||||
options.onprogress(percent, e.loaded, e.total);
|
||||
onprogress(percent, e.loaded, e.total);
|
||||
} else {
|
||||
options.onprogress(null);
|
||||
onprogress(0, 0, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
xhr.onload = function (e) {
|
||||
xhr.onload = function () {
|
||||
if (xhr.status >= 400) {
|
||||
options.onerror && options.onerror();
|
||||
} else {
|
||||
@ -34,6 +40,4 @@ function get(options) {
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
export default {
|
||||
get: get
|
||||
};
|
||||
export { get };
|
||||
|
||||
301
src/core/util.ts
301
src/core/util.ts
@ -1,202 +1,129 @@
|
||||
// @ts-nocheck
|
||||
let guid = 0;
|
||||
|
||||
const ArrayProto = Array.prototype;
|
||||
const nativeForEach = ArrayProto.forEach;
|
||||
|
||||
/**
|
||||
* Util functions
|
||||
* @namespace clay.core.util
|
||||
* Generate GUID
|
||||
* @return {number}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
const util = {
|
||||
/**
|
||||
* Generate GUID
|
||||
* @return {number}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
genGUID: function () {
|
||||
return ++guid;
|
||||
},
|
||||
/**
|
||||
* Relative path to absolute path
|
||||
* @param {string} path
|
||||
* @param {string} basePath
|
||||
* @return {string}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
relative2absolute: function (path, basePath) {
|
||||
if (!basePath || path.match(/^\//)) {
|
||||
return path;
|
||||
}
|
||||
const pathParts = path.split('/');
|
||||
const basePathParts = basePath.split('/');
|
||||
export function genGUID(): number {
|
||||
return ++guid;
|
||||
}
|
||||
/**
|
||||
* Relative path to absolute path
|
||||
* @param {string} path
|
||||
* @param {string} basePath
|
||||
* @return {string}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
export function relative2absolute(path: string, basePath: string) {
|
||||
if (!basePath || path.match(/^\//)) {
|
||||
return path;
|
||||
}
|
||||
const pathParts = path.split('/');
|
||||
const basePathParts = basePath.split('/');
|
||||
|
||||
let item = pathParts[0];
|
||||
while (item === '.' || item === '..') {
|
||||
if (item === '..') {
|
||||
basePathParts.pop();
|
||||
}
|
||||
pathParts.shift();
|
||||
item = pathParts[0];
|
||||
let item = pathParts[0];
|
||||
while (item === '.' || item === '..') {
|
||||
if (item === '..') {
|
||||
basePathParts.pop();
|
||||
}
|
||||
return basePathParts.join('/') + '/' + pathParts.join('/');
|
||||
},
|
||||
pathParts.shift();
|
||||
item = pathParts[0];
|
||||
}
|
||||
return basePathParts.join('/') + '/' + pathParts.join('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend target with source
|
||||
* @param {Object} target
|
||||
* @param {Object} source
|
||||
* @return {Object}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
extend: function (target, source) {
|
||||
if (source) {
|
||||
for (const name in source) {
|
||||
if (util.hasOwn(source, name)) {
|
||||
target[name] = source[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
},
|
||||
|
||||
/**
|
||||
* Extend properties to target if not exist.
|
||||
* @param {Object} target
|
||||
* @param {Object} source
|
||||
* @return {Object}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
defaults: function (target, source) {
|
||||
if (source) {
|
||||
for (const propName in source) {
|
||||
if (target[propName] === undefined) {
|
||||
target[propName] = source[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
},
|
||||
/**
|
||||
* Extend properties with a given property list to avoid for..in.. iteration.
|
||||
* @param {Object} target
|
||||
* @param {Object} source
|
||||
* @param {Array.<string>} propList
|
||||
* @return {Object}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
extendWithPropList: function (target, source, propList) {
|
||||
if (source) {
|
||||
for (let i = 0; i < propList.length; i++) {
|
||||
const propName = propList[i];
|
||||
/**
|
||||
* Extend properties to target if not exist.
|
||||
* @param {Object} target
|
||||
* @param {Object} source
|
||||
* @return {Object}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
export function defaults(target: any, source: any) {
|
||||
if (source) {
|
||||
for (const propName in source) {
|
||||
if (target[propName] === undefined) {
|
||||
target[propName] = source[propName];
|
||||
}
|
||||
}
|
||||
return target;
|
||||
},
|
||||
/**
|
||||
* Extend properties to target if not exist. With a given property list avoid for..in.. iteration.
|
||||
* @param {Object} target
|
||||
* @param {Object} source
|
||||
* @param {Array.<string>} propList
|
||||
* @return {Object}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
defaultsWithPropList: function (target, source, propList) {
|
||||
if (source) {
|
||||
for (let i = 0; i < propList.length; i++) {
|
||||
const propName = propList[i];
|
||||
if (target[propName] == null) {
|
||||
target[propName] = source[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
},
|
||||
/**
|
||||
* @param {Object|Array} obj
|
||||
* @param {Function} iterator
|
||||
* @param {Object} [context]
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
each: function (obj, iterator, context) {
|
||||
if (!(obj && iterator)) {
|
||||
return;
|
||||
}
|
||||
if (obj.forEach && obj.forEach === nativeForEach) {
|
||||
obj.forEach(iterator, context);
|
||||
} else if (obj.length === +obj.length) {
|
||||
for (let i = 0, len = obj.length; i < len; i++) {
|
||||
iterator.call(context, obj[i], i, obj);
|
||||
}
|
||||
} else {
|
||||
for (const key in obj) {
|
||||
if (util.hasOwn(obj, key)) {
|
||||
iterator.call(context, obj[key], key, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Is object
|
||||
* @param {} obj
|
||||
* @return {boolean}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
isObject: function (obj) {
|
||||
return obj === Object(obj);
|
||||
},
|
||||
|
||||
/**
|
||||
* Is array ?
|
||||
* @param {} obj
|
||||
* @return {boolean}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
isArray: function (obj) {
|
||||
return Array.isArray(obj);
|
||||
},
|
||||
|
||||
/**
|
||||
* Is array like, which have a length property
|
||||
* @param {} obj
|
||||
* @return {boolean}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
isArrayLike: function (obj) {
|
||||
if (!obj) {
|
||||
return false;
|
||||
} else {
|
||||
return obj.length === +obj.length;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} obj
|
||||
* @return {}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
clone: function (obj) {
|
||||
if (!util.isObject(obj)) {
|
||||
return obj;
|
||||
} else if (util.isArray(obj)) {
|
||||
return obj.slice();
|
||||
} else if (util.isArrayLike(obj)) {
|
||||
// is typed array
|
||||
const ret = new obj.constructor(obj.length);
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
ret[i] = obj[i];
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return util.extend({}, obj);
|
||||
}
|
||||
},
|
||||
|
||||
hasOwn: function (obj, key) {
|
||||
return obj != null && Object.prototype.hasOwnProperty.call(obj, key);
|
||||
}
|
||||
};
|
||||
return target;
|
||||
}
|
||||
/**
|
||||
* @param {Object|Array} obj
|
||||
* @param {Function} iterator
|
||||
* @param {Object} [context]
|
||||
* @deprecated
|
||||
*/
|
||||
export function each(obj: any, iterator: Function, context: any) {
|
||||
if (!(obj && iterator)) {
|
||||
return;
|
||||
}
|
||||
if (obj.forEach && obj.forEach === nativeForEach) {
|
||||
obj.forEach(iterator, context);
|
||||
} else if (obj.length === +obj.length) {
|
||||
for (let i = 0, len = obj.length; i < len; i++) {
|
||||
iterator.call(context, obj[i], i, obj);
|
||||
}
|
||||
} else {
|
||||
for (const key in obj) {
|
||||
if (hasOwn(obj, key)) {
|
||||
iterator.call(context, obj[key], key, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default util;
|
||||
/**
|
||||
* Is object
|
||||
* @param {} obj
|
||||
* @return {boolean}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
export function isObject(obj: any) {
|
||||
return obj === Object(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array like, which have a length property
|
||||
* @param {} obj
|
||||
* @return {boolean}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
export function isArrayLike(obj: any): obj is ArrayLike<any> {
|
||||
if (!obj) {
|
||||
return false;
|
||||
} else {
|
||||
return obj.length === +obj.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {} obj
|
||||
* @return {}
|
||||
* @memberOf clay.core.util
|
||||
*/
|
||||
export function clone<T>(obj: T): T {
|
||||
if (!isObject(obj)) {
|
||||
return obj;
|
||||
} else if (Array.isArray(obj)) {
|
||||
return obj.slice() as unknown as T;
|
||||
} else if (isArrayLike(obj)) {
|
||||
// is typed array
|
||||
const ret = new (obj as any).constructor(obj.length);
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
ret[i] = obj[i];
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return Object.assign({}, obj);
|
||||
}
|
||||
}
|
||||
|
||||
export function hasOwn(obj: any, key: string) {
|
||||
return obj != null && Object.prototype.hasOwnProperty.call(obj, key);
|
||||
}
|
||||
|
||||
@ -1,9 +1,20 @@
|
||||
// @ts-nocheck
|
||||
import request from './request';
|
||||
import { get } from './request';
|
||||
|
||||
let supportWebGL;
|
||||
let supportWebGL: boolean;
|
||||
|
||||
const vendor = {};
|
||||
interface Vendor {
|
||||
supportWebGL: () => boolean;
|
||||
requestAnimationFrame: (cb: () => void) => void;
|
||||
/* global HTMLCanvasElement HTMLImageElement */
|
||||
createCanvas: () => HTMLCanvasElement;
|
||||
createImage: () => HTMLImageElement;
|
||||
request: {
|
||||
get: typeof get;
|
||||
};
|
||||
addEventListener: (dom: any, type: string, func: Function, useCapture?: boolean) => void;
|
||||
removeEventListener: (dom: any, type: string, func: Function) => void;
|
||||
}
|
||||
const vendor = {} as Vendor;
|
||||
|
||||
/**
|
||||
* If support WebGL
|
||||
@ -25,21 +36,7 @@ vendor.supportWebGL = function () {
|
||||
return supportWebGL;
|
||||
};
|
||||
|
||||
vendor.Int8Array = typeof Int8Array === 'undefined' ? Array : Int8Array;
|
||||
|
||||
vendor.Uint8Array = typeof Uint8Array === 'undefined' ? Array : Uint8Array;
|
||||
|
||||
vendor.Uint16Array = typeof Uint16Array === 'undefined' ? Array : Uint16Array;
|
||||
|
||||
vendor.Uint32Array = typeof Uint32Array === 'undefined' ? Array : Uint32Array;
|
||||
|
||||
vendor.Int16Array = typeof Int16Array === 'undefined' ? Array : Int16Array;
|
||||
|
||||
vendor.Float32Array = typeof Float32Array === 'undefined' ? Array : Float32Array;
|
||||
|
||||
vendor.Float64Array = typeof Float64Array === 'undefined' ? Array : Float64Array;
|
||||
|
||||
let g = {};
|
||||
let g: any;
|
||||
if (typeof window !== 'undefined') {
|
||||
g = window;
|
||||
} else if (typeof global !== 'undefined') {
|
||||
@ -49,10 +46,7 @@ if (typeof window !== 'undefined') {
|
||||
|
||||
vendor.requestAnimationFrame =
|
||||
g.requestAnimationFrame ||
|
||||
g.msRequestAnimationFrame ||
|
||||
g.mozRequestAnimationFrame ||
|
||||
g.webkitRequestAnimationFrame ||
|
||||
function (func) {
|
||||
function (func: () => void) {
|
||||
setTimeout(func, 16);
|
||||
};
|
||||
|
||||
@ -65,7 +59,7 @@ vendor.createImage = function () {
|
||||
};
|
||||
|
||||
vendor.request = {
|
||||
get: request.get
|
||||
get
|
||||
};
|
||||
|
||||
vendor.addEventListener = function (dom, type, func, useCapture) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import util from './core/util';
|
||||
import * as util from './core/util';
|
||||
import Compositor from './compositor/Compositor';
|
||||
import CompoSceneNode from './compositor/SceneNode';
|
||||
import CompoTextureNode from './compositor/TextureNode';
|
||||
|
||||
@ -17,7 +17,7 @@ import Vector3 from '../math/Vector3';
|
||||
import GBuffer from './GBuffer';
|
||||
|
||||
import prezGlsl from '../shader/source/prez.glsl.js';
|
||||
import utilGlsl from '../shader/source/util.glsl.js';
|
||||
import * as utilGlsl from '../shader/source/util.glsl.js';
|
||||
|
||||
import lightvolumeGlsl from '../shader/source/deferred/lightvolume.glsl.js';
|
||||
// Light shaders
|
||||
|
||||
@ -66,7 +66,7 @@ const Cube = Geometry.extend(
|
||||
for (let k = 0; k < attrList.length; k++) {
|
||||
this.attributes[attrList[k]].init(vertexNumber);
|
||||
}
|
||||
this.indices = new vendor.Uint16Array(faceNumber);
|
||||
this.indices = new Uint16Array(faceNumber);
|
||||
let faceOffset = 0;
|
||||
let vertexOffset = 0;
|
||||
for (const pos in planes) {
|
||||
|
||||
@ -29,7 +29,7 @@ function checkShaderErrorMsg(_gl, shader, shaderString) {
|
||||
}
|
||||
}
|
||||
|
||||
const tmpFloat32Array16 = new vendor.Float32Array(16);
|
||||
const tmpFloat32Array16 = new Float32Array(16);
|
||||
|
||||
const GLProgram = Base.extend(
|
||||
{
|
||||
@ -163,7 +163,7 @@ const GLProgram = Base.extend(
|
||||
case 'm4v':
|
||||
// Raw value
|
||||
if (Array.isArray(value) && Array.isArray(value[0])) {
|
||||
const array = new vendor.Float32Array(value.length * 16);
|
||||
const array = new Float32Array(value.length * 16);
|
||||
let cursor = 0;
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const item = value[i];
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import Light from '../Light';
|
||||
import vendor from '../core/vendor';
|
||||
|
||||
/**
|
||||
* Spherical Harmonic Ambient Light
|
||||
@ -19,7 +18,7 @@ const AmbientSHLight = Light.extend(
|
||||
coefficients: []
|
||||
},
|
||||
function () {
|
||||
this._coefficientsTmpArr = new vendor.Float32Array(9 * 3);
|
||||
this._coefficientsTmpArr = new Float32Array(9 * 3);
|
||||
},
|
||||
{
|
||||
type: 'AMBIENT_SH_LIGHT',
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
* TODO Morph targets
|
||||
*/
|
||||
import Base from '../core/Base';
|
||||
import util from '../core/util';
|
||||
import * as util from '../core/util';
|
||||
import vendor from '../core/vendor';
|
||||
|
||||
import Scene from '../Scene';
|
||||
@ -45,12 +45,12 @@ const semanticAttributeMap = {
|
||||
};
|
||||
|
||||
const ARRAY_CTOR_MAP = {
|
||||
5120: vendor.Int8Array,
|
||||
5121: vendor.Uint8Array,
|
||||
5122: vendor.Int16Array,
|
||||
5123: vendor.Uint16Array,
|
||||
5125: vendor.Uint32Array,
|
||||
5126: vendor.Float32Array
|
||||
5120: Int8Array,
|
||||
5121: Uint8Array,
|
||||
5122: Int16Array,
|
||||
5123: Uint16Array,
|
||||
5125: Uint32Array,
|
||||
5126: Float32Array
|
||||
};
|
||||
const SIZE_MAP = {
|
||||
SCALAR: 1,
|
||||
@ -67,7 +67,7 @@ function getAccessorData(json, lib, accessorIdx, isIndices) {
|
||||
|
||||
const buffer = lib.bufferViews[accessorInfo.bufferView];
|
||||
const byteOffset = accessorInfo.byteOffset || 0;
|
||||
const ArrayCtor = ARRAY_CTOR_MAP[accessorInfo.componentType] || vendor.Float32Array;
|
||||
const ArrayCtor = ARRAY_CTOR_MAP[accessorInfo.componentType] || Float32Array;
|
||||
|
||||
let size = SIZE_MAP[accessorInfo.type];
|
||||
if (size == null && isIndices) {
|
||||
@ -79,7 +79,7 @@ function getAccessorData(json, lib, accessorIdx, isIndices) {
|
||||
// eslint-disable-next-line
|
||||
accessorInfo.extensions && accessorInfo.extensions['WEB3D_quantized_attributes'];
|
||||
if (quantizeExtension) {
|
||||
const decodedArr = new vendor.Float32Array(size * accessorInfo.count);
|
||||
const decodedArr = new Float32Array(size * accessorInfo.count);
|
||||
const decodeMatrix = quantizeExtension.decodeMatrix;
|
||||
const decodeOffset = [];
|
||||
const decodeScale = [];
|
||||
@ -540,7 +540,7 @@ const GLTFLoader = Base.extend(
|
||||
const offset = IBMInfo.byteOffset || 0;
|
||||
const size = IBMInfo.count * 16;
|
||||
|
||||
const array = new vendor.Float32Array(buffer, offset, size);
|
||||
const array = new Float32Array(buffer, offset, size);
|
||||
|
||||
skeleton.setJointMatricesArray(array);
|
||||
} else {
|
||||
@ -812,7 +812,7 @@ const GLTFLoader = Base.extend(
|
||||
}
|
||||
if (isStandardMaterial) {
|
||||
material = new StandardMaterial(
|
||||
util.extend(
|
||||
Object.assign(
|
||||
{
|
||||
name: materialInfo.name,
|
||||
alphaTest: alphaTest,
|
||||
@ -1000,7 +1000,7 @@ const GLTFLoader = Base.extend(
|
||||
let attributeArray = getAccessorData(json, lib, accessorIdx);
|
||||
// WebGL attribute buffer not support uint32.
|
||||
// Direct use Float32Array may also have issue.
|
||||
if (attributeArray instanceof vendor.Uint32Array) {
|
||||
if (attributeArray instanceof Uint32Array) {
|
||||
attributeArray = new Float32Array(attributeArray);
|
||||
}
|
||||
if (semantic === 'WEIGHTS_0' && size === 4) {
|
||||
@ -1035,13 +1035,13 @@ const GLTFLoader = Base.extend(
|
||||
}
|
||||
|
||||
let attributeType = 'float';
|
||||
if (attributeArray instanceof vendor.Uint16Array) {
|
||||
if (attributeArray instanceof Uint16Array) {
|
||||
attributeType = 'ushort';
|
||||
} else if (attributeArray instanceof vendor.Int16Array) {
|
||||
} else if (attributeArray instanceof Int16Array) {
|
||||
attributeType = 'short';
|
||||
} else if (attributeArray instanceof vendor.Uint8Array) {
|
||||
} else if (attributeArray instanceof Uint8Array) {
|
||||
attributeType = 'ubyte';
|
||||
} else if (attributeArray instanceof vendor.Int8Array) {
|
||||
} else if (attributeArray instanceof Int8Array) {
|
||||
attributeType = 'byte';
|
||||
}
|
||||
geometry.attributes[attributeName].type = attributeType;
|
||||
@ -1062,14 +1062,11 @@ const GLTFLoader = Base.extend(
|
||||
// Parse indices
|
||||
if (primitiveInfo.indices != null) {
|
||||
geometry.indices = getAccessorData(json, lib, primitiveInfo.indices, true);
|
||||
if (
|
||||
geometry.vertexCount <= 0xffff &&
|
||||
geometry.indices instanceof vendor.Uint32Array
|
||||
) {
|
||||
geometry.indices = new vendor.Uint16Array(geometry.indices);
|
||||
if (geometry.vertexCount <= 0xffff && geometry.indices instanceof Uint32Array) {
|
||||
geometry.indices = new Uint16Array(geometry.indices);
|
||||
}
|
||||
if (geometry.indices instanceof vendor.Uint8Array) {
|
||||
geometry.indices = new vendor.Uint16Array(geometry.indices);
|
||||
if (geometry.indices instanceof Uint8Array) {
|
||||
geometry.indices = new Uint16Array(geometry.indices);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import util from '../core/util';
|
||||
import * as util from '../core/util';
|
||||
|
||||
const GestureMgr = function () {
|
||||
this._track = [];
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// @ts-nocheck
|
||||
import lightEssl from './source/header/light';
|
||||
import utilEssl from './source/util.glsl.js';
|
||||
import * as utilEssl from './source/util.glsl.js';
|
||||
|
||||
import basicEssl from './source/basic.glsl.js';
|
||||
import lambertEssl from './source/lambert.glsl.js';
|
||||
|
||||
@ -55,7 +55,7 @@ float edgeFactor(float width)
|
||||
// Pack depth
|
||||
// !!!! Float value can only be [0.0 - 1.0)
|
||||
@export clay.util.encode_float
|
||||
vec4 encodeFloat(let in float depth)
|
||||
vec4 encodeFloat(const in float depth)
|
||||
{
|
||||
// const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
|
||||
// const vec3 PackFactors = vec3(256. * 256. * 256., 256. * 256., 256.);
|
||||
@ -75,7 +75,7 @@ vec4 encodeFloat(let in float depth)
|
||||
@end
|
||||
|
||||
@export clay.util.decode_float
|
||||
float decodeFloat(let in vec4 color)
|
||||
float decodeFloat(const in vec4 color)
|
||||
{
|
||||
// const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)
|
||||
// const vec3 PackFactors = vec3(256. * 256. * 256., 256. * 256., 256.);
|
||||
@ -252,7 +252,7 @@ vec3 parallaxCorrect(in vec3 dir, in vec3 pos, in vec3 boxMin, in vec3 boxMax) {
|
||||
|
||||
@export clay.util.clamp_sample
|
||||
// Sample with stereo clamp
|
||||
vec4 clampSample(let in sampler2D texture, let in vec2 coord)
|
||||
vec4 clampSample(const in sampler2D texture, const in vec2 coord)
|
||||
{
|
||||
#ifdef STEREO
|
||||
// Left is 0.0 - 0.5, Right is 0.5 - 1.0, avoid leaking
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -35,10 +35,10 @@ function projectEnvironmentMapGPU(renderer, envMap) {
|
||||
|
||||
framebuffer.bind(renderer);
|
||||
// TODO Only chrome and firefox support Float32Array
|
||||
const pixels = new vendor.Float32Array(9 * 4);
|
||||
const pixels = new Float32Array(9 * 4);
|
||||
renderer.gl.readPixels(0, 0, 9, 1, Texture.RGBA, Texture.FLOAT, pixels);
|
||||
|
||||
const coeff = new vendor.Float32Array(9 * 3);
|
||||
const coeff = new Float32Array(9 * 3);
|
||||
for (let i = 0; i < 9; i++) {
|
||||
coeff[i * 3] = pixels[i * 4];
|
||||
coeff[i * 3 + 1] = pixels[i * 4 + 1];
|
||||
@ -88,7 +88,7 @@ const normalTransform = {
|
||||
|
||||
// Project on cpu.
|
||||
function projectEnvironmentMapCPU(renderer, cubePixels, width, height) {
|
||||
const coeff = new vendor.Float32Array(9 * 3);
|
||||
const coeff = new Float32Array(9 * 3);
|
||||
const normal = vec3.create();
|
||||
const texel = vec3.create();
|
||||
const fetchNormal = vec3.create();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import util from '../core/util';
|
||||
import * as util from '../core/util';
|
||||
import Geometry from '../Geometry';
|
||||
import BoundingBox from '../math/BoundingBox';
|
||||
import Vector3 from '../math/Vector3';
|
||||
@ -25,7 +25,7 @@ const transferableUtil = {
|
||||
return null;
|
||||
}
|
||||
const data = {
|
||||
metadata: util.extend({}, META)
|
||||
metadata: Object.assign({}, META)
|
||||
};
|
||||
//transferable buffers
|
||||
const buffers = [];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user