@eva/react-eva
Version:
React EVA是一个让开发同学能够在React技术体系下,利用EVA JS的游戏研发能力,开发动画、游戏类场景的框架。它可以让开发同学用熟悉的JSX和Hooks语法编写动画、游戏场景的代码。
176 lines (159 loc) • 7.92 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
var _excluded = ["preloadResources", "preloadTimeout", "onPreloadStart", "onPreloadProgress", "onPreloadLoaded", "onPreloadComplete", "onPreloadError", "systems", "listeningProps", "children"],
_excluded2 = ["systems", "listeningProps", "children"];
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
import { useRef, useImperativeHandle, forwardRef, useMemo, memo, useLayoutEffect } from 'react';
import { resource } from '@eva/eva.js';
import instance from '../misc/instance';
import preload from '../misc/preload';
import { instanceContext, preloadContext } from '../misc/context';
import ReconcilerEva from '@eva/fiber-eva';
function initInstance(ref) {
instance.rootElement = ref.current;
instance.canvasElement = instance.rootElement.querySelector('canvas[eva-canvas=true]');
instance.backgroundElement = instance.rootElement.querySelector('div[eva-bg=true]');
instance.hudElement = instance.rootElement.querySelector('div[eva-hud=true]');
instance.gameInstance = instance.rootElement.gameInstance;
instance.listeningProps = instance.rootElement.listeningProps;
}
function initPreload(preloadResources, preloadTimeout, onPreloadStart, onPreloadProgress, onPreloadLoaded, onPreloadComplete, onPreloadError) {
onPreloadStart && preload.onStart(onPreloadStart);
onPreloadProgress && preload.onProgress(onPreloadProgress);
onPreloadLoaded && preload.onLoaded(onPreloadLoaded);
onPreloadComplete && preload.onComplete(onPreloadComplete);
onPreloadError && preload.onError(onPreloadError);
var resources = [];
if (preloadResources instanceof Array) {
for (var _iterator = _createForOfIteratorHelperLoose(preloadResources), _step; !(_step = _iterator()).done;) {
var res = _step.value;
if (typeof res === 'object') {
if (res.name !== undefined) {
res.preload = true;
resources.push(res);
preload.resources[res.name] = res.name;
} else {
throw new Error("\"Name\" prop is Necessary: " + JSON.stringify(res));
}
} else {
throw new Error("Resource Data Should Be An Object: " + JSON.stringify(res));
}
}
} else if (typeof preloadResources === 'object') {
for (var name in preloadResources) {
var _res = preloadResources[name];
var resourceId = void 0;
if (typeof _res === 'object') {
_res.preload = true;
resourceId = _res.name;
resources.push(_res);
} else if (typeof _res === 'string') {
resourceId = _res;
} else {
throw new Error("Resource Data Should Be An Object Or ResourceId: " + JSON.stringify(_res));
}
preload.resources[name] = resourceId;
}
} else {
throw new Error("Resource Data Should Be An Array or An Object: " + JSON.stringify(preloadResources));
}
resource.addResource(resources);
resource.timeout = preloadTimeout;
resource.preload();
} //https://github.com/facebook/react/issues/13336
//react does not currently support seamlessly passing context
var Eva = /*#__PURE__*/forwardRef(function (_ref2, ref) {
var _ref2$preloadResource = _ref2.preloadResources,
preloadResources = _ref2$preloadResource === void 0 ? [] : _ref2$preloadResource,
_ref2$preloadTimeout = _ref2.preloadTimeout,
preloadTimeout = _ref2$preloadTimeout === void 0 ? 30 * 1000 : _ref2$preloadTimeout,
onPreloadStart = _ref2.onPreloadStart,
onPreloadProgress = _ref2.onPreloadProgress,
onPreloadLoaded = _ref2.onPreloadLoaded,
onPreloadComplete = _ref2.onPreloadComplete,
onPreloadError = _ref2.onPreloadError,
_ref2$systems = _ref2.systems,
systems = _ref2$systems === void 0 ? [] : _ref2$systems,
_ref2$listeningProps = _ref2.listeningProps,
listeningProps = _ref2$listeningProps === void 0 ? [] : _ref2$listeningProps,
children = _ref2.children,
props = _objectWithoutPropertiesLoose(_ref2, _excluded);
var _ref = useRef(null);
useImperativeHandle(ref, function () {
return instance;
}, []);
useMemo(function () {
initPreload(preloadResources, preloadTimeout, onPreloadStart, onPreloadProgress, onPreloadLoaded, onPreloadComplete, onPreloadError);
}, []);
useLayoutEffect(function () {
initInstance(_ref);
return function () {
if (instance.gameInstance) {
try {
instance.gameInstance.pause();
instance.gameInstance.destroy();
} catch (e) {}
}
};
}, []);
return /*#__PURE__*/React.createElement(instanceContext.Provider, {
value: instance
}, /*#__PURE__*/React.createElement(preloadContext.Provider, {
value: preload
}, /*#__PURE__*/React.createElement(preloadContext.Consumer, null, function (value) {
return /*#__PURE__*/React.createElement("eva", _extends({}, props, {
value: preload,
ref: _ref,
systems: systems,
listeningProps: listeningProps
}), /*#__PURE__*/React.createElement(preloadContext.Provider, {
value: value
}, children));
})));
});
var EvaContainer = /*#__PURE__*/forwardRef(function (args, ref) {
var _args$systems = args.systems,
systems = _args$systems === void 0 ? [] : _args$systems,
_args$listeningProps = args.listeningProps,
listeningProps = _args$listeningProps === void 0 ? [] : _args$listeningProps,
children = args.children,
props = _objectWithoutPropertiesLoose(args, _excluded2);
var _container = useRef(null);
useImperativeHandle(ref, function () {
return instance;
}, []);
var systemsMemo = useMemo(function () {
return [].concat(instance.systems, systems);
}, []);
var listeningPropsMemo = useMemo(function () {
return [].concat(instance.listeningProps, listeningProps);
}, []);
useLayoutEffect(function () {
var root = _container.current;
var render = ReconcilerEva.render;
render( /*#__PURE__*/React.createElement(Eva, _extends({}, props, {
systems: systemsMemo,
listeningProps: listeningPropsMemo
}), children), root, _extends({}, props, {
systems: systemsMemo,
listeningProps: listeningPropsMemo
}));
}, [props, children, systemsMemo, listeningPropsMemo]);
useLayoutEffect(function () {
var root = _container.current;
var unmountComponentAtNode = ReconcilerEva.unmountComponentAtNode;
return function () {
unmountComponentAtNode(root);
};
}, []);
return /*#__PURE__*/React.createElement("div", {
ref: _container,
style: _extends({
width: args.width,
height: args.height
}, args.style)
});
});
export default /*#__PURE__*/memo(EvaContainer);