[SOLVED] Resizing Stock

Game development with Board Game Arena Studio
Post Reply
User avatar
apollo1001
Posts: 191
Joined: 21 July 2015, 10:41

[SOLVED] Resizing Stock

Post by apollo1001 »

I have a stock containing some tiles, but would like to display them at only 50% size. Does anyone have a good idea as to how I can resize the stock items with js/css? I have tried overriding the 'stockitem' class with max-height/max-width elements which merely crops the images, and background-size:contain doesn't help either... Additionally, this current approach will leave unnecessary gaps between the stock items.

Is there a standard resize ability on the stock component or an easy equivalent?

Thanks in advance, A.

Edit: I have also considered creating the stock at 50% size, but with using the background-size: 50% 50%; to shrink the sprite as well, but alas, no luck as yet...
Last edited by apollo1001 on 30 August 2015, 21:34, edited 1 time in total.
User avatar
Rudolf
Posts: 566
Joined: 24 December 2011, 23:04

Re: Resizing Stock

Post by Rudolf »

Hello.
At the beginning of the current project I was using two size (one 50% and one 100%) for my tiles.

The pb you will face, is to have to reduce also the background position... that's why I opened a post to see if there was a simple way to adapt background-position in delta...
But I was using this:

Code: Select all

.card {
    	width: 210px;
    	height: 70px;
    	position:absolute;
	background-image: url('img/cards.jpg');  
	background-position: 0px 	-630px; 
	z-index:1; 	
}

.token {
    	width: 70px;
    	height: 70px;
    	position:absolute;
	background-image: url('img/token.png');
	z-index:1; 	
}
.pbreducecard	{ width:99px; height:33px;background-size:840px; background-position: 0px 	-315px;  }
.pbreducetoken	{ width:35px; height:35px;background-size:385px; background-position: -245px 	0px;  }
adding preducecard will resize...by example.

But Finally, I use only one size :) ...
User avatar
apollo1001
Posts: 191
Joined: 21 July 2015, 10:41

Re: Resizing Stock

Post by apollo1001 »

Thank you. It's always something small that is wrong.

In case anyone else needs the solution, merely create the stock at 50% sizes; in my case (64,56) instead of (128,112) and then add the 50% width:

Code: Select all

.stockitem {background-size: 1024px;}
User avatar
Quinarbre
Posts: 140
Joined: 15 December 2013, 23:26

Re: [SOLVED] Resizing Stock

Post by Quinarbre »

I have made Stock fully scalable but it required a fair bit of hijacking :
  • I've copied the updateDisplay function and tweaked it so that overlap is in percentage of the rendered card size, not the actual size
  • Every time I add a card to the stock I rewrite its backgroundPosition, width, height and padding-bottom in percentages
  • And I keep the stock's dimensions in check too
So yeah, it's doable but it's a pain in the butt, and not the cleanest code I've ever written.

It's not quite what you asked for, but I can give you the code if you want it.
User avatar
pikiou
Posts: 389
Joined: 03 October 2011, 05:36

Re: [SOLVED] Resizing Stock

Post by pikiou »

I've dreamt for a long time for a Stock2 component with the kind of feature your guys worked on.
Maybe should we write it ourselves and submit it to admins...
User avatar
Brainchild
Posts: 71
Joined: 31 January 2014, 19:42

Re: [SOLVED] Resizing Stock

Post by Brainchild »

I solved this problem by ignoring Stock's sprite-sheet support and handling it myself in CSS. To achieve this I pass an empty string for the image file path when initializing the Stock.

Code: Select all

