UNPKG

17.8 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.isArrayLike = exports.ensureRGB = exports.ensureRGBA = exports.clampToMaxSize = exports.scaleWithCanvas = exports.makePowerOfTwo = exports.getScreenOrientation = exports.createCanvas = exports.nearestPowerOfTwo = exports.get = exports.assignDefaults = exports.lerp = exports.radians = exports.debug = undefined;
7
8var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
9
10var _debug = require('debug');
11
12var _debug2 = _interopRequireDefault(_debug);
13
14var _isTypedarray = require('is-typedarray');
15
16var _isTypedarray2 = _interopRequireDefault(_isTypedarray);
17
18var _document = require('global/document');
19
20var _document2 = _interopRequireDefault(_document);
21
22var _window = require('global/window');
23
24var _window2 = _interopRequireDefault(_window);
25
26var _extend = require('extend');
27
28var _extend2 = _interopRequireDefault(_extend);
29
30var _clamp = require('clamp');
31
32var _clamp2 = _interopRequireDefault(_clamp);
33
34function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
36function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
37
38var kLibraryVersion = '0.5.2';
39var TypedArray = Object.getPrototypeOf(Float32Array.prototype).constructor;
40
41var HTMLImageElement = _window2.default.HTMLImageElement,
42 HTMLCanvasElement = _window2.default.HTMLCanvasElement;
43var debug = exports.debug = (0, _debug2.default)('[axis3d@' + kLibraryVersion + ']');
44
45var radians = exports.radians = function radians(n) {
46 return n == n ? n * Math.PI / 180.0 : 0;
47};
48var lerp = exports.lerp = function lerp(v0, v1, t) {
49 return v0 * (1 - t) + v1 * t;
50};
51
52var assignDefaults = exports.assignDefaults = function assignDefaults(object, defaults) {
53 return (0, _extend2.default)(true, object, (0, _extend2.default)(true, {}, defaults, object));
54};
55
56var get = exports.get = function get(k, objs) {
57 return (objs.filter(function (o) {
58 return o;
59 }).find(function (o) {
60 return null != o[k];
61 }) || {})[k];
62};
63
64var nearestPowerOfTwo = exports.nearestPowerOfTwo = function nearestPowerOfTwo(value) {
65 return Math.pow(2, Math.round(Math.log(value) / Math.LN2));
66};
67
68var createCanvas = exports.createCanvas = function createCanvas() {
69 return _document2.default.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
70};
71
72var getScreenOrientation = exports.getScreenOrientation = function getScreenOrientation() {
73 var type = null;
74 if ('object' == _typeof(_window2.default.screen)) {
75 if ('object' == _typeof(_window2.default.screen.orientation)) {
76 type = _window2.default.screen.orientation.type;
77 } else if ('string' == typeof _window2.default.screen.orientation) {
78 type = _window2.default.screen.orientation;
79 } else if ('object' == _typeof(_window2.default.screen.mozOrientation)) {
80 type = _window2.default.screen.mozOrientation.type;
81 } else if ('string' == typeof _window2.default.screen.mozOrientation) {
82 type = _window2.default.screen.mozOrientation;
83 }
84 }
85 switch (type) {
86 case 'landscape-primary':
87 return 90;
88 case 'landscape-secondary':
89 return -90;
90 case 'portrait-secondary':
91 return 180;
92 case 'portrait-primary':
93 return 0;
94 default:
95 return _window2.default.orientation || _window2.default.mozOrientation || 0;
96 }
97};
98
99var makePowerOfTwo = exports.makePowerOfTwo = function makePowerOfTwo(image) {
100 if (image instanceof HTMLImageElement || image instanceof HTMLCanvasElement) {
101 var canvas = createCanvas();
102 var context = canvas.getContext('2d');
103 canvas.width = nearestPowerOfTwo(image.width);
104 canvas.height = nearestPowerOfTwo(image.height);
105 context.drawImage(image, 0, 0, canvas.width, canvas.height);
106 return canvas;
107 }
108 return image;
109};
110
111var scaleWithCanvas = exports.scaleWithCanvas = function scaleWithCanvas(image, scale, scaleNearestPowerOfTwo) {
112 var canvas = createCanvas();
113 var context = canvas.getContext('2d');
114 var width = image.width,
115 height = image.height;
116
117 if (scaleNearestPowerOfTwo) {
118 width = nearestPowerOfTwo(width);
119 height = nearestPowerOfTwo(height);
120 }
121 canvas.width = Math.floor(image.width * scale);
122 canvas.height = Math.floor(image.height * scale);
123 context.drawImage(image, 0, 0, width, height, 0, 0, canvas.width, canvas.height);
124 return canvas;
125};
126
127var clampToMaxSize = exports.clampToMaxSize = function clampToMaxSize(image, maxSize, scaleNearestPowerOfTwo) {
128 if (image.width > maxSize || image.height > maxSize) {
129 var scale = maxSize / Math.max(image.width, image.height);
130 return scaleWithCanvas(image, scale, scaleNearestPowerOfTwo);
131 } else {
132 return scaleNearestPowerOfTwo ? makePowerOfTwo(image) : image;
133 }
134};
135
136var ensureRGBA = exports.ensureRGBA = function ensureRGBA(color) {
137 color = [].concat(_toConsumableArray(color || []));
138 for (var i = 0; i < 3; ++i) {
139 if ('number' != typeof color[i]) {
140 color[i] = 0;
141 } else {
142 color[i] = (0, _clamp2.default)(color[i], 0, 1);
143 }
144 }
145 if ('number' != typeof color[3]) {
146 color[3] = 1;
147 } else {
148 color[3] = (0, _clamp2.default)(color[3], 0, 1);
149 }
150 return [].concat(_toConsumableArray(color)).slice(0, 4);
151};
152
153var ensureRGB = exports.ensureRGB = function ensureRGB(color) {
154 return ensureRGBA(color).slice(0, 3);
155};
156
157var isArrayLike = exports.isArrayLike = function isArrayLike(array) {
158 return Boolean(array && (Array.isArray(array) || array instanceof TypedArray || (0, _isTypedarray2.default)(array) || 'number' == array.length || 'function' == typeof array[Symbol.iterator]));
159};
160//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlscy5qcyJdLCJuYW1lcyI6WyJrTGlicmFyeVZlcnNpb24iLCJUeXBlZEFycmF5IiwiT2JqZWN0IiwiZ2V0UHJvdG90eXBlT2YiLCJGbG9hdDMyQXJyYXkiLCJwcm90b3R5cGUiLCJjb25zdHJ1Y3RvciIsIkhUTUxJbWFnZUVsZW1lbnQiLCJIVE1MQ2FudmFzRWxlbWVudCIsImRlYnVnIiwicmFkaWFucyIsIm4iLCJNYXRoIiwiUEkiLCJsZXJwIiwidjAiLCJ2MSIsInQiLCJhc3NpZ25EZWZhdWx0cyIsIm9iamVjdCIsImRlZmF1bHRzIiwiZ2V0IiwiayIsIm9ianMiLCJmaWx0ZXIiLCJvIiwiZmluZCIsIm5lYXJlc3RQb3dlck9mVHdvIiwidmFsdWUiLCJwb3ciLCJyb3VuZCIsImxvZyIsIkxOMiIsImNyZWF0ZUNhbnZhcyIsImNyZWF0ZUVsZW1lbnROUyIsImdldFNjcmVlbk9yaWVudGF0aW9uIiwidHlwZSIsInNjcmVlbiIsIm9yaWVudGF0aW9uIiwibW96T3JpZW50YXRpb24iLCJtYWtlUG93ZXJPZlR3byIsImltYWdlIiwiY2FudmFzIiwiY29udGV4dCIsImdldENvbnRleHQiLCJ3aWR0aCIsImhlaWdodCIsImRyYXdJbWFnZSIsInNjYWxlV2l0aENhbnZhcyIsInNjYWxlIiwic2NhbGVOZWFyZXN0UG93ZXJPZlR3byIsImZsb29yIiwiY2xhbXBUb01heFNpemUiLCJtYXhTaXplIiwibWF4IiwiZW5zdXJlUkdCQSIsImNvbG9yIiwiaSIsInNsaWNlIiwiZW5zdXJlUkdCIiwiaXNBcnJheUxpa2UiLCJhcnJheSIsIkJvb2xlYW4iLCJBcnJheSIsImlzQXJyYXkiLCJsZW5ndGgiLCJTeW1ib2wiLCJpdGVyYXRvciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7OztBQUVBLElBQU1BLHlCQUFOO0FBQ0EsSUFBTUMsYUFBYUMsT0FBT0MsY0FBUCxDQUFz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Q0FBTixDQUFOLEVBQWdCLENBQWhCLEVBQW1CLENBQW5CLENBQVg7QUFBa0M7QUFDekMsU0FBTyw2QkFBSUEsS0FBSixHQUFXRSxLQUFYLENBQWlCLENBQWpCLEVBQW9CLENBQXBCLENBQVA7QUFDRCxDQVRNOztBQVdBLElBQU1DLGdDQUFZLFNBQVpBLFNBQVksQ0FBQ0gsS0FBRCxFQUFXO0FBQ2xDLFNBQU9ELFdBQVdDLEtBQVgsRUFBa0JFLEtBQWxCLENBQXdCLENBQXhCLEVBQTJCLENBQTNCLENBQVA7QUFDRCxDQUZNOztBQUlBLElBQU1FLG9DQUFjLFNBQWRBLFdBQWMsQ0FBQ0MsS0FBRCxFQUFXO0FBQ3BDLFNBQU9DLFFBQVFELFVBQ1ZFLE1BQU1DLE9BQU4sQ0FBY0gsS0FBZCxLQUNDQSxpQkFBaUI1RCxVQUFqQixJQUErQiw0QkFBYTRELEtBQWIsQ0FEaEMsSUFFQSxZQUFZQSxNQUFNSSxNQUZsQixJQUdBLGNBQWMsT0FBT0osTUFBTUssT0FBT0MsUUFBYixDQUpYLENBQVIsQ0FBUDtBQU1ELENBUE0iLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY3JlYXRlRGVidWcgZnJvbSAnZGVidWcnXG5pbXBvcnQgaXNUeXBlZEFycmF5IGZyb20gJ2lzLXR5cGVkYXJyYXknXG5pbXBvcnQgZG9jdW1lbnQgZnJvbSAnZ2xvYmFsL2RvY3VtZW50J1xuaW1wb3J0IHdpbmRvdyBmcm9tICdnbG9iYWwvd2luZG93J1xuaW1wb3J0IGV4dGVuZCBmcm9tICdleHRlbmQnXG5pbXBvcnQgY2xhbXAgZnJvbSAnY2xhbXAnXG5cbmNvbnN0IGtMaWJyYXJ5VmVyc2lvbiA9IF9fQVhJUzNEX1ZFUlNJT05fX1xuY29uc3QgVHlwZWRBcnJheSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihGbG9hdDMyQXJyYXkucHJvdG90eXBlKS5jb25zdHJ1Y3RvclxuXG5jb25zdCB7IEhUTUxJbWFnZUVsZW1lbnQsIEhUTUxDYW52YXNFbGVtZW50IH0gPSB3aW5kb3dcblxuZXhwb3J0IGNvbnN0IGRlYnVnID0gY3JlYXRlRGVidWcoYFtheGlzM2RAJHtrTGlicmFyeVZlcnNpb259XWApXG5cbmV4cG9ydCBjb25zdCByYWRpYW5zID0gKG4pID0+IG4gPT0gbiA/IChuKk1hdGguUEkvMTgwLjApIDogMFxuZXhwb3J0IGNvbnN0IGxlcnAgPSAodjAsIHYxLCB0KSA9PiB2MCooMSAtIHQpICsgdjEqdFxuXG5leHBvcnQgY29uc3QgYXNzaWduRGVmYXVsdHMgPSAob2JqZWN0LCBkZWZhdWx0cykgPT4ge1xuICByZXR1cm4gZXh0ZW5kKHRydWUsIG9iamVjdCwgZXh0ZW5kKHRydWUsIHt9LCBkZWZhdWx0cywgb2JqZWN0KSlcbn1cblxuZXhwb3J0IGNvbnN0IGdldCA9IChrLCBvYmpzKSA9PiB7XG4gIHJldHVybiAob2Jqcy5maWx0ZXIoKG8pID0+IG8pLmZpbmQoKG8pID0+IG51bGwgIT0gb1trXSkgfHwge30pW2tdXG59XG5cbmV4cG9ydCBjb25zdCBuZWFyZXN0UG93ZXJPZlR3byA9ICh2YWx1ZSkgPT4ge1xuICByZXR1cm4gTWF0aC5wb3coMiwgTWF0aC5yb3VuZChNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMikpXG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVDYW52YXMgPSAoKSA9PiB7XG4gIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnLCAnY2FudmFzJylcbn1cblxuZXhwb3J0IGNvbnN0IGdldFNjcmVlbk9yaWVudGF0aW9uID0gKCkgPT4ge1xuICBsZXQgYW5nbGUgPSAwXG4gIGxldCB0eXBlID0gbnVsbFxuICBpZiAoJ29iamVjdCcgPT0gdHlwZW9mIHdpbmRvdy5zY3JlZW4pIHtcbiAgICBpZiAoJ29iamVjdCcgPT0gdHlwZW9mIHdpbmRvdy5zY3JlZW4ub3JpZW50YXRpb24pIHtcbiAgICAgIHR5cGUgPSB3aW5kb3cuc2NyZWVuLm9yaWVudGF0aW9uLnR5cGVcbiAgICB9IGVsc2UgaWYgKCdzdHJpbmcnID09IHR5cGVvZiB3aW5kb3cuc2NyZWVuLm9yaWVudGF0aW9uKSB7XG4gICAgICB0eXBlID0gd2luZG93LnNjcmVlbi5vcmllbnRhdGlvblxuICAgIH0gZWxzZSBpZiAoJ29iamVjdCcgPT0gdHlwZW9mIHdpbmRvdy5zY3JlZW4ubW96T3JpZW50YXRpb24pIHtcbiAgICAgIHR5cGUgPSB3aW5kb3cuc2NyZWVuLm1vek9yaWVudGF0aW9uLnR5cGVcbiAgICB9IGVsc2UgaWYgKCdzdHJpbmcnID09IHR5cGVvZiB3aW5kb3cuc2NyZWVuLm1vek9yaWVudGF0aW9uKSB7XG4gICAgICB0eXBlID0gd2luZG93LnNjcmVlbi5tb3pPcmllbnRhdGlvblxuICAgIH1cbiAgfVxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdsYW5kc2NhcGUtcHJpbWFyeSc6IHJldHVybiA5MFxuICAgIGNhc2UgJ2xhbmRzY2FwZS1zZWNvbmRhcnknOiByZXR1cm4gLTkwXG4gICAgY2FzZSAncG9ydHJhaXQtc2Vjb25kYXJ5JzogcmV0dXJuIDE4MFxuICAgIGNhc2UgJ3BvcnRyYWl0LXByaW1hcnknOiByZXR1cm4gMFxuICAgIGRlZmF1bHQ6IHJldHVybiB3aW5kb3cub3JpZW50YXRpb24gfHwgd2luZG93Lm1vek9yaWVudGF0aW9uIHx8IDBcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgbWFrZVBvd2VyT2ZUd28gPSAoaW1hZ2UpID0+IHtcblx0aWYgKGltYWdlIGluc3RhbmNlb2YgSFRNTEltYWdlRWxlbWVudCB8fCBpbWFnZSBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB7XG5cdFx0Y29uc3QgY2FudmFzID0gY3JlYXRlQ2FudmFzKClcblx0XHRjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoJzJkJylcblx0XHRjYW52YXMud2lkdGggPSBuZWFyZXN0UG93ZXJPZlR3byhpbWFnZS53aWR0aClcblx0XHRjYW52YXMuaGVpZ2h0ID0gbmVhcmVzdFBvd2VyT2ZUd28oaW1hZ2UuaGVpZ2h0KVxuXHRcdGNvbnRleHQuZHJhd0ltYWdlKGltYWdlLCAwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpXG5cdFx0cmV0dXJuIGNhbnZhc1xuXHR9XG5cdHJldHVybiBpbWFnZVxufVxuXG5leHBvcnQgY29uc3Qgc2NhbGVXaXRoQ2FudmFzID0gKGltYWdlLCBzY2FsZSwgc2NhbGVOZWFyZXN0UG93ZXJPZlR3bykgPT4ge1xuICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKVxuICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoJzJkJylcbiAgbGV0IHt3aWR0aCwgaGVpZ2h0fSA9IGltYWdlXG4gIGlmIChzY2FsZU5lYXJlc3RQb3dlck9mVHdvKSB7XG4gICAgd2lkdGggPSBuZWFyZXN0UG93ZXJPZlR3byh3aWR0aClcbiAgICBoZWlnaHQgPSBuZWFyZXN0UG93ZXJPZlR3byhoZWlnaHQpXG4gIH1cbiAgY2FudmFzLndpZHRoID0gTWF0aC5mbG9vcihpbWFnZS53aWR0aCAqIHNjYWxlKVxuICBjYW52YXMuaGVpZ2h0ID0gTWF0aC5mbG9vcihpbWFnZS5oZWlnaHQgKiBzY2FsZSlcbiAgY29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIDAsMCwgd2lkdGgsIGhlaWdodCwgMCwwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpXG4gIHJldHVybiBjYW52YXNcbn1cblxuZXhwb3J0IGNvbnN0IGNsYW1wVG9NYXhTaXplID0gKGltYWdlLCBtYXhTaXplLCBzY2FsZU5lYXJlc3RQb3dlck9mVHdvKSA9PiB7XG5cdGlmIChpbWFnZS53aWR0aCA+IG1heFNpemUgfHwgaW1hZ2UuaGVpZ2h0ID4gbWF4U2l6ZSkge1xuICAgIGNvbnN0IHNjYWxlID0gbWF4U2l6ZS9NYXRoLm1heChpbWFnZS53aWR0aCwgaW1hZ2UuaGVpZ2h0KVxuICAgIHJldHVybiBzY2FsZVdpdGhDYW52YXMoaW1hZ2UsIHNjYWxlLCBzY2FsZU5lYXJlc3RQb3dlck9mVHdvKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBzY2FsZU5lYXJlc3RQb3dlck9mVHdvID8gbWFrZVBvd2VyT2ZUd28oaW1hZ2UpIDogaW1hZ2VcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZW5zdXJlUkdCQSA9IChjb2xvcikgPT4ge1xuICBjb2xvciA9IFsuLi4oY29sb3IgfHwgW10pXVxuICBmb3IgKGxldCBpID0gMDsgaSA8IDM7ICsraSkge1xuICAgIGlmICgnbnVtYmVyJyAhPSB0eXBlb2YgY29sb3JbaV0pIHsgY29sb3JbaV0gPSAwIH1cbiAgICBlbHNlIHsgY29sb3JbaV0gPSBjbGFtcChjb2xvcltpXSwgMCwgMSkgfVxuICB9XG4gIGlmICgnbnVtYmVyJyAhPSB0eXBlb2YgY29sb3JbM10pIHsgY29sb3JbM10gPSAxIH1cbiAgZWxzZSB7IGNvbG9yWzNdID0gY2xhbXAoY29sb3JbM10sIDAsIDEpIH1cbiAgcmV0dXJuIFsuLi5jb2xvcl0uc2xpY2UoMCwgNClcbn1cblxuZXhwb3J0IGNvbnN0IGVuc3VyZVJHQiA9IChjb2xvcikgPT4ge1xuICByZXR1cm4gZW5zdXJlUkdCQShjb2xvcikuc2xpY2UoMCwgMylcbn1cblxuZXhwb3J0IGNvbnN0IGlzQXJyYXlMaWtlID0gKGFycmF5KSA9PiB7XG4gIHJldHVybiBCb29sZWFuKGFycmF5ICYmIChcbiAgICAgICBBcnJheS5pc0FycmF5KGFycmF5KVxuICAgIHx8IChhcnJheSBpbnN0YW5jZW9mIFR5cGVkQXJyYXkgfHwgaXNUeXBlZEFycmF5KGFycmF5KSlcbiAgICB8fCAnbnVtYmVyJyA9PSBhcnJheS5sZW5ndGhcbiAgICB8fCAnZnVuY3Rpb24nID09IHR5cGVvZiBhcnJheVtTeW1ib2wuaXRlcmF0b3JdKVxuICApXG59XG4iXX0=
\No newline at end of file