Skip to content

Commit

Permalink
feat: adds columns and columnWidth properties (closes #34)
Browse files Browse the repository at this point in the history
  • Loading branch information
valentine195 committed Jan 20, 2022
1 parent dac68bc commit 7c37d17
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 33 deletions.
4 changes: 4 additions & 0 deletions @types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export interface Monster {
render?: boolean;
layout?: string;
statblock?: string;
columns?: number;
columnWidth?: number;
columnHeight?: number;
forceColumns?: boolean;
[property: string]: any;
}

Expand Down
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@ Traits, such as Actions, Reactions and Legendary Actions, should be added as a Y

```md
traits:
- [Amphibious, The dragon can breathe air and water.]
- ...

- [Amphibious, The dragon can breathe air and water.]
- ...
```

### Spellcasting
Expand Down Expand Up @@ -186,6 +187,27 @@ legendary_actions:
```
````

### Columns

The plugin will intelligently create two columns if the stat block it is rendering is long and there is enough space for the second column.

<img src="https://raw.githubusercontent.com/valentine195/obsidian-5e-statblocks/beta/images/columns.PNG">

You can customize the behavior of the columns with a few different parameters:

| Parameter | Behavior | Default |
| -------------- | ------------------------------------------------------------------ | :-----: |
| `columns` | Customize the number of columns that will be rendered. | |
| `columnWidth` | Customize the width of the columns in **pixels**. | 400 |
| `columnHeight` | Maximum height of a column before wrapping in **pixels**. | 600 |
| `forceColumns` | The plugin will create the columns regardless of note page sizing. | false |

> **:pencil: Note!**
>
> If you set `columns`, the plugin will _always_ try to split the statblock into that many columns, regardless of height.
>
> It will still respect the width of the note, unless `forceColumns` is set.
# Customizing the CSS

The statblocks generated can be customized using [CSS snippets](https://help.obsidian.md/How+to/Add+custom+styles#Use+Themes+and+or+CSS+snippets).
Expand Down Expand Up @@ -219,7 +241,7 @@ The plugin creates and uses 4 CSS variables to determine the color of the statbl
}
```

These can be overridden globally (on the `:root` element) to change the default color *globally*, or to the statblock containers themselves to [target specific statblocks](#targeting-a-statblock).
These can be overridden globally (on the `:root` element) to change the default color _globally_, or to the statblock containers themselves to [target specific statblocks](#targeting-a-statblock).

# Layouts

Expand Down
Binary file added images/columns.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 0 additions & 5 deletions src/importers/TetraCubeImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,6 @@ class TetraMonster {
(monster.hitDice && /(\d+) \((.+)\)/.test(monster.hpText))
) {
const [_, hp, dice] = monster.hpText.match(/(\d+) \((.+)\)/) ?? [];
console.log(
"🚀 ~ file: TetraCubeImport.ts ~ line 284 ~ hp, dice",
hp,
dice
);
return { hp, dice };
}
if (monster.hitDice) {
Expand Down
41 changes: 35 additions & 6 deletions src/view/Statblock.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@
export let layout: string;
export let icons: boolean = true;
let maxColumns =
!isNaN(Number(monster.columns)) && Number(monster.columns) > 0
? Number(monster.columns)
: 2;
$: monsterColumnWidth = Number(`${monster.columnWidth}`.replace(/\D/g, ""));
$: columnWidth =
!isNaN(monsterColumnWidth) && monsterColumnWidth > 0
? monsterColumnWidth
: 400;
let canExport = monster.export ?? plugin.settings.export;
let canDice =
plugin.canUseDiceRoller && (monster.dice ?? plugin.settings.useDice);
Expand All @@ -45,12 +56,24 @@
setContext<Writable<boolean>>("reset", reset);
let container: HTMLElement;
let columns: number = 1;
let columns: number = maxColumns;
let ready = false;
const setColumns = () => {
if (monster.forceColumns) {
columns = maxColumns;
observer.disconnect();
return;
}
const width = container.clientWidth;
columns = Math.min(
Math.max(Math.floor(width / columnWidth), 1),
maxColumns
);
};
const onResize = debounce(
() => {
const width = container.clientWidth;
columns = Math.min(Math.max(Math.floor(width / 400), 1), 2);
setColumns();
if (!ready) ready = true;
},
100,
Expand All @@ -59,8 +82,7 @@
const observer = new ResizeObserver(onResize);
onMount(() => {
const width = container.clientWidth;
columns = Math.max(Math.min(Math.floor(width / 400), 2), 1);
setColumns();
observer.observe(container);
});
Expand Down Expand Up @@ -122,7 +144,14 @@
{#if monster}
<Bar />
{#key columns}
<Content {columns} {statblock} {ready} on:save on:export />
<Content
{columns}
{maxColumns}
{statblock}
{ready}
on:save
on:export
/>
{/key}
<Bar />
{:else}
Expand Down
7 changes: 1 addition & 6 deletions src/view/statblock.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { MarkdownRenderChild } from "obsidian";
import {
Layout,
Layout5e,
Statblock5e,
StatblockItem
} from "../data/constants";
import { Layout, Layout5e } from "../data/constants";
import type { Monster } from "@types";

import Statblock from "./Statblock.svelte";
Expand Down
70 changes: 57 additions & 13 deletions src/view/ui/Content.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
export let statblock: StatblockItem[];
export let columns: number = 1;
export let ready: boolean;
export let maxColumns: number = columns;
const monster = getContext<Monster>("monster");
const checkConditioned = (item: StatblockItem) => {
Expand Down Expand Up @@ -68,7 +70,8 @@
switch (item.type) {
case "group": {
for (const nested of item.nested ?? []) {
targets.push(...getElementForStatblockItem(nested, target));
const element = getElementForStatblockItem(nested, target);
targets.push(...element);
}
break;
}
Expand Down Expand Up @@ -216,32 +219,58 @@
}
return targets;
};
$: maxHeight =
!isNaN(Number(monster.columnHeight)) && monster.columnHeight > 0
? monster.columnHeight
: 600;
const buildStatblock = (node: HTMLElement) => {
node.empty();
let columnEl = node.createDiv("column");
const targets: HTMLElement[] = [];
for (let item of statblock) {
targets.push(...getElementForStatblockItem(item));
}
const temp = document.body.createDiv("statblock-detached");
targets.forEach((b) => {
temp.appendChild(b.cloneNode(true));
}, 0);
const splitHeight = Math.min(Math.max(temp.clientHeight / 2, 600), 600);
temp.detach();
let columnEl = node.createDiv("column");
if (columns == 1) {
targets.forEach((el) => columnEl.appendChild(el));
return;
}
const temp = document.body.createDiv("statblock-detached");
for (let target of targets) {
temp.appendChild(target);
}
temp.style.width = columnWidth;
let split: number;
if (monster.forceColumns) {
split = temp.clientHeight / maxColumns;
console.log(
"🚀 ~ file: Content.svelte ~ line 250 ~ maxColumns",
maxColumns,
split
);
} else if (monster.columns && monster.columns > 0) {
split = Math.max(
temp.clientHeight / monster.columns,
temp.clientHeight / columns
);
} else {
split = Math.min(
Math.max(temp.clientHeight / columns, maxHeight),
maxHeight
);
}
temp.empty();
temp.detach();
for (let target of targets) {
columnEl.appendChild(target);
if (
columnEl.clientHeight > splitHeight &&
columnEl.clientHeight > split &&
node.childElementCount != columns
) {
target.detach();
Expand All @@ -263,9 +292,24 @@
buildStatblock(content);
}
}
let columnWidth = "400px";
if (monster.columnWidth) {
if (typeof monster.columnWidth == "number") {
columnWidth = `${monster.columnWidth}px`;
}
if (typeof monster.columnWidth == "string") {
columnWidth = monster.columnWidth;
}
}
</script>

<div class="statblock-content" bind:this={content} />
<div
class="statblock-content-container"
style="--statblock-column-width: {columnWidth};"
>
<div class="statblock-content" bind:this={content} />
</div>

<style>
.statblock-content {
Expand All @@ -283,7 +327,7 @@
gap: 1rem;
}
.statblock-content > :global(.column) {
width: 400px;
width: var(--statblock-column-width);
}
@media screen and (max-width: 400px) {
Expand Down

0 comments on commit 7c37d17

Please sign in to comment.