123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- import React from "react";
- import { memo } from "react";
- import styled, { css } from "styled-components";
- import { useItemInteraction } from "react-sync-board";
- import { opacify } from "color2k";
- import { isItemInsideElement, getItemElement } from "../utils";
- import useGameItemActions from "./useGameItemActions";
- const ZoneWrapper = styled.div`
- ${({
- width = 200,
- height = 200,
- borderColor = "#cccccc33",
- borderStyle = "dotted",
- backgroundColor = "transparent",
- }) => css`
- width: ${width}px;
- height: ${height}px;
- border: 0.5em ${borderStyle} ${borderColor};
- background-color: ${backgroundColor};
- border-radius: 5px;
- position: relative;
- & .zone__label {
- font-size: 1.5em;
- user-select: none;
- background-color: ${opacify(borderColor, 1)};
- position: absolute;
- border-radius: 0.5em;
- color: var(--color-darkGrey);
- }
- & .zone__label.left {
- padding: 1em 0em;
- top: 1em;
- left: -1em;
- letter-spacing: -3px;
- writing-mode: vertical-rl;
- text-orientation: upright;
- }
- & .zone__label.top {
- padding: 0em 1em;
- top: -1em;
- left: 1em;
- }
- `}
- `;
- const Zone = ({
- width,
- height,
- label,
- onItem,
- borderColor,
- borderStyle,
- backgroundColor,
- labelPosition = "left",
- }) => {
- const { register } = useItemInteraction("place");
- const zoneRef = React.useRef(null);
- const { actionMap } = useGameItemActions();
- const onInsideItem = React.useCallback(
- (itemIds) => {
- const insideItems = itemIds.filter((itemId) =>
- isItemInsideElement(getItemElement(itemId), zoneRef.current)
- );
- if (!insideItems.length) return;
- const onItemActions = onItem.map((action) => {
- if (typeof action === "string") {
- return { name: action };
- }
- return action;
- });
- onItemActions.forEach(({ name, args }) => {
- switch (name) {
- case "reveal":
- actionMap["reveal"].action(args)(insideItems);
- break;
- case "hide":
- actionMap["hide"].action(args)(insideItems);
- break;
- case "revealSelf":
- actionMap["revealSelf"].action(args)(insideItems);
- break;
- case "hideSelf":
- actionMap["hideSelf"].action(args)(insideItems);
- break;
- case "stack":
- actionMap["stack"].action(args)(insideItems);
- break;
- }
- });
- },
- [actionMap, onItem]
- );
- React.useEffect(() => {
- const unregisterList = [];
- if (onItem?.length) {
- unregisterList.push(register(onInsideItem));
- }
- return () => {
- unregisterList.forEach((callback) => callback());
- };
- }, [onInsideItem, onItem, register]);
- return (
- <ZoneWrapper
- width={width}
- height={height}
- ref={zoneRef}
- borderStyle={borderStyle}
- borderColor={borderColor}
- backgroundColor={backgroundColor}
- >
- <div className={`zone__label ${labelPosition}`}>{label}</div>
- </ZoneWrapper>
- );
- };
- export default memo(Zone);
|