From 994b9b5ebbd8ca06c65079f389bee7749f20c71d Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 25 Apr 2021 17:10:32 +1000 Subject: [PATCH] Added circle and rect outline options and optimised storage structure --- src/components/map/MapToken.js | 52 +++++++++++++++++++++------------ src/database.js | 38 +++--------------------- src/modals/SelectTokensModal.js | 9 +++--- src/tokens/index.js | 11 +------ 4 files changed, 43 insertions(+), 67 deletions(-) diff --git a/src/components/map/MapToken.js b/src/components/map/MapToken.js index c2f0ebb..e30b36c 100644 --- a/src/components/map/MapToken.js +++ b/src/components/map/MapToken.js @@ -1,5 +1,5 @@ import React, { useState, useEffect, useRef } from "react"; -import { Image as KonvaImage, Group, Line } from "react-konva"; +import { Image as KonvaImage, Group, Line, Rect, Circle } from "react-konva"; import { useSpring, animated } from "react-spring/konva"; import useImage from "use-image"; import Konva from "konva"; @@ -246,6 +246,37 @@ function MapToken({ tokenName = tokenName + "-locked"; } + let outline = tokenState.outline; + if (Array.isArray(tokenState.outline)) { + outline = [...outline]; // Copy array so we can edit it imutably + for (let i = 0; i < outline.length; i += 2) { + // Scale outline to the token + outline[i] = (outline[i] / tokenState.width) * tokenWidth; + outline[i + 1] = (outline[i + 1] / tokenState.height) * tokenHeight; + } + } + + function renderOutline() { + const sharedProps = { + fill: colors.black, + width: tokenWidth, + height: tokenHeight, + x: 0, + y: 0, + rotation: tokenState.rotation, + offsetX: tokenWidth / 2, + offsetY: tokenHeight / 2, + opacity: 0.8, + }; + if (outline === "rect") { + return ; + } else if (outline === "circle") { + return ; + } else { + return ; + } + } + return ( {!tokenImage ? ( - - [x * tokenWidth, y * tokenHeight]) - .flat(1)} - fill={colors.black} - width={tokenWidth} - height={tokenHeight} - x={0} - y={0} - rotation={tokenState.rotation} - offsetX={tokenWidth / 2} - offsetY={tokenHeight / 2} - closed - // Round edges for more complex shapes - tension={tokenState.outline.length > 6 ? 0.333 : 0} - /> - + renderOutline() ) : ( ({ - x: x / image.width, - y: y / image.height, - })); + let outline = imageOutline(image); if (outline.length > 100) { outline = Vector2.resample(outline, 100); } + // Flatten and round outline to save on storage size + outline = outline + .map(({ x, y }) => [Math.round(x), Math.round(y)]) + .flat(); const token = { name, diff --git a/src/tokens/index.js b/src/tokens/index.js index f4174e4..07f5108 100644 --- a/src/tokens/index.js +++ b/src/tokens/index.js @@ -90,16 +90,7 @@ export const tokens = Object.keys(tokenSources).map((key) => ({ hideInSidebar: false, width: 256, height: 256, - outline: [ - { x: 0.5, y: 0.0 }, - { x: 0.85, y: 0.15 }, - { x: 1.0, y: 0.5 }, - { x: 0.85, y: 0.85 }, - { x: 0.5, y: 1.0 }, - { x: 0.15, y: 0.85 }, - { x: 0.0, y: 0.5 }, - { x: 0.15, y: 0.15 }, - ], + outline: "circle", })); export const unknownSource = unknown;