Initial commit
continuous-integration/drone Build is passing

This commit is contained in:
2022-04-06 10:46:44 +02:00
commit 2fd4e104b8
18 changed files with 1553 additions and 0 deletions
+106
View File
@@ -0,0 +1,106 @@
<script lang="ts">
import Card from './Card.svelte';
import CardInput from './CardInput.svelte';
import LZString from 'lz-string';
const MAX_CARDS = 9;
let cards = [];
let mhp = {
name: "Minor healing potion",
type: "Item 1",
tags: ["Consumable", "Healing", "Magical", "Necromancy", "Positive", "Potion"],
attributes: `<p><b>Usage</b> Held in 1 hand; <b>Bulk</b> L</p>
<p><b>Activate (A)</b> Interact</p>`,
description: `<p>A healing potion is a vial of a ruby-red liquid that imparts a tingling sensation as the drinkers wounds heal rapidly. When you drink a healing potion, you regain 2d8+5 Hit Points.</p>`
};
if (window.location.hash !== "") {
debugger;
cards = JSON.parse(LZString.decompressFromEncodedURIComponent(window.location.hash.substring(1)));
} else {
cards = [{id: 0, ...mhp}];
}
function get_idx_by_id(id) {
for(let idx = 0; idx < cards.length; idx++) {
if(id === cards[idx].id) {
return idx
}
}
}
//let card_selected = 0;
//$: selected_card = cards[card_selected];
let selector = cards[0].id;
//$: selector = cards[card_selected].id;
$: selected_card = cards.filter(x => x.id === selector)[0];
$: selected_idx = get_idx_by_id(selector);
$: window.location.hash = LZString.compressToEncodedURIComponent(JSON.stringify(cards));
function change_tags(e) {
selected_card.tags = e.detail.tags.split(',').map(x => x.replace(/\s+/g, '')).filter(x => x != '');
cards[selected_idx] = selected_card;
}
function add_card() {
if (cards.length < MAX_CARDS) {
cards = [...cards, {id: cards[cards.length-1].id+1, ...mhp}];
selector = cards[cards.length-1].id;
}
}
function remove_card() {
console.log(cards);
console.log(selected_idx);
if (cards.length > 1) { // remove only if there is more than 1 card
cards = cards.filter(x => x.id != selector);
if (selected_idx >= cards.length) {
selector = cards[cards.length-1].id;
} else {
selector = cards[selected_idx].id;
}
}
}
</script>
<main>
<section class="controls">
<h1>PF2e card generator</h1>
<CardInput bind:name={selected_card.name} bind:type={selected_card.type} tags={selected_card.tags} bind:attributes={selected_card.attributes} bind:description={selected_card.description} on:change_tags={change_tags} on:add_card={add_card} on:remove_card={remove_card}/>
</section>
<section class="cards">
{#each cards as card, idx (card.id)}
<div class="card">
<Card {...card}/>
<input class="card-selector" type="radio" bind:group={selector} value={card.id}/>
</div>
{/each}
</section>
</main>
<style>
@media print {
@page {
margin: 0;
}
.controls {
display: none;
}
.card-selector {
display: none;
}
}
.cards {
display: flex;
flex-wrap: wrap;
}
h1 {
text-transform: uppercase;
font-size: 4em;
font-weight: 100;
}
</style>
+75
View File
@@ -0,0 +1,75 @@
<script lang="ts">
import DOMPurify from 'dompurify';
export let name:string, type, tags = [], attributes:string, description:string;
</script>
<style>
.card {
width: 2.5in;
height: 3.5in;
font-size: 8pt;
border: 2mm solid black;
/*background-image: url("/bg.webp");*/
background-clip: border-box;
page-break-after: auto;
page-break-inside: avoid;
}
.header {
display: flex;
justify-content: space-between;
border-bottom: 2px solid black;
}
.name, .type {
font-family: serif;
font-size: 10pt;
font-weight: bold;
}
.tags {
margin: 1pt 1pt 0pt 1pt;
padding: 0;
display: flex;
flex-wrap: wrap;
}
.tag {
font-family: sans-serif;
font-size: 6pt;
font-variant: all-small-caps;
color: white;
background-color: #5e0000;
padding: 0.5pt 1pt;
border: 1pt solid #d9c484;
}
.content {
margin: 1pt;
}
:global(section.content p) {
padding-bottom: 2pt;
margin: 0;
}
.description {
border-top: 1pt solid black;
text-align: justify;
}
</style>
<div class="card">
<section class="header">
<div class="name">{name}</div>
<div class="type">{type}</div>
</section>
<section class="tags">
{#each tags as tag}
<div class="tag">{tag}</div>
{/each}
</section>
<section class="content">
<p class="attributes">
{@html DOMPurify.sanitize(attributes)}
</p>
<p class="description">
{@html DOMPurify.sanitize(description)}
</p>
</section>
</div>
+35
View File
@@ -0,0 +1,35 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
export let name, type, tags, attributes, description;
const dispatch = createEventDispatcher();
function change_tags(e) {
dispatch("change_tags", {tags: e.target.value});
}
</script>
<style>
div.cardInput {
width: 5in;
display: flex;
flex-direction: column;
}
</style>
<div class="cardInput">
<div class="row">Name: <input name="name" bind:value={name}/></div>
<div class="row">Type: <input name="type" bind:value={type}/></div>
<div class="row">Tags: <input name="tags" on:change={change_tags} value={tags}/></div>
<div class="row">Attributes:
<textarea bind:value={attributes}></textarea>
</div>
<div class="row">Description:
<textarea bind:value={description}></textarea>
</div>
<div class="row">
<button on:click={e => dispatch('add_card')}>+</button>
<button on:click={e => dispatch('remove_card')}>-</button>
</div>
</div>
+1
View File
@@ -0,0 +1 @@
/// <reference types="svelte" />
+7
View File
@@ -0,0 +1,7 @@
import App from './App.svelte';
const app = new App({
target: document.body,
});
export default app;