Added multiple dice tray sizes

This commit is contained in:
Mitchell McCaffrey
2020-05-27 11:24:17 +10:00
parent 0a5b33a69f
commit b786b176b0
17 changed files with 269 additions and 81 deletions
+2 -2
View File
@@ -2,7 +2,7 @@ import React, { useState } from "react";
import { Flex, IconButton } from "theme-ui";
import ExpandMoreDiceIcon from "../../icons/ExpandMoreDiceIcon";
import DiceTray from "./dice/DiceTray";
import DiceTrayOverlay from "./dice/DiceTrayOverlay";
function MapDice() {
const [isExpanded, setIsExpanded] = useState(false);
@@ -32,7 +32,7 @@ function MapDice() {
>
<ExpandMoreDiceIcon isExpanded={isExpanded} />
</IconButton>
<DiceTray isOpen={isExpanded} />
<DiceTrayOverlay isOpen={isExpanded} />
</Flex>
);
}
+25 -2
View File
@@ -1,5 +1,5 @@
import React, { useState } from "react";
import { Flex } from "theme-ui";
import { Flex, IconButton } from "theme-ui";
import D20Icon from "../../../icons/D20Icon";
import D12Icon from "../../../icons/D12Icon";
@@ -8,6 +8,7 @@ import D8Icon from "../../../icons/D8Icon";
import D6Icon from "../../../icons/D6Icon";
import D4Icon from "../../../icons/D4Icon";
import D100Icon from "../../../icons/D100Icon";
import ExpandMoreDiceTrayIcon from "../../../icons/ExpandMoreDiceTrayIcon";
import DiceButton from "./DiceButton";
import SelectDiceButton from "./SelectDiceButton";
@@ -16,7 +17,12 @@ import Divider from "../../Divider";
import { dice } from "../../../dice";
function DiceButtons({ diceRolls, onDiceAdd }) {
function DiceButtons({
diceRolls,
onDiceAdd,
diceTraySize,
onDiceTraySizeChange,
}) {
const [currentDice, setCurrentDice] = useState(dice[0]);
const diceCounts = {};
@@ -91,6 +97,23 @@ function DiceButtons({ diceRolls, onDiceAdd }) {
>
<D100Icon />
</DiceButton>
<Divider vertical color="hsl(210, 50%, 96%)" />
<IconButton
aria-label={
diceTraySize === "single" ? "Expand Dice Tray" : "Shrink Dice Tray"
}
title={
diceTraySize === "single" ? "Expand Dice Tray" : "Shrink Dice Tray"
}
sx={{
transform: diceTraySize === "single" ? "rotate(0)" : "rotate(180deg)",
}}
onClick={() =>
onDiceTraySizeChange(diceTraySize === "single" ? "double" : "single")
}
>
<ExpandMoreDiceTrayIcon />
</IconButton>
</Flex>
);
}
+4
View File
@@ -10,6 +10,8 @@ function DiceControls({
onDiceAdd,
onDiceClear,
onDiceReroll,
diceTraySize,
onDiceTraySizeChange,
}) {
const [diceRolls, setDiceRolls] = useState([]);
@@ -114,6 +116,8 @@ function DiceControls({
{ type, roll: "unknown" },
]);
}}
onDiceTraySizeChange={onDiceTraySizeChange}
diceTraySize={diceTraySize}
/>
</div>
</>
+1 -1
View File
@@ -74,7 +74,7 @@ function DiceScene({ onSceneMount, onPointerDown, onPointerUp }) {
const scene = sceneRef.current;
if (scene) {
const pickInfo = scene.pick(scene.pointerX, scene.pointerY);
if (pickInfo.hit && pickInfo.pickedMesh.id !== "tray") {
if (pickInfo.hit && pickInfo.pickedMesh.name !== "dice_tray") {
pickInfo.pickedMesh.physicsImpostor.setLinearVelocity(
BABYLON.Vector3.Zero()
);
@@ -1,4 +1,10 @@
import React, { useRef, useCallback, useEffect, useContext } from "react";
import React, {
useRef,
useCallback,
useEffect,
useContext,
useState,
} from "react";
import * as BABYLON from "babylonjs";
import { Box } from "theme-ui";
@@ -8,13 +14,11 @@ import Scene from "./DiceScene";
import DiceControls from "./DiceControls";
import Dice from "../../../dice/Dice";
import createDiceTray, {
diceTraySize,
} from "../../../dice/diceTray/DiceTrayMesh";
import DiceTray from "../../../dice/diceTray/DiceTray";
import MapInteractionContext from "../../../contexts/MapInteractionContext";
function DiceTray({ isOpen }) {
function DiceTrayOverlay({ isOpen }) {
const sceneRef = useRef();
const shadowGeneratorRef = useRef();
const diceRefs = useRef([]);
@@ -22,6 +26,26 @@ function DiceTray({ isOpen }) {
const sceneInteractionRef = useRef(false);
// Set to true to ignore scene sleep and visible values
const forceSceneRenderRef = useRef(false);
const diceTrayRef = useRef();
const [diceTraySize, setDiceTraySize] = useState("single");
useEffect(() => {
const diceTray = diceTrayRef.current;
let resizeTimout;
if (diceTray) {
diceTray.size = diceTraySize;
// Force rerender
forceSceneRenderRef.current = true;
resizeTimout = setTimeout(() => {
forceSceneRenderRef.current = false;
}, 1000);
}
return () => {
if (resizeTimout) {
clearTimeout(resizeTimout);
}
};
}, [diceTraySize]);
useEffect(() => {
let openTimeout;
@@ -49,7 +73,7 @@ function DiceTray({ isOpen }) {
}, []);
async function initializeScene(scene) {
var light = new BABYLON.DirectionalLight(
let light = new BABYLON.DirectionalLight(
"DirectionalLight",
new BABYLON.Vector3(-0.5, -1, -0.5),
scene
@@ -62,7 +86,7 @@ function DiceTray({ isOpen }) {
shadowGenerator.darkness = 0.7;
shadowGeneratorRef.current = shadowGenerator;
var ground = BABYLON.Mesh.CreateGround("ground", 100, 100, 2, scene);
let ground = BABYLON.Mesh.CreateGround("ground", 100, 100, 2, scene);
ground.physicsImpostor = new BABYLON.PhysicsImpostor(
ground,
BABYLON.PhysicsImpostor.BoxImpostor,
@@ -72,36 +96,7 @@ function DiceTray({ isOpen }) {
ground.isVisible = false;
ground.position.y = 0.2;
const wallSize = 50;
function createWall(name, x, z, yaw) {
let wall = BABYLON.Mesh.CreateBox(
name,
wallSize,
scene,
true,
BABYLON.Mesh.DOUBLESIDE
);
wall.rotation = new BABYLON.Vector3(0, yaw, 0);
wall.position.z = z;
wall.position.x = x;
wall.physicsImpostor = new BABYLON.PhysicsImpostor(
wall,
BABYLON.PhysicsImpostor.BoxImpostor,
{ mass: 0, friction: 10.0 },
scene
);
wall.isVisible = false;
}
const wallOffsetWidth = wallSize / 2 + diceTraySize.width / 2 - 0.5;
const wallOffsetHeight = wallSize / 2 + diceTraySize.height / 2 - 0.5;
createWall("wallTop", 0, -wallOffsetHeight, 0);
createWall("wallRight", -wallOffsetWidth, 0, Math.PI / 2);
createWall("wallBottom", 0, wallOffsetHeight, Math.PI);
createWall("wallLeft", wallOffsetWidth, 0, -Math.PI / 2);
var roof = BABYLON.Mesh.CreateGround("roof", 100, 100, 2, scene);
let roof = BABYLON.Mesh.CreateGround("roof", 100, 100, 2, scene);
roof.physicsImpostor = new BABYLON.PhysicsImpostor(
roof,
BABYLON.PhysicsImpostor.BoxImpostor,
@@ -117,7 +112,9 @@ function DiceTray({ isOpen }) {
);
scene.environmentIntensity = 1.0;
createDiceTray(scene, shadowGenerator);
let diceTray = new DiceTray("single", scene, shadowGenerator);
await diceTray.load();
diceTrayRef.current = diceTray;
}
function update(scene) {
@@ -222,9 +219,12 @@ function DiceTray({ isOpen }) {
return (
<Box
sx={{
width: "500px",
maxWidth: "calc(50vh - 48px)",
paddingBottom: "200%",
width: diceTraySize === "single" ? "500px" : "1000px",
maxWidth:
diceTraySize === "single"
? "calc(50vh - 48px)"
: "calc(100vh - 48px)",
paddingBottom: diceTraySize === "single" ? "200%" : "100%",
borderRadius: "4px",
display: isOpen ? "block" : "none",
position: "relative",
@@ -249,9 +249,11 @@ function DiceTray({ isOpen }) {
onDiceAdd={handleDiceAdd}
onDiceClear={handleDiceClear}
onDiceReroll={handleDiceReroll}
diceTraySize={diceTraySize}
onDiceTraySizeChange={setDiceTraySize}
/>
</Box>
);
}
export default DiceTray;
export default DiceTrayOverlay;
+6 -1
View File
@@ -26,7 +26,12 @@ function SelectDiceButton({ onDiceChange, currentDice }) {
return (
<>
<IconButton color="hsl(210, 50%, 96%)" onClick={openModal}>
<IconButton
aria-label="Select Dice Style"
title="Select Dice Style"
color="hsl(210, 50%, 96%)"
onClick={openModal}
>
<SelectDiceIcon />
</IconButton>
<SelectDiceModal