commission picker

main^2
Midnight 2 years ago
parent 65c972d551
commit 475aa899b7

1298
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -27,6 +27,7 @@
"svelte-check": "^2.2.6",
"svelte-preprocess": "^4.9.4",
"tailwindcss": "^3.0.18",
"tailwindcss-text-fill-stroke": "^1.1.2",
"tslib": "^2.3.1",
"typescript": "^4.4.3"
},

@ -23,6 +23,9 @@
}
hr {
border-color: rgb(255, 255, 255, 0.3);
border-width: 1px;
background-color: rgb(255, 255, 255, 0.3);
height: 3px;
border: unset;
width: 100%;
margin: 0.5em 0;
}

@ -0,0 +1,228 @@
<script lang="ts">
import Button from "$lib/header/Button.svelte";
import { onMount } from "svelte";
import words from "$lib/en-lang.json";
import { base } from "$app/paths";
let lang = words["calculator"];
let types = lang["types"];
interface Commission {
type: string,
name: string,
price: number,
example: string,
questions?: any[],
answers?: any[],
}
let commissions: Commission[] = [];
let number: number;
$: number = commissions.length + 1;
function setup() {
const urlParams = new URLSearchParams(window.location.search);
urlParams.forEach((value, key) => {
if(key == "commissions") {
commissions = JSON.parse(value);
}
});
if(commissions.length == 0) base();
}
function update_example(commission: Commission) {
let lastQuestion = commission.questions[commission.questions.length - 1];
let lastAnswer = commission.answers[commission.answers.length - 1];
let example = "";
commission.example = "";
let type = types.filter(value => {
return value['name'] == commission.type;
});
type = type[0];
let count = 0;
commission.questions.forEach(value => {
if(type['examples_from'] == value['name']) {
lastQuestion = commission.questions[count];
lastAnswer = commission.answers[count];
}
count++;
})
lastQuestion.options.forEach(value => {
if(value['name'] == lastAnswer['option']) {
example = value['example'];
}
});
console.log(example);
type['examples'].forEach(value => {
if(value['name'] == example) {
commission.example = value['url'];
}
});
}
function base() {
let commission = {
"type": types[0]["name"],
"name": "Commission " + number,
"example": types[0]["example"],
"price": 10,
};
update_commission_type(commission);
update_example(commission);
update_price(commission);
commissions.push(commission);
commissions = commissions;
}
function save() {
const urlParams = new URLSearchParams(window.location.search);
urlParams.set("commissions", JSON.stringify(commissions));
let url = window.location.origin + window.location.pathname + "?" + urlParams.toString();
navigator.clipboard.writeText(url);
window.history.replaceState( {} , document.title, url);
}
function update_commission_type(commission: Commission) {
types.forEach(element => {
if(element["name"] == commission.type) {
commission.questions = element["questions"];
}
});
commission.answers = [];
commission.questions.forEach(value => {
commission.answers.push({'name': value.name, 'option': value.options[0]['name']});
});
update_price(commission);
update_example(commission);
console.log(commission.answers);
}
function update_price(commission: Commission) {
commission.price = 0;
for (let index = 0; index < commission.questions.length; index++) {
const question = commission.questions[index];
const answer = commission.answers[index];
question['options'].forEach(value => {
if(value['name'] == answer['option']) {
commission.price += value['price'];
}
});
}
}
async function load() {
window.location.href = await navigator.clipboard.readText();
}
function createNew() {
base();
save();
}
function remove(name: string) {
commissions = commissions.filter(value => {
return value.name != name;
});
save();
}
onMount(() => {
setup();
});
</script>
<main class="container flex flex-col gap-5">
<section class="container bg-slate-800 rounded-lg shadow-lg p-3 flex flex-col w-full gap-5">
<nav class="flex flex-col lg:flex-row gap-3 justify-between justify-items-stretch items-center">
<Button href="/">⬅️ Back to home</Button>
<Button href="/commissions">🎨 Visit commissions page</Button>
<Button href="/commissions/tos">⚖️ Read Terms of Service</Button>
</nav>
</section>
<section class="container bg-slate-800 rounded-lg shadow-lg p-5 flex flex-col w-full gap-10">
<div class="flex justify-between -ml-2 -mr-2">
<div class="w-full flex gap-3">
<span><Button on:click={createNew}> Add Commission</Button></span>
</div>
<div class="w-full flex justify-end gap-3">
<span><Button on:click={save}>💾 Save to Clipboard</Button></span>
<span><Button on:click={load}> Load from Clipboard</Button></span>
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center gap-5">
<h3 class="text-6xl">🧮</h3>
<div class="flex flex-col gap-2">
<div class="flex gap-3">
<h4 class="text-xl font-bold">Total</h4>
<p class="bg-green-500 py-1 text-sm px-5 rounded-lg">$20</p>
</div>
<p class="italic text-gray-200 text-sm">This figure is an estimate, the final price may differ.<br/>All commissions are strictly SFW only.</p>
</div>
</div>
</div>
</section>
{#each [...commissions].reverse() as commission}
<section class="flex gap-5">
<div class="w-3/5 bg-slate-800 rounded-lg shadow-lg p-5 flex flex-col gap-5">
<div class="flex justify-between">
<h3 class="text-xl font-bold flex gap-5">{commission.name}<p class="bg-green-500 py-1 text-sm px-5 rounded-lg">${commission.price}</p></h3>
<span>
<Button on:click={() => {remove(commission.name)}}>🗑️</Button>
</span>
</div>
<form class="flex flex-col gap-10" on:change={() => {update_example(commission)}}>
<div class="flex flex-col gap-1">
<label for={commission.type}>Type of commission</label>
<select class="bg-slate-600 p-2 rounded-lg" bind:value={commission.type} on:change={() => {update_commission_type(commission)}}>
{#each types as question}
<option value={question.name}>{question.name}</option>
{/each}
</select>
</div>
{#each commission.questions as question, key}
<div class="flex flex-col gap-1">
<label for={commission.answers[key]['option']}>{question.name}</label>
<select class="bg-slate-600 p-2 rounded-lg" bind:value={commission.answers[key]['option']} on:change={() => {update_price(commission)}}>
{#each question.options as option}
<option value={option.name}>{option.name} | ${option.price}</option>
{/each}
</select>
</div>
{/each}
</form>
</div>
<div class="w-2/5">
{#if commission.example != ""}
<div class="relative bg-black bg-opacity-50 rounded-xl shadow-xl">
<p class="xl:block hidden absolute top-0 right-0 text-right -rotate-12 font-bold text-4xl -mb-40 -mr-40">
🠔 Example!
</p>
<img src={commission.example} alt="example" class="rounded-xl shadow-xl w-full" />
</div>
{:else}
<div class="relative w-full aspect-square bg-black bg-opacity-50 rounded-xl shadow-xl">
<p class="w-full h-full absolute inset-0 flex items-center justify-center text-center opacity-50 -rotate-45 font-bold text-6xl">
NO EXAMPLE AVAILABLE
</p>
</div>
{/if}
</div>
</section>
{/each}
</main>

@ -0,0 +1,51 @@
<script>
import { page } from "$app/stores";
console.log($page.url.pathname);
</script>
<header class="relative flex flex-col gap-10 max-w-[1400px] mx-auto my-20 dropanim">
<img src="/calculator/bannername.png" class="w-3/6 mb-10 lg:mb-0 mx-auto drop-shadow-2xl" alt="header siv kyne" />
<h1>
<img src="/calculator/banner.png" class="mb-10 lg:mb-0 mx-auto drop-shadow-2xl grow" alt="header siv kyne" />
</h1>
</header>
<style>
.dropanim {
animation: dropanim;
animation-duration: 0.4s;
animation-timing-function: ease-in-out;
}
@keyframes dropanim {
0% {
transform: translateY(-50vh);
}
50% {
transform: translateY(1vh);
}
100% {
transform: translateY(0);
}
}
.grow {
animation: grow;
animation-duration: 4s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
}
@keyframes grow {
0% {
transform: rotate3d(0, 20, 0, 20deg);
}
50% {
transform: rotate3d(0, 20, 0, -20deg);
}
100% {
transform: rotate3d(0, 20, 0, 20deg);
}
}
</style>

@ -0,0 +1,3 @@
import { writable } from 'svelte/store';
export const calculatorImages = writable([]);

@ -28,9 +28,9 @@
}
</script>
<section class="container bg-gray-800 rounded-lg shadow-lg p-5 flex flex-col gap-5" id={id}>
<section class="container bg-slate-800 rounded-lg shadow-lg p-5 flex flex-col gap-5" id={id}>
<div class="flex justify-between items-center">
<h2 class="text-2xl font-bold">{title}</h2>
<h2 class="text-2xl font-bold">{@html title}</h2>
<button type="none" id="{id}-trigger" on:click={openAccordion} class="text-2xl">➡️</button>
</div>

@ -3,19 +3,37 @@
export let price;
export let picture = null;
export let note = null;
export let link = null;
</script>
<div class="flex flex-col items-center gap-2">
<span class="w-full flex justify-between">
<h3 class="text-xl font-bold break-words">{name}</h3>
<span><span class="bg-green-500 py-1 text-sm px-5 rounded-lg">{price}</span></span>
</span>
{#if note}
<p class="text-sm text-gray-200 w-full">{@html note}</p>
{/if}
{#if picture}
<img src={picture} alt={name} class="w-full rounded-xl shadow" />
{:else}
<p class="p-2 italic text-gray-200 bg-gray-700 rounded-xl shadow w-full flex justify-center items-center text-center aspect-square">Example TBA</p>
{/if}
</div>
{#if link != null}
<a href={link} class="flex flex-col items-center gap-2">
<span class="w-full flex justify-between">
<h3 class="text-xl font-bold break-words">{name}</h3>
<span><span class="bg-green-500 py-1 text-sm px-5 rounded-lg">{price}</span></span>
</span>
{#if note}
<p class="text-sm text-gray-200 w-full">{@html note}</p>
{/if}
{#if picture}
<img src={picture} alt={name} class="w-full rounded-xl shadow" />
{:else}
<p class="p-2 italic text-gray-200 bg-gray-700 rounded-xl shadow w-full flex justify-center items-center text-center aspect-square">Example TBA</p>
{/if}
</a>
{:else}
<div class="flex flex-col items-center gap-2">
<span class="w-full flex justify-between">
<h3 class="text-xl font-bold break-words">{name}</h3>
<span><span class="bg-green-500 py-1 text-sm px-5 rounded-lg">{price}</span></span>
</span>
{#if note}
<p class="text-sm text-gray-200 w-full">{@html note}</p>
{/if}
{#if picture}
<img src={picture} alt={name} class="w-full rounded-xl shadow" />
{:else}
<p class="p-2 italic text-gray-200 bg-gray-700 rounded-xl shadow w-full flex justify-center items-center text-center aspect-square">Example TBA</p>
{/if}
</div>
{/if}

@ -44,7 +44,7 @@
}
</script>
<main class="flex flex-col gap-5 lg:w-2/3 mx-auto">
<main class="flex flex-col gap-5">
<form
class="flex flex-col gap-5"
action="https://api.staticforms.xyz/submit"

@ -4,6 +4,157 @@
"title": "Hello! I'm Siv Kyne!",
"description": "I'm a young Asian artist who specializes in cartoony 2D animals.<br/>You can find more information below."
},
"calculator": {
"title": "Commission Picker",
"description": "Use Siv Kyne's commission picker to estimate how much your commission would cost. Including multiple commissions, saving your presets, and more!",
"types": [
{
"name": "Icon",
"examples_from": "Detail level",
"examples": [
{
"name": "complexlineless",
"url": "/commissions/alakai again.jpg"
},
{
"name": "basic",
"url": "/commissions/iconbasic.jpg"
},
{
"name": "sketchy",
"url": "/commissions/nick.jpg"
},
{
"name": "ultralineart",
"url": "/commissions/iconultralineart.jpg"
},
{
"name": "basiclineless",
"url": "/commissions/iconbasiclineless.jpg"
},
{
"name": "cellshaded",
"url": "/commissions/iconcellshaded.jpg"
}
],
"questions": [
{
"name": "Detail level",
"options": [
{
"name": "Sketchy",
"example": "sketchy",
"price": 13
},
{
"name": "Basic",
"example": "basic",
"price": 18
},
{
"name": "Basic Lineless",
"example": "basiclineless",
"price": 18
},
{
"name": "Cell Shaded",
"example": "cellshaded",
"price": 23
},
{
"name": "Ultra Lineart",
"example": "ultralineart",
"price": 30
},
{
"name": "Complex Lineless",
"example": "complexlineless",
"price": 33
}
]
},
{
"name": "Fur",
"options": [
{
"name": "1-3 fur colors",
"price": 0
},
{
"name": "4-5 fur colors",
"price": 7
},
{
"name": "6+ fur colors",
"price": 10
}
]
}
]
},
{
"name": "Sticker/Emote",
"examples_from": "Fur",
"examples": [
{
"name": "4fur",
"url": "/commissions/emote2.jpg"
},
{
"name": "3fur",
"url": "/commissions/emote4.jpg"
}
],
"questions": [
{
"name": "Amount",
"options": [
{
"name": "Individual",
"example": "sticker",
"price": 7
},
{
"name": "Pack of 4",
"example": "sticker",
"price": 26
},
{
"name": "Pack of 5",
"example": "sticker",
"price": 31
},
{
"name": "Pack of 6",
"example": "sticker",
"price": 38
}
]
},
{
"name": "Fur",
"options": [
{
"name": "1-3 fur colors",
"example": "3fur",
"price": 0
},
{
"name": "4-5 fur colors",
"example": "4fur",
"price": 5
},
{
"name": "6+ fur colors",
"example": "4fur",
"price": 8
}
]
}
]
}
]
},
"tos": {
"title": "Terms of Service",
"description": "By commissioning Siv Kyne, you are agreeing to all of these terms and are held responsible for any noncomformities. These terms may be updated at any time without notice.",
@ -30,8 +181,8 @@
"ko-fi": "/icons/paw icon.png",
"paypal": "/icons/paw icon.png",
"trello": "/icons/paw icon.png",
"twitch": "/icons/paw icon.png"
"twitch": "/icons/paw icon.png",
"commission picker": "/icons/paw icon.png"
},
"frontpage": {
"items": [
@ -101,32 +252,38 @@
{
"name": "Sketchy",
"price": "$13",
"picture": "/commissions/nick.jpg"
"picture": "/commissions/nick.jpg",
"link": "/calculator?commissions=%5B%7B%22type%22%3A%22Icon%22%2C%22name%22%3A%22Commission+1%22%2C%22example%22%3A%22%2Fcommissions%2Fnick.jpg%22%2C%22price%22%3A13%2C%22questions%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22options%22%3A%5B%7B%22name%22%3A%22Sketchy%22%2C%22example%22%3A%22basic%22%2C%22price%22%3A13%7D%2C%7B%22name%22%3A%22Basic%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Basic+Lineless%22%2C%22example%22%3A%22complexlineless%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Cell+Shaded%22%2C%22example%22%3A%22complexlineless%22%2C%22price%22%3A23%7D%2C%7B%22name%22%3A%22Ultra+Lineart%22%2C%22example%22%3A%22ultralineart%22%2C%22price%22%3A30%7D%2C%7B%22name%22%3A%22Complex+Lineart%22%2C%22example%22%3A%22complexlineless%22%2C%22price%22%3A33%7D%5D%7D%5D%2C%22answers%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22option%22%3A%22Sketchy%22%7D%5D%7D%5D"
},
{
"name": "Basic",
"price": "$18",
"picture": "/commissions/iconbasic.jpg"
"picture": "/commissions/iconbasic.jpg",
"link": "/calculator?commissions=%5B%7B%22type%22%3A%22Icon%22%2C%22name%22%3A%22Commission+1%22%2C%22example%22%3A%22%2Fcommissions%2Ficonbasic.jpg%22%2C%22price%22%3A18%2C%22questions%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22options%22%3A%5B%7B%22name%22%3A%22Sketchy%22%2C%22example%22%3A%22sketchy%22%2C%22price%22%3A13%7D%2C%7B%22name%22%3A%22Basic%22%2C%22example%22%3A%22basic%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Basic+Lineless%22%2C%22example%22%3A%22basiclineless%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Cell+Shaded%22%2C%22example%22%3A%22cellshaded%22%2C%22price%22%3A23%7D%2C%7B%22name%22%3A%22Ultra+Lineart%22%2C%22example%22%3A%22ultralineart%22%2C%22price%22%3A30%7D%2C%7B%22name%22%3A%22Complex+Lineless%22%2C%22example%22%3A%22complexlineless%22%2C%22price%22%3A33%7D%5D%7D%2C%7B%22name%22%3A%22Fur%22%2C%22options%22%3A%5B%7B%22name%22%3A%221-3+fur+colors%22%2C%22price%22%3A0%7D%2C%7B%22name%22%3A%224-5+fur+colors%22%2C%22price%22%3A7%7D%2C%7B%22name%22%3A%226%2B+fur+colors%22%2C%22price%22%3A10%7D%5D%7D%5D%2C%22answers%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22option%22%3A%22Basic%22%7D%2C%7B%22name%22%3A%22Fur%22%2C%22option%22%3A%221-3+fur+colors%22%7D%5D%7D%5D"
},
{
"name": "Basic Lineless",
"price": "$18",
"picture": "/commissions/iconbasiclineless.jpg"
"picture": "/commissions/iconbasiclineless.jpg",
"link": "/calculator?commissions=%5B%7B%22type%22%3A%22Icon%22%2C%22name%22%3A%22Commission+1%22%2C%22example%22%3A%22%2Fcommissions%2Ficonbasiclineless.jpg%22%2C%22price%22%3A18%2C%22questions%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22options%22%3A%5B%7B%22name%22%3A%22Sketchy%22%2C%22example%22%3A%22sketchy%22%2C%22price%22%3A13%7D%2C%7B%22name%22%3A%22Basic%22%2C%22example%22%3A%22basic%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Basic+Lineless%22%2C%22example%22%3A%22basiclineless%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Cell+Shaded%22%2C%22example%22%3A%22cellshaded%22%2C%22price%22%3A23%7D%2C%7B%22name%22%3A%22Ultra+Lineart%22%2C%22example%22%3A%22ultralineart%22%2C%22price%22%3A30%7D%2C%7B%22name%22%3A%22Complex+Lineless%22%2C%22example%22%3A%22complexlineless%22%2C%22price%22%3A33%7D%5D%7D%2C%7B%22name%22%3A%22Fur%22%2C%22options%22%3A%5B%7B%22name%22%3A%221-3+fur+colors%22%2C%22price%22%3A0%7D%2C%7B%22name%22%3A%224-5+fur+colors%22%2C%22price%22%3A7%7D%2C%7B%22name%22%3A%226%2B+fur+colors%22%2C%22price%22%3A10%7D%5D%7D%5D%2C%22answers%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22option%22%3A%22Basic+Lineless%22%7D%2C%7B%22name%22%3A%22Fur%22%2C%22option%22%3A%221-3+fur+colors%22%7D%5D%7D%5D"
},
{
"name": "Cell Shaded",
"price": "$23",
"picture": "/commissions/iconcellshaded.jpg"
"picture": "/commissions/iconcellshaded.jpg",
"link": "/calculator?commissions=%5B%7B%22type%22%3A%22Icon%22%2C%22name%22%3A%22Commission+1%22%2C%22example%22%3A%22%2Fcommissions%2Ficoncellshaded.jpg%22%2C%22price%22%3A23%2C%22questions%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22options%22%3A%5B%7B%22name%22%3A%22Sketchy%22%2C%22example%22%3A%22sketchy%22%2C%22price%22%3A13%7D%2C%7B%22name%22%3A%22Basic%22%2C%22example%22%3A%22basic%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Basic+Lineless%22%2C%22example%22%3A%22basiclineless%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Cell+Shaded%22%2C%22example%22%3A%22cellshaded%22%2C%22price%22%3A23%7D%2C%7B%22name%22%3A%22Ultra+Lineart%22%2C%22example%22%3A%22ultralineart%22%2C%22price%22%3A30%7D%2C%7B%22name%22%3A%22Complex+Lineless%22%2C%22example%22%3A%22complexlineless%22%2C%22price%22%3A33%7D%5D%7D%2C%7B%22name%22%3A%22Fur%22%2C%22options%22%3A%5B%7B%22name%22%3A%221-3+fur+colors%22%2C%22price%22%3A0%7D%2C%7B%22name%22%3A%224-5+fur+colors%22%2C%22price%22%3A7%7D%2C%7B%22name%22%3A%226%2B+fur+colors%22%2C%22price%22%3A10%7D%5D%7D%5D%2C%22answers%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22option%22%3A%22Cell+Shaded%22%7D%2C%7B%22name%22%3A%22Fur%22%2C%22option%22%3A%221-3+fur+colors%22%7D%5D%7D%5D"
},
{
"name": "Ultra Lineart",
"price": "$30",
"picture": "/commissions/iconultralineart.jpg"
"picture": "/commissions/iconultralineart.jpg",
"link": "/calculator?commissions=%5B%7B%22type%22%3A%22Icon%22%2C%22name%22%3A%22Commission+1%22%2C%22example%22%3A%22%2Fcommissions%2Ficonultralineart.jpg%22%2C%22price%22%3A30%2C%22questions%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22options%22%3A%5B%7B%22name%22%3A%22Sketchy%22%2C%22example%22%3A%22sketchy%22%2C%22price%22%3A13%7D%2C%7B%22name%22%3A%22Basic%22%2C%22example%22%3A%22basic%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Basic+Lineless%22%2C%22example%22%3A%22basiclineless%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Cell+Shaded%22%2C%22example%22%3A%22cellshaded%22%2C%22price%22%3A23%7D%2C%7B%22name%22%3A%22Ultra+Lineart%22%2C%22example%22%3A%22ultralineart%22%2C%22price%22%3A30%7D%2C%7B%22name%22%3A%22Complex+Lineless%22%2C%22example%22%3A%22complexlineless%22%2C%22price%22%3A33%7D%5D%7D%2C%7B%22name%22%3A%22Fur%22%2C%22options%22%3A%5B%7B%22name%22%3A%221-3+fur+colors%22%2C%22price%22%3A0%7D%2C%7B%22name%22%3A%224-5+fur+colors%22%2C%22price%22%3A7%7D%2C%7B%22name%22%3A%226%2B+fur+colors%22%2C%22price%22%3A10%7D%5D%7D%5D%2C%22answers%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22option%22%3A%22Ultra+Lineart%22%7D%2C%7B%22name%22%3A%22Fur%22%2C%22option%22%3A%221-3+fur+colors%22%7D%5D%7D%5D"
},
{
"name": "Complex Lineless",
"price": "$33",
"picture": "/commissions/alakai again.jpg"
"picture": "/commissions/alakai again.jpg",
"link": "/calculator?commissions=%5B%7B%22type%22%3A%22Icon%22%2C%22name%22%3A%22Commission+1%22%2C%22example%22%3A%22%2Fcommissions%2Falakai+again.jpg%22%2C%22price%22%3A33%2C%22questions%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22options%22%3A%5B%7B%22name%22%3A%22Sketchy%22%2C%22example%22%3A%22sketchy%22%2C%22price%22%3A13%7D%2C%7B%22name%22%3A%22Basic%22%2C%22example%22%3A%22basic%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Basic+Lineless%22%2C%22example%22%3A%22basiclineless%22%2C%22price%22%3A18%7D%2C%7B%22name%22%3A%22Cell+Shaded%22%2C%22example%22%3A%22cellshaded%22%2C%22price%22%3A23%7D%2C%7B%22name%22%3A%22Ultra+Lineart%22%2C%22example%22%3A%22ultralineart%22%2C%22price%22%3A30%7D%2C%7B%22name%22%3A%22Complex+Lineless%22%2C%22example%22%3A%22complexlineless%22%2C%22price%22%3A33%7D%5D%7D%2C%7B%22name%22%3A%22Fur%22%2C%22options%22%3A%5B%7B%22name%22%3A%221-3+fur+colors%22%2C%22price%22%3A0%7D%2C%7B%22name%22%3A%224-5+fur+colors%22%2C%22price%22%3A7%7D%2C%7B%22name%22%3A%226%2B+fur+colors%22%2C%22price%22%3A10%7D%5D%7D%5D%2C%22answers%22%3A%5B%7B%22name%22%3A%22Detail+level%22%2C%22option%22%3A%22Complex+Lineless%22%7D%2C%7B%22name%22%3A%22Fur%22%2C%22option%22%3A%221-3+fur+colors%22%7D%5D%7D%5D"
}
]
},

@ -1,3 +1,5 @@
<footer>
<h4 class="text-center py-20 text-sm text-gray-200">copyright {new Date().getFullYear()} -- site made by <a href="https://bartindustries.com/" target="blank" class="hover:underline border-b border-dashed hover:border-b-0">midblep</a> -- art by siv kyne -- bg art by smol-static</h4>
<h4 class="text-center py-20 text-sm text-gray-200">
copyright {new Date().getFullYear()} -- site made by <a href="https://bartindustries.com/" target="blank" class="hover:underline border-b border-dashed hover:border-b-0">midblep</a> -- art by siv kyne
</h4>
</footer>

@ -1,6 +1,7 @@
<script>
export let href;
export let href = "";
export let active = "";
export let added_classes = "";
let classes = "hover:bg-gradient-to-tr hover:from-red-500 hover:to-pink-500 bg-red-500 duration-300 active:translate-y-1 py-2 px-3 w-full rounded-lg shadow";
@ -9,8 +10,10 @@
} else {
classes += " bg-opacity-50";
}
classes += " " + added_classes;
</script>
<a href={href} class={classes}>
<a href={href} class={classes} on:click>
<slot />
</a>

@ -1,11 +1,42 @@
<header>
<script>
import { page } from "$app/stores";
import Button from "./Button.svelte";
console.log($page.url.pathname);
</script>
<header class="relative mt-20 max-w-[1400px] mx-auto dropanim">
<a href="/">
<img src="/title.png" class="w-11/12 lg:w-2/3 mb-10 lg:mb-0 mx-auto grow drop-shadow-2xl" alt="header siv kyne" />
<img src="/title.png" class="mb-10 lg:mb-0 mx-auto drop-shadow-2xl grow" alt="header siv kyne" />
</a>
{#if $page.url.pathname != "/" && $page.url.pathname != "/calculator" }
<span href="/calculator" class="hidden xl:block text-s absolute w-full py-6 bottom-0 left-0 right-0 text-center hover:scale-105 transition duration-300 z-50">
<Button href="/calculator" added_classes="bg-opacity-100 shadow-xl">
🧮 Check out the new interactive commission picker!
</Button>
</span>
{/if}
</header>
<style>
.dropanim {
animation: dropanim;
animation-duration: 0.4s;
animation-timing-function: ease-in-out;
}
@keyframes dropanim {
0% {
transform: translateY(-50vh);
}
50% {
transform: translateY(1vh);
}
100% {
transform: translateY(0);
}
}
.grow {
animation: grow;
animation-duration: 2s;

@ -4,7 +4,7 @@
export let page;
</script>
<section class="container bg-gray-800 rounded-lg shadow-lg p-3 flex flex-col lg:flex-row gap-3 justify-between justify-items-stretch items-center -mt-10 z-20">
<section class="container bg-slate-800 rounded-lg shadow-lg p-3 flex flex-col lg:flex-row gap-3 justify-between justify-items-stretch items-center z-20">
{#if page == "/"}
<Button href="/" active="true">
🏠 Home
@ -37,11 +37,11 @@
{#if page == "/contact"}
<Button href="/contact" active="true">
✉️ Social Links
✉️ Socials
</Button>
{:else}
<Button href="/contact">
✉️ Social Links
✉️ Socials
</Button>
{/if}
</section>

@ -1,7 +1,6 @@
<script>
import Footer from "$lib/footer/Footer.svelte";
import Header from "$lib/header/Header.svelte";
import "../app.css";
</script>
@ -13,21 +12,43 @@
</svelte:head>
<main class="bg-green-600 text-white relative w-screen bg-cover bg-fixed" style="background-image: url('/bg2.png')">
<div class="absolute inset-0 z-0 overflow-y-hidden ">
<div class="absolute inset-0 z-0 overflow-y-hidden">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320">
<path fill="rgb(244 63 94)" fill-opacity="1" d="M0,288L30,272C60,256,120,224,180,186.7C240,149,300,107,360,101.3C420,96,480,128,540,154.7C600,181,660,203,720,229.3C780,256,840,288,900,304C960,320,1020,320,1080,304C1140,288,1200,256,1260,224C1320,192,1380,160,1410,144L1440,128L1440,320L1410,320C1380,320,1320,320,1260,320C1200,320,1140,320,1080,320C1020,320,960,320,900,320C840,320,780,320,720,320C660,320,600,320,540,320C480,320,420,320,360,320C300,320,240,320,180,320C120,320,60,320,30,320L0,320Z"></path>
</svg>
<div class="bg-gradient-to-b from-rose-500 via-pink-800 to-gray-900 -mt-1 z-10 h-screen"></div>
<div class="bg-gray-900 h-full">
<div class="bg-gradient-to-b from-rose-500 via-pink-800 to-slate-900 -mt-1 z-10 h-screen"></div>
<div class="bg-slate-900 h-full">
<div style="background-image: url('/bg3.png')" class="h-full bg-cover bg-opacity-1 blur-xl"></div>
</div>
</div>
<article class="px-3 lg:px-0 py-10 lg:py-20 flex flex-col gap-10 h-full">
<div class="flex flex-col gap-10 min-h-screen z-50">
<article class="px-3 lg:px-0 py-0 flex flex-col gap-10 h-full">
<div class="flex flex-col justify-start gap-10 min-h-screen z-50">
<Header />
<slot />
<Footer />
<span class="loadanim">
<slot />
<Footer />
</span>
</div>
</article>
</main>
</main>
<style>
.loadanim {
animation: loadanim;
animation-duration: 0.4s;
animation-timing-function: ease-in-out;
}
@keyframes loadanim {
0% {
transform: translateY(50vh);
}
50% {
transform: translateY(-1vh);
}
100% {
transform: translateY(0);
}
}
</style>

@ -14,7 +14,7 @@
<main class="flex flex-col gap-5">
<Navbar page="/about" />
<section class="container bg-gray-800 rounded-lg shadow-lg p-5 flex flex-col gap-5">
<section class="container bg-slate-800 rounded-lg shadow-lg p-5 flex flex-col gap-5">
<h1 class="text-2xl font-bold fira-bold">{lang["title"]}</h1>
<hr/>
<p class="text-sm lg:text-base">

@ -0,0 +1,56 @@
<script>
import CalculatorHeader from "$lib/calculator/CalculatorHeader.svelte";
import Footer from "$lib/footer/Footer.svelte";
import "../../app.css";
</script>
<svelte:head>
<meta property="og:type" content="website" />
<meta property="og:url" content="https://sivkyne.xyz" />
<meta property="og:image" content="https://sivkyne.xyz/pic.png" />
<meta name="theme-color" content="rgb(244 63 94)">
</svelte:head>
<main class="bg-black text-white relative w-screen">
<div class="absolute inset-0 w-full h-full bg-cover bg-fixed bg-bottom" style="background-image: url('/commissions/complex1.jpg')"></div>
<div class="absolute inset-0 h-[800px] bg-gradient-to-tr from-[#4d9937] via-[#57a940]"></div>
<div class="absolute inset-0 z-0 overflow-y-hidden mt-60">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320">
<path fill="rgb(244 63 94)" fill-opacity="1" d="M0,0L80,37.3C160,75,320,149,480,181.3C640,213,800,203,960,170.7C1120,139,1280,85,1360,58.7L1440,32L1440,320L1360,320C1280,320,1120,320,960,320C800,320,640,320,480,320C320,320,160,320,80,320L0,320Z"></path>
</svg>
<div class="bg-gradient-to-b from-rose-500 via-pink-800 to-slate-900 -mt-1 z-10 h-screen"></div>
<div class="bg-slate-900 h-full">
<div style="background-image: url('/bg3.png')" class="h-full bg-cover bg-opacity-1 blur-xl"></div>
</div>
</div>
<article class="px-3 lg:px-0 py-0 flex flex-col gap-10 h-full">
<div class="flex flex-col justify-start gap-10 min-h-screen z-50">
<CalculatorHeader/>
<span class="loadanim">
<slot />
<Footer />
</span>
</div>
</article>
</main>
<style>
.loadanim {
animation: loadanim;
animation-duration: 0.4s;
animation-timing-function: ease-in-out;
}
@keyframes loadanim {
0% {
transform: translateY(50vh);
}
50% {
transform: translateY(-1vh);
}
100% {
transform: translateY(0);
}
}
</style>

@ -0,0 +1,17 @@
<script>
import words from "$lib/en-lang.json";
import Calculator from "$lib/calculator/Calculator.svelte";
import Button from "$lib/header/Button.svelte";
let lang = words["calculator"];
</script>
<svelte:head>
<meta property="og:title" content={lang["title"] + " || Siv Kyne"} />
<meta property="og:description" content={lang["description"]} />
<title>{lang["title"]} || Siv Kyne</title>
</svelte:head>
<main class="flex flex-col gap-5">
<Calculator/>
</main>

@ -17,23 +17,31 @@
<main class="flex flex-col gap-5">
<Navbar page="/commissions" />
<section class="container bg-slate-800 rounded-lg shadow-lg p-5 flex flex-col">
<h2 class="flex gap-2 items-end">
<span class="font-bold text-green-500 text-xl">Pro Tip!</span>
Press on the pictures to visit them in the Commission Picker
</h2>
</section>
{#each lang["accordions"] as accordion}
<Accordion title={accordion["title"]} id={accordion["id"]} note={accordion["note"]} autoOpen={accordion["autoOpen"]}>
<div class="grid grid-cols-1 lg:grid-cols-{accordion["cols"]} gap-5">
{#each accordion["items"] as item}
<Item picture={item["picture"]} name={item["name"]} price={item["price"]} note={item["note"]} />
<Item picture={item["picture"]} name={item["name"]} price={item["price"]} note={item["note"]} link={item['link']} />
{/each}
</div>
</Accordion>
{/each}
<section class="container bg-gray-800 rounded-lg shadow-lg p-5 flex flex-col">
<section class="container bg-slate-800 rounded-lg shadow-lg p-5 flex flex-col">
<div class="flex flex-wrap justify-center items-center gap-5">
<Social href="https://trello.com/b/JfPAzQyJ/siv-kynes-commission-queue" icon="📑" text="Commission Queue" />
<Social href="https://ko-fi.com/sivkyne" icon="☕" text="Ko-fi" />
<Social href="https://paypal.me/sivkyne" icon="💰" text="PayPal" />
<Social href="/contact" icon="✉️" text="Contact" />
<Social href="/commissions/tos" icon="⚖️" text="Terms of Service" />
<Social href="/calculator" icon="🧮" text="Commission Picker" />
</div>
</section>

@ -14,7 +14,7 @@
<main class="flex flex-col gap-5">
<Navbar page="/commissions" />
<section class="container bg-gray-800 rounded-lg shadow-lg p-5 flex flex-col gap-5">
<section class="container bg-slate-800 rounded-lg shadow-lg p-5 flex flex-col gap-5">
<span>
<h1 class="text-2xl font-bold fira-bold">{lang["title"]}</h1>
<h3 class="text-gray-300 italic text-sm">{lang["lastEdit"]}</h3>

@ -13,26 +13,30 @@
<main class="flex flex-col gap-5">
<Navbar page="/contact" />
<section class="container bg-gray-800 rounded-lg shadow-lg p-5 flex flex-col">
<div class="flex flex-wrap justify-center items-center gap-5">
<Social href="/about" icon="📄" text="About Me" />
<Social href="https://twitter.com/SivKyne" icon="🐦" text="Twitter" />
<Social href="https://discord.com/invite/5JCZTv3TtF" icon="💬" text="Discord" />
<Social href="https://www.youtube.com/channel/UC1pnonYCZv1mi3XImhX35-A" icon="📺" text="YouTube" />
<Social href="https://www.deviantart.com/sivkyne" icon="🖼️" text="DeviantArt" />
<Social href="https://steamcommunity.com/id/sivkyne" icon="🎮" text="Steam" />
<Social href="https://open.spotify.com/user/uqwz46n0jki4zdwiedca5gbp2" icon="🎵" text="Spotify" />
<Social href="https://toyhou.se/sivkyne" icon="👪" text="Toyhouse" />
<Social href="https://trello.com/b/JfPAzQyJ/siv-kynes-commission-queue" icon="📑" text="Trello" />
<Social href="https://myanimelist.net/animelist/SivKyne" icon="🎞️" text="My Anime List" />
<Social href="https://ko-fi.com/sivkyne" icon="☕" text="Ko-fi" />
<Social href="https://paypal.me/sivkyne" icon="💰" text="PayPal" />
<Social href="/commissions/tos" icon="⚖️" text="Terms of Service" />
<Social href="https://twitch.tv/sivkyne" icon="📹" text="Twitch" />
<section class="container flex lg:flex-row flex-col gap-10 bg-slate-800 rounded-lg shadow-lg p-5">
<div class="lg:w-2/4 flex flex-col gap-5">
<h2 class="text-2xl font-bold font-mono">✉️ Mail me!</h2>
<hr/>
<Form />
</div>
</section>
<section class="container bg-gray-800 rounded-lg shadow-lg p-5 flex flex-col">
<Form />
<div class="lg:w-2/4 flex flex-col gap-5">
<h2 class="text-2xl font-bold font-mono">💬 Find me online!</h2>
<hr/>
<div class="flex flex-wrap justify-center items-center gap-5">
<Social href="https://twitter.com/SivKyne" icon="🐦" text="Twitter" />
<Social href="https://discord.com/invite/5JCZTv3TtF" icon="💬" text="Discord" />
<Social href="https://www.youtube.com/channel/UC1pnonYCZv1mi3XImhX35-A" icon="📺" text="YouTube" />
<Social href="https://www.deviantart.com/sivkyne" icon="🖼️" text="DeviantArt" />
<Social href="https://steamcommunity.com/id/sivkyne" icon="🎮" text="Steam" />
<Social href="https://open.spotify.com/user/uqwz46n0jki4zdwiedca5gbp2" icon="🎵" text="Spotify" />
<Social href="https://toyhou.se/sivkyne" icon="👪" text="Toyhouse" />
<Social href="https://trello.com/b/JfPAzQyJ/siv-kynes-commission-queue" icon="📑" text="Trello" />
<Social href="https://myanimelist.net/animelist/SivKyne" icon="🎞️" text="My Anime List" />
<Social href="https://ko-fi.com/sivkyne" icon="☕" text="Ko-fi" />
<Social href="https://paypal.me/sivkyne" icon="💰" text="PayPal" />
<Social href="https://twitch.tv/sivkyne" icon="📹" text="Twitch" />
</div>
</div>
</section>
</main>

@ -1,20 +1,15 @@
<script>
import Card from "$lib/elements/Card.svelte";
import Social from "$lib/elements/Social.svelte";
import Button from "$lib/header/Button.svelte";
import { onMount } from "svelte";
import words from "$lib/en-lang.json";
let lang = words["home"];
let items = words["frontpage"]["items"];
onMount(() => {
const soundBtn = document.querySelector('#clickMeow');
soundBtn.addEventListener('click',() => {
let meow = new Audio("/squeak.mp3");
meow.volume = 0.1;
meow.play();
});
});
function meow() {
let meow = new Audio("/squeak.mp3");
meow.volume = 0.1;
meow.play();
}
</script>
<svelte:head>
@ -24,11 +19,11 @@
</svelte:head>
<main class="flex flex-col gap-5">
<section class="container bg-gray-800 rounded-lg shadow-lg p-5 flex flex-col -mt-5 lg:mt-0 xl:-mt-5">
<div class="flex flex-col justify-center items-center gap-3 -mt-20 sm:-mt-28">
<div class="bg-gradient-to-t from-gray-800 via-gray-800 to-red-500 p-2 lg:p-3 rounded-full z-50">
<img src="/pic.png" id="clickMeow" class="pop w-40 h-40 sm:w-60 sm:h-60 rounded-full bg-gray-800" alt="profile pic" />
</div>
<section class="container bg-gradient-to-b from-slate-700 to-slate-800 rounded-lg shadow-lg p-5 flex flex-col -mt-5 lg:mt-0 xl:-mt-5">
<div class="flex flex-col justify-center items-center gap-3 -mt-20 sm:-mt-28 relative">
<div class="absolute inset-0 mx-auto bg-slate-700 rounded-full -z-10 w-40 h-40 sm:w-60 sm:h-60"></div>
<img src="/pic.png" class="absolute inset-0 mx-auto p-2 lg:p-3 pop w-40 h-40 sm:w-60 sm:h-60 rounded-full z-40" alt="profile pic" on:click={meow} />
<div class="h-60"></div>
<h2 class="text-2xl font-bold fira-bold text-center">{lang["title"]}</h2>
<p class="text-center">
@ -37,7 +32,12 @@
</div>
</section>
<section class="container bg-gray-800 rounded-lg shadow-lg p-5 flex flex-col gap-5">
<section class="container bg-slate-800 rounded-lg shadow-lg p-5 flex flex-col gap-5">
<div class="flex flex-wrap justify-center items-center gap-5">
<Social href="/about" icon="📄" text="About Me" />
<Social href="/calculator" icon="🧮" text="Commission Picker" />
<Social href="/contact" icon="✉️" text="Contact" />
</div>
<div class="flex flex-wrap justify-center items-center gap-5">
<Social href="https://twitter.com/SivKyne" target="_blank" icon="🐦" text="Twitter" />
<Social href="https://discord.com/invite/5JCZTv3TtF" target="_blank" icon="💬" text="Discord" />
@ -47,9 +47,6 @@
<Social href="https://open.spotify.com/user/uqwz46n0jki4zdwiedca5gbp2" target="_blank" icon="🎵" text="Spotify" />
<Social href="https://toyhou.se/sivkyne" target="_blank" icon="👪" text="Toyhouse" />
<Social href="https://myanimelist.net/animelist/SivKyne" target="_blank" icon="🎞️" text="My Anime List" />
<Social href="/about" icon="📄" text="About Me" />
<Social href="/contact" icon="✉️" text="Contact" />
<Social href="/commissions/tos" icon="⚖️" text="Terms of Service" />
<Social href="https://twitch.tv/sivkyne" icon="📹" text="Twitch" />
</div>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

@ -11,7 +11,7 @@ module.exports = {
sm: '100%',
md: '100%',
lg: '700px',
xl: '900px'
xl: '1000px'
},
borderWidth: {
DEFAULT: '1px',

Loading…
Cancel
Save