wip: update core module to typescript

This commit is contained in:
pissang 2022-04-23 20:00:26 +08:00
parent 49e1f145d3
commit 872b465cde
37 changed files with 699 additions and 934 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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 = {};

View File

@ -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';

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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';

View File

@ -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;

View File

@ -1,5 +1,5 @@
// @ts-nocheck
import util from '../core/util';
import * as util from '../core/util';
import Task from './Task';
/**

View File

@ -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';

View File

@ -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 = {};

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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
};

View File

@ -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 };

View File

@ -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);
}

View File

@ -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) {

View File

@ -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';

View File

@ -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

View File

@ -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) {

View File

@ -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];

View File

@ -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',

View File

@ -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);
}
}

View File

@ -1,5 +1,5 @@
// @ts-nocheck
import util from '../core/util';
import * as util from '../core/util';
const GestureMgr = function () {
this._track = [];

View File

@ -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';

View File

@ -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

View File

@ -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();

View File

@ -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 = [];