UNPKG

@trap_stevo/legendarybuilderproreact-ui

Version:

The legendary UI & utility API that makes your application a legendary application. ~ Created by Steven Compton

442 lines 22.6 kB
import _extends from "@babel/runtime/helpers/extends"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import React, { useState, useEffect, useRef, useMemo } from "react"; import * as THREE from "three"; import { Canvas, useThree, useFrame } from "@react-three/fiber"; import { OrthographicCamera } from "@react-three/drei"; import { EffectComposer, Bloom, Noise } from "@react-three/postprocessing"; import { useHUDTerrain } from "./HUDTerrainProvider.js"; var Entity = function Entity(_ref) { var _entityData$radius, _getEntityPosition$x, _getEntityPosition, _getEntityPosition$y, _getEntityPosition2; var entity = _ref.entity, zoom = _ref.zoom, zoomLimits = _ref.zoomLimits, renderEntity = _ref.renderEntity; var _useHUDTerrain = useHUDTerrain(), getEntityPosition = _useHUDTerrain.getEntityPosition, getEntityData = _useHUDTerrain.getEntityData, trackEntity = _useHUDTerrain.trackEntity, untrackEntity = _useHUDTerrain.untrackEntity; var _useState = useState(0), _useState2 = _slicedToArray(_useState, 2), version = _useState2[0], setVersion = _useState2[1]; var groupRef = useRef(); var entityData = useMemo(function () { var _getEntityData; return (_getEntityData = getEntityData(entity.id)) !== null && _getEntityData !== void 0 ? _getEntityData : {}; }, [entity === null || entity === void 0 ? void 0 : entity.id, version]); var radius = (_entityData$radius = entityData === null || entityData === void 0 ? void 0 : entityData.radius) !== null && _entityData$radius !== void 0 ? _entityData$radius : entity.radius; var minZoom = (zoomLimits === null || zoomLimits === void 0 ? void 0 : zoomLimits.min) || 0.1; var maxZoom = (zoomLimits === null || zoomLimits === void 0 ? void 0 : zoomLimits.max) || 100; var zoomRatio = (zoom - minZoom) / (maxZoom - minZoom); var clampedZoomRatio = Math.max(0, Math.min(1, zoomRatio)); var minSize = Math.max(20, radius * 0.2); var maxSize = radius; var adjustedRadius = minSize + (maxSize - minSize) * (1 - clampedZoomRatio); useFrame(function () { var pos = getEntityPosition(entity.id); if (groupRef.current && pos) { var _pos$z; groupRef.current.position.set(pos.x, pos.y, (_pos$z = pos.z) !== null && _pos$z !== void 0 ? _pos$z : 0); } }); useEffect(function () { var updateEntityVersion = function updateEntityVersion() { setVersion(function (v) { return v + 1; }); }; trackEntity(entity.id, updateEntityVersion); return function () { untrackEntity(entity.id, updateEntityVersion); }; }, []); return /*#__PURE__*/React.createElement("group", { ref: groupRef }, renderEntity(_objectSpread(_objectSpread(_objectSpread({}, entity), entityData !== null && entityData !== void 0 ? entityData : {}), {}, { x: (_getEntityPosition$x = (_getEntityPosition = getEntityPosition(entity.id)) === null || _getEntityPosition === void 0 ? void 0 : _getEntityPosition.x) !== null && _getEntityPosition$x !== void 0 ? _getEntityPosition$x : entity.x, y: (_getEntityPosition$y = (_getEntityPosition2 = getEntityPosition(entity.id)) === null || _getEntityPosition2 === void 0 ? void 0 : _getEntityPosition2.y) !== null && _getEntityPosition$y !== void 0 ? _getEntityPosition$y : entity.y, radius: adjustedRadius, zoom: zoom, maxZoom: maxZoom, minZoom: minZoom, zoomRatio: clampedZoomRatio }))); }; var GridOverlay = function GridOverlay(_ref2) { var viewBox = _ref2.viewBox, zoom = _ref2.zoom, _ref2$gridColor = _ref2.gridColor, gridColor = _ref2$gridColor === void 0 ? "rgba(255,255,255,0.1)" : _ref2$gridColor; var lines = []; var gridSpacing = 100 / zoom; var startX = Math.floor(viewBox.xRange[0] / gridSpacing) * gridSpacing; var endX = viewBox.xRange[1]; var startY = Math.floor(viewBox.yRange[0] / gridSpacing) * gridSpacing; var endY = viewBox.yRange[1]; for (var x = startX; x <= endX; x += gridSpacing) { lines.push( /*#__PURE__*/React.createElement("lineSegments", { key: "x-".concat(x) }, /*#__PURE__*/React.createElement("bufferGeometry", null, /*#__PURE__*/React.createElement("bufferAttribute", { attach: "attributes-position", count: 2, array: new Float32Array([x, startY, 0, x, endY, 0]), itemSize: 3 })), /*#__PURE__*/React.createElement("lineBasicMaterial", { color: gridColor, linewidth: 1 }))); } for (var y = startY; y <= endY; y += gridSpacing) { lines.push( /*#__PURE__*/React.createElement("lineSegments", { key: "y-".concat(y) }, /*#__PURE__*/React.createElement("bufferGeometry", null, /*#__PURE__*/React.createElement("bufferAttribute", { attach: "attributes-position", count: 2, array: new Float32Array([startX, y, 0, endX, y, 0]), itemSize: 3 })), /*#__PURE__*/React.createElement("lineBasicMaterial", { color: gridColor, linewidth: 1 }))); } return /*#__PURE__*/React.createElement(React.Fragment, null, lines); }; var CameraControls = function CameraControls(_ref3) { var enableZoom = _ref3.enableZoom, enablePanning = _ref3.enablePanning, zoomLimits = _ref3.zoomLimits; var _useThree = useThree(), camera = _useThree.camera, gl = _useThree.gl; var state = useRef({ isDragging: false, lastX: 0, lastY: 0, lastDistance: null }); useEffect(function () { var preventDefault = function preventDefault(e) { return e.preventDefault(); }; var handleWheel = function handleWheel(e) { if (!enableZoom) return; e.preventDefault(); var delta = e.deltaY * 0.001; var newZoom = camera.zoom * (1 - delta); if (zoomLimits) { newZoom = Math.max(zoomLimits.min * 0.01, Math.min(zoomLimits.max * 0.01, newZoom)); } camera.zoom = newZoom; camera.updateProjectionMatrix(); }; var handleMouseDown = function handleMouseDown(e) { if (!enablePanning) return; state.current.isDragging = true; state.current.lastX = e.clientX; state.current.lastY = e.clientY; }; var handleMouseUp = function handleMouseUp() { state.current.isDragging = false; }; var handleMouseMove = function handleMouseMove(e) { if (!enablePanning || !state.current.isDragging) return; var dx = (e.clientX - state.current.lastX) / camera.zoom; var dy = (e.clientY - state.current.lastY) / camera.zoom; camera.position.x -= dx; camera.position.y += dy; state.current.lastX = e.clientX; state.current.lastY = e.clientY; }; var handleTouchMove = function handleTouchMove(e) { if (!enableZoom || e.touches.length !== 2) return; e.preventDefault(); var _e$touches = _slicedToArray(e.touches, 2), touch1 = _e$touches[0], touch2 = _e$touches[1]; var dx = touch1.clientX - touch2.clientX; var dy = touch1.clientY - touch2.clientY; var distance = Math.sqrt(dx * dx + dy * dy); if (state.current.lastDistance) { var delta = distance - state.current.lastDistance; var newZoom = camera.zoom * (1 + delta * 0.005); if (zoomLimits) { newZoom = Math.max(zoomLimits.min * 0.01, Math.min(zoomLimits.max * 0.01, newZoom)); } camera.zoom = newZoom; camera.updateProjectionMatrix(); } state.current.lastDistance = distance; }; var handleTouchEnd = function handleTouchEnd() { state.current.lastDistance = null; }; gl.domElement.addEventListener("wheel", handleWheel, { passive: false }); gl.domElement.addEventListener("mousedown", handleMouseDown); gl.domElement.addEventListener("mouseup", handleMouseUp); gl.domElement.addEventListener("mousemove", handleMouseMove); gl.domElement.addEventListener("touchmove", handleTouchMove, { passive: false }); gl.domElement.addEventListener("touchend", handleTouchEnd); gl.domElement.addEventListener("gesturestart", preventDefault, { passive: false }); gl.domElement.addEventListener("gesturechange", preventDefault, { passive: false }); gl.domElement.addEventListener("gestureend", preventDefault, { passive: false }); return function () { gl.domElement.removeEventListener("wheel", handleWheel); gl.domElement.removeEventListener("mousedown", handleMouseDown); gl.domElement.removeEventListener("mouseup", handleMouseUp); gl.domElement.removeEventListener("mousemove", handleMouseMove); gl.domElement.removeEventListener("touchmove", handleTouchMove); gl.domElement.removeEventListener("touchend", handleTouchEnd); gl.domElement.removeEventListener("gesturestart", preventDefault); gl.domElement.removeEventListener("gesturechange", preventDefault); gl.domElement.removeEventListener("gestureend", preventDefault); }; }, [enableZoom, enablePanning, zoomLimits, camera, gl]); return null; }; var CameraLinkedLight = function CameraLinkedLight(_ref4) { var _lightRef$current; var _ref4$terrainCameraLi = _ref4.terrainCameraLightConfigurations, terrainCameraLightConfigurations = _ref4$terrainCameraLi === void 0 ? {} : _ref4$terrainCameraLi; var _useThree2 = useThree(), camera = _useThree2.camera, scene = _useThree2.scene; var lightRef = useRef(); useFrame(function () { if (lightRef.current) { var offset = new THREE.Vector3(300, 100, 500); var lightPos = camera.position.clone().add(offset); lightRef.current.position.copy(lightPos); var directionOffset = new THREE.Vector3(0.3, -0.3, -1).normalize().multiplyScalar(100); var targetPos = camera.position.clone().add(directionOffset); lightRef.current.target.position.copy(targetPos); lightRef.current.target.updateMatrixWorld(); } }); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("directionalLight", _extends({ ref: lightRef, castShadow: true, intensity: 1.69, color: "white" }, terrainCameraLightConfigurations !== null && terrainCameraLightConfigurations !== void 0 ? terrainCameraLightConfigurations : {})), ((_lightRef$current = lightRef.current) === null || _lightRef$current === void 0 ? void 0 : _lightRef$current.target) && /*#__PURE__*/React.createElement("primitive", { object: lightRef.current.target })); }; var HUDTerrainScene = function HUDTerrainScene(_ref5) { var _ref5$terrainBackgrou = _ref5.terrainBackgroundMaterialConfigurations, terrainBackgroundMaterialConfigurations = _ref5$terrainBackgrou === void 0 ? {} : _ref5$terrainBackgrou, _ref5$terrainBackgrou2 = _ref5.terrainBackgroundPlaneConfigurations, terrainBackgroundPlaneConfigurations = _ref5$terrainBackgrou2 === void 0 ? {} : _ref5$terrainBackgrou2, _ref5$terrainAmbientL = _ref5.terrainAmbientLightConfigurations, terrainAmbientLightConfigurations = _ref5$terrainAmbientL === void 0 ? {} : _ref5$terrainAmbientL, _ref5$terrainCameraLi = _ref5.terrainCameraLightConfigurations, terrainCameraLightConfigurations = _ref5$terrainCameraLi === void 0 ? {} : _ref5$terrainCameraLi, _ref5$terrainBackgrou3 = _ref5.terrainBackgroundConfigurations, terrainBackgroundConfigurations = _ref5$terrainBackgrou3 === void 0 ? {} : _ref5$terrainBackgrou3, _ref5$terrainBloomCon = _ref5.terrainBloomConfigurations, terrainBloomConfigurations = _ref5$terrainBloomCon === void 0 ? {} : _ref5$terrainBloomCon, _ref5$terrainNoiseCon = _ref5.terrainNoiseConfigurations, terrainNoiseConfigurations = _ref5$terrainNoiseCon === void 0 ? {} : _ref5$terrainNoiseCon, _ref5$backgroundEffec = _ref5.backgroundEffects, backgroundEffects = _ref5$backgroundEffec === void 0 ? [] : _ref5$backgroundEffec, _ref5$sceneEffects = _ref5.sceneEffects, sceneEffects = _ref5$sceneEffects === void 0 ? [] : _ref5$sceneEffects, renderEntity = _ref5.renderEntity, visibilityMargin = _ref5.visibilityMargin, startAtPoint = _ref5.startAtPoint, zoomLimits = _ref5.zoomLimits, enablePanning = _ref5.enablePanning, enableZoom = _ref5.enableZoom, showGrid = _ref5.showGrid, gridColor = _ref5.gridColor, _ref5$terrainBackgrou4 = _ref5.terrainBackgroundZPosition, terrainBackgroundZPosition = _ref5$terrainBackgrou4 === void 0 ? -1 : _ref5$terrainBackgrou4, background = _ref5.background; var _useHUDTerrain2 = useHUDTerrain(), registerCamera = _useHUDTerrain2.registerCamera, cameraRef = _useHUDTerrain2.cameraRef, entities = _useHUDTerrain2.entities, rawZoom = _useHUDTerrain2.zoom, viewBox = _useHUDTerrain2.viewBox, jumpToPoint = _useHUDTerrain2.jumpToPoint, setZoom = _useHUDTerrain2.setZoom; var clampedZoom = useMemo(function () { return Math.max(zoomLimits.min, Math.min(zoomLimits.max, rawZoom)); }, [rawZoom, zoomLimits]); useEffect(function () { if (rawZoom !== clampedZoom) { setZoom(clampedZoom); } }, [rawZoom, clampedZoom, setZoom]); useEffect(function () { if (cameraRef.current) { registerCamera(cameraRef.current); } }, []); useEffect(function () { if (startAtPoint) { var timeout = setTimeout(function () { jumpToPoint(startAtPoint.x, startAtPoint.y); }, 50); return function () { return clearTimeout(timeout); }; } }, [JSON.stringify(startAtPoint)]); var zoom = clampedZoom; var cameraZoom = zoom * 0.01; var maxGrainOpacity = 0.05; var baseOpacity = (zoomLimits.max - zoom) / (zoomLimits.max - zoomLimits.min) * maxGrainOpacity; var isEntityVisible = function isEntityVisible(entity) { var margin = visibilityMargin * zoom; if (entity.radius) { return entity.x + entity.radius > viewBox.xRange[0] - margin && entity.x - entity.radius < viewBox.xRange[1] + margin && entity.y + entity.radius > viewBox.yRange[0] - margin && entity.y - entity.radius < viewBox.yRange[1] + margin; } else if (entity.width && entity.height) { return entity.x + entity.width > viewBox.xRange[0] - margin && entity.x < viewBox.xRange[1] + margin && entity.y + entity.height > viewBox.yRange[0] - margin && entity.y < viewBox.yRange[1] + margin; } return false; }; var renderBackgroundEffects = function renderBackgroundEffects() { return backgroundEffects.map(function (effect, index) { var position = effect.position, width = effect.width, height = effect.height, element = effect.element; var isVisible = viewBox.xRange[1] > position[0] - width / 2 && viewBox.xRange[0] < position[0] + width / 2 && viewBox.yRange[1] > position[1] - height / 2 && viewBox.yRange[0] < position[1] + height / 2; if (!isVisible) return null; return /*#__PURE__*/React.cloneElement(element, { key: index }); }); }; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(OrthographicCamera, { ref: cameraRef, makeDefault: true, zoom: cameraZoom, position: [0, 0, 10] }), /*#__PURE__*/React.createElement(CameraControls, { enableZoom: enableZoom, enablePanning: enablePanning, zoomLimits: zoomLimits }), /*#__PURE__*/React.createElement("ambientLight", _extends({ intensity: 1 }, terrainAmbientLightConfigurations !== null && terrainAmbientLightConfigurations !== void 0 ? terrainAmbientLightConfigurations : {})), /*#__PURE__*/React.createElement(CameraLinkedLight, { terrainCameraLightConfigurations: terrainCameraLightConfigurations }), /*#__PURE__*/React.createElement("mesh", _extends({ position: [(viewBox.xRange[0] + viewBox.xRange[1]) / 2, (viewBox.yRange[0] + viewBox.yRange[1]) / 2, terrainBackgroundZPosition] }, terrainBackgroundConfigurations !== null && terrainBackgroundConfigurations !== void 0 ? terrainBackgroundConfigurations : {}), /*#__PURE__*/React.createElement("planeGeometry", _extends({ args: [viewBox.xRange[1] - viewBox.xRange[0], viewBox.yRange[1] - viewBox.yRange[0]] }, terrainBackgroundPlaneConfigurations !== null && terrainBackgroundPlaneConfigurations !== void 0 ? terrainBackgroundPlaneConfigurations : {})), /*#__PURE__*/React.createElement("meshBasicMaterial", _extends({ color: background }, terrainBackgroundMaterialConfigurations !== null && terrainBackgroundMaterialConfigurations !== void 0 ? terrainBackgroundMaterialConfigurations : {}))), renderBackgroundEffects(), showGrid && /*#__PURE__*/React.createElement(GridOverlay, { viewBox: viewBox, zoom: zoom, gridColor: gridColor }), entities.filter(isEntityVisible).map(function (entity) { return /*#__PURE__*/React.createElement(Entity, { key: entity.id, entity: entity, zoomLimits: zoomLimits, zoom: zoom, renderEntity: renderEntity }); }), /*#__PURE__*/React.createElement(EffectComposer, null, /*#__PURE__*/React.createElement(Bloom, _extends({ luminanceThreshold: 0.2, luminanceSmoothing: 0.9, intensity: 1.2069 }, terrainBloomConfigurations !== null && terrainBloomConfigurations !== void 0 ? terrainBloomConfigurations : {})), /*#__PURE__*/React.createElement(Noise, _extends({ opacity: baseOpacity }, terrainNoiseConfigurations !== null && terrainNoiseConfigurations !== void 0 ? terrainNoiseConfigurations : {})), sceneEffects === null || sceneEffects === void 0 ? void 0 : sceneEffects.map(function (effect, index) { return /*#__PURE__*/React.createElement(React.Fragment, { key: "scene-effect-".concat(index) }, effect); }))); }; var HUDTerrain = function HUDTerrain(_ref6) { var _ref6$terrainBackgrou = _ref6.terrainBackgroundMaterialConfigurations, terrainBackgroundMaterialConfigurations = _ref6$terrainBackgrou === void 0 ? {} : _ref6$terrainBackgrou, _ref6$terrainBackgrou2 = _ref6.terrainBackgroundPlaneConfigurations, terrainBackgroundPlaneConfigurations = _ref6$terrainBackgrou2 === void 0 ? {} : _ref6$terrainBackgrou2, _ref6$terrainAmbientL = _ref6.terrainAmbientLightConfigurations, terrainAmbientLightConfigurations = _ref6$terrainAmbientL === void 0 ? {} : _ref6$terrainAmbientL, _ref6$terrainSceneCan = _ref6.terrainSceneCanvasConfigurations, terrainSceneCanvasConfigurations = _ref6$terrainSceneCan === void 0 ? {} : _ref6$terrainSceneCan, _ref6$terrainCameraLi = _ref6.terrainCameraLightConfigurations, terrainCameraLightConfigurations = _ref6$terrainCameraLi === void 0 ? {} : _ref6$terrainCameraLi, _ref6$terrainBackgrou3 = _ref6.terrainBackgroundConfigurations, terrainBackgroundConfigurations = _ref6$terrainBackgrou3 === void 0 ? {} : _ref6$terrainBackgrou3, _ref6$terrainBloomCon = _ref6.terrainBloomConfigurations, terrainBloomConfigurations = _ref6$terrainBloomCon === void 0 ? {} : _ref6$terrainBloomCon, _ref6$terrainNoiseCon = _ref6.terrainNoiseConfigurations, terrainNoiseConfigurations = _ref6$terrainNoiseCon === void 0 ? {} : _ref6$terrainNoiseCon, _ref6$backgroundEffec = _ref6.backgroundEffects, backgroundEffects = _ref6$backgroundEffec === void 0 ? [] : _ref6$backgroundEffec, _ref6$sceneEffects = _ref6.sceneEffects, sceneEffects = _ref6$sceneEffects === void 0 ? [] : _ref6$sceneEffects, renderEntity = _ref6.renderEntity, _ref6$visibilityMargi = _ref6.visibilityMargin, visibilityMargin = _ref6$visibilityMargi === void 0 ? 200 : _ref6$visibilityMargi, _ref6$enablePanning = _ref6.enablePanning, enablePanning = _ref6$enablePanning === void 0 ? true : _ref6$enablePanning, _ref6$enableZoom = _ref6.enableZoom, enableZoom = _ref6$enableZoom === void 0 ? true : _ref6$enableZoom, _ref6$showGrid = _ref6.showGrid, showGrid = _ref6$showGrid === void 0 ? true : _ref6$showGrid, _ref6$gridColor = _ref6.gridColor, gridColor = _ref6$gridColor === void 0 ? "rgba(255, 255, 255, 0.1)" : _ref6$gridColor, _ref6$terrainBackgrou4 = _ref6.terrainBackgroundZPosition, terrainBackgroundZPosition = _ref6$terrainBackgrou4 === void 0 ? -1 : _ref6$terrainBackgrou4, _ref6$background = _ref6.background, background = _ref6$background === void 0 ? "#000" : _ref6$background, _ref6$startAtPoint = _ref6.startAtPoint, startAtPoint = _ref6$startAtPoint === void 0 ? { x: 0, y: 0 } : _ref6$startAtPoint; var _useHUDTerrain3 = useHUDTerrain(), jumpToPoint = _useHUDTerrain3.jumpToPoint, zoomLimits = _useHUDTerrain3.zoomLimits; return /*#__PURE__*/React.createElement(Canvas, _extends({ orthographic: true, style: { height: "100vh", width: "100vw" }, dpr: [1, 2] }, terrainSceneCanvasConfigurations !== null && terrainSceneCanvasConfigurations !== void 0 ? terrainSceneCanvasConfigurations : {}), /*#__PURE__*/React.createElement(HUDTerrainScene, { terrainBackgroundMaterialConfigurations: terrainBackgroundMaterialConfigurations, terrainBackgroundPlaneConfigurations: terrainBackgroundPlaneConfigurations, terrainAmbientLightConfigurations: terrainAmbientLightConfigurations, terrainCameraLightConfigurations: terrainCameraLightConfigurations, terrainBackgroundConfigurations: terrainBackgroundConfigurations, terrainBloomConfigurations: terrainBloomConfigurations, terrainNoiseConfigurations: terrainNoiseConfigurations, backgroundEffects: backgroundEffects, sceneEffects: sceneEffects, renderEntity: renderEntity, visibilityMargin: visibilityMargin, startAtPoint: startAtPoint, zoomLimits: zoomLimits, enablePanning: enablePanning, enableZoom: enableZoom, showGrid: showGrid, gridColor: gridColor, terrainBackgroundZPosition: terrainBackgroundZPosition, background: background })); }; export default HUDTerrain;