X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=public%2Fjavascripts%2Fcomponents%2Fboard.js;h=a59e41f7bc1d68d048b498f08fca1676986c36e4;hb=b955c65b942d09d24b5c3bed0d755d4f2f8f71f1;hp=e786e899fda24261165f68c67c2c1f1289cf522b;hpb=8d7e2786f5a67a1b9a77c742d7951e0efbe8747d;p=vchess.git diff --git a/public/javascripts/components/board.js b/public/javascripts/components/board.js index e786e899..a59e41f7 100644 --- a/public/javascripts/components/board.js +++ b/public/javascripts/components/board.js @@ -1,3 +1,13 @@ +// This can work for squared boards (2 or 4 players), with some adaptations (TODO) +// TODO: for 3 players, write a "board3.js" +Vue.component('my-board', { + // Last move cannot be guessed from here, and is required to highlight squares + // vr: object to check moves, print board... + // mode: HH, HC or analyze + // userColor: for mode HH or HC + props: ["vr","lastMove","mode","orientation","userColor"], + data: function () { + return { hints: (!localStorage["hints"] ? true : localStorage["hints"] === "1"), bcolor: localStorage["bcolor"] || "lichess", //lichess, chesscom or chesstempo possibleMoves: [], //filled after each valid click/dragstart @@ -5,235 +15,231 @@ selectedPiece: null, //moving piece (or clicked piece) incheck: [], start: {}, //pixels coordinates + id of starting square (click or drag) - vr: null, //object to check moves, store them, FEN.. - orientation: "w", //useful if click on "flip board" - - - - const [sizeX,sizeY] = [V.size.x,V.size.y]; + }; + }, + render(h) { + if (!this.vr) + return; + const [sizeX,sizeY] = [V.size.x,V.size.y]; // Precompute hints squares to facilitate rendering let hintSquares = doubleArray(sizeX, sizeY, false); this.possibleMoves.forEach(m => { hintSquares[m.end.x][m.end.y] = true; }); // Also precompute in-check squares let incheckSq = doubleArray(sizeX, sizeY, false); this.incheck.forEach(sq => { incheckSq[sq[0]][sq[1]] = true; }); - const choices = h('div', - { - attrs: { "id": "choices" }, - 'class': { 'row': true }, - style: { - "display": this.choices.length>0?"block":"none", - "top": "-" + ((sizeY/2)*squareWidth+squareWidth/2) + "px", - "width": (this.choices.length * squareWidth) + "px", - "height": squareWidth + "px", - }, + const squareWidth = 40; //TODO: compute this + const choices = h( + 'div', + { + attrs: { "id": "choices" }, + 'class': { 'row': true }, + style: { + "display": this.choices.length>0?"block":"none", + "top": "-" + ((sizeY/2)*squareWidth+squareWidth/2) + "px", + "width": (this.choices.length * squareWidth) + "px", + "height": squareWidth + "px", }, - this.choices.map( m => { //a "choice" is a move - return h('div', - { - 'class': { - 'board': true, - ['board'+sizeY]: true, - }, - style: { - 'width': (100/this.choices.length) + "%", - 'padding-bottom': (100/this.choices.length) + "%", - }, + }, + this.choices.map(m => { //a "choice" is a move + return h('div', + { + 'class': { + 'board': true, + ['board'+sizeY]: true, + }, + style: { + 'width': (100/this.choices.length) + "%", + 'padding-bottom': (100/this.choices.length) + "%", }, - [h('img', - { - attrs: { "src": '/images/pieces/' + - VariantRules.getPpath(m.appear[0].c+m.appear[0].p) + '.svg' }, - 'class': { 'choice-piece': true }, - on: { - "click": e => { this.play(m); this.choices=[]; }, - // NOTE: add 'touchstart' event to fix a problem on smartphones - "touchstart": e => { this.play(m); this.choices=[]; }, - }, - }) - ] - ); - }) - ); - // Create board element (+ reserves if needed by variant or mode) - const lm = this.vr.lastMove; - const showLight = this.hints && variant.name!="Dark" && - (this.mode != "idle" || - (this.vr.moves.length > 0 && this.cursor==this.vr.moves.length)); - const gameDiv = h('div', - { - 'class': { - 'game': true, - 'clearer': true, }, - }, - [_.range(sizeX).map(i => { - let ci = (this.mycolor=='w' ? i : sizeX-i-1); - return h( - 'div', + [h('img', { - 'class': { - 'row': true, + attrs: { "src": '/images/pieces/' + + V.getPpath(m.appear[0].c+m.appear[0].p) + '.svg' }, + 'class': { 'choice-piece': true }, + on: { + "click": e => { this.play(m); this.choices=[]; }, + // NOTE: add 'touchstart' event to fix a problem on smartphones + "touchstart": e => { this.play(m); this.choices=[]; }, }, - style: { 'opacity': this.choices.length>0?"0.5":"1" }, - }, - _.range(sizeY).map(j => { - let cj = (this.mycolor=='w' ? j : sizeY-j-1); - let elems = []; - if (this.vr.board[ci][cj] != VariantRules.EMPTY && (variant.name!="Dark" - || this.score!="*" || this.vr.enlightened[this.mycolor][ci][cj])) - { - elems.push( - h( - 'img', - { - 'class': { - 'piece': true, - 'ghost': !!this.selectedPiece - && this.selectedPiece.parentNode.id == "sq-"+ci+"-"+cj, - }, - attrs: { - src: "/images/pieces/" + - VariantRules.getPpath(this.vr.board[ci][cj]) + ".svg", - }, - } - ) - ); - } - if (this.hints && hintSquares[ci][cj]) - { - elems.push( - h( - 'img', - { - 'class': { - 'mark-square': true, - }, - attrs: { - src: "/images/mark.svg", - }, - } - ) - ); - } - return h( - 'div', - { - 'class': { - 'board': true, - ['board'+sizeY]: true, - 'light-square': (i+j)%2==0, - 'dark-square': (i+j)%2==1, - [this.bcolor]: true, - 'in-shadow': variant.name=="Dark" && this.score=="*" - && !this.vr.enlightened[this.mycolor][ci][cj], - 'highlight': showLight && !!lm && _.isMatch(lm.end, {x:ci,y:cj}), - 'incheck': showLight && incheckSq[ci][cj], - }, - attrs: { - id: this.getSquareId({x:ci,y:cj}), - }, - }, - elems - ); }) - ); - }), choices] - ); - if (!!this.vr.reserve) + ] + ); + }) + ); + // Create board element (+ reserves if needed by variant or mode) + const lm = this.lastMove; + const showLight = this.hints && variant.name != "Dark"; + const gameDiv = h( + 'div', { - const shiftIdx = (this.mycolor=="w" ? 0 : 1); - let myReservePiecesArray = []; - for (let i=0; i { + let ci = (this.orientation=='w' ? i : sizeX-i-1); + return h( + 'div', { - 'class': {'board':true, ['board'+sizeY]:true}, - attrs: { id: this.getSquareId({x:sizeX+shiftIdx,y:i}) } + 'class': { + 'row': true, + }, + style: { 'opacity': this.choices.length>0?"0.5":"1" }, }, - [ - h('img', + _.range(sizeY).map(j => { + let cj = (this.orientation=='w' ? j : sizeY-j-1); + let elems = []; + if (this.vr.board[ci][cj] != V.EMPTY && (variant.name!="Dark" + || this.gameOver || this.mode == "analyze" + || this.vr.enlightened[this.userColor][ci][cj])) { - 'class': {"piece":true, "reserve":true}, - attrs: { - "src": "/images/pieces/" + - this.vr.getReservePpath(this.mycolor,i) + ".svg", - } - }), - h('sup', - {"class": { "reserve-count": true } }, - [ this.vr.reserve[this.mycolor][VariantRules.RESERVE_PIECES[i]] ] - ) - ])); - } - let oppReservePiecesArray = []; - const oppCol = this.vr.getOppCol(this.mycolor); - for (let i=0; i 1) @@ -355,31 +350,8 @@ }); return moves; }, - animateMove: function(move) { - let startSquare = document.getElementById(this.getSquareId(move.start)); - let endSquare = document.getElementById(this.getSquareId(move.end)); - let rectStart = startSquare.getBoundingClientRect(); - let rectEnd = endSquare.getBoundingClientRect(); - let translation = {x:rectEnd.x-rectStart.x, y:rectEnd.y-rectStart.y}; - let movingPiece = - document.querySelector("#" + this.getSquareId(move.start) + " > img.piece"); - // HACK for animation (with positive translate, image slides "under background") - // Possible improvement: just alter squares on the piece's way... - squares = document.getElementsByClassName("board"); - for (let i=0; i { - for (let i=0; i