Page 1 of 1

[SOLVED] Resizing Stock

Posted: 30 August 2015, 14:59
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...

Re: Resizing Stock

Posted: 30 August 2015, 19:37
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 :) ...

Re: Resizing Stock

Posted: 30 August 2015, 21:34
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;}

Re: [SOLVED] Resizing Stock

Posted: 30 August 2015, 23:14
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.

Re: [SOLVED] Resizing Stock

Posted: 31 August 2015, 02:18
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...

Re: [SOLVED] Resizing Stock

Posted: 26 June 2020, 00:18
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!