Skip to content
Arnold Smith edited this page Oct 5, 2024 · 46 revisions

Overview

The room is 1600x1000px. It is then scaled to completely cover the browser window (while keeping the aspect ratio). So all pixel values in the properties are in relation to those 1600x1000.

If you are familiar with the playingcards.io JSON format, you might be looking for boards, counters and hands. Hands are just a holder with a few properties preset. Counters are just a preset with labels and buttons. Boards are just BasicWidgets.

Global properties for every widget

Please note that some widget types override the global default value. See tables below.

And keep in mind that any of these properties (except id and type) will be updated while playing the game. For example x, y and z when dragging widgets or parent when moving a widget to a holder. But all of them can be changed using Functions.

Property Default value Description Tutorial
changeRoutine [] When any property of the widget changes, this routine is called. If you want to restrict execution to changes in a particular property, use <propertyName>ChangeRoutine (for example, millisecondsChangeRoutine will fire only when the milliseconds value of its timer changes). basic, Card Deal Animation
classes "" CSS classes separated by spaces that will be added to the widget. This is currently mainly used for _BasicWidget_s and for transparent _Holder_s.
clickable false When set to false, the widget will ignore clicking (manually as well as via CLICK operation)
clickRoutine [] This routine is called when the widget is clicked, assuming its clickable property is true.
css "" Custom CSS that will be added to the widget. For example "border-radius: 100%; background: red".
debug false If this is true a clickable widget or one with automation routines will show an overlay with its variables and collections after each operation.
dropOffsetX, dropOffsetY 0 IF this widget gets another widget as child, the child will get these x,y coordinates relative to the widget. basic, advanced
enlarge false This can be false or a number. If it's a number, the widget will show an enlarged version of itself as an overlay. The number is the scale. So a 3 says that the enlarged version is 3x the size of the widget. A 0.5 would actually show a version that's half as big as the original. Negative values will flip the enlarged widget around its center.
enterRoutine []
grid [] This is an array of "snap to grid" definitions. Each object in the array must have x and y (distance between two objects). Example: [ { "x": 100, "y": 150 } ]
Optionally it can contain minX/Y and maxX/Y to limit where the grid takes effect. Example: [{ "x": 103, "y": 60, "minX": 400, "maxX": 1200, "minY": 300, "maxY": 700}]
It can also have rotation to force the widget's rotation at that snap point and offsetX/Y for offsetting the complete grid. Example: [{ "offsetX": 200, "x": 300, "y": 173.2, "rotation": 90 }, { "offsetX": 350, "offsetY": 86.6, "x": 300, "y": 173.2, "rotation": 90 }, … ]
grid, min/max
id A unique identifier of a widget. Pretty much any string but control characters like newlines will probably break somewhere.
ignoreOnLeave false If set to true, this widget will ignore the onLeave property of a holder.
In practice this can be used to set if a card will be flipped to its back side when leaving the hand.
inheritChildZ false See z and layer. If this is set to true, the widget will inherit the largest layer+z combination of its children.
Makes it possible to have a button on top of a holder that disappears when cards are put into the holder.
As a child, the card just becomes part of the holder and will be rendered at the same Z coordinate. So without this property the button would be above the card.
layer 0 Widgets with layer 0 are always below widgets with layer 1 (if they have the same parent).
Technically, the real CSS z-index is calculated by (layer+10)*100000+z. See inheritChildZ.
leaveRoutine []
movable true If set to false, the widget will only be movable in edit mode.
movableInEdit true If set to false, the widget will not be movable in edit mode.
This is sometimes useful for child widgets of more complex widget groups. For example buttons of counters.
overlap true If set to false, this widget will override the stackOffsetX/Y of a holder so that it will be completely visible. basic, advanced
owner null If this is not null, it is the name of a player (see player list overlay) or an array of player names. This widget will only be visible for the specified player(s). See childrenPerOwner of holder.
This makes the hand only show your own cards.
parent null This is null if the widget is directly on the main room surface. Or it is the id of another widget.
rotation 0 Rotation of the widget in degrees (any value should work - even below -360 or above 360) around the center (can be changed using "transform-origin" in the css property).
It is worth noting that children "inherit" this because they become part of their parent. So if you create a holder with a 15° rotation, any cards put into it will be rotated 15° (plus their own rotation value).
scale 1 Scale factor of the widget.
The same inheritance as for rotation applies. So if you scale the hand by 2, all cards in it will be displayed at twice their normal size.
As with rotation the origin is the center of the widget and can be changed using "transform-origin" in the css property).
type This is a special value that determines what class the widget instantiates. See below for further properties of the different types. Valid values are: "button", "canvas", "card", "deck", "holder", "label", "pile", "spinner", and "timer" (no capital letters allowed). If no value (or any other value) is given, it will become a BasicWidget.
typeClasses "widget" Further CSS classes that will be added to the widget. These are the internal ones: "widget" and the ones specific to the widget type.
Not intended to be changed.
width, height 100 The width and height of the widget in pixels.
x, y 0 The left and top offsets in pixels relative to the parent widget.
z 0 The Z coordinate. Widgets with higher Z coordinate are on top of others.
The property layer divides the Z coordinates into different layers.
The Z coordinate only affects children of the same parent. See inheritChildZ.

BasicWidget

This is a somewhat generic widget. It can be used to add an image but it also has some additional features making it useful for other purposes.

Property Default value Description
activeFace 0 The index of the faces array that is currently active. This is what changes when you click the widget.
classes "" The same global default. Supported classes the default game pieces are: "classicPiece", "checkersPiece" and "pinPiece".
color "black" The color can be any value supported by CSS. It is exposed as the CSS variable --color and is used by the game piece classes.
faceCycle "ordered" Can be "ordered" or "random". The "ordered" faceCycle allows to iteratively cycle through the faces
faces [ {} ] When clicking a widget, it cycles through its faces (the only way to prevent this would be putting an invisible widget on top of it). This property is an array of objects that each contain widget properties. This way you can override any property of the widget. Example: [{ "classes": "checkersPiece" }, { "classes": "checkersPiece crowned" }]
Make sure that when you use a property in one face definition, you set that same property in all the other face definitions as well. For example if you override the property image in face 0, but not in face 1, it won't be removed when switching to face 1.
An example for this is the default checkers piece that adds the class "crowned" to its classes on click.
image
layer 1 Same property as in the global properties but with a different default value. Puts the widget above cards (assuming this will be used mostly for tokens / game pieces).
If you add a board using the "Upload board" button on the "Add widget" overlay, the generated widget will have its layer set to -4.
svgReplaces
text "" Text that will be displayed on the widget. Use css to change size and other properties.
See the unicode images at the bottom of the "Game Pieces" column in the "Add widget" overlay as examples.

Button

Property Default value Description
backgroundColor
backgroundColorOH
borderColor
borderColorOH
classes "" The same global default. But buttons support a "transparent" class here that removes the default white background.
clickable true Same property as in the global properties but with a different default value.
clickRoutine [] This is what happens when you click the button. See Functions.
color
image
layer -1 Same property as in the global properties but with a different default value. Puts the button below cards/tokens.
movable false Same property as in the global properties but with a different default value.
svgReplaces
text "" The text displayed on the button.
textColor
textColorOH
typeClasses "widget button" Same property as in the global properties but with a different default value. This gives a button its default appearance. Removing the class "button" MIGHT also break its functionality so just don't touch this property. Consider using "transparent" in classes or set custom appearance with the css property.
width, height 80 Same property as in the global properties but with a different default value.

Canvas

Property Default value Description
activeColor 1 The default color is VirtualTableTop blue (#1F5CA6).
c00 - c99 null Canvas encodes pixels and colors into properties labeled c00 to c99. These change dynamically as the canvas is used.
colorMap [ ] A button cycles through the default color palette in the following order: #1F5CA6, #000000, #FF0000, #008000, #FFFF00, #FFA500, #FFC0CB, #800080, #A52A2A,#F0F0F0. Different built-in palettes are available, but the array values may be also be custom modified as desired.
resolution 100 Controls size of pixels displayed on the canvas. The larger the number, the finer the detail.
typeClasses "widget canvas" Same property as in the global properties but with a different default value. This gives a canvas its default appearance. You should not alter this property or the canvas widget might break.
width, height 400, 400 Same property as in the global properties but with a different default value. Although the default values are 400x400, the composed widget that is added through the Add Widget button is 800x800.

Card

Property Default value Description
activeFace 0 The index of the currently visible card face. This is what changes when you click the card (or flip the card using a button). The faces are defined in the deck.
clickable true Same property as in the global properties but with a different default value.
deck null This is the id of a deck.
Leaving this null will probably break or at least make the card REALLY useless.
If you want to create a card without a deck, consider using a BasicWidget.
faceCycle "ordered" Can be "ordered" or "random". The "ordered" faceCycle allows to iteratively cycle through the faces
height 160 Same property as in the global properties but with a different default value. Typically, this is set using deck's cardDefaults.
typeClasses "widget card" Same property as in the global properties but with a different default value. This gives the card its default appearance. Without the class "card" the objects defined in the deck will not display properly. Use classes or css to customize its appearance.
width 103 Same property as in the global properties but with a different default value. Typically, this is set using deck's cardDefaults.

Deck

Property Default value Description
cardDefaults {} An object of any properties that will be "added" to all the cards belonging to this deck. See cards. Example: { "width": 70, "height": 70 }
cardTypes {} The definition of all different card types. This will be its own wiki page, but for now here is an example: { "1J": {"image": "/i/cards-default/1J.svg"}, "2J": {"image": "/i/cards-default/2J.svg"}, ... }
faceTemplates [] The definition of how the different faces of the cards look like. This will be its own wiki page, but for now, here is an example from the Rotation tutorial: [ {"border": false,"radius": 8,"objects": [{"type": "image", "x": 0, "y": 0, "width": 103, "height": 160, "valueType": "static", "value": "/i/cards-default/2B.svg"}] }, {"border": false,"radius": 8,"objects": [{"type": "image", "x": 0, "y": 0, "width": 103, "height": 160, "valueType": "dynamic", "value": "image" }] } ]
typeClasses "widget deck" Same property as in the global properties but with a different default value. This gives the deck its default appearance and hides it in play mode.
width, height 86 Same property as in the global properties but with a different default value. Please note that this has nothing to do with the cards and only affects the edit mode representation of the deck.

Holder

Holders are marked areas on a board you can put cards (or other widgets if you override dropTarget) into. If multiple cards are inside a holder (or piled anywhere on the board), they form a pile with the number of cards attached to it.

Property Default value Description
alignChildren true If set to false, a new child will not be aligned to the holder. So you can have a hand area where the player can put widgets wherever he wants.
childrenPerOwner false If set to true, a new child will have its owner set to the player dragging the child.
This is set to true when you add a new hand.
dropLimit -1 (no limit) The holder will not act as a valid drop target if adding the widgets would exceed the limit
dropOffsetX, dropOffsetY 4 Same property as in the global properties but with a different default value.
dropTarget { "type": "card" } This defines what widgets can be put into this holder and what widgets are affected by button operations using this holder. It can check any property of the potential child.
The default is that any card works. A good example would be using deck instead.
height 168 Same property as in the global properties but with a different default value. It's the default card height plus two times dropOffsetY.
layer -3 Same property as in the global properties but with a different default value. Above boards but below everything else.
movable false Same property as in the global properties but with a different default value.
onEnter {} A set of properties that is applied to new children when they enter this holder.
For example setting the activeFace to 1 so cards flip to their front face when putting them into the hand. To perform some type of automation when a widget enters the holder, use [[enterRoutine
onLeave {} See onEnter. Only applied when the child leaves the holder. To perform some type of automation when a widget enters the holder, use [[leaveRoutine
stackOffsetX, stackOffsetY 0 If alignChildren is true, the first child will get dropOffsetX as its x; the second child will get dropOffsetX+stackOffsetX as its x and so forth. So this is the offset between children (cards) for example in the hand. See overlap for an exception.
typeClasses "widget holder" Same property as in the global properties but with a different default value. This gives the holder its default appearance. No guarantees if you change this.
width 111 Same property as in the global properties but with a different default value. It's the default card width plus two times dropOffsetX.

Label

Property Default value Description
editable false If this is set to true, players can edit the text while playing.
height 20 Same property as in the global properties but with a different default value.
layer -2 Same property as in the global properties but with a different default value. Above boards and holders but below everything else.
movable false Same property as in the global properties but with a different default value.
text "" The text displayed on the label.
twoRowBottomAlign false This is a pretty hack way to make the label resemble playingcards.io holder labels.
If the text does not span two rows, a padding-top value is applied to make it bottom aligned.
The problem is that labels are always a <textarea>. That may probably change.
typeClasses "widget label" Same property as in the global properties but with a different default value. Without "label" it will be weird. Because editable.

Pile

Piles are multiple cards with a handle to move, shuffle or flip all of them.

Property Default value Description
alignChildren true This is a holder property but if this is false, the pile would not properly stack its children/cards.
inheritChildZ true Same property as in the global properties but with a different default value. For the player the pile is just a "virtual" object so it should inherit the Z value of its children.
layer -2 Same property as in the global properties but with a different default value. Above boards and holders but below everything else.
movable false Same property as in the global properties but with a different default value.
typeClasses "widget pile" Same property as in the global properties but with a different default value. Without "pile" the handle probably totally breaks.
width, height 1 Same property as in the global properties but with a different default value. This is set to its first child when it is created on the fly.
x, y 4 Same property as in the global properties but with a different default value. It's 4 because the dropOffsetX/Y on holders is 4 by default.

Spinner

Property Default value Description
angle 0 The angle of the arrow in degrees. It determines the value but if you edit the widget directly, they can differ until someone spins the spinner again. Right is 0, Bottom is 90.
backgroundCSS "" Custom CSS that will be added to the generated background SVG (the options).
clickable true Same property as in the global properties but with a different default value.
lineColor "'#d2d2d2'" Changes the color of the lines that divides the options.
movable false Same property as in the global properties but with a different default value.
options [1,2,3,4,5,6] The different values the spinner can output. The default is equivalent to a normal die.
spinnerCSS "" Custom CSS that will be added to the spinning arrow (the arrow itself is the background-image).
textColor "#000000" Changes the font color of the spinner's options.
typeClasses "widget spinner" Same property as in the global properties but with a different default value. Without "spinner" the spinner will die a horrible death.
value "🎲" The current value of the spinner that is displayed on top of it. Changed when clicking/spinning it.
valueCSS "" Custom CSS that will be added to the overlay circle that shows the current value.
width, height 110 Same property as in the global properties but with a different default value. Non-square spinners probably break in horrible ways.

Timer

Property Default value Description
alert false If set to true and if the timer reaches a set "end" time, then the timer's CSS will change to red.
countdown false If set to true the timer will countdown when activated.
end null Time, in milliseconds, used as a reference to activate the alert property.
height 36 Same property as in the global properties but with a different default value.
layer -1 Same property as in the global properties but with a different default value. Above boards and holders but below everything else.
milliseconds 0 Time displayed by the timer. This value is converted to minutes and seconds in the timer.
movable false Same property as in the global properties but with a different default value.
paused true If set to false the timer will start running.
precision 1000 Time, in milliseconds, between each update of the property "milliseconds." Values below 100 (1/10 of a second) will be converted to 100 although the user entered value will still be displayed
start 0 Time used by click routines to reset the timer.
typeClasses "widget timer" Same property as in the global properties but with a different default value. Without "widget timer" the css for the timer will be the same as for a default widget.
width 74 Same property as in the global properties but with a different default value.
Clone this wiki locally