Allow custom card rarity and ink colours to be selected

This commit is contained in:
Andrio Celos 2024-02-16 15:56:46 +11:00
parent 42dc0b462b
commit e07cdc8904
4 changed files with 115 additions and 8 deletions

View File

@ -604,6 +604,13 @@
</main>
<dialog id="galleryCardDialog">
<div id="galleryCardEditor" hidden>
<div id="galleryCardEditorProperties">
<label for="galleryCardEditorRarityBox">Rarity: <select id="galleryCardEditorRarityBox"></select></label>
Colours:
<input type="color" id="galleryCardEditorColour2"/>
<input type="color" id="galleryCardEditorColour1"/>
<select id="galleryCardEditorColourPresetBox"></select>
</div>
<textarea type="text" id="galleryCardEditorName" placeholder="Card name"></textarea>
<div id="galleryCardEditorGrid"></div>
<div id="galleryCardEditorSpecialCost">

View File

@ -1,12 +1,16 @@
class CardDisplay implements ICardElement {
readonly card: Card;
level: number;
readonly element: HTMLElement;
readonly svg: SVGSVGElement;
private readonly sizeElement: SVGTextElement;
private readonly specialCostGroup: SVGGElement;
private level: number;
private idNumber: number;
private static nextIdNumber = 0;
constructor(card: Card, level: number, elementType: string = 'div') {
this.idNumber = CardDisplay.nextIdNumber++;
this.card = card;
this.level = level;
@ -28,6 +32,7 @@ class CardDisplay implements ICardElement {
// Background
const image = document.createElementNS('http://www.w3.org/2000/svg', 'image');
image.setAttribute('class', 'cardDisplayBackground');
image.setAttribute('href', `assets/CardBackground-${card.rarity}-${level > 0 ? '1' : '0'}.webp`);
image.setAttribute('width', '100%');
image.setAttribute('height', '100%');
@ -37,10 +42,10 @@ class CardDisplay implements ICardElement {
svg.insertAdjacentHTML('beforeend', `<image href="assets/external/CardInk.webp" width="635" height="885" clip-path="url(#myClip)"/>`);
} else {
svg.insertAdjacentHTML('beforeend', `
<filter id="ink1-${card.number}" color-interpolation-filters="sRGB"><feColorMatrix type="matrix" values="${card.inkColour1.r / 255} 0 0 0 0 0 ${card.inkColour1.g / 255} 0 0 0 0 0 ${card.inkColour1.b / 255} 0 0 0 0 0 0.88 0"/></filter>
<image href="assets/external/CardInk-1.webp" width="635" height="885" clip-path="url(#myClip)" filter="url(#ink1-${card.number})"/>
<filter id="ink2-${card.number}" color-interpolation-filters="sRGB"><feColorMatrix type="matrix" values="${card.inkColour2.r / 255} 0 0 0 0 0 ${card.inkColour2.g / 255} 0 0 0 0 0 ${card.inkColour2.b / 255} 0 0 0 0 0 0.88 0"/></filter>
<image href="assets/external/CardInk-2.webp" width="635" height="885" clip-path="url(#myClip)" filter="url(#ink2-${card.number})"/>
<filter id="ink1-${this.idNumber}" class="inkFilter" color-interpolation-filters="sRGB"><feColorMatrix type="matrix" values="${card.inkColour1.r / 255} 0 0 0 0 0 ${card.inkColour1.g / 255} 0 0 0 0 0 ${card.inkColour1.b / 255} 0 0 0 0 0 0.88 0"/></filter>
<image href="assets/external/CardInk-1.webp" width="635" height="885" clip-path="url(#myClip)" filter="url(#ink1-${this.idNumber})"/>
<filter id="ink2-${this.idNumber}" class="inkFilter" color-interpolation-filters="sRGB"><feColorMatrix type="matrix" values="${card.inkColour2.r / 255} 0 0 0 0 0 ${card.inkColour2.g / 255} 0 0 0 0 0 ${card.inkColour2.b / 255} 0 0 0 0 0 0.88 0"/></filter>
<image href="assets/external/CardInk-2.webp" width="635" height="885" clip-path="url(#myClip)" filter="url(#ink2-${this.idNumber})"/>
`);
}
@ -121,7 +126,7 @@ class CardDisplay implements ICardElement {
svg.appendChild(text1);
// Size
svg.insertAdjacentHTML('beforeend', `<image href='assets/external/Game Assets/CardCost_0${card.rarity}.png' width='80' height='80' transform='translate(12 798) rotate(-45) scale(1.33)'/>`);
svg.insertAdjacentHTML('beforeend', `<image class='cardSizeBackground' href='assets/external/Game Assets/CardCost_0${card.rarity}.png' width='80' height='80' transform='translate(12 798) rotate(-45) scale(1.33)'/>`);
svg.insertAdjacentHTML('beforeend', `<text fill='white' stroke='${card.rarity == Rarity.Common ? '#482BB4' : card.rarity == Rarity.Rare ? '#8B7E25' : '#481EF9'}' paint-order='stroke' stroke-width='5' font-size='48' y='816' x='87' text-anchor='middle'>${card.size}</text>`);
this.sizeElement = svg.lastElementChild as SVGTextElement;

View File

@ -10,6 +10,10 @@ const bitsToCompleteField = document.getElementById('bitsToCompleteField') as HT
let galleryCardDisplay: CardDisplay | null = null;
let gallerySelectedCardDisplay: CardDisplay | null = null;
const galleryCardEditor = document.getElementById('galleryCardEditor') as HTMLButtonElement;
const galleryCardEditorRarityBox = document.getElementById('galleryCardEditorRarityBox') as HTMLSelectElement;
const galleryCardEditorColour1 = document.getElementById('galleryCardEditorColour1') as HTMLInputElement;
const galleryCardEditorColour2 = document.getElementById('galleryCardEditorColour2') as HTMLInputElement;
const galleryCardEditorColourPresetBox = document.getElementById('galleryCardEditorColourPresetBox') as HTMLSelectElement;
const galleryCardEditorName = document.getElementById('galleryCardEditorName') as HTMLTextAreaElement;
const galleryCardEditorGridButtons: HTMLButtonElement[][] = [ ];
const galleryCardEditorSpecialCostButtons: HTMLButtonElement[] = [ ];
@ -21,6 +25,12 @@ const galleryCardEditorDeleteButton = document.getElementById('galleryCardEditor
const galleryCardEditorCancelButton = document.getElementById('galleryCardEditorCancelButton') as HTMLButtonElement;
const galleryCardEditorDeleteYesButton = document.getElementById('galleryCardEditorDeleteYesButton') as HTMLButtonElement;
const colourPresets: {[key: string]: [ Colour, Colour ]} = {
"Default": [ Card.DEFAULT_INK_COLOUR_1, Card.DEFAULT_INK_COLOUR_2 ],
"Octarian": [ { r: 166, g: 105, b: 169 }, { r: 121, g: 111, b: 174 } ],
"Salmonid": [ { r: 84, g: 142, b: 122 }, { r: 193, g: 111, b: 98 } ],
};
const ownedCards: {[key: number]: number} = { 6: 0, 34: 0, 159: 0, 13: 0, 45: 0, 137: 0, 22: 0, 52: 0, 141: 0, 28: 0, 55: 0, 103: 0, 40: 0, 56: 0, 92: 0 };
let lastGridButton: HTMLButtonElement | null = null;
let customCardSize = 0;
@ -93,6 +103,11 @@ function openGalleryCardView(card: Card) {
galleryCardEditorSubmitButton.hidden = true;
galleryCardEditorCancelButton.innerText = 'Close';
galleryCardEditorRarityBox.value = card.rarity.toString();
galleryCardEditorColour1.value = `#${card.inkColour1.r.toString(16).padStart(2, '0')}${card.inkColour1.g.toString(16).padStart(2, '0')}${card.inkColour1.b.toString(16).padStart(2, '0')}`;
galleryCardEditorColour2.value = `#${card.inkColour2.r.toString(16).padStart(2, '0')}${card.inkColour2.g.toString(16).padStart(2, '0')}${card.inkColour2.b.toString(16).padStart(2, '0')}`;
updateSelectedPreset([card.inkColour1, card.inkColour2]);
galleryCardEditorName.value = card.line2 == null ? card.name : `${card.line1}\n${card.line2}`;
for (let y = 0; y < 8; y++) {
for (let x = 0; x < 8; x++) {
@ -104,6 +119,18 @@ function openGalleryCardView(card: Card) {
galleryCardDialog.showModal();
}
function updateSelectedPreset(selectedColours: Colour[]) {
for (const key in colourPresets) {
const colours = colourPresets[key];
if (selectedColours[0].r == colours[0].r && selectedColours[0].g == colours[0].g && selectedColours[0].b == colours[0].b
&& selectedColours[1].r == colours[1].r && selectedColours[1].g == colours[1].g && selectedColours[1].b == colours[1].b) {
galleryCardEditorColourPresetBox.value = key;
return;
}
}
galleryCardEditorColourPresetBox.value = 'Custom';
}
function startEditingCustomCard() {
galleryCardEditor.hidden = false;
galleryCardDisplay?.element.classList.add('editing');
@ -157,6 +184,23 @@ function updateBitsToComplete() {
}
{
for (var i = 0; ; i++) {
if (!(i in Rarity)) break;
const option = document.createElement('option');
option.value = i.toString();
option.innerText = Rarity[i];
galleryCardEditorRarityBox.appendChild(option);
}
for (const k in colourPresets) {
const option = document.createElement('option');
option.innerText = k;
galleryCardEditorColourPresetBox.appendChild(option);
}
const optionCustom = document.createElement('option');
optionCustom.innerText = 'Custom';
galleryCardEditorColourPresetBox.appendChild(optionCustom);
for (let x = 0; x < 8; x++) {
const row = [ ];
for (let y = 0; y < 8; y++) {
@ -277,6 +321,46 @@ function updateCustomCardSpecialCost() {
}
}
galleryCardEditorRarityBox.addEventListener('change', () => {
const display = galleryCardDisplay!;
display.element.classList.remove('common');
display.element.classList.remove('rare');
display.element.classList.remove('fresh');
display.element.classList.add(Rarity[parseInt(galleryCardEditorRarityBox.value)].toLowerCase());
const sizeImage = <SVGImageElement> display.svg.getElementsByClassName('cardSizeBackground')[0];
sizeImage.setAttribute('href', `assets/external/Game Assets/CardCost_0${galleryCardEditorRarityBox.value}.png`);
const backgroundImage = <SVGImageElement> display.svg.getElementsByClassName('cardDisplayBackground')[0];
backgroundImage.setAttribute('href', `assets/CardBackground-${galleryCardEditorRarityBox.value}-1.webp`);
});
galleryCardEditorColour1.addEventListener('change', galleryCardEditorColour_change);
galleryCardEditorColour2.addEventListener('change', galleryCardEditorColour_change);
function galleryCardEditorColour_change() {
const display = galleryCardDisplay!;
const filters = display.svg.getElementsByClassName('inkFilter');
const selectedColours = [];
for (let i = 0; i < 2; i++) {
const value = [galleryCardEditorColour1, galleryCardEditorColour2][i].value;
const colour = { r: parseInt(value.substring(1, 3), 16), g: parseInt(value.substring(3, 5), 16), b: parseInt(value.substring(5, 7), 16) };
selectedColours.push(colour);
filters[i].getElementsByTagName('feColorMatrix')[0].setAttribute('values', `${colour.r / 255} 0 0 0 0 0 ${colour.g / 255} 0 0 0 0 0 ${colour.b / 255} 0 0 0 0 0 0.88 0`)
}
updateSelectedPreset(selectedColours);
}
galleryCardEditorColourPresetBox.addEventListener('change', () => {
const preset = colourPresets[galleryCardEditorColourPresetBox.value];
if (!preset) return;
galleryCardEditorColour1.value = `#${preset[0].r.toString(16).padStart(2, '0')}${preset[0].g.toString(16).padStart(2, '0')}${preset[0].b.toString(16).padStart(2, '0')}`;
galleryCardEditorColour2.value = `#${preset[1].r.toString(16).padStart(2, '0')}${preset[1].g.toString(16).padStart(2, '0')}${preset[1].b.toString(16).padStart(2, '0')}`;
galleryCardEditorColour_change();
});
galleryCardEditorSpecialCostDefaultBox.addEventListener('change', () => {
if (galleryCardEditorSpecialCostDefaultBox.checked)
updateCustomCardSize();
@ -291,11 +375,13 @@ galleryNewCustomCardButton.addEventListener('click', () => {
});
galleryCardEditorSubmitButton.addEventListener('click', () => {
function parseColour(value: string) { return { r: parseInt(value.substring(1, 3), 16), g: parseInt(value.substring(3, 5), 16), b: parseInt(value.substring(5, 7), 16) }; }
const isNew = galleryCardDisplay!.card.number == UNSAVED_CUSTOM_CARD_INDEX;
const number = isNew ? CUSTOM_CARD_START - cardDatabase.customCards.length : galleryCardDisplay!.card.number;
const lines = Card.wrapName(galleryCardEditorName.value);
const card = new Card(number, galleryCardEditorName.value.replaceAll('\n', ' '), lines[0], lines[1], Card.DEFAULT_INK_COLOUR_1, Card.DEFAULT_INK_COLOUR_2,
Rarity.Common, customCardSpecialCost, Array.from(galleryCardEditorGridButtons, r => Array.from(r, b => parseInt(b.dataset.state!))));
const card = new Card(number, galleryCardEditorName.value.replaceAll('\n', ' '), lines[0], lines[1], parseColour(galleryCardEditorColour1.value), parseColour(galleryCardEditorColour2.value),
<Rarity> parseInt(galleryCardEditorRarityBox.value), customCardSpecialCost, Array.from(galleryCardEditorGridButtons, r => Array.from(r, b => parseInt(b.dataset.state!))));
if (isNew) {
cardDatabase.customCards.push(card);
addCardToGallery(card);

View File

@ -1862,6 +1862,15 @@ button.dragging {
font-size: calc(min(75vh, 100vw) * 0.08);
}
#galleryCardEditorProperties {
position: absolute;
left: 5%;
top: 3%;
font: 33% 'Splatoon 2', sans-serif;
background: grey;
padding: 0 1em;
}
#galleryCardEditorName {
position: absolute;
left: 5%;