UNPKG

@egjs/view360

Version:

360 integrated viewing solution from inside-out view to outside-in view. It provides user-friendly service by rotating 360 degrees through various user interaction such as motion sensor and touch.

1,680 lines (1,460 loc) 161 kB
/* Copyright (c) 2017-present NAVER Corp. name: @egjs/view360 license: MIT author: NAVER Corp. repository: https://github.com/naver/egjs-view360 version: 3.6.4 */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.eg = global.eg || {}, global.eg.view360 = factory())); }(this, (function () { 'use strict'; var VERSION = "3.6.4"; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; } || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function () { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } var merge = function (target) { var srcs = []; for (var _i = 1; _i < arguments.length; _i++) { srcs[_i - 1] = arguments[_i]; } srcs.forEach(function (source) { Object.keys(source).forEach(function (key) { var value = source[key]; if (Array.isArray(target[key]) && Array.isArray(value)) { target[key] = __spread(target[key], value); } else { target[key] = value; } }); }); return target; }; /* Copyright (c) NAVER Corp. name: @egjs/component license: MIT author: NAVER Corp. repository: https://github.com/naver/egjs-component version: 3.0.2 */ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read$1(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spread$1() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read$1(arguments[i])); return ar; } /* * Copyright (c) 2015 NAVER Corp. * egjs projects are licensed under the MIT license */ var isUndefined = function (value) { return typeof value === "undefined"; }; /** * Event class to provide additional properties * @ko Component에서 추가적인 프로퍼티를 제공하는 이벤트 클래스 */ var ComponentEvent = /*#__PURE__*/ function () { /** * Create a new instance of ComponentEvent. * @ko ComponentEvent의 새로운 인스턴스를 생성한다. * @param eventType The name of the event.<ko>이벤트 이름.</ko> * @param props An object that contains additional event properties.<ko>추가적인 이벤트 프로퍼티 오브젝트.</ko> */ function ComponentEvent(eventType, props) { var e_1, _a; this._canceled = false; if (props) { try { for (var _b = __values(Object.keys(props)), _c = _b.next(); !_c.done; _c = _b.next()) { var key = _c.value; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment this[key] = props[key]; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } } this.eventType = eventType; } /** * Stop the event. {@link ComponentEvent#isCanceled} will return `true` after. * @ko 이벤트를 중단한다. 이후 {@link ComponentEvent#isCanceled}가 `true`를 반환한다. */ var __proto = ComponentEvent.prototype; __proto.stop = function () { this._canceled = true; }; /** * Returns a boolean value that indicates whether {@link ComponentEvent#stop} is called before. * @ko {@link ComponentEvent#stop}이 호출되었는지 여부를 반환한다. * @return {boolean} A boolean value that indicates whether {@link ComponentEvent#stop} is called before.<ko>이전에 {@link ComponentEvent#stop}이 불려졌는지 여부를 반환한다.</ko> */ __proto.isCanceled = function () { return this._canceled; }; return ComponentEvent; }(); /** * A class used to manage events in a component * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스 */ var Component = /*#__PURE__*/ function () { /** * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"} */ function Component() { this._eventHandler = {}; } /** * Trigger a custom event. * @ko 커스텀 이벤트를 발생시킨다 * @param {string | ComponentEvent} event The name of the custom event to be triggered or an instance of the ComponentEvent<ko>발생할 커스텀 이벤트의 이름 또는 ComponentEvent의 인스턴스</ko> * @param {any[]} params Event data to be sent when triggering a custom event <ko>커스텀 이벤트가 발생할 때 전달할 데이터</ko> * @return An instance of the component itself<ko>컴포넌트 자신의 인스턴스</ko> * @example * ```ts * import Component, { ComponentEvent } from "@egjs/component"; * * class Some extends Component<{ * beforeHi: ComponentEvent<{ foo: number; bar: string }>; * hi: { foo: { a: number; b: boolean } }; * someEvent: (foo: number, bar: string) => void; * someOtherEvent: void; // When there's no event argument * }> { * some(){ * if(this.trigger("beforeHi")){ // When event call to stop return false. * this.trigger("hi");// fire hi event. * } * } * } * * const some = new Some(); * some.on("beforeHi", e => { * if(condition){ * e.stop(); // When event call to stop, `hi` event not call. * } * // `currentTarget` is component instance. * console.log(some === e.currentTarget); // true * * typeof e.foo; // number * typeof e.bar; // string * }); * some.on("hi", e => { * typeof e.foo.b; // boolean * }); * // If you want to more know event design. You can see article. * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F * ``` */ var __proto = Component.prototype; __proto.trigger = function (event) { var params = []; for (var _i = 1; _i < arguments.length; _i++) { params[_i - 1] = arguments[_i]; } var eventName = event instanceof ComponentEvent ? event.eventType : event; var handlers = __spread$1(this._eventHandler[eventName] || []); if (handlers.length <= 0) { return this; } if (event instanceof ComponentEvent) { event.currentTarget = this; handlers.forEach(function (handler) { handler(event); }); } else { handlers.forEach(function (handler) { // eslint-disable-next-line @typescript-eslint/no-unsafe-call handler.apply(void 0, __spread$1(params)); }); } return this; }; /** * Executed event just one time. * @ko 이벤트가 한번만 실행된다. * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.<ko>등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트</ko> * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko> * @return An instance of the component itself<ko>컴포넌트 자신의 인스턴스</ko> * @example * ```ts * import Component, { ComponentEvent } from "@egjs/component"; * * class Some extends Component<{ * hi: ComponentEvent; * }> { * hi() { * alert("hi"); * } * thing() { * this.once("hi", this.hi); * } * } * * var some = new Some(); * some.thing(); * some.trigger(new ComponentEvent("hi")); * // fire alert("hi"); * some.trigger(new ComponentEvent("hi")); * // Nothing happens * ``` */ __proto.once = function (eventName, handlerToAttach) { var _this = this; if (typeof eventName === "object" && isUndefined(handlerToAttach)) { var eventHash = eventName; for (var key in eventHash) { this.once(key, eventHash[key]); } return this; } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { var listener_1 = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } // eslint-disable-next-line @typescript-eslint/no-unsafe-call handlerToAttach.apply(void 0, __spread$1(args)); _this.off(eventName, listener_1); }; this.on(eventName, listener_1); } return this; }; /** * Checks whether an event has been attached to a component. * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다. * @param {string} eventName The name of the event to be attached <ko>등록 여부를 확인할 이벤트의 이름</ko> * @return {boolean} Indicates whether the event is attached. <ko>이벤트 등록 여부</ko> * @example * ```ts * import Component from "@egjs/component"; * * class Some extends Component<{ * hi: void; * }> { * some() { * this.hasOn("hi");// check hi event. * } * } * ``` */ __proto.hasOn = function (eventName) { return !!this._eventHandler[eventName]; }; /** * Attaches an event to a component. * @ko 컴포넌트에 이벤트를 등록한다. * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.<ko>등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트</ko> * @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko> * @return An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko> * @example * ```ts * import Component, { ComponentEvent } from "@egjs/component"; * * class Some extends Component<{ * hi: void; * }> { * hi() { * console.log("hi"); * } * some() { * this.on("hi",this.hi); //attach event * } * } * ``` */ __proto.on = function (eventName, handlerToAttach) { if (typeof eventName === "object" && isUndefined(handlerToAttach)) { var eventHash = eventName; for (var name in eventHash) { this.on(name, eventHash[name]); } return this; } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { var handlerList = this._eventHandler[eventName]; if (isUndefined(handlerList)) { this._eventHandler[eventName] = []; handlerList = this._eventHandler[eventName]; } handlerList.push(handlerToAttach); } return this; }; /** * Detaches an event from the component.<br/>If the `eventName` is not given this will detach all event handlers attached.<br/>If the `handlerToDetach` is not given, this will detach all event handlers for `eventName`. * @ko 컴포넌트에 등록된 이벤트를 해제한다.<br/>`eventName`이 주어지지 않았을 경우 모든 이벤트 핸들러를 제거한다.<br/>`handlerToAttach`가 주어지지 않았을 경우 `eventName`에 해당하는 모든 이벤트 핸들러를 제거한다. * @param {string?} eventName The name of the event to be detached <ko>해제할 이벤트의 이름</ko> * @param {function?} handlerToDetach The handler function of the event to be detached <ko>해제할 이벤트의 핸들러 함수</ko> * @return An instance of a component itself <ko>컴포넌트 자신의 인스턴스</ko> * @example * ```ts * import Component, { ComponentEvent } from "@egjs/component"; * * class Some extends Component<{ * hi: void; * }> { * hi() { * console.log("hi"); * } * some() { * this.off("hi",this.hi); //detach event * } * } * ``` */ __proto.off = function (eventName, handlerToDetach) { var e_1, _a; // Detach all event handlers. if (isUndefined(eventName)) { this._eventHandler = {}; return this; } // Detach all handlers for eventname or detach event handlers by object. if (isUndefined(handlerToDetach)) { if (typeof eventName === "string") { delete this._eventHandler[eventName]; return this; } else { var eventHash = eventName; for (var name in eventHash) { this.off(name, eventHash[name]); } return this; } } // Detach single event handler var handlerList = this._eventHandler[eventName]; if (handlerList) { var idx = 0; try { for (var handlerList_1 = __values(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) { var handlerFunction = handlerList_1_1.value; if (handlerFunction === handlerToDetach) { handlerList.splice(idx, 1); if (handlerList.length <= 0) { delete this._eventHandler[eventName]; } break; } idx++; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1); } finally { if (e_1) throw e_1.error; } } } return this; }; /** * Version info string * @ko 버전정보 문자열 * @name VERSION * @static * @example * Component.VERSION; // ex) 3.0.0 * @memberof Component */ Component.VERSION = "3.0.2"; return Component; }(); /* * Copyright (c) 2015 NAVER Corp. * egjs projects are licensed under the MIT license */ var ComponentEvent$1 = ComponentEvent; /* Copyright (c) 2015 NAVER Corp. name: @egjs/agent license: MIT author: NAVER Corp. repository: git+https://github.com/naver/agent.git version: 2.2.1 */ function some(arr, callback) { var length = arr.length; for (var i = 0; i < length; ++i) { if (callback(arr[i], i)) { return true; } } return false; } function find(arr, callback) { var length = arr.length; for (var i = 0; i < length; ++i) { if (callback(arr[i], i)) { return arr[i]; } } return null; } function getUserAgent(agent) { var userAgent = agent; if (typeof userAgent === "undefined") { if (typeof navigator === "undefined" || !navigator) { return ""; } userAgent = navigator.userAgent || ""; } return userAgent.toLowerCase(); } function execRegExp(pattern, text) { try { return new RegExp(pattern, "g").exec(text); } catch (e) { return null; } } function hasUserAgentData() { if (typeof navigator === "undefined" || !navigator || !navigator.userAgentData) { return false; } var userAgentData = navigator.userAgentData; var brands = userAgentData.brands || userAgentData.uaList; return !!(brands && brands.length); } function findVersion(versionTest, userAgent) { var result = execRegExp("(" + versionTest + ")((?:\\/|\\s|:)([0-9|\\.|_]+))?", userAgent); return result ? result[3] : ""; } function convertVersion(text) { return text.replace(/_/g, "."); } function findPreset(presets, userAgent) { var userPreset = null; var version = "-1"; some(presets, function (preset) { var result = execRegExp("(" + preset.test + ")((?:\\/|\\s|:)([0-9|\\.|_]+))?", userAgent); if (!result || preset.brand) { return false; } userPreset = preset; version = result[3] || "-1"; if (preset.versionAlias) { version = preset.versionAlias; } else if (preset.versionTest) { version = findVersion(preset.versionTest.toLowerCase(), userAgent) || version; } version = convertVersion(version); return true; }); return { preset: userPreset, version: version }; } function findBrand(brands, preset) { return find(brands, function (_a) { var brand = _a.brand; return execRegExp("" + preset.test, brand.toLowerCase()); }); } var BROWSER_PRESETS = [{ test: "phantomjs", id: "phantomjs" }, { test: "whale", id: "whale" }, { test: "edgios|edge|edg", id: "edge" }, { test: "msie|trident|windows phone", id: "ie", versionTest: "iemobile|msie|rv" }, { test: "miuibrowser", id: "miui browser" }, { test: "samsungbrowser", id: "samsung internet" }, { test: "samsung", id: "samsung internet", versionTest: "version" }, { test: "chrome|crios", id: "chrome" }, { test: "firefox|fxios", id: "firefox" }, { test: "android", id: "android browser", versionTest: "version" }, { test: "safari|iphone|ipad|ipod", id: "safari", versionTest: "version" }]; // chromium's engine(blink) is based on applewebkit 537.36. var CHROMIUM_PRESETS = [{ test: "(?=.*applewebkit/(53[0-7]|5[0-2]|[0-4]))(?=.*\\schrome)", id: "chrome" }, { test: "chromium", id: "chrome" }, { test: "whale", id: "chrome", brand: true }]; var WEBKIT_PRESETS = [{ test: "applewebkit", id: "webkit" }]; var WEBVIEW_PRESETS = [{ test: "(?=(iphone|ipad))(?!(.*version))", id: "webview" }, { test: "(?=(android|iphone|ipad))(?=.*(naver|daum|; wv))", id: "webview" }, { // test webview test: "webview", id: "webview" }]; var OS_PRESETS = [{ test: "windows phone", id: "windows phone" }, { test: "windows 2000", id: "window", versionAlias: "5.0" }, { test: "windows nt", id: "window" }, { test: "iphone|ipad|ipod", id: "ios", versionTest: "iphone os|cpu os" }, { test: "mac os x", id: "mac" }, { test: "android", id: "android" }, { test: "tizen", id: "tizen" }, { test: "webos|web0s", id: "webos" }]; function parseUserAgentData(osData) { var userAgentData = navigator.userAgentData; var brands = (userAgentData.uaList || userAgentData.brands).slice(); var isMobile = userAgentData.mobile || false; var firstBrand = brands[0]; var browser = { name: firstBrand.brand, version: firstBrand.version, majorVersion: -1, webkit: false, webview: some(WEBVIEW_PRESETS, function (preset) { return findBrand(brands, preset); }), chromium: some(CHROMIUM_PRESETS, function (preset) { return findBrand(brands, preset); }) }; var os = { name: "unknown", version: "-1", majorVersion: -1 }; browser.webkit = !browser.chromium && some(WEBKIT_PRESETS, function (preset) { return findBrand(brands, preset); }); if (osData) { var platform_1 = osData.platform.toLowerCase(); var result = find(OS_PRESETS, function (preset) { return new RegExp("" + preset.test, "g").exec(platform_1); }); os.name = result ? result.id : platform_1; os.version = osData.platformVersion; } some(BROWSER_PRESETS, function (preset) { var result = findBrand(brands, preset); if (!result) { return false; } browser.name = preset.id; browser.version = osData ? osData.uaFullVersion : result.version; return true; }); if (navigator.platform === "Linux armv8l") { os.name = "android"; } else if (browser.webkit) { os.name = isMobile ? "ios" : "mac"; } if (os.name === "ios" && browser.webview) { browser.version = "-1"; } os.version = convertVersion(os.version); browser.version = convertVersion(browser.version); os.majorVersion = parseInt(os.version, 10); browser.majorVersion = parseInt(browser.version, 10); return { browser: browser, os: os, isMobile: isMobile, isHints: true }; } function parseUserAgent(userAgent) { var nextAgent = getUserAgent(userAgent); var isMobile = !!/mobi/g.exec(nextAgent); var browser = { name: "unknown", version: "-1", majorVersion: -1, webview: !!findPreset(WEBVIEW_PRESETS, nextAgent).preset, chromium: !!findPreset(CHROMIUM_PRESETS, nextAgent).preset, webkit: false }; var os = { name: "unknown", version: "-1", majorVersion: -1 }; var _a = findPreset(BROWSER_PRESETS, nextAgent), browserPreset = _a.preset, browserVersion = _a.version; var _b = findPreset(OS_PRESETS, nextAgent), osPreset = _b.preset, osVersion = _b.version; browser.webkit = !browser.chromium && !!findPreset(WEBKIT_PRESETS, nextAgent).preset; if (osPreset) { os.name = osPreset.id; os.version = osVersion; os.majorVersion = parseInt(osVersion, 10); } if (browserPreset) { browser.name = browserPreset.id; browser.version = browserVersion; if (browser.webview && os.name === "ios" && browser.name !== "safari") { browser.webview = false; } } browser.majorVersion = parseInt(browser.version, 10); return { browser: browser, os: os, isMobile: isMobile, isHints: false }; } /** * Extracts browser and operating system information from the user agent string. * @ko 유저 에이전트 문자열에서 브라우저와 운영체제 정보를 추출한다. * @function eg.agent#agent * @param - user agent string to parse <ko>파싱할 유저에이전트 문자열</ko> * @return - agent Info <ko> 에이전트 정보 </ko> * @example import agent from "@egjs/agent"; // eg.agent(); const { os, browser, isMobile } = agent(); */ function agent(userAgent) { if (typeof userAgent === "undefined" && hasUserAgentData()) { return parseUserAgentData(); } else { return parseUserAgent(userAgent); } } /* Copyright (c) NAVER Crop. name: @cfcs/core license: MIT author: NAVER Crop. repository: https://github.com/naver/cfcs version: 0.0.4 */ /** * cfcs * Copyright (c) 2022-present NAVER Corp. * MIT license */ function keys(obj) { return Object.keys(obj); } var OBSERVERS_PATH = "__observers__"; var Observer = /*#__PURE__*/ function () { function Observer(value) { this._emitter = new Component(); this._current = value; } var __proto = Observer.prototype; Object.defineProperty(__proto, "current", { get: function () { return this._current; }, set: function (value) { var isUpdate = value !== this._current; this._current = value; if (isUpdate) { this._emitter.trigger("update", value); } }, enumerable: false, configurable: true }); __proto.subscribe = function (callback) { this._emitter.on("update", callback); }; __proto.unsubscribe = function (callback) { this._emitter.off("update", callback); }; return Observer; }(); function observe(defaultValue) { return new Observer(defaultValue); } function getObservers(instance) { if (!instance[OBSERVERS_PATH]) { instance[OBSERVERS_PATH] = {}; } return instance[OBSERVERS_PATH]; } function getObserver(instance, name, defaultValue) { var observers = getObservers(instance); if (!observers[name]) { observers[name] = observe(defaultValue); } return observers[name]; } function injectReactiveSubscribe(object) { object["subscribe"] = function (name, callback) { getObserver(this, name).subscribe(callback); }; object["unsubscribe"] = function (name, callback) { var _this = this; if (!name) { keys(getObservers(this)).forEach(function (observerName) { _this.unsubscribe(observerName); }); return; } if (!(name in this)) { return; } getObserver(this, name).unsubscribe(callback); }; } function ReactiveSubscribe(Constructor) { var prototype = Constructor.prototype; injectReactiveSubscribe(prototype); } /* Copyright (c) NAVER Corp. name: @egjs/axes license: MIT author: NAVER Corp. repository: https://github.com/naver/egjs-axes version: 3.8.3 */ /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics$1 = function (d, b) { extendStatics$1 = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; } || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics$1(d, b); }; function __extends$1(d, b) { extendStatics$1(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign$1 = function () { __assign$1 = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign$1.apply(this, arguments); }; function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } /* * Copyright (c) 2015 NAVER Corp. * egjs projects are licensed under the MIT license */ /* eslint-disable no-new-func, no-nested-ternary */ var win; if (typeof window === "undefined") { // window is undefined in node.js win = { navigator: { userAgent: "" } }; } else { win = window; } /* * Copyright (c) 2015 NAVER Corp. * egjs projects are licensed under the MIT license */ var DIRECTION_NONE = 1; var DIRECTION_LEFT = 2; var DIRECTION_RIGHT = 4; var DIRECTION_HORIZONTAL = 2 | 4; var DIRECTION_UP = 8; var DIRECTION_DOWN = 16; var DIRECTION_VERTICAL = 8 | 16; var DIRECTION_ALL = 2 | 4 | 8 | 16; var MOUSE_LEFT = "left"; var MOUSE_RIGHT = "right"; var MOUSE_MIDDLE = "middle"; var ANY = "any"; var NONE = "none"; var SHIFT = "shift"; var CTRL = "ctrl"; var ALT = "alt"; var META = "meta"; var VELOCITY_INTERVAL = 16; var IOS_EDGE_THRESHOLD = 30; var IS_IOS_SAFARI = "ontouchstart" in win && agent().browser.name === "safari"; var TRANSFORM = function () { if (typeof document === "undefined") { return ""; } var bodyStyle = (document.head || document.getElementsByTagName("head")[0]).style; var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; for (var i = 0, len = target.length; i < len; i++) { if (target[i] in bodyStyle) { return target[i]; } } return ""; }(); var PREVENT_DRAG_CSSPROPS = { "user-select": "none", "-webkit-user-drag": "none" }; var toArray = function (nodes) { // const el = Array.prototype.slice.call(nodes); // for IE8 var el = []; for (var i = 0, len = nodes.length; i < len; i++) { el.push(nodes[i]); } return el; }; var $ = function (param, multi) { if (multi === void 0) { multi = false; } var el; if (typeof param === "string") { // String (HTML, Selector) // check if string is HTML tag format var match = param.match(/^<([a-z]+)\s*([^>]*)>/); // creating element if (match) { // HTML var dummy = document.createElement("div"); dummy.innerHTML = param; el = toArray(dummy.childNodes); } else { // Selector el = toArray(document.querySelectorAll(param)); } if (!multi) { el = el.length >= 1 ? el[0] : undefined; } } else if (param === win) { // window el = param; } else if ("value" in param || "current" in param) { el = param.value || param.current; } else if (param.nodeName && (param.nodeType === 1 || param.nodeType === 9)) { // HTMLElement, Document el = param; } else if ("jQuery" in win && param instanceof jQuery || param.constructor.prototype.jquery) { // jQuery el = multi ? param.toArray() : param.get(0); } else if (Array.isArray(param)) { el = param.map(function (v) { return $(v); }); if (!multi) { el = el.length >= 1 ? el[0] : undefined; } } return el; }; var raf = win.requestAnimationFrame || win.webkitRequestAnimationFrame; var caf = win.cancelAnimationFrame || win.webkitCancelAnimationFrame; if (raf && !caf) { var keyInfo_1 = {}; var oldraf_1 = raf; raf = function (callback) { var wrapCallback = function (timestamp) { if (keyInfo_1[key]) { callback(timestamp); } }; var key = oldraf_1(wrapCallback); keyInfo_1[key] = true; return key; }; caf = function (key) { delete keyInfo_1[key]; }; } else if (!(raf && caf)) { raf = function (callback) { return win.setTimeout(function () { callback(win.performance && win.performance.now && win.performance.now() || new Date().getTime()); }, 16); }; caf = win.clearTimeout; } /** * A polyfill for the window.requestAnimationFrame() method. * @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame * @private */ var requestAnimationFrame = function (fp) { return raf(fp); }; /** * A polyfill for the window.cancelAnimationFrame() method. It cancels an animation executed through a call to the requestAnimationFrame() method. * @param {Number} key − The ID value returned through a call to the requestAnimationFrame() method. <ko>requestAnimationFrame() 메서드가 반환한 아이디 값</ko> * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame * @private */ var cancelAnimationFrame = function (key) { caf(key); }; var map = function (obj, callback) { var tranformed = {}; for (var k in obj) { if (k) { tranformed[k] = callback(obj[k], k); } } return tranformed; }; var filter = function (obj, callback) { var filtered = {}; for (var k in obj) { if (k && callback(obj[k], k)) { filtered[k] = obj[k]; } } return filtered; }; var every = function (obj, callback) { for (var k in obj) { if (k && !callback(obj[k], k)) { return false; } } return true; }; var equal = function (target, base) { return every(target, function (v, k) { return v === base[k]; }); }; var roundNumFunc = {}; var roundNumber = function (num, roundUnit) { // Cache for performance if (!roundNumFunc[roundUnit]) { roundNumFunc[roundUnit] = getRoundFunc(roundUnit); } return roundNumFunc[roundUnit](num); }; var roundNumbers = function (num, roundUnit) { if (!num || !roundUnit) { return num; } return map(num, function (value, key) { return roundNumber(value, typeof roundUnit === "number" ? roundUnit : roundUnit[key]); }); }; var getDecimalPlace = function (val) { if (!isFinite(val)) { return 0; } var v = "".concat(val); if (v.indexOf("e") >= 0) { // Exponential Format // 1e-10, 1e-12 var p = 0; var e = 1; while (Math.round(val * e) / e !== val) { e *= 10; p++; } return p; } // In general, following has performance benefit. // https://jsperf.com/precision-calculation return v.indexOf(".") >= 0 ? v.length - v.indexOf(".") - 1 : 0; }; var inversePow = function (n) { // replace Math.pow(10, -n) to solve floating point issue. // eg. Math.pow(10, -4) => 0.00009999999999999999 return 1 / Math.pow(10, n); }; var getRoundFunc = function (v) { var p = v < 1 ? Math.pow(10, getDecimalPlace(v)) : 1; return function (n) { if (v === 0) { return 0; } return Math.round(Math.round(n / v) * v * p) / p; }; }; var getAngle = function (posX, posY) { return Math.atan2(posY, posX) * 180 / Math.PI; }; var isCssPropsFromAxes = function (originalCssProps) { var same = true; Object.keys(PREVENT_DRAG_CSSPROPS).forEach(function (prop) { if (!originalCssProps || originalCssProps[prop] !== PREVENT_DRAG_CSSPROPS[prop]) { same = false; } }); return same; }; var getDirection = function (useHorizontal, useVertical) { if (useHorizontal && useVertical) { return DIRECTION_ALL; } else if (useHorizontal) { return DIRECTION_HORIZONTAL; } else if (useVertical) { return DIRECTION_VERTICAL; } else { return DIRECTION_NONE; } }; var useDirection = function (checkType, direction, userDirection) { if (userDirection) { return !!(direction === DIRECTION_ALL || direction & checkType && userDirection & checkType); } else { return !!(direction & checkType); } }; var setCssProps = function (element, option, direction) { var _a; var touchActionMap = (_a = {}, _a[DIRECTION_NONE] = "auto", _a[DIRECTION_ALL] = "none", _a[DIRECTION_VERTICAL] = "pan-x", _a[DIRECTION_HORIZONTAL] = "pan-y", _a); var oldCssProps = {}; if (element && element.style) { var touchAction = option.touchAction ? option.touchAction : touchActionMap[direction]; var newCssProps_1 = __assign$1(__assign$1({}, PREVENT_DRAG_CSSPROPS), { "touch-action": element.style["touch-action"] === "none" ? "none" : touchAction }); Object.keys(newCssProps_1).forEach(function (prop) { oldCssProps[prop] = element.style[prop]; element.style[prop] = newCssProps_1[prop]; }); } return oldCssProps; }; var revertCssProps = function (element, originalCssProps) { if (element && element.style && originalCssProps) { Object.keys(originalCssProps).forEach(function (prop) { element.style[prop] = originalCssProps[prop]; }); } return; }; var EventManager = /*#__PURE__*/ function () { function EventManager(_axes) { this._axes = _axes; } /** * This event is fired when a user holds an element on the screen of the device. * @ko 사용자가 기기의 화면에 손을 대고 있을 때 발생하는 이벤트 * @event Axes#hold * @type {object} * @property {Object.<string, number>} pos coordinate <ko>좌표 정보</ko> * @property {Object} input The instance of inputType where the event occurred<ko>이벤트가 발생한 inputType 인스턴스</ko> * @property {Object} inputEvent The event object received from inputType <ko>inputType으로 부터 받은 이벤트 객체</ko> * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko> * * @example * ```js * const axes = new eg.Axes({ * "x": { * range: [0, 100] * }, * "zoom": { * range: [50, 30] * } * }).on("hold", function(event) { * // event.pos * // event.input * // event.inputEvent * // isTrusted * }); * ``` */ var __proto = EventManager.prototype; __proto.hold = function (pos, option) { var roundPos = this._getRoundPos(pos).roundPos; this._axes.trigger(new ComponentEvent$1("hold", { pos: roundPos, input: option.input || null, inputEvent: option.event || null, isTrusted: true })); }; /** * Specifies the coordinates to move after the 'change' event. It works when the holding value of the change event is true. * @ko 'change' 이벤트 이후 이동할 좌표를 지정한다. change이벤트의 holding 값이 true일 경우에 동작한다 * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko> * @example * ```js * const axes = new eg.Axes({ * "x": { * range: [0, 100] * }, * "zoom": { * range: [50, 30] * } * }).on("change", function(event) { * event.holding && event.set({x: 10}); * }); * ``` */ /** Specifies the animation coordinates to move after the 'release' or 'animationStart' events. * @ko 'release' 또는 'animationStart' 이벤트 이후 이동할 좌표를 지정한다. * @param {Object.<string, number>} pos The coordinate to move to <ko>이동할 좌표</ko> * @param {Number} [duration=0] Duration of the animation (unit: ms) <ko>애니메이션 진행 시간(단위: ms)</ko> * @example * ```js * const axes = new eg.Axes({ * "x": { * range: [0, 100] * }, * "zoom": { * range: [50, 30] * } * }).on("animationStart", function(event) { * event.setTo({x: 10}, 2000); * }); * ``` */ /** * This event is fired when a user release an element on the screen of the device. * @ko 사용자가 기기의 화면에서 손을 뗐을 때 발생하는 이벤트 * @event Axes#release * @type {object} * @property {Object.<string, number>} depaPos The coordinates when releasing an element<ko>손을 뗐을 때의 좌표 </ko> * @property {Object.<string, number>} destPos The coordinates to move to after releasing an element<ko>손을 뗀 뒤에 이동할 좌표</ko> * @property {Object.<string, number>} delta The movement variation of coordinate <ko>좌표의 변화량</ko> * @property {Object.<string, number>} bounceRatio If the coordinates at the time of release are in the bounce area, the current bounce value divided by the maximum bounce value <ko>손을 뗐을 때의 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치.</ko> * @property {Object} inputEvent The event object received from inputType <ko>inputType으로 부터 받은 이벤트 객체</ko> * @property {Object} input The instance of inputType where the event occurred<ko>이벤트가 발생한 inputType 인스턴스</ko> * @property {setTo} setTo Specifies the animation coordinates to move after the event <ko>이벤트 이후 이동할 애니메이션 좌표를 지정한다</ko> * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko> * * @example * ```js * const axes = new eg.Axes({ * "x": { * range: [0, 100] * }, * "zoom": { * range: [50, 30] * } * }).on("release", function(event) { * // event.depaPos * // event.destPos * // event.delta * // event.input * // event.inputEvent * // event.setTo * // event.isTrusted * * // if you want to change the animation coordinates to move after the 'release' event. * event.setTo({x: 10}, 2000); * }); * ``` */ __proto.triggerRelease = function (param) { var _a = this._getRoundPos(param.destPos, param.depaPos), roundPos = _a.roundPos, roundDepa = _a.roundDepa; param.destPos = roundPos; param.depaPos = roundDepa; param.setTo = this._createUserControll(param.destPos, param.duration); this._axes.trigger(new ComponentEvent$1("release", __assign$1(__assign$1({}, param), { bounceRatio: this._getBounceRatio(roundPos) }))); }; /** * This event is fired when coordinate changes. * @ko 좌표가 변경됐을 때 발생하는 이벤트 * @event Axes#change * @type {object} * @property {Object.<string, number>} pos The coordinate <ko>좌표</ko> * @property {Object.<string, number>} delta The movement variation of coordinate <ko>좌표의 변화량</ko> * @property {Object.<string, number>} bounceRatio If the current coordinates are in the bounce area, the current bounce value divided by the maximum bounce value <ko>현재 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치.</ko> * @property {Boolean} holding Indicates whether a user holds an element on the screen of the device.<ko>사용자가 기기의 화면을 누르고 있는지 여부</ko> * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.<ko>이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다.</ko> * @property {Object} inputEvent The event object received from inputType. If the value is changed by animation, it returns 'null'.<ko>inputType으로 부터 받은 이벤트 객체. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다.</ko> * @property {set} set Specifies the coordinates to move after the event. It works when the holding value is true <ko>이벤트 이후 이동할 좌표를 지정한다. holding 값이 true일 경우에 동작한다.</ko> * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko> * * @example * ```js * const axes = new eg.Axes({ * "x": { * range: [0, 100] * }, * "zoom": { * range: [50, 30] * } * }).on("change", function(event) { * // event.pos * // event.delta * // event.input * // event.inputEvent * // event.holding * // event.set * // event.isTrusted * * // if you want to change the coordinates to move after the 'change' event. * // it works when the holding value of the change event is true. * event.holding && event.set({x: 10}); * }); * ``` */ __proto.triggerChange = function (pos, depaPos, option, holding) { var _this = this; if (holding === void 0) { holding = false; } var animationManager = this.animationManager; var axisManager = animationManager.axisManager; var eventInfo = animationManager.getEventInfo(); var _a = this._getRoundPos(pos, depaPos), roundPos = _a.roundPos, roundDepa = _a.roundDepa; var moveTo = axisManager.moveTo(roundPos, roundDepa); var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.event) || null; var param = { pos: moveTo.pos, delta: moveTo.delta, bounceRatio: this._getBounceRatio(moveTo.pos), holding: holding, inputEvent: inputEvent, isTrusted: !!inputEvent, input: (option === null || option === void 0 ? void 0 : option.input) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.input) || null, set: inputEvent ? this._createUserControll(moveTo.pos) : function () {} // eslint-disable-line @typescript-eslint/no-empty-function }; var event = new ComponentEvent$1("change", param); this._axes.trigger(event); Object.keys(moveTo.pos).forEach(function (axis) { var p = moveTo.pos[axis]; getObserver(_this._axes, axis, p).current = p; }); if (inputEvent) { axisManager.set(param.set().destPos); } return !event.isCanceled(); }; /** * This event is fired when animation starts. * @ko 에니메이션이 시작할 때 발생한다. * @event Axes#animationStart * @type {object} * @property {Object.<string, number>} depaPos The coordinates when animation starts<ko>애니메이션이 시작 되었을 때의 좌표 </ko> * @property {Object.<string, number>} destPos The coordinates to move to. If you change this value, you can run the animation<ko>이동할 좌표. 이값을 변경하여 애니메이션을 동작시킬수 있다</ko> * @property {Object.<string, number>} delta The movement variation of coordinate <ko>좌표의 변화량</ko> * @property {Number} duration Duration of the animation (unit: ms). If you change this value, you can control the animation duration time.<ko>애니메이션 진행 시간(단위: ms). 이값을 변경하여 애니메이션의 이동시간을 조절할 수 있다.</ko> * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.<ko>이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다.</ko> * @property {Object} inputEvent The event object received from inputType <ko>inputType으로 부터 받은 이벤트 객체</ko> * @property {setTo} setTo Specifies the animation coordinates to move after the event <ko>이벤트 이후 이동할 애니메이션 좌표를 지정한다</ko> * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call <ko>사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다.</ko> * * @example * ```js * const axes = new eg.Axes({ * "x": { * range: [0, 100] * }, * "zoom": { * range: [50, 30] * } * }).on("release", function(event) { * // event.depaPos * // event.destPos * // event.delta * // event.input * // event.inputEvent * // event.setTo * // event.isTrusted * * // if you want to change the animation coordinates to move after the 'animationStart' event. * event.setTo({x: 10}, 2000); * }); * ``` */ __proto.triggerAnimationStart = function (param) { var _a = this._getRoundPos(param.destPos, param.depaPos), roundPos = _a.roundPos, roundDepa = _a.roundDepa; param.de