UNPKG

@freeboardgame.org/boardgame.io

Version:
1,647 lines (1,362 loc) 98 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('prop-types'), require('three'), require('@tweenjs/tween.js'), require('react-dragtastic')) : typeof define === 'function' && define.amd ? define(['exports', 'react', 'prop-types', 'three', '@tweenjs/tween.js', 'react-dragtastic'], factory) : (global = global || self, factory(global.UI = {}, global.React, global.PropTypes, global.THREE, global.TWEEN, global.ReactDragtastic)); }(this, function (exports, React, PropTypes, THREE, TWEEN, reactDragtastic) { 'use strict'; React = React && React.hasOwnProperty('default') ? React['default'] : React; PropTypes = PropTypes && PropTypes.hasOwnProperty('default') ? PropTypes['default'] : PropTypes; TWEEN = TWEEN && TWEEN.hasOwnProperty('default') ? TWEEN['default'] : TWEEN; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } /* * Copyright 2018 The boardgame.io Authors * * Use of this source code is governed by a MIT-style * license that can be found in the LICENSE file or at * https://opensource.org/licenses/MIT. */ var UIContext = React.createContext(); /** * Root element of the React based 2D UI framework. */ var UI = /*#__PURE__*/ function (_React$Component) { _inherits(UI, _React$Component); function UI(props) { var _this; _classCallCheck(this, UI); _this = _possibleConstructorReturn(this, _getPrototypeOf(UI).call(this, props)); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getContext", function () { return { genID: function genID() { return _this._nextID++; } }; }); _this._nextID = 1; return _this; } _createClass(UI, [{ key: "render", value: function render() { return React.createElement(UIContext.Provider, { value: this.getContext() }, React.createElement("div", { className: "bgio-ui" }, this.props.children)); } }]); return UI; }(React.Component); _defineProperty(UI, "propTypes", { children: PropTypes.any }); function styleInject(css, ref) { if ( ref === void 0 ) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css = ".loader {\n border: 16px solid #f3f3f3; /* Light grey */\n border-top: 16px solid #3498db; /* Blue */\n border-radius: 50%;\n width: 80px;\n height: 80px;\n animation: spin 2s linear infinite;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n"; styleInject(css); /** * Root element of the React/threejs based 3D UI framework. */ var UI$1 = /*#__PURE__*/ function (_React$Component) { _inherits(UI, _React$Component); function UI(props) { var _this; _classCallCheck(this, UI); _this = _possibleConstructorReturn(this, _getPrototypeOf(UI).call(this, props)); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "animate", function () { requestAnimationFrame(_this.animate); TWEEN.update(); _this.renderer.render(_this.scene, _this.camera); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "add", function (obj, callback) { _this.childGroup.add(obj); if (callback !== undefined) { _this.callbacks_[obj.id] = callback; } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "registerCallback", function (obj, callback) { if (obj && callback) { _this.callbacks_[obj.id] = callback; } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getContext", function () { return { three: true, add: _this.add, remove: function remove(obj) { return _this.scene.remove(obj); }, scene: _this.scene, camera: _this.camera, regCall: _this.registerCallback }; }); _this.state = { isLoading: false }; /** * Set of callbacks that children of this element pass via context.subscribeToMouseEvents * in order to receive mouse events that pertain to the objects that they manage. * @private */ _this.callbacks_ = {}; /** * Reference to the root div element. * @private */ _this.ref_ = React.createRef(); // Set up scene. _this.scene = new THREE.Scene(); _this.scene.background = new THREE.Color(0xffffff); // Set up renderer. _this.renderer = new THREE.WebGLRenderer({ antialias: true }); _this.renderer.shadowMap.enabled = true; _this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; _this.renderer.setSize(_this.props.width, _this.props.height); // Set up camera. _this.camera = new THREE.PerspectiveCamera(45, _this.props.width / _this.props.height, 0.1, 1000); _this.camera.position.z = 7; _this.camera.position.y = 10; _this.camera.lookAt(new THREE.Vector3()); _this.scene.add(_this.camera); // Set up lights. var ambientLight = new THREE.AmbientLight(0xffffff, 0.7); _this.scene.add(ambientLight); var light = new THREE.DirectionalLight(0x555555); light.position.y = 50; light.shadow.camera.left = -10; light.shadow.camera.bottom = -10; light.shadow.camera.right = 10; light.shadow.camera.top = 10; light.castShadow = true; _this.scene.add(light); // Set up ground. var geometry = new THREE.PlaneBufferGeometry(100, 100); var material = new THREE.MeshLambertMaterial({ color: 0xffffff }); var plane = new THREE.Mesh(geometry, material); plane.receiveShadow = true; plane.lookAt(plane.up); plane.position.y = -0.01; _this.plane = plane; _this.scene.add(plane); var helper = new THREE.GridHelper(2000, 2000); helper.material.opacity = 0.1; helper.material.transparent = true; _this.scene.add(helper); _this.childGroup = new THREE.Group(); _this.scene.add(_this.childGroup); // set up loading screen _this.loader = React.createElement("div", { className: "loader" }); THREE.DefaultLoadingManager.onStart = function () { _this.setState({ isLoading: true }); _this.ref_.current.removeChild(_this.renderer.domElement); console.log('Started loading file'); }; THREE.DefaultLoadingManager.onLoad = function () { _this.setState({ isLoading: false }); _this.ref_.current.appendChild(_this.renderer.domElement); console.log('Loading Complete!'); }; THREE.DefaultLoadingManager.onProgress = function (url, itemsLoaded, itemsTotal) { console.log('Loading file: ' + url + '\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.'); }; THREE.DefaultLoadingManager.onError = function (url) { console.log('There was an error loading: ' + url); }; return _this; } _createClass(UI, [{ key: "setupMouseEvents", value: function setupMouseEvents() { var _this2 = this; // List of objects currently being dragged. var dragging_ = []; // The 2D viewport co-ordinates of the mouse. var mouse = new THREE.Vector2(); // Raycaster that's used to calculate objects that the // mouse intersects. this.raycaster = new THREE.Raycaster(); var getClickType = function getClickType(e) { if (e.which !== undefined) { switch (e.which) { case 1: return 'leftclick'; case 2: return 'middleclick'; case 3: return 'rightclick'; } } if (e.button !== undefined) { switch (e.button) { case 0: return 'leftclick'; case 1: return 'middleclick'; case 2: return 'rightclick'; } } }; var dispatchMouseCallbacks = function dispatchMouseCallbacks(e, objects) { if (objects === undefined) { _this2.raycaster.setFromCamera(mouse, _this2.camera); objects = _this2.raycaster.intersectObjects(_this2.childGroup.children, true); } if (_this2.props.onMouseEvent) { _this2.props.onMouseEvent(e, objects); } // only intersect the nearest object. var obj = objects[0]; if (obj) { e.point = obj.point; var current = _this2.childGroup.getObjectById(obj.object.id); // check parents until we hit a callback or hit the top level. while (current && current.parent && current.id != _this2.childGroup.id) { if (current.id in _this2.callbacks_) { _this2.callbacks_[current.id](e); break; } current = current.parent; } } }; var onMouseDown = function onMouseDown(e) { var type = getClickType(e); _this2.raycaster.setFromCamera(mouse, _this2.camera); var objects = _this2.raycaster.intersectObjects(_this2.childGroup.children, true); if (type == 'leftclick') { dragging_ = objects.filter(function (obj) { return obj.object.userData.draggable && obj.object.userData.responsive; }); } else { e = _objectSpread({}, e, { type: type }); } dispatchMouseCallbacks(e, objects); if (dragging_.length > 0) { dragging_ = [dragging_[0]]; dispatchMouseCallbacks(_objectSpread({}, e, { type: 'dragStart' }), dragging_); } }; var onMouseUp = function onMouseUp(e) { _this2.raycaster.setFromCamera(mouse, _this2.camera); var objects = _this2.raycaster.intersectObjects(_this2.childGroup.children, true); dispatchMouseCallbacks(e, objects); if (dragging_.length > 0) { var droppable = objects.filter(function (obj) { return obj.object.userData.droppable && obj.object.userData.responsive; }); if (droppable.length > 0) { var what = dragging_.map(function (o) { return o.object; }); dispatchMouseCallbacks(_objectSpread({}, e, { type: 'drop', what: what }), droppable); } dispatchMouseCallbacks(_objectSpread({}, e, { type: 'dragEnd' }), dragging_); dragging_ = []; } }; var onMouseMove = function onMouseMove(e) { var x = e.clientX; var y = e.clientY; var el = document.getElementById('bgio-canvas'); var t = el; while (t) { if (t.offsetLeft) x -= t.offsetLeft; if (t.offsetTop) y -= t.offsetTop; t = t.offsetParent; } t = el; while (t) { if (t.scrollLeft) x += t.scrollLeft; if (t.scrollTop) y += t.scrollTop; t = t.parentNode; } mouse.x = x / _this2.props.width * 2 - 1; mouse.y = -(y / _this2.props.height) * 2 + 1; dispatchMouseCallbacks(e); _this2.raycaster.setFromCamera(mouse, _this2.camera); var r = _this2.raycaster.intersectObject(_this2.plane); if (r.length > 0) { var _e = _objectSpread({}, _e, { type: 'drag' }); dragging_.forEach(function (obj) { _e.point = r[0].point; if (obj.object.id in _this2.callbacks_) { _this2.callbacks_[obj.object.id](_e); } if (obj.object.parent.id in _this2.callbacks_) { _this2.callbacks_[obj.object.parent.id](_e); } }); } }; var onMouseWheel = function onMouseWheel(e) { dispatchMouseCallbacks(e); if (e.defaultPrevented) { return; } if (e.wheelDelta > 0) { _this2.camera.zoom += 0.5; _this2.camera.updateProjectionMatrix(); } else if (_this2.camera.zoom > 0.5) { _this2.camera.zoom -= 0.5; _this2.camera.updateProjectionMatrix(); } e.preventDefault(); }; var root = this.ref_.current; root.addEventListener('mousemove', onMouseMove); root.addEventListener('wheel', onMouseWheel); root.addEventListener('mousedown', onMouseDown); root.addEventListener('mouseup', onMouseUp); root.addEventListener('click', dispatchMouseCallbacks); root.addEventListener('contextmenu', function (e) { return e.preventDefault(); }); } }, { key: "_initCanvas", value: function _initCanvas() { this.renderer.domElement.id = 'bgio-canvas'; this.ref_.current.appendChild(this.renderer.domElement); this.setupMouseEvents(); this.animate(); } }, { key: "componentDidMount", value: function componentDidMount() { this._initCanvas(); } }, { key: "render", value: function render() { var children = React.Children.map(this.props.children, function (child) { return React.cloneElement(child, { three: true }); }); return React.createElement(UIContext.Provider, { value: this.getContext() }, React.createElement("div", { className: "bgio-ui", ref: this.ref_ }, this.state.isLoading ? this.loader : children)); } }]); return UI; }(React.Component); _defineProperty(UI$1, "propTypes", { width: PropTypes.number, height: PropTypes.number, children: PropTypes.any, onMouseEvent: PropTypes.func }); _defineProperty(UI$1, "defaultProps", { width: 1024, height: 768 }); /* * Copyright 2018 The boardgame.io Authors * * Use of this source code is governed by a MIT-style * license that can be found in the LICENSE file or at * https://opensource.org/licenses/MIT. */ /** * Root component of the UI framework. */ var UI$2 = function UI$$1(props) { return props.three ? React.createElement(UI$1, props, props.children) : React.createElement(UI, props, props.children); }; UI$2.propTypes = { three: PropTypes.bool, children: PropTypes.any }; /* * Copyright 2018 The boardgame.io Authors * * Use of this source code is governed by a MIT-style * license that can be found in the LICENSE file or at * https://opensource.org/licenses/MIT. */ var Logo = function Logo(_ref) { var width = _ref.width, height = _ref.height; return React.createElement("svg", { width: width || 128, height: height || 128, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 128 128" }, React.createElement("path", { d: "M64,120.37,15.27,92.28V35.91L64,7.82l48.73,28.09V92.28Z", fill: "#373748" }), React.createElement("path", { fill: "#000", d: "M64,124,12,94V34L64,4l52,30V94ZM18.33,90.37,64,116.74l45.67-26.37V37.63L64,11.26,18.33,37.63Z" }), React.createElement("path", { d: "M81.77,43.17c5.92,0,10.51,1.72,13.57,5.16,3.25,3.44,4.77,8.41,4.77,14.71q0,10.32-5.15,16.06c-3.44,3.82-8.22,5.73-14.53,5.73-5.92,0-10.51-1.72-13.56-5.35-3.25-3.63-4.78-8.6-4.78-15.29s1.72-12,5.16-15.67S75.46,43.17,81.77,43.17Zm-.57,5.16c-4.4,0-7.45,1.15-9.56,3.63s-3,6.31-3,11.66c0,5.73,1,9.74,3,12.42,2.11,2.48,5.16,3.82,9.56,3.82s7.64-1.34,9.74-3.82,3.25-6.5,3.25-11.85c0-5.54-1.15-9.55-3.25-12C88.65,49.48,85.59,48.33,81.2,48.33Z", fill: "#fff" }), React.createElement("path", { d: "M39.35,71.45l.19,12.8H33.43L33.62,72l-.19-28.48h6.11l-.19,27.9Z", fill: "#fff" })); }; Logo.propTypes = { width: PropTypes.string, height: PropTypes.string }; var css$1 = "/*\n * Copyright 2017 The boardgame.io Authors\n *\n * Use of this source code is governed by a MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n */\n\n.bgio-card {\n display: flex;\n user-select: none;\n font-family: monospace;\n font-weight: bold;\n font-size: 18px;\n color: #ababab;\n text-align: center;\n flex-direction: column;\n justify-content: center;\n cursor: pointer;\n background: #fff;\n border-radius: 6px;\n border: 1px solid #cdcdcd;\n width: 100px;\n height: 140px;\n overflow: hidden;\n transition: transform 0.1s;\n}\n\n.bgio-card.placeholder {\n cursor: default;\n opacity: 0;\n pointer-events: none;\n}\n\n.bgio-card.accept {\n transform: rotate(10deg);\n box-shadow: 5px 5px 5px #ddd;\n}\n\n.bgio-card.reject {\n}\n\n.bgio-card__front,\n.bgio-card__back {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: hidden;\n}\n\n.bgio-card__back {\n background-image: url(\"data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 64 64' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 16c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm0-2c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6zm33.414-6l5.95-5.95L45.95.636 40 6.586 34.05.636 32.636 2.05 38.586 8l-5.95 5.95 1.414 1.414L40 9.414l5.95 5.95 1.414-1.414L41.414 8zM40 48c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm0-2c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6zM9.414 40l5.95-5.95-1.414-1.414L8 38.586l-5.95-5.95L.636 34.05 6.586 40l-5.95 5.95 1.414 1.414L8 41.414l5.95 5.95 1.414-1.414L9.414 40z' fill='%23ababab' fill-opacity='0.4' fill-rule='evenodd'/%3E%3C/svg%3E\");\n background-position: 2px 2px;\n outline: 8px solid #eee;\n outline-offset: -20px;\n}\n"; styleInject(css$1); function GetDraggable(props, classNames, cardStyle, onClick) { /* eslint-disable-next-line react/display-name */ return function (_ref) { var isActive = _ref.isActive, events = _ref.events; return React.createElement("div", _extends({ className: classNames.join(' '), style: _objectSpread({}, props.style, cardStyle, { opacity: isActive ? 0 : 1, pointerEvents: isActive ? 'none' : 'all' }), onClick: onClick }, events), props.isFaceUp ? props.front : props.back); }; } function GetDragComponent(props, classNames, ref, isOverAcceptedCallback) { /* eslint-disable-next-line react/display-name, react/prop-types */ return function (_ref2) { var x = _ref2.x, y = _ref2.y, isOverAccepted = _ref2.isOverAccepted, currentlyHoveredDroppableId = _ref2.currentlyHoveredDroppableId; var classes = _toConsumableArray(classNames); /* eslint-disable-next-line react/prop-types */ var content = props.back; isOverAcceptedCallback(isOverAccepted); /* eslint-disable-next-line react/prop-types */ if (props.isFaceUp) { /* eslint-disable-next-line react/prop-types */ content = props.front; } if (currentlyHoveredDroppableId !== null) { if (isOverAccepted) { classes.push('accept'); } else { classes.push('reject'); } } return React.createElement("div", { className: classes.join(' '), ref: ref, style: { cursor: 'pointer', borderWidth: 2, pointerEvents: 'none', position: 'fixed', zIndex: 2000000000, boxShadow: '5px 5px 5px #eee', left: x - 50, top: y - 70 } }, content); }; } /* eslint-enable */ var CardImpl = /*#__PURE__*/ function (_React$Component) { _inherits(CardImpl, _React$Component); function CardImpl(props) { var _this; _classCallCheck(this, CardImpl); _this = _possibleConstructorReturn(this, _getPrototypeOf(CardImpl).call(this, props)); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onClick", function () { _this.props.onClick(_this.props.data); }); _this.id = props.context.genID(); _this.dragComponentRef = React.createRef(); _this.isOverAccepted = false; return _this; } _createClass(CardImpl, [{ key: "render", value: function render() { var _this2 = this; var classNames = ['bgio-card']; if (this.props.className) { classNames.push(this.props.className); } var cardStyle = {}; if (this.props.inDeck) { cardStyle = { position: 'absolute', zIndex: this.props.deckPosition }; } return React.createElement("div", null, React.createElement(reactDragtastic.Draggable, { id: this.id, type: this.props.dragZone, data: this.props.data }, GetDraggable(this.props, classNames, cardStyle, this.onClick)), React.createElement(reactDragtastic.DragComponent, { for: this.id }, GetDragComponent(this.props, classNames, this.dragComponentRef, function (o) { return _this2.isOverAccepted = o; }))); } }]); return CardImpl; }(React.Component); _defineProperty(CardImpl, "propTypes", { isFaceUp: PropTypes.bool, front: PropTypes.node, back: PropTypes.node, className: PropTypes.string, dragZone: PropTypes.string, style: PropTypes.any, onClick: PropTypes.func, context: PropTypes.any.isRequired, inDeck: PropTypes.bool, data: PropTypes.any, deckPosition: PropTypes.number }); _defineProperty(CardImpl, "defaultProps", { onClick: function onClick() {}, isFaceUp: false, dragZone: 'bgio-card', front: React.createElement("div", { className: "bgio-card__front" }, "Card"), back: React.createElement("div", { className: "bgio-card__back" }, React.createElement(Logo, { width: "48" })) }); var Card = function Card(props) { return React.createElement(UIContext.Consumer, null, function (context) { return React.createElement(CardImpl, _extends({}, props, { context: context })); }); }; var CardImpl$1 = /*#__PURE__*/ function (_React$Component) { _inherits(CardImpl, _React$Component); function CardImpl(props) { var _this; _classCallCheck(this, CardImpl); _this = _possibleConstructorReturn(this, _getPrototypeOf(CardImpl).call(this, props)); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onEvent", function (e) { if (!_this.props.responsive) { return; } if (e.type == 'dragStart') { _this.obj.castShadow = true; new TWEEN.Tween(_this.obj.position).to({ y: _this.originalY + 0.5 }, 100).easing(TWEEN.Easing.Quadratic.Out).start(); } if (e.type == 'dragEnd') { new TWEEN.Tween(_this.obj.position).to({ y: _this.originalY }, 100).onComplete(function () { return _this.obj.castShadow = false; }).start(); } if (e.type == 'drag') { _this.obj.position.x = e.point.x; _this.obj.position.z = e.point.z; } }); _this.originalY = props.thickness / 2 - 0.0001; var geometry = new THREE.BoxGeometry(props.width, props.thickness, props.height); var opts = { color: 0x777777 }; if (props.image) { opts = { map: new THREE.TextureLoader().load(props.image) }; } var material = new THREE.MeshLambertMaterial(opts); _this.obj = new THREE.Mesh(geometry, material); _this.obj.receiveShadow = true; _this.obj.position.y = _this.originalY; _this.obj.userData.draggable = props.draggable; _this.obj.userData.responsive = props.responsive; return _this; } _createClass(CardImpl, [{ key: "componentDidMount", value: function componentDidMount() { this.props.context.add(this.obj, this.onEvent); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.props.context.remove(this.obj); } }, { key: "render", value: function render() { this.obj.position.x = this.props.x + this.props.splayX; this.obj.position.z = this.props.z + this.props.splayZ; this.obj.position.y = this.originalY + this.props.splayY; return null; } }]); return CardImpl; }(React.Component); _defineProperty(CardImpl$1, "propTypes", { context: PropTypes.any.isRequired, image: PropTypes.string, width: PropTypes.number, height: PropTypes.number, thickness: PropTypes.number, responsive: PropTypes.bool, draggable: PropTypes.bool, x: PropTypes.number, z: PropTypes.number, splayX: PropTypes.number, splayY: PropTypes.number, splayZ: PropTypes.number }); _defineProperty(CardImpl$1, "defaultProps", { responsive: true, draggable: true, splayX: 0, splayY: 0, splayZ: 0, x: 0, z: 0, width: 1, height: 1.5, thickness: 0.01 }); var Card$1 = function Card(props) { return React.createElement(UIContext.Consumer, null, function (context) { return React.createElement(CardImpl$1, _extends({}, props, { context: context })); }); }; var Card$2 = function Card$$1(props) { return React.createElement(UIContext.Consumer, null, function (context) { return context.three ? React.createElement(Card$1, _extends({}, props, { context: context })) : React.createElement(Card, _extends({}, props, { context: context })); }); }; Card$2.propTypes = { children: PropTypes.any }; var css$2 = "/*\n * Copyright 2017 The boardgame.io Authors\n *\n * Use of this source code is governed by a MIT-style\n * license that can be found in the LICENSE file or at\n * https://opensource.org/licenses/MIT.\n */\n\n.bgio-deck {\n border: 1px dashed #ddd;\n position: relative;\n display: inline-flex;\n border-radius: 6px;\n padding: 5px;\n margin-top: 20px;\n margin-bottom: 20px;\n margin-right: 20px;\n width: 100px;\n height: 140px;\n}\n"; styleInject(css$2); var DeckImpl = /*#__PURE__*/ function (_React$Component) { _inherits(DeckImpl, _React$Component); function DeckImpl(props) { var _this; _classCallCheck(this, DeckImpl); _this = _possibleConstructorReturn(this, _getPrototypeOf(DeckImpl).call(this, props)); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onClick", function () { var cards = React.Children.toArray(_this.props.children); var topCardProps = null; if (cards.length > 0) { topCardProps = cards[cards.length - 1].props; _this.props.onClick(topCardProps.data); } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onDrop", function (cardData) { // Don't fire onDrop if the top card of this deck was // dragged away and then dropped back. var isChild = false; React.Children.forEach(_this.props.children, function (card) { if (cardData !== undefined && card.props.data === cardData) { isChild = true; } }); if (!isChild) { _this.props.onDrop(cardData); } }); _this.id = props.context.genID(); return _this; } _createClass(DeckImpl, [{ key: "render", value: function render() { var _this2 = this; var cardIndex = 0; var cards = React.Children.map(this.props.children, function (card) { return React.cloneElement(card, { dragZone: _this2.props.dragZone, inDeck: true, deckPosition: cardIndex++ }); }); return React.createElement("div", { onClick: this.onClick }, React.createElement(reactDragtastic.Droppable, { accepts: this.props.dragZone, onDrop: this.onDrop }, function (_ref) { var events = _ref.events; return React.createElement("div", _extends({}, events, { className: _this2.props.className, style: { background: '#eee', marginRight: 20, padding: _this2.props.padding, position: 'relative', width: '100px', height: '140px', display: 'block', float: 'left' } }), cards); })); } }]); return DeckImpl; }(React.Component); _defineProperty(DeckImpl, "propTypes", { context: PropTypes.any, children: PropTypes.any, onClick: PropTypes.func, onDrop: PropTypes.func, splayWidth: PropTypes.number, dragZone: PropTypes.string, padding: PropTypes.number, className: PropTypes.string }); _defineProperty(DeckImpl, "defaultProps", { padding: 10, splayWidth: 3, dragZone: 'bgio-card', onDrop: function onDrop() {}, onClick: function onClick() {} }); var Deck = function Deck(props) { return React.createElement(UIContext.Consumer, null, function (context) { return React.createElement(DeckImpl, _extends({}, props, { context: context })); }); }; var DeckImpl$1 = /*#__PURE__*/ function (_React$Component) { _inherits(DeckImpl, _React$Component); function DeckImpl(props) { var _this; _classCallCheck(this, DeckImpl); _this = _possibleConstructorReturn(this, _getPrototypeOf(DeckImpl).call(this, props)); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "state", { isHighlighted: false }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onEvent", function (e) { if (e.type == 'drop') { e.what[0].position.x = -2; e.what[0].position.z = 0; e.what[0].position.y += 20 * 0.02; } }); _this.originalY = props.thickness / 2 - 0.0001; var geometry = new THREE.BoxGeometry(props.width, props.thickness, props.height); var material = new THREE.MeshLambertMaterial({ color: 0xcccccc }); _this.obj = new THREE.Mesh(geometry, material); _this.obj.userData.droppable = true; _this.obj.userData.responsive = true; _this.obj.position.y = _this.originalY; return _this; } _createClass(DeckImpl, [{ key: "componentDidMount", value: function componentDidMount() { this.props.context.add(this.obj, this.onEvent); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.props.context.remove(this.obj); } }, { key: "render", value: function render() { this.obj.position.x = -2; var cards = []; for (var i = 0; i < 20; i++) { cards.push(React.createElement(Card$1, { key: i, responsive: false, x: -2, splayY: i * 0.02 })); } return cards; } }]); return DeckImpl; }(React.Component); _defineProperty(DeckImpl$1, "propTypes", { context: PropTypes.any.isRequired, width: PropTypes.number, height: PropTypes.number, thickness: PropTypes.number }); _defineProperty(DeckImpl$1, "defaultProps", { width: 1, height: 1.5, thickness: 0.01 }); var Deck$1 = function Deck(props) { return React.createElement(UIContext.Consumer, null, function (context) { return React.createElement(DeckImpl$1, _extends({}, props, { context: context })); }); }; var Deck$2 = function Deck$$1(props) { return React.createElement(UIContext.Consumer, null, function (context) { return context.three ? React.createElement(Deck$1, _extends({}, props, { context: context })) : React.createElement(Deck, _extends({}, props, { context: context })); }); }; Deck$2.propTypes = { children: PropTypes.any }; /** * Grid * * Component that will show children on a cartesian regular grid. * * Props: * rows - Number of rows (height) of the grid. * cols - Number of columns (width) of the grid. * style - CSS style of the Grid HTML element. * colorMap - A map from 'x,y' => color. * onClick - (x, y) => {} * Called when a square is clicked. * onMouseOver - (x, y) => {} * Called when a square is mouse over. * onMouseOut - (x, y) => {} * Called when a square is mouse out. * * Usage: * * <Grid rows={8} cols={8}> * <Token x={1} y={2}/> * </Grid> */ var Grid = /*#__PURE__*/ function (_React$Component) { _inherits(Grid, _React$Component); function Grid() { var _getPrototypeOf2; var _this; _classCallCheck(this, Grid); for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) { _args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Grid)).call.apply(_getPrototypeOf2, [this].concat(_args))); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "_svgRef", React.createRef()); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onClick", function (args) { if (_this.props.onClick) { _this.props.onClick(args); } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onMouseOver", function (args) { if (_this.props.onMouseOver) { _this.props.onMouseOver(args); } }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onMouseOut", function (args) { if (_this.props.onMouseOut) { _this.props.onMouseOut(args); } }); return _this; } _createClass(Grid, [{ key: "_getCellColor", value: function _getCellColor(x, y) { var key = "".concat(x, ",").concat(y); var color = 'white'; if (key in this.props.colorMap) { color = this.props.colorMap[key]; } return color; } }, { key: "_getGrid", value: function _getGrid() { if (!this.props.outline) { return null; } var squares = []; for (var x = 0; x < this.props.cols; x++) { for (var y = 0; y < this.props.rows; y++) { squares.push(React.createElement(Square, { key: this.props.cols * y + x, style: { fill: this._getCellColor(x, y) }, x: x, y: y, size: this.props.cellSize, onClick: this.onClick, onMouseOver: this.onMouseOver, onMouseOut: this.onMouseOut })); } } return squares; } }, { key: "render", value: function render() { var _this2 = this; var tokens = React.Children.map(this.props.children, function (child) { return React.cloneElement(child, { template: Square, // Overwrites Token's onClick, onMouseOver, onMouseOut onClick: _this2.onClick, onMouseOver: _this2.onMouseOver, onMouseOut: _this2.onMouseOut, svgRef: _this2._svgRef }); }); return React.createElement("svg", { ref: this._svgRef, viewBox: '0 0 ' + this.props.cols + ' ' + this.props.rows, style: this.props.style }, React.createElement("g", null, this._getGrid()), tokens); } }]); return Grid; }(React.Component); /** * Square * * Component that renders a square inside a Grid. * * Props: * x - X coordinate on grid coordinates. * y - Y coordinate on grid coordinates. * size - Square size. * style - Custom styling. * onClick - Invoked when a Square is clicked. * onMouseOver - Invoked when a Square is mouse over. * onMouseOut - Invoked when a Square is mouse out. * eventListeners - Array of objects with name and callback * for DOM events. * * Not meant to be used by the end user directly (use Token). * Also not exposed in the NPM. */ _defineProperty(Grid, "propTypes", { rows: PropTypes.number.isRequired, cols: PropTypes.number.isRequired, outline: PropTypes.bool, style: PropTypes.object, colorMap: PropTypes.object, cellSize: PropTypes.number, onClick: PropTypes.func, onMouseOver: PropTypes.func, onMouseOut: PropTypes.func, children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.element), PropTypes.element]) }); _defineProperty(Grid, "defaultProps", { colorMap: {}, outline: true, cellSize: 1 }); var Square = /*#__PURE__*/ function (_React$Component2) { _inherits(Square, _React$Component2); function Square() { var _getPrototypeOf3; var _this3; _classCallCheck(this, Square); for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } _this3 = _possibleConstructorReturn(this, (_getPrototypeOf3 = _getPrototypeOf(Square)).call.apply(_getPrototypeOf3, [this].concat(args))); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this3)), "_gRef", React.createRef()); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this3)), "onClick", function (e) { _this3.props.onClick(_this3.getCoords(), e); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this3)), "onMouseOver", function (e) { _this3.props.onMouseOver(_this3.getCoords(), e); }); _defineProperty(_assertThisInitialized(_assertThisInitialized(_this3)), "onMouseOut", function (e) { _this3.props.onMouseOut(_this3.getCoords(), e); }); return _this3; } _createClass(Square, [{ key: "getCoords", value: function getCoords() { return { x: this.props.x, y: this.props.y }; } }, { key: "componentDidMount", value: function componentDidMount() { var element = this._gRef.current; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this.props.eventListeners[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var listener = _step.value; element.addEventListener(listener.name, listener.callback); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { var element = this._gRef.current; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = this.props.eventListeners[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var listener = _step2.value; element.removeEventListener(listener.name, listener.callback); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return != null) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } }, { key: "render", value: function render() { var tx = this.props.x * this.props.size; var ty = this.props.y * this.props.size; // If no child, render a square. var children = React.createElement("rect", { style: this.props.style, width: this.props.size, height: this.props.size, x: 0, y: 0 }); // If a child is passed, render child. if (this.props.children) { children = this.props.children; } return React.createElement("g", { ref: this._gRef, onClick: this.onClick, onMouseOver: this.onMouseOver, onMouseOut: this.onMouseOut, transform: "translate(".concat(tx, ", ").concat(ty, ")") }, children); } }]); return Square; }(React.Component); _defineProperty(Square, "propTypes", { x: PropTypes.number.isRequired, y: PropTypes.number.isRequired, size: PropTypes.number, style: PropTypes.any, onClick: PropTypes.func, onMouseOver: PropTypes.func, onMouseOut: PropTypes.func, eventListeners: PropTypes.array, children: PropTypes.element }); _defineProperty(Square, "defaultProps", { size: 1, x: 0, y: 0, style: { fill: '#fff' }, eventListeners: [] }); /** * Grid * * Component that will show children on a cartesian regular grid. * * Props: * rows - Number of rows (height) of the grid. * cols - Number of columns (width) of the grid. * cellSize - Size of a square. * thichness - Thichness of a square. * padding - Padding between squares. * colorMap - A map from 'x,y' => color. * onClick - (x, y) => {} * Called when a square is clicked. * onMouseOver - (x, y) => {} * Called when a square is mouse over. * onMouseOut - (x, y) => {} * Called when a square is mouse out. * * Usage: * * <Grid rows={8} cols={8}> * <Token x={1} y={2}/> * </Grid> */ var Grid$1 = function Grid(props) { return React.createElement(UIContext.Consumer, null, function (context) { return React.createElement(GridImpl, _extends({}, props, { context: context })); }); }; var GridImpl = /*#__PURE__*/ function (_React$Component) { _inherits(GridImpl, _React$Component); function GridImpl(props) { var _this; _classCallCheck(this, GridImpl); _this = _possibleConstructorReturn(this, _getPrototypeOf(GridImpl).call(this, props)); _this.boardGroup = new THREE.Group(); _this.tokenGroup = new THREE.Group(); _this.boardGroup.add(_this.tokenGroup); // translate the board to center on (0,0,0) _this.boardGroup.translateX(-(_this.props.padding + _this.props.cellSize) * (_this.props.cols - 1) / 2); _this.boardGroup.translateZ(-(_this.props.padding + _this.props.cellSize) * (_this.props.rows - 1) / 2); return _this; } _createClass(GridImpl, [{ key: "_getCellColor", value: function _getCellColor(x, y) { var key = "".concat(x, ",").concat(y); var color = '#777777'; if (key in this.props.colorMap) { color = this.props.colorMap[key]; } return color; } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.context.remove(this.boardGroup); } }, { key: "render", value: function render() { var _this2 = this; this.context = this.props.context; this.conte