this.playerHand.addItemType(card_type_id, card_type_id, "", i);
In the create() method I pass in dynamic values (based on the user's screen width) for the dimensions of each stock item. The technique is described by Een in this thread.

Code: Select all

            let topbarCoords = dojo.position("topbar");

            // Determine layout size based on screen width.
            if (topbarCoords.w >= 1900)
            {
                dojo.addClass("ebd-body", "fistfulofgold_large");
                this.dontPreloadImage("playmat.jpg");
            }
            else
            {
                this.dontPreloadImage("playmat_1480.jpg");
            }
I use the class added to ebd-body to define the card size for each layout.

Code: Select all

/* default card dimensions */
.fog_card {
    position: absolute;
    width: 103px;
    height: 144px;
}
/* card dimensions for large screens */
.fistfulofgold_large .fog_card {
    width: 206px;
    height: 288px;
}
I also use this technique to define the size of the card art, which is independent of the card itself. The art is also used in the tooltip, which doesn't need any of the other styling belonging to actual cards.

Code: Select all

/* the art is the actual image size in the sprite-sheet */
.fog_card_art {
    position: relative;
    width: 206px; /* this must be the card width from the sprite-sheet */
    height: 288px; /* this must be the card height from the sprite-sheet */
    transform: scale(0.5); /* the default layout uses half-size cards */
    transform-origin: top left;
    margin: auto; /* center the image horizontally */
    border-radius: 20px;
    background-image: url('img/cards.jpg');
}
.fistfulofgold_large .fog_card_art {
    transform: scale(1.0); /* use full-size cards for large screens */
}
Note there is only one sprite-sheet - I use the high-res version for all layouts and scale down accordingly. This allows for zooming, e.g. on mobile where card text can be hard to read otherwise.

In the HTML template (.tpl) file, I added a couple of dummy card elements (with display: none) so I can read their computed style when the game is loaded and real cards don't exist yet. I also have a JS template for the real card that will be created later in Stock's onItemCreate().

Code: Select all

    <div id="dummy_card" class="fog_card"></div>
    <div id="dummy_card_art" class="fog_card_art"></div>
    
let jstpl_card = '\
    <div class="fog_card fog_card_art" style="background-position:-${x}px -${y}px">\
        <div class="fog_card_content">\
            <div class="fog_card_text">${text}</div>\
            <div class="fog_card_note">${note}</div>\
        </div>\
    </div>';
Back in Javascript I query the card size from the dummy element. Since this happens after the screen width detection, the computed width and height will already be scaled appropriately for the screen size.

Code: Select all

            // Read the computed card dimensions from CSS now that the layout size has been determined.
            let dummy_card_element = dojo.byId("dummy_card");
            let cardWidth = dojo.getStyle(dummy_card_element, "width");
            let cardHeight = dojo.getStyle(dummy_card_element, "height");
            
            this.playerHand = new ebg.stock();
            this.playerHand.create(this, $("my_hand"), cardWidth, cardHeight);            
            this.playerHand.image_items_per_row = 10;
            this.playerHand.item_margin = 2;
            this.playerHand.centerItems = true;
            this.playerHand.onItemCreate = dojo.hitch(this, "setupNewCard"); 
            dojo.connect(this.playerHand, "onChangeSelection", this, "onPlayerHandSelectionChanged");            
I use the same technique to query the sprite size.

Code: Select all

        getCardSpriteOffset: function(card_type_id)
        {
            let card = this.gamedatas.card_defs[card_type_id];

            // Read the computed card art dimensions from CSS.
            let dummy_card_art_element = dojo.byId("dummy_card_art");
            let card_sprite_width = dojo.getStyle(dummy_card_art_element, "width");
            let card_sprite_height = dojo.getStyle(dummy_card_art_element, "height");

            let card_sprite_x_offset = card_sprite_width * (card_type_id - 1 - (card.color == this.colorRed ? 10 : 0));
            let card_sprite_y_offset = card_sprite_height * (card.color == this.colorRed ? 1 : 0); // red cards are on the second row in the sprite-sheet

            return {
                x: card_sprite_x_offset,
                y: card_sprite_y_offset
            }
        },
The final step is implementing Stock's onItemCreate callback (seen above) to generate the card's html and attach it to the stock item.

Code: Select all

        setupNewCard: function(card_div, card_type_id, card_id)
        {
            let card = this.gamedatas.card_defs[card_type_id];            
            let card_sprite_offset = this.getCardSpriteOffset(card_type_id);

            if (typeof card.text == "undefined")
                card.text = "";

            if (typeof card.note == "undefined")
                card.note = "";

            card.text = this.nl2br(_(card.text), false);
            card.note = this.nl2br(_(card.note), false);

            if (card.text.length > 0 || card.note.length > 0)
            {
                let tooltipHtml = this.format_block("jstpl_card_tooltip",
                    {
                        name: card.name,
                        x: card_sprite_offset.x,
                        y: card_sprite_offset.y,
                        text: card.text,
                        note: card.note
                    });
            
                this.addTooltipHtml(card_div.id, tooltipHtml, 100);
            }

            dojo.place(
                this.format_block("jstpl_card",
                {
                    id: card_id,
                    x: card_sprite_offset.x,
                    y: card_sprite_offset.y,
                    text: card.text,
                    note: card.note
                }), card_div.id);
        },
 
Hopefully this helps someone!
Post Reply

Return to “Developers”