28118 sujets

CSS et mise en forme, CSS3

Pages :
(reprise du message précédent)

ce qui donne upload/1685811284-61012-move.png
Modifié par alain_47 (03 Jun 2023 - 18:54)
Bonjour,

Merci beaucoup mais la réponse est collective.

Pour tout dire, je ne savais pas que les pièces de jeu d'échecs existaient en code UTF. Très pratique.

Ce matin, je suis en train de modifier un peu le <table> en mettant des <th> pour les lettres et les chiffres.

De même, j'ai un peu modifié le CSS (j'ai enlevé les px comme le préciser Parsimonhi).

<table> apporte un peu plus de facilité d'un côté mais en enleve de l'autre (par exemple, plus possible d'utiliser 'aspect-ratio' dans une TD , dommage).

J'ai remarqué également que les pieces blanches, quand elles sont sur les cases 'noires" deviennent grises foncées. On peut y remédier en mettant "color : white" dans les <td> mais dans ce cas c'est les pièces noires qui deviennent blanches ! Il va falloir passer par JS pour contrôler les pieces à mouvoir et dans ce cas mettre la color à white.

C'était un sujet très interessant. Merci de nous l'avoir proposé.

Bonne journée.
Modifié par alain_47 (04 Jun 2023 - 11:24)
alain_47 a écrit :
Bonjour,

Merci beaucoup mais la réponse est collective.
C'était un sujet très interessant. Merci de nous l'avoir proposé.
Bonne journée.

Au plaisir de se recroiser , cette nuit j'ai testé une dernière fois, et j'ai vu un tout petit détail bien caché Smiley rolleyes
Lorsque tu joue ta dernière version RAS sauf que les pièces sont plus haute que large.
Heureusement ces pièces ne sont qu'une fonte alors passe la fonte à 6 au lieu de 8 et ce sera IMPEC

td{
	width: 60px; height: 60px;
	font-size: 6vmin;
	border: 0;
	text-align: center;
}

donc 6vmin Smiley confused Bon dimanche
Merci, j'ai mis 6 vmin.

Voila la derniere mouture (j'ai fait le petit roque et je me suis arreté là).

J'ai repris l'image du marbre de Uniuc que j'ai modifié (png de 16 Ko).

Bonne soirée.
upload/1685884511-61012-plateaumarbre.gif
Je n'ai pas trouvé pour mettre les 'blancs' blancs.

Les pieces noires sont en couleur pleine mais les pieces blanches semblent etre en couleur transparente. Le contour est noir mais l'intérieur est transparent, donc on voit le background.
J'ai essayé "color" mais ca met le contour en blanc, et blanc sur blanc, on ne voit plus rien sur les cases blanches !
J'ai essayé 'opacity' mais rien n'y fait.

voilà les 3 nouveaux fichiers :

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="https://forum.alsacreations.com/topic-4-90489-1.html">
<title>plateau du 04 Juin</title> 
<link rel="stylesheet" href="style.css">
</head>
<body>
    <!--   https://forum.alsacreations.com/topic-4-90489-1.html  - mai 2023  -->
    <div class="plateau">
        <button>Move</button>
        <table>
        <thead>
            <tr>
                <th>&nbsp;</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td>&nbsp;</td> <td></td>
                </tr>
        </thead>
        <tbody>
            <tr id="r8">
                <th>8</th><td>&#9820;</td><td>&#9822;</td><td>&#9821;</td><td>&#9819;</td><td>&#9818;</td><td>&#9821;</td><td>&#9822;</td><td>&#9820;</td> <td></td>
                </tr>
            <tr id="r7">
                <th>7</th><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td> <td></td>
                </tr>
            <tr id="r6">
                <th>6</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td> <td></td>
                </tr>
            <tr id="r5">
                <th>5</th><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td> <td></td>
                </tr>
            <tr id="r4">
                <th>4</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td> <td></td>
                </tr>
            <tr id="r3">
                <th>3</th><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td> <td></td>
                </tr>
            <tr id="r2">
                <th>2</th><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td> <td></td>
                </tr> 
            <tr id="r1">
                <th>1</th><td>&#9814;</td><td>&#9816;</td><td>&#9815;</td><td>&#9813;</td><td>&#9812;</td><td>&#9815;</td><td>&#9816;</td><td>&#9814;</td> <td></td>
                </tr>
        </tbody>
        <tfoot>
            <tr id="r0">
                <th></th><th>a</th><th>b</th><th>c</th><th>d</th><th>e</th><th>f</th><th>g</th><th>h</th> <th></th>
            </tr>
        </tfoot>
        
        </table>
    </div>

<script src="app.js"></script>

</body>
</html>


body {
	display:flex;
	margin: 0; padding: 0;
	height: 100vh; 
	box-sizing: border-box;
}

.plateau{
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	margin: auto;
}

button{
	margin-bottom: 10px;
	background-color: rgb(17, 146, 189);
	color: white;
	border-radius: 5px;
}


table{
	border-collapse: collapse;
	background-image: url('marbre.png');
}
/* inutile ici sauf si on veut mettre des bordures par la suite */

td, th{
	width: 6vmin; line-height: 6vmin;
	border: 0;
	text-align: center;
}
td{font-size: 6vmin;}
th{font-size: 2vmin; color: rgb(20, 100, 180);}

tbody tr:nth-of-type(2n+1) td:nth-of-type(2n){background-color: #1117;}
tbody tr:nth-of-type(2n) td:nth-of-type(2n+1):not(td:nth-of-type(9)){background-color: #1117;}


  let movesCollection = [
        ['d2', 'd4'], ['g8', 'f6'],
        ['c2', 'c4'], ['e7', 'e6'],
        ['b1', 'c3'], ['f8', 'b4'],
        ['d1', 'c2'], ['c7', 'c5'],
        ['d4', 'c5'], ['h8', 'f8'],
                      ['e8', 'g8'],
        ['g1', 'f3'], ['b8', 'a6'] 
    ]

    let moveIndex = 0
    let button = document.querySelector('button');

    button.addEventListener("click", () => {
            if(moveIndex < 13){
                [moveOrigine, moveDestination] = movesCollection[moveIndex] 
                
                let rowOrigine = moveOrigine[1]; 
                let colOrigine = moveOrigine.charCodeAt(0)-96
                let caseOrigine  = document.querySelector(`tbody #r${rowOrigine} td:nth-of-type(${colOrigine})`)
                
                let rowDestination = moveDestination[1];
                let colDestination = moveDestination.charCodeAt(0)-96
                let caseDestination = document.querySelector(` tbody #r${rowDestination} td:nth-of-type(${colDestination})`)
                
                caseDestination.textContent = caseOrigine.textContent
                caseOrigine.textContent = "" 

                moveIndex++
            }
    });

@alain_47 : c'est pas mal du tout ça ! Tu as une page de démo ? Tu pourrais nous commenter ton code (si tu veux bien) ?

Pour la couleur des pièces blanches, je me contenterais de reprendre les pièces noires et de définir leur couleur en blanc, tout simplement (mais perso j'utiliserais plutôt des SVG).
Modifié par Olivier C (06 Jun 2023 - 15:30)
Bonsoir Olivier,

Le code est presque le meme que celui deja mis. Je suis en congés actuellement, alors j'en profite pour coder. Depuis 3 jours, je suis dessus (j'adore ca).

Je vais mettre le nouveau code (très peu de changement par rapport à celui déjà posté) en dessous.

Commenter le code : tres simple. la piece est en fait une lettre. C'est comme mettre la lettre "a" qui est dans une <span>dans une autre span. La difficulté est la lettre. Par exemple la lettre "d" dans "d2" est la 4eme lettre à partir de la lettre "a". J'ai pensé au code ANSI, et là j'ai trouvé les codes des lettres. A partir de là, il suffisait d'enlever 96 à tous les code ANSI pour trouver la place de la colonne (lettre 'd' = colonne 4). Donc "d2" vaut colonne 4 ligne 2. Comme j'ai utilisé un <table> avec un "id" : tres facile de trouver <tr id=2> et <td:nth-of-type(4)>.

Pour les cases, j'ai fait à "taton". J'ai vu les solutions avec les <div>, j'avoue que j étais perdu. Mais je me suis dis qu'en faisant les lignes paires et ensuite les lignes impaires, on avait besoin que de 2 lignes et ca faisait toutes les cases.

Pour le code JS pour "play" je ne l'ai pas encore fait. Mais tres simple, il suffira de faire un "intervale" en JS. J'ai mis toutes les infos utilisées dans le JS dans un "array". Ca m'a semblé plus simple car on utilise les 2 premiers éléments, mais on peut très bien ajouter des éléments complémentaires (je le ferai pour le roque, et pour le 'echec' et le 'mat').

Ce qu'il reste à faire :

- allumer la case de depart et d'arrivee pendant quelques secondes
- essayer de faire un passage "lent" d'une case à une autre avec des @keyframes
- externaliser le "array" des DATA pour pouvoir utiliser d'autres arrays voire une BD
...

Bonne soiree ... et bravo à tous ceux qui ont participé qui ont apporté la pierre à l'édifice (encore merci au (grand) Parsimonhi qui a tjrs été présent).


NB : pour le "play" j'ai vu ca ce matin sur un site d'échecs , de meme que la partie du norvégien Magnus CARLSEN , le plus grand champion du monde (il a atteint un classement "ELO" le plus élevé de tous les temps ; 5 fois champions d'echecs ... il court après le record de Kasparov 6 fois champion du monde d'echec).
Modifié par alain_47 (07 Jun 2023 - 06:58)
voici les 3 codes :


<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="https://forum.alsacreations.com/topic-4-90489-1.html">
<title>Rejouer une partie</title> 
<link rel="stylesheet" href="style.css">
</head>
<body>

    <div class="container">
        <div class="view">
            <div> <button>Move</button> <button>Play</button> </div>
            <table>
                <thead>
                    <tr>
                        <th>&nbsp;</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td>&nbsp;</td> <td></td>
                        </tr>
                </thead>
                <tbody>
                    <tr id="r8">
                        <th>8</th><td>&#9820;</td><td>&#9822;</td><td>&#9821;</td><td>&#9819;</td><td>&#9818;</td><td>&#9821;</td><td>&#9822;</td><td>&#9820;</td> <td></td>
                        </tr>
                    <tr id="r7">
                        <th>7</th><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td><td>&#9823;</td> <td></td>
                        </tr>
                    <tr id="r6">
                        <th>6</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td> <td></td>
                        </tr>
                    <tr id="r5">
                        <th>5</th><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td> <td></td>
                        </tr>
                    <tr id="r4">
                        <th>4</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td> <td></td>
                        </tr>
                    <tr id="r3">
                        <th>3</th><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td> <td></td>
                        </tr>
                    <tr id="r2">
                        <th>2</th><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td><td>&#9817;</td> <td></td>
                        </tr> 
                    <tr id="r1">
                        <th>1</th><td>&#9814;</td><td>&#9816;</td><td>&#9815;</td><td>&#9813;</td><td>&#9812;</td><td>&#9815;</td><td>&#9816;</td><td>&#9814;</td> <td></td>
                        </tr>
                </tbody>
                <tfoot>
                    <tr id="r0">
                        <th></th><th>a</th><th>b</th><th>c</th><th>d</th><th>e</th><th>f</th><th>g</th><th>h</th> <th></th>
                    </tr>
                </tfoot>
            </table>
        </div>
        <div class="moves">
            <h1>M. CARLSEN<br> &nbsp; / S. TER-SAHAKYAN</h1>
            <p>Janvier 2023</p>
            <table>
                    <thead>
                        <tr>
                            <th>N°</th>
                            <th>Blancs</th>
                            <th>Noirs</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr> <td>1.</td><td>a4</td><td><span>&#9822;</span>f6</td> </tr>
                        <tr> <td>2.</td><td>d4</td><td>d5</td> </tr>
                        <tr> <td>3.</td><td>&#9816;f3</td><td><span>&#9821;</span>f5</td> </tr>
                        <tr> <td>4.</td><td>&#9816;h4</td><td><span>&#9821;</span>e4</td> </tr>
                        <tr> <td>5.</td><td>f3</td><td><span>&#9821;</span>g6</td> </tr>
                        <tr> <td>6.</td><td>&#9816;c3</td><td><span></span>c5</td> </tr>
                        <tr> <td>7.</td><td>e4</td><td><span></span>cxd4</td> </tr>
                        <tr> <td>8.</td><td>&#9816xG6</td><td><span></span>hxg6</td> </tr>
                        <tr> <td>9.</td><td>&#9813;xd4</td><td><span>&#9822;</span>c6</td> </tr>
                        <tr> <td>10.</td><td>&#9813;f2</td><td><span></span>d4</td> </tr>
                        <tr> <td>11.</td><td>&#9816;d1</td><td><span></span>e5</td> </tr>
                        <tr> <td>12.</td><td>&#9815;c4</td><td><span>&#9820;</span>c8</td> </tr>
                    </tbody>
            </table>
        </div>
    </div>
    
<script src="app.js"></script>

</body>
</html>



body {
	margin: 0; padding: 0;
	display:flex;
	justify-content: center;
	align-items: center;
	height: 100vh; 
	box-sizing: border-box;
	background-color: rgb(3, 117, 3);
}


.container{
	display:flex;
	flex-direction: row;
	justify-content: center;
	align-items: center;
}


/* -------- Plateau et annexes --------- */
.view{
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	margin: auto;
}

.view div{margin-bottom: 10px;}
button{
	margin-bottom: 10px;
	background-color: rgb(17, 146, 189);
	color: white;
	border-radius: 5px;}
.view button:nth-of-type(1){margin-right: 20px;}

.view table{
	border-collapse: collapse;
	background-image: url('marbre.png');
	border-radius: 8px;
}


.view td, th{
	width: 6vmin; line-height: 6vmin;
	border: 0;
	text-align: center;
}
.view td{font-size: 6vmin;}
.view th{font-size: 2vmin; color: rgb(20, 100, 180);}

.view tbody tr:nth-of-type(2n+1) td:nth-of-type(2n){background-color: #1117;}
.view tbody tr:nth-of-type(2n) td:nth-of-type(2n+1):not(td:nth-of-type(9)){background-color: #1117;}

.texte{color : grey;}

/* ------- Coups joués ---------  */ 
.moves{
	font-size: 2vmin;
	margin: auto;
	margin-left: 50px;
}

h1{font-size: 2vmin;}
.moves h1+p{text-align: center; font-size: 1.2vmin; margin-top: -10px;}

.moves table{text-align: center; margin-left: -15px;}
.moves th{font-size: 1.5vmin; line-height: 3vmin; text-align: right;}
.moves th:nth-of-type(1){padding-right: 20px;}
.moves tbody td{color: white; width: 3vmin; text-align: right;}
.moves tbody td:nth-of-type(1){font-size: 1.5vmin; color: rgb(197, 197, 189); padding-right: 20px;}
.moves tbody span{color: black;}



let movesCollection = [
        ['a2', 'a4'], ['g8', 'f6'],
        ['d2', 'd4'], ['d7', 'd5'],
        ['g1', 'f3'], ['c8', 'f5'],
        ['f3', 'h4'], ['f5', 'e4'],
        ['f2', 'f3'], ['e4', 'g6'],
        ['b1', 'c3'], ['c7', 'c5'],
        ['e2', 'e4'], ['c5', 'd4'],
        ['h4', 'g6'], ['h7', 'g6'],
        ['d1', 'd4'], ['b8', 'c6'],
        ['d4', 'f2'], ['d5', 'd4'],
        ['c3', 'd1'], ['e7', 'e5'],
        ['f1', 'c4'], ['a8', 'c8']
    ]

    let moveIndex = 0
    let button = document.querySelector('button');

    button.addEventListener("click", () => {
            if(moveIndex < movesCollection.length){
                [moveOrigine, moveDestination] = movesCollection[moveIndex] 
                
                let rowOrigine = moveOrigine[1]; 
                let colOrigine = moveOrigine.charCodeAt(0)-96
                let caseOrigine  = document.querySelector(`tbody #r${rowOrigine} td:nth-of-type(${colOrigine})`)
                
                let rowDestination = moveDestination[1];
                let colDestination = moveDestination.charCodeAt(0)-96
                let caseDestination = document.querySelector(` tbody #r${rowDestination} td:nth-of-type(${colDestination})`)
                
                caseDestination.textContent = caseOrigine.textContent
                caseOrigine.textContent = "" 

                moveIndex++
            }
    });
Merci pour toutes ces explications. Moi aussi je code sur mon temps libre (et j'adore ça !). Si ça continue comme ça je vais moi aussi finir par m'y mettre tellement c'est passionnant...

Pour les pièces, je parlais de la solution SVG car elle offre des possibilités de personnalisation illimitées **, mais l'unicode peut très bien changer de couleur comme n'importe quel caractère de police : CodePen, chess test unicode color.

** édit : notons que rien n'empêche d'utiliser - voir même de créer - une police d'icônes spécialisée qui ferait le taf. Mais de nos jours, vu le support du SVG natif, ça n'a plus trop d'intérêt.
Modifié par Olivier C (06 Jun 2023 - 23:44)
Bonsoir,

Voila le nouveau fichier JS (fonctionne le "play").



    let movesCollection = [
        ['a2', 'a4'], ['g8', 'f6'],
        ['d2', 'd4'], ['d7', 'd5'],
        ['g1', 'f3'], ['c8', 'f5'],
        ['f3', 'h4'], ['f5', 'e4'],
        ['f2', 'f3'], ['e4', 'g6'],
        ['b1', 'c3'], ['c7', 'c5'],
        ['e2', 'e4'], ['c5', 'd4'],
        ['h4', 'g6'], ['h7', 'g6'],
        ['d1', 'd4'], ['b8', 'c6'],
        ['d4', 'f2'], ['d5', 'd4'],
        ['c3', 'd1'], ['e7', 'e5'],
        ['f1', 'c4'], ['a8', 'c8']
    ]


    function resetPlateau(){
        let piecesNoires = ['&#9820;', '&#9822;', '&#9821;', '&#9819;', '&#9818;', '&#9821;', '&#9822;', '&#9820;']
        let piecesBlanches = ['&#9814;', '&#9816;', '&#9815;', '&#9813;', '&#9812;', '&#9815;', '&#9816;', '&#9814;']
        for(let i=0; i<8; i++){
            // noirs à remplacer
            document.querySelector(`#r8 td:nth-of-type(${i+1})`).innerHTML = piecesNoires[i]
            document.querySelector(`#r7 td:nth-of-type(${i+1})`).innerHTML = '&#9823;'
            // blancs à replacer
            document.querySelector(`#r2 td:nth-of-type(${i+1})`).innerHTML = '&#9817;'
            document.querySelector(`#r1 td:nth-of-type(${i+1})`).innerHTML = piecesBlanches[i]
        }
        // les 4 rangees entre les noirs et blancs. Les cases doivent etre vidées.
        for(let ligne=3; ligne<7; ligne++){
            for(let i=1; i<9; i++){document.querySelector(`#r${ligne} td:nth-of-type(${i})`).innerHTML = ''}
        } 
    }

    // index de la collection (array) des coups à jouer (chaque coup = 1 array)
    let moveIndex = 0 // 1er array de la collection, donc 1er coup à jouer (= 1er déplacement à faire)

    let buttonMove = document.querySelector('.view button:nth-of-type(1)');
    let buttonPlay =  document.querySelector('.view button:nth-of-type(2)');

    

    function stepByStep(){
            if(moveIndex == 0){resetPlateau()}
            if(moveIndex < movesCollection.length){
                move(movesCollection, moveIndex)
                moveIndex++
            }
    }

    function enableFunctionListener(){
        buttonMove.addEventListener("click", stepByStep);
    }
    enableFunctionListener()
    
    // quand 'play' fonctionne, 'move' doit etre desactivé.
    function disableFunctionListener(){
        buttonMove.removeEventListener("click", stepByStep);
    }
    
    


    buttonPlay.addEventListener('click', () => {
        resetPlateau(); 
        disableFunctionListener()
        play(movesCollection)
        // play a fini, remise à zero du compteur 
        moveIndex = 0
    })


    function play(movesCollection){
        function movePlay(moveIndex){
                move(movesCollection, moveIndex)
                if(moveIndex==(movesCollection.length-1)){enableFunctionListener(); return}
                /* else */ setTimeout( ()=>{ movePlay(moveIndex+1)  }, 1500)
            }
            movePlay(0)
    }


    /**
     * Fconction commune . fait le deplacement d'une case à une autre.
     * @param {array} movesCollection 
     * @param {number} moveIndex
     * @return {void} 
     */
    function move(movesCollection, moveIndex)
    { 
        let moveOrigine = movesCollection[moveIndex][0]
            let moveDestination = movesCollection[moveIndex][1]
                                    
            let rowOrigine = moveOrigine[1]; 
            let colOrigine = moveOrigine.charCodeAt(0)-96
            let caseOrigine  = document.querySelector(`tbody #r${rowOrigine} td:nth-of-type(${colOrigine})`)
                                    
            let rowDestination = moveDestination[1];
            let colDestination = moveDestination.charCodeAt(0)-96
            let caseDestination = document.querySelector(` tbody #r${rowDestination} td:nth-of-type(${colDestination})`)
                                    
            caseDestination.textContent = caseOrigine.textContent
            caseOrigine.textContent = "" 
    }


En principe, ca marche, mais quelle galère.
Je voulais faire array.foreach( ... ) avec à l'interieur un 'setTimeout' mais pble car il faut une fonction asynchrone. J'ai utilisé une astuce vu chez Grafikart : fonction qui s'auto-appelle et s'auto-implémente : plus besoin d'utiliser async await. ouf !

Bon, il reste encore à faire.

Pour la couleur des blancs, ce n'est pas encore trop grave. on peut laisser comme ça.