This is a documentation for Board Game Arena: play board games online !

Anti-Stock: Difference between revisions

From Board Game Arena
Jump to navigation Jump to search
No edit summary
Line 118: Line 118:


[[File:Deck Layouts - codepen.io.png]]
[[File:Deck Layouts - codepen.io.png]]
== Selection and Click Handlers ==
To hookup selection or clicking, you have to manually hook up handler to all cards, which is easy
<pre>
document.querySelectorAll(".card").forEach(node=>node.addEventListener("click", (event) => {
  var target = event.target;
  target.classList.toggle('selected');
  }
}));
</pre>
And you define class for selected in css
  .selected {
    outline: dashed blue 0.1em;
  }
How if you need to do some action based on select this can be your do something button bandler (this will create array of ids of cards)
<pre>
  const card_ids = Array.from(document.querySelectorAll('.card.selected')).map(x=>x.id);
</pre>
If you need single selection, just add a call to remove all previous 'selected' from all card, before adding it.
If you don't need selection you can hook ajax call directly to handler above.

Revision as of 23:52, 3 October 2021

work in progress

Overivew

If Stock component works for you great, you don't need this. If you start tweaking it and doing something slightly more complex and you cannot find answer, it may be best to not use it. This wiki on how to replace this. What is Stock? Its component that does a lot of stuff in one:

  • It generates inline attributes of object the represent graphics and sizes of "cards" (can be anything really)
  • It also manages layout of one single container of such cards, and cards within it - including animation
  • It also manages selection in that container

Recipe to get rid of stock (the gist of it):

  • Create all cards as divs in template file with help of view.php is needed
  • Create generic card css with image, sizing etc, create/generate css per card type with bg positioning - there are script in sharecode to generate grid positioning (what stock does)
  • Create a parent for card placement and use dojo.place to move cards there, for css use your favour layout for this, including margins, etc
  • Trickky one: When cards are moved for animation you have to use special method, none of animation methods from bga parent class will work as card will not have absolute positioning, you can use methods from sharedcode project or create your own (the trick is during animation object has to have absolute positioning which is removed after animation)


Presentation

In modern word the objects that we want to render will be always represented by

element in the dom. This div will have unique Id, classes and also custom data attributes which can use for styling and selection.

This is some sort of card 1 of type card_21

  <div id="card_21_1" class="card card_21" data-num="21"></div>

This is 10 of hearts and king of clubs inside a hand inside a game

<div id="game" class="classic_deck">
  <div id="hand" class="hand">
    <div id="card_H_10" class="card" data-suit='H' data-rank="10"> </div>
    <div id="card_C_K" class="card" data-suit='C' data-rank="K"> </div>
  </div>
</div>

Now we can use css to show graphics and defined size. Note unlike stock - the size should not be bound this component, you cards can have different size for example in tooltips vs hand

We will use the BGA card stock https://x.boardgamearena.net/data/others/cards/FULLREZ_CARDS_ORIGINAL_NORMAL.jpg. It has 15 columns.

.card {
   background-image: url('https://x.boardgamearena.net/data/others/cards/FULLREZ_CARDS_ORIGINAL_NORMAL.jpg');   /* don't do full url in your game, copy this file inside img folder */
   background-size: 1500% auto;  /* this mean size of background is 15 times bigger than size of card, because its sprite */
   border-radius: 5%;
   width: 10em;
   height: 13.5em;
   box-shadow: 0.1em 0.1em 0.2em 0.1em #555;
}


.card[data-rank="10"] { /* 10 is column number 10 - 2 because we start from 0 and first card is sprite is 2. The multiplier is (15 - 1) is because we have 15 columns. -1 is because % in CSS is weird like that. */
   background-position-x: calc(100% / (15 - 1) * (10 - 2));
}
.card[data-rank="K"] { /* King will be number 13 in rank */
   background-position-x: calc(100% / (15 - 1) * (13 - 2));
}

.card[data-suit="H"] { /* Hears row position is 1 (because we count from 0). Multiplier (4 - 1) is because we have 4 rows and -1 is because % in CSS is weird like that. */
   background-position-y: calc(100% / (4 - 1) * (1));
}
.card[data-suit="C"] { /* Clubs row position is 2 */
   background-position-y: calc(100% / (4 - 1) * (2));
}

Now if you want to see these cards, we can put them in some specific component for example hand, and there we can define layout and sizing just for hand

.hand .card {
  font-size: 2.4rem;
  display: inline-block;
}

To finish the deck you have to finish css for all rows/columns which whould be only 10-20 records, really easy and repetitive!

Working example: https://codepen.io/VictoriaLa/pen/rNwgWrB


And now if you want to user to have preferece for what deck style to use its just matter of change class from "classic_deck" to "fancy_deck" in our game parent div and adding in CSS

.fancy_deck .card {
   background-image: url('https://x.boardgamearena.net/data/others/cards/FULLREZ_CARDS_DESIGN_COLORED.jpg');
}

Layout

You can use all web resources and powser of css to do any sort of fancy layout for your cards, you not bound to any predefined layouts. The simplest would be display: inline-block as we already did above. You can also add margins to overlap cards for example

.tableau {
   position: relative;
   width: 50em;
   height: 30em;
   outline: dashed 1px green;
   transform: rotate(-90deg) scale(0.5); 
   padding: 1em;
    display: flex;
  justify-content: center;
  flex-direction: row;
  flex-wrap: wrap;
}

.tableau .card{
  margin-right: -2em;
}

In this example cards on tableu are smaller, rotated 90 degrees and overlaping.


https://codepen.io/VictoriaLa/pen/PojvWEV


Deck Layouts - codepen.io.png

Selection and Click Handlers

To hookup selection or clicking, you have to manually hook up handler to all cards, which is easy

document.querySelectorAll(".card").forEach(node=>node.addEventListener("click", (event) => {
  var target = event.target;
  target.classList.toggle('selected');
  }
}));

And you define class for selected in css

 .selected {
    outline: dashed blue 0.1em;
 }

How if you need to do some action based on select this can be your do something button bandler (this will create array of ids of cards)

  const card_ids = Array.from(document.querySelectorAll('.card.selected')).map(x=>x.id);

If you need single selection, just add a call to remove all previous 'selected' from all card, before adding it.

If you don't need selection you can hook ajax call directly to handler above.