Show mandala thumbnails.
rodzic
2c8f517d8a
commit
0def79264c
|
@ -13,6 +13,11 @@ import { CreatureDesign } from "./creature-page/core";
|
||||||
import { deserializeCreatureDesign } from "./creature-page/serialization";
|
import { deserializeCreatureDesign } from "./creature-page/serialization";
|
||||||
|
|
||||||
import "./gallery-page.css";
|
import "./gallery-page.css";
|
||||||
|
import {
|
||||||
|
createMandalaAnimationRenderer,
|
||||||
|
MandalaDesign,
|
||||||
|
} from "./mandala-page/core";
|
||||||
|
import { deserializeMandalaDesign } from "./mandala-page/serialization";
|
||||||
|
|
||||||
function compositionRemixUrl(comp: GalleryComposition): string {
|
function compositionRemixUrl(comp: GalleryComposition): string {
|
||||||
return (
|
return (
|
||||||
|
@ -23,6 +28,8 @@ function compositionRemixUrl(comp: GalleryComposition): string {
|
||||||
|
|
||||||
const THUMBNAIL_CLASS = "gallery-thumbnail canvas";
|
const THUMBNAIL_CLASS = "gallery-thumbnail canvas";
|
||||||
|
|
||||||
|
const THUMBNAIL_SCALE = 0.2;
|
||||||
|
|
||||||
const EmptyThumbnail: React.FC = () => (
|
const EmptyThumbnail: React.FC = () => (
|
||||||
<div className={THUMBNAIL_CLASS + " is-empty"}></div>
|
<div className={THUMBNAIL_CLASS + " is-empty"}></div>
|
||||||
);
|
);
|
||||||
|
@ -39,7 +46,7 @@ const CreatureThumbnail: React.FC<{ design: CreatureDesign }> = (props) => {
|
||||||
<div className={THUMBNAIL_CLASS} style={{ backgroundColor: background }}>
|
<div className={THUMBNAIL_CLASS} style={{ backgroundColor: background }}>
|
||||||
<CreatureContext.Provider value={ctx}>
|
<CreatureContext.Provider value={ctx}>
|
||||||
<AutoSizingSvg padding={10} ref={svgRef} bgColor={background}>
|
<AutoSizingSvg padding={10} ref={svgRef} bgColor={background}>
|
||||||
<SvgTransform transform={svgScale(0.2)}>
|
<SvgTransform transform={svgScale(THUMBNAIL_SCALE)}>
|
||||||
<CreatureSymbol {...props.design.creature} />
|
<CreatureSymbol {...props.design.creature} />
|
||||||
</SvgTransform>
|
</SvgTransform>
|
||||||
</AutoSizingSvg>
|
</AutoSizingSvg>
|
||||||
|
@ -48,6 +55,29 @@ const CreatureThumbnail: React.FC<{ design: CreatureDesign }> = (props) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MandalaThumbnail: React.FC<{ design: MandalaDesign }> = (props) => {
|
||||||
|
const render = createMandalaAnimationRenderer(props.design, THUMBNAIL_SCALE);
|
||||||
|
const { background } = props.design.baseCompCtx;
|
||||||
|
const svgRef = useRef<SVGSVGElement>(null);
|
||||||
|
const canvasRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={THUMBNAIL_CLASS}
|
||||||
|
style={{ backgroundColor: background }}
|
||||||
|
ref={canvasRef}
|
||||||
|
>
|
||||||
|
<AutoSizingSvg
|
||||||
|
ref={svgRef}
|
||||||
|
bgColor={background}
|
||||||
|
sizeToElement={canvasRef}
|
||||||
|
>
|
||||||
|
{render(0)}
|
||||||
|
</AutoSizingSvg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
function getThumbnail(gc: GalleryComposition): JSX.Element {
|
function getThumbnail(gc: GalleryComposition): JSX.Element {
|
||||||
if (gc.kind === "creature") {
|
if (gc.kind === "creature") {
|
||||||
let design: CreatureDesign;
|
let design: CreatureDesign;
|
||||||
|
@ -59,6 +89,16 @@ function getThumbnail(gc: GalleryComposition): JSX.Element {
|
||||||
}
|
}
|
||||||
return <CreatureThumbnail design={design} />;
|
return <CreatureThumbnail design={design} />;
|
||||||
}
|
}
|
||||||
|
if (gc.kind === "mandala") {
|
||||||
|
let design: MandalaDesign;
|
||||||
|
try {
|
||||||
|
design = deserializeMandalaDesign(gc.serializedValue);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(`Could not deserialize creature "${gc.title}"`, e);
|
||||||
|
return <EmptyThumbnail />;
|
||||||
|
}
|
||||||
|
return <MandalaThumbnail design={design} />;
|
||||||
|
}
|
||||||
return <EmptyThumbnail />;
|
return <EmptyThumbnail />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,14 +226,17 @@ function isDesignAnimated(design: MandalaDesign): boolean {
|
||||||
return getCirclesFromDesign(design).some((c) => c.animateSymbolRotation);
|
return getCirclesFromDesign(design).some((c) => c.animateSymbolRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAnimationRenderer({
|
export function createMandalaAnimationRenderer(
|
||||||
|
{
|
||||||
baseCompCtx,
|
baseCompCtx,
|
||||||
invertCircle2,
|
invertCircle2,
|
||||||
circle1,
|
circle1,
|
||||||
circle2,
|
circle2,
|
||||||
useTwoCircles,
|
useTwoCircles,
|
||||||
firstBehind,
|
firstBehind,
|
||||||
}: MandalaDesign): AnimationRenderer {
|
}: MandalaDesign,
|
||||||
|
scale = 0.5
|
||||||
|
): AnimationRenderer {
|
||||||
const symbolCtx = noFillIfShowingSpecs(baseCompCtx);
|
const symbolCtx = noFillIfShowingSpecs(baseCompCtx);
|
||||||
const circle2SymbolCtx = invertCircle2 ? swapColors(symbolCtx) : symbolCtx;
|
const circle2SymbolCtx = invertCircle2 ? swapColors(symbolCtx) : symbolCtx;
|
||||||
|
|
||||||
|
@ -259,7 +262,7 @@ function createAnimationRenderer({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <SvgTransform transform={svgScale(0.5)}>{circles}</SvgTransform>;
|
return <SvgTransform transform={svgScale(scale)}>{circles}</SvgTransform>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +339,10 @@ export const MandalaPageWithDefaults: React.FC<{
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
const isAnimated = isDesignAnimated(design);
|
const isAnimated = isDesignAnimated(design);
|
||||||
const render = useMemo(() => createAnimationRenderer(design), [design]);
|
const render = useMemo(
|
||||||
|
() => createMandalaAnimationRenderer(design),
|
||||||
|
[design]
|
||||||
|
);
|
||||||
|
|
||||||
useDebouncedEffect(
|
useDebouncedEffect(
|
||||||
250,
|
250,
|
||||||
|
|
Ładowanie…
Reference in New Issue