User talk:קיפודנחש/chess-animator.js

About this board

קיפודנחש (talkcontribs)

this script is used with conjunction with a back-end piece (currently Module:ChessBowserPrototype), which generates the HTML of a chessboard with notations, buttons, etc. and passes a data-structure that represents the progress of the chess game. the structure is documented at the top of the module.

below a short description of the code itself.

General

The code does mainly 2 things:

  • parse the data created by the back-end, and generates the required data structures for the rest
  • installs event-handlers responding to button and annotation clicks. the main job of these handlers is to "goto" a specific ply: e.g., clicking the "advance" button will "goto" the next ply, clicking any specific annotation will go to the corresponding ply etc. there are 2 exceptions: start/stop autoplay, and "flip". in the future there might be one more - hide/show comments.

generated data structures

there are 2 data-structures: "pieces" and "boards".

  • "pieces" are div elements, generated during the "parsing" stage. each such element carry several classes: a "piece" class, which causes it to show the image of the piece, using the "background-image" attribute, a "row" and "file" classes that cause it to be shown in the correct position, and one or two auxiliary classes, e.g. a class to "hide" it, when the ply is past the one this piece was captured. for convenience there is on "pieces" array holding all those pieces.
  • "boards" are sparsely populated arrays, whose indexes represent square: index 0 is a1, 1 is a2, 8 is b1, and 63 is h8. the content of the "board" are pointers to the pieces described above - each non-empty square points to the piece occupying it at that ply. the whole game is an array of those "boards" - one for each ply.

both data structures are generated and populated 2 functions: the 19-liner processFen(fen) takes the "fen" of the opening position (passed by the back-end), and generate board #0, and (almost) all the pieces, and the 18-liner processPly(board, ply) function, creates the next board out of the current one and the ply passed by the back-end. processPly() will create a new piece, when encountering a promotion.

since it's expected that the back-end will already populate the board, so no-JS readers, as well as "print" rendering will show it, the first thing the generating function does is removing the existing "piece" divs. the two funhctions mentioned above use a createPiece() function which generate the piece, shoves it into the "pieces" array, and append it to the container div, representing the chessboard. it the returns the piece object, so the caller can add it to the current board in the correct index, or square.

event handlers

as mentioned above, the main function is the script is gotoBoard(plyNum). there are 3 actions that need to be taken in order to do that:

  • draw the board as appears for this ply
  • mark the appropriate notation corresponding to this ply
  • show the "source" and "destination" squares in the last ply resulting in this "plyNum". we call this "<code>showPly()</code>".

almost everything is done by toggling css classes on and off. drawing the board is done by setting the "don't show your face here" to all the pieces that exist in the "pieces" array, but not on the current board. for all the pieces that _are_ on this board, i.e., are pointed to by one of the array entries, the row and file are calculated from the index, and the appropriate row/file "class" is attached to the div, while all other row/file classes are removed, and the "go hide" class is also removed.

for the annotations, there is a "current move" class (pgn-current-move). this class is cleaned from all the notations, and then attached to the one matching the ply#.

the only action not done by adding/removing CSS classes is the act of scrolling the "notations" container such that the current notation is visible. although there it's possible to do this also by using CSS, i could not figure out a way to do this politely: using css means telling the "current move" to be visible not only in its own container, but in the browse at large which may trigger scrolling of the whole page - not a very polite thing to do. so this is done by setting the "scrollTop" attribute of the notations' container.

apart for this one little infraction, the only thing the event handlers do is toggle classes for the appropriate elements: the pieces, the notations, and the buttons themselves.

flipping is implemented by toggling a "flip-it" class to the container div, and an "on-state" class to the button. the CSS defines different "top" and "left" to the row and file classes, when they appear after "flip". here is a fragment:

/* raw (aka "rank" ) */
.pgn-flip	.pgn-prow-0, .pgn-prow-7 { top: 0; }
.pgn-flip	.pgn-prow-1, .pgn-prow-6 { top: 12.5%; }
/* and so on and so forth */
/* file */
.pgn-flip	.pgn-pfile-7, .pgn-pfile-0 { left: 0; }
.pgn-flip	.pgn-pfile-6, .pgn-pfile-1 { left: 12.5%; }
/* ditto */

showPly()

this is meant to indicate the last move that led to the currently viewed board. so there are no marking for the opening board of the game. marking is done so:

  • if there is an element with class "pgn-ply-source", this element is given the appropriate file and row classes, so it will position itself on the correct square.
  • for the "destination", the logic is a bit different: since there's always a piece on the destination square, we do not create a special "destination" element, and instead, we attach "pgn-ply-destination" class to the piece on the destination square. defining display attributes to these classes will mark the source/destination square for each move.
  • and last, but not least, we also draw an arrow from source square to distination square.

the visual effect can be modified or even eliminated by assigning and removing attributes from the pgn-ply-source and pgn-ply-destination css classes.

in order to draw the arrow, front-end utilizes a "canvas" element. this is done, unconditionally, in a single function (drawArraw(source, dest)). eventually, some logic is required so the arrow can be enabled or disabled, either by the back-end, by the reader, or both.

Reply to "Outline"
There are no older topics