commit 2cfb5211c323a2b446dab2eced1aa8a8d1b9a6c2 Author: Wamster Date: Mon Feb 26 19:17:32 2024 +0100 TP01, TP02 & TP03EX01 diff --git a/TP01/EX1/app.js b/TP01/EX1/app.js new file mode 100644 index 0000000..1b1d9d1 --- /dev/null +++ b/TP01/EX1/app.js @@ -0,0 +1,73 @@ +import render from "./modules/langton-renderer-canvas2d"; +import Ant from "./modules/Ant.js"; + + +const options = { + antStateColors : ['red','yellow'], + tileStateColors : ['white','black'], + tileSize : 10 +}; + + +// For the view + +const STEP_INTERVAL = 5; +const BTN_AUTOPLAY_ID = 'autoplay'; +const BTN_NEXT_MOVE_ID = 'next-move'; +const BTN_RESET_ID = 'reset'; +const MOVE_VAL_ID = 'move-value'; +const BTN_PLUS_100_ID = 'plus-100'; + + + + +let autoplayInterval; +let auto=false; +let canvas = document.querySelector("canvas"); + + +canvas.width = window.innerWidth ; +canvas.height = window.innerHeight; + +let ant = new Ant(Math.floor(canvas.width / options.tileSize),Math.floor(canvas.height/options.tileSize)); + +function boucle() { + ant.moveForward(); + updateView(ant,canvas,options) + if (auto === true){ + setTimeout(boucle, STEP_INTERVAL); + } + } + +document.getElementById(BTN_AUTOPLAY_ID).addEventListener('click', () => { + auto = !auto; + boucle(); +}); + + +document.getElementById(BTN_PLUS_100_ID).addEventListener('click', () => { + for (let i=0; i<100; i++){ + ant.moveForward(); + } + updateView(ant,canvas,options) +}); + +document.getElementById(BTN_NEXT_MOVE_ID).addEventListener('click', () => { + ant.moveForward(); + updateView(ant,canvas,options) +}) + +document.getElementById(BTN_RESET_ID).addEventListener('click', () => { + ant.reset(); + updateView(ant,canvas,options) +}) + + +function updateView(ant,canvas,options) +{ + document.getElementById(MOVE_VAL_ID).textContent = `${ant.move}`; + render(ant,canvas,options); +} + + +updateView(ant,canvas,options,1) diff --git a/TP01/EX1/index.html b/TP01/EX1/index.html new file mode 100644 index 0000000..e5dde01 --- /dev/null +++ b/TP01/EX1/index.html @@ -0,0 +1,47 @@ + + + + + + + + Fourmi de Langton + + + + + + +
+

+ Fourmi de Langton +

+ + + +

+ Nombre de mouvements : +

+
+ + + + diff --git a/TP01/EX1/modules/Ant.js b/TP01/EX1/modules/Ant.js new file mode 100644 index 0000000..2dfb4f2 --- /dev/null +++ b/TP01/EX1/modules/Ant.js @@ -0,0 +1,86 @@ +class Ant { + x = 0; // position + y = 0; + move = 0; + + w = 0; // universe dimensions + h = 0; + + direction = 0; // 0 90 180 270 + state = 0; + tiles = null; + + constructor (w,h) + { + this.tiles = new Array(w).fill(null); + this.tiles.forEach((el,i) => this.tiles[i] = new Array(h).fill(0)); + this.w = w; + this.h = h; + this.x = Math.floor(w/2); + this.y = Math.floor(h/2); + } + + reset() { + this.direction = 0; + this.x = Math.floor(this.w/2); + this.y = Math.floor(this.h/2); + this.state = 0; + this.tiles.forEach(el=>el.fill(0)); + } + + moveForward() + { + switch (this.direction) { + case 0: + this.x = ((this.x + 1) + this.w) % this.w; + break + case 90: + this.y = ((this.y + 1) + this.h) % this.h; + break + case 180: + this.x = ((this.x - 1) + this.w) % this.w; + break + case 270: + this.y = ((this.y - 1) + this.h) % this.h; + break + } + this.move ++; + this.computeNextState(); + } + rotateRight() { + // TODO + this.direction = (this.direction+90)%360; + } + + rotateLeft() { + // TODO + this.direction = (this.direction+270)%360; + } + + computeNextState() + { + // TODO + if (this.tiles[this.x][this.y]===1){ //noir + if (this.state ===1){ + this.state = 0; + this.tiles[this.x][this.y] = 0; + } + else{ + this.rotateLeft(); + this.tiles[this.x][this.y] = 0; + } + } + else{ // blanc + if (this.state ===1){ + this.rotateRight(); + this.tiles[this.x][this.y] = 1; + } + else{ + this.state = 1; + this.tiles[this.x][this.y] = 1; + } + } + } +} + +export default Ant; diff --git a/TP01/EX1/modules/langton-renderer-canvas2d.js b/TP01/EX1/modules/langton-renderer-canvas2d.js new file mode 100644 index 0000000..1551e5a --- /dev/null +++ b/TP01/EX1/modules/langton-renderer-canvas2d.js @@ -0,0 +1,99 @@ +/** + * render - renders the universe to a 2D canvas. + * + * @param langtonsAnt - the universe. + * @param canvas - The 2D canvas. + * @param options - The rendering options (all optional). + * @returns {undefined} - Nothing is returned. + */ + +function render(langtonsAnt, canvas, options) { + + // Grab our options. + const { + tileStateColors, + antStateColors, + tileSize + } = options; + + + // Drawing style. + const backgroundColor = '#FFFFFF'; + + // Size constants. + const w = canvas.width; + const h = canvas.height; + + // Bounds constants. + const gridSizeW = langtonsAnt.tiles.length; + const gridSizeH = langtonsAnt.tiles[0].length; + + // We're going to draw each square with a given edge size + + const tileSizeW = tileSize//w / gridSizeW ; + const tileSizeH = tileSize //h / gridSizeH ; + + // Get the drawing context. + var ctx = canvas.getContext('2d'); + + // Clear the background. + ctx.fillStyle = backgroundColor; + ctx.fillRect(0, 0, w, h); + + // Draw the grid. + ctx.strokeStyle='#00000011'; + for (let x = 0; x <= gridSizeW; x++) { + ctx.beginPath(); + ctx.moveTo(x * tileSizeW , 0); + ctx.lineTo(x * tileSizeW , h); + ctx.closePath(); + ctx.stroke(); + } + for (let y = 0 ; y <= gridSizeH; y++) { + ctx.beginPath(); + ctx.moveTo(0, y * tileSizeH); + ctx.lineTo(w, y * tileSizeH); + ctx.closePath(); + ctx.stroke(); + } + + + // Start drawing those tiles. + langtonsAnt.tiles.forEach((tileRow,i) => { + tileRow.forEach((tile,j)=>{ + + // Get the tile state index. + + // Skip state zero tiles (i.e. white tiles) + if (tile !== 0) { + // Set the tile colour, defaulting to grey if it is not set. + ctx.fillStyle = tileStateColors[tile] || '#CCCCCC'; + ctx.fillRect(i * tileSizeW + 1, j * tileSizeH +1, tileSizeW - 1, tileSizeH - 1); + } + + }) + }) + + + // Draw the ant. + var antX = langtonsAnt.x * tileSizeW, + antY = langtonsAnt.y * tileSizeH; + const antState = langtonsAnt.state; + + ctx.fillStyle = antStateColors[antState]; + // Tranform before we draw the ant, it makes it easier. + // + ctx.save(); + ctx.translate(antX + tileSizeW/2, antY+tileSizeH/2); + ctx.rotate((langtonsAnt.direction / 180) * Math.PI); + ctx.beginPath(); + ctx.moveTo(-tileSizeW/2, -tileSizeH/2); + ctx.lineTo(tileSizeW/2, 0); + ctx.lineTo(-tileSizeW/2, tileSizeH/2); + ctx.fill(); + ctx.closePath(); + ctx.restore(); +} + + +export default render; diff --git a/TP01/EX3/array.html b/TP01/EX3/array.html new file mode 100644 index 0000000..89378d4 --- /dev/null +++ b/TP01/EX3/array.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + +
+
+ +
+

Simple Array

+ +
+ +
+

Add 3 (using map)

+ +
+ +
+

Sorted

+ +
+ +
+

Filtered (positives values)

+ +
+ +
+
+ + diff --git a/TP01/EX3/graph.js b/TP01/EX3/graph.js new file mode 100644 index 0000000..92eb3e6 --- /dev/null +++ b/TP01/EX3/graph.js @@ -0,0 +1,34 @@ +"use strict"; + +const colors = [ + '#00429d', '#204fa3', '#325da9', '#406aaf', '#4e78b5', '#5a86bb', + '#6694c1', '#73a2c6', '#80b1cc', '#8ebfd1', '#9dced6', '#addcda', + '#c0eade', '#d8f6e1', '#ffffe0' +] + +function graph(canvasId, array) { + if (array.length == 0) { + throw "array.length == 0" + } + + var min = array.reduce(function(a, b) { return (a < b)? a: b; }) + var max = array.reduce(function(a, b) { return (a < b)? b: a; }) + + var canvas = document.getElementById(canvasId) + var context = canvas.getContext("2d") + context.clearRect(0, 0, canvas.width, canvas.height) + + context.beginPath() + context.strokeStyle = "black" + context.moveTo(0, canvas.height / 2) + context.lineTo(canvas.width, canvas.height / 2) + context.stroke() + + array.forEach(function(v, i) { + + context.fillStyle = colors[(i) % colors.length] + context.fillRect((i + 0.1) * canvas.width / array.length, canvas.height / 2, 0.8 * canvas.width / array.length, v * canvas.height / (min - max) / 2) + context.strokeText(v, (i + 0.4)* canvas.width / array.length, canvas.height /10) + }) +} + diff --git a/TP01/EX3/minmax.html b/TP01/EX3/minmax.html new file mode 100644 index 0000000..ea5f34a --- /dev/null +++ b/TP01/EX3/minmax.html @@ -0,0 +1,59 @@ + + + + + + + +
+

Random Array

+
+ +

Min/Max

+

+ Min : +

+

+ Max : +

+
+ + + diff --git a/TP02/EX01/data.js b/TP02/EX01/data.js new file mode 100644 index 0000000..27cc9d4 --- /dev/null +++ b/TP02/EX01/data.js @@ -0,0 +1,22 @@ +let data = [ + {"idStanding":"2282066","intRank":"1","idTeam":"133714","strTeam":"Paris SG","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/rwqrrq1473504808.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WLWWW","strDescription":"Promotion - Champions League (Group Stage)","intPlayed":"18","intWin":"15","intLoss":"1","intDraw":"2","intGoalsFor":"48","intGoalsAgainst":"13","intGoalDifference":"35","intPoints":"47","dateUpdated":"2023-01-12 23:01:12"}, + {"idStanding":"2282067","intRank":"2","idTeam":"133822","strTeam":"Lens","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/3pxoum1598797195.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DWDWW","strDescription":"Promotion - Champions League (Group Stage)","intPlayed":"18","intWin":"12","intLoss":"1","intDraw":"5","intGoalsFor":"31","intGoalsAgainst":"13","intGoalDifference":"18","intPoints":"41","dateUpdated":"2023-01-12 23:01:12"}, + {"idStanding":"2282068","intRank":"3","idTeam":"133707","strTeam":"Marseille","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/uutsyt1473504764.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WWWWW","strDescription":"Promotion - Champions League (Qualification)","intPlayed":"18","intWin":"12","intLoss":"3","intDraw":"3","intGoalsFor":"36","intGoalsAgainst":"15","intGoalDifference":"21","intPoints":"39","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282069","intRank":"4","idTeam":"133719","strTeam":"Rennes","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/ypturx1473504818.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LWLWD","strDescription":"Promotion - Europa League (Group Stage)","intPlayed":"18","intWin":"10","intLoss":"4","intDraw":"4","intGoalsFor":"35","intGoalsAgainst":"20","intGoalDifference":"15","intPoints":"34","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282070","intRank":"5","idTeam":"133823","strTeam":"Monaco","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/819x3z1655593495.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DWWLW","strDescription":"Promotion - Europa Conference League (Qualification)","intPlayed":"18","intWin":"10","intLoss":"4","intDraw":"4","intGoalsFor":"35","intGoalsAgainst":"25","intGoalDifference":"10","intPoints":"34","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282071","intRank":"6","idTeam":"133715","strTeam":"Lorient","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/sxsttw1473504748.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DWLDL","strDescription":"","intPlayed":"18","intWin":"9","intLoss":"4","intDraw":"5","intGoalsFor":"30","intGoalsAgainst":"26","intGoalDifference":"4","intPoints":"32","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282072","intRank":"7","idTeam":"133711","strTeam":"Lille","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/2giize1534005340.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DDWWD","strDescription":"","intPlayed":"18","intWin":"9","intLoss":"5","intDraw":"4","intGoalsFor":"30","intGoalsAgainst":"24","intGoalDifference":"6","intPoints":"31","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282073","intRank":"8","idTeam":"133713","strTeam":"Lyon","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/blk9771656932845.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DLWDL","strDescription":"","intPlayed":"18","intWin":"7","intLoss":"7","intDraw":"4","intGoalsFor":"27","intGoalsAgainst":"21","intGoalDifference":"6","intPoints":"25","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282074","intRank":"9","idTeam":"134713","strTeam":"Clermont Foot","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/wrytst1426871249.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WWLLD","strDescription":"","intPlayed":"18","intWin":"7","intLoss":"7","intDraw":"4","intGoalsFor":"22","intGoalsAgainst":"26","intGoalDifference":"-4","intPoints":"25","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282075","intRank":"10","idTeam":"133712","strTeam":"Nice","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/msy7ly1621593859.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WLDDW","strDescription":"","intPlayed":"18","intWin":"6","intLoss":"6","intDraw":"6","intGoalsFor":"22","intGoalsAgainst":"20","intGoalDifference":"2","intPoints":"24","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282076","intRank":"11","idTeam":"133934","strTeam":"Stade de Reims","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/xcrw1b1592925946.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WDWDW","strDescription":"","intPlayed":"18","intWin":"5","intLoss":"4","intDraw":"9","intGoalsFor":"21","intGoalsAgainst":"23","intGoalDifference":"-2","intPoints":"24","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282077","intRank":"12","idTeam":"133703","strTeam":"Toulouse","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/3kqxs61547893229.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"WWLLL","strDescription":"","intPlayed":"18","intWin":"6","intLoss":"8","intDraw":"4","intGoalsFor":"28","intGoalsAgainst":"33","intGoalDifference":"-5","intPoints":"22","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282078","intRank":"13","idTeam":"134789","strTeam":"Troyes","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/swuwpq1426544753.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LWDLD","strDescription":"","intPlayed":"18","intWin":"4","intLoss":"8","intDraw":"6","intGoalsFor":"29","intGoalsAgainst":"35","intGoalDifference":"-6","intPoints":"18","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282079","intRank":"14","idTeam":"133861","strTeam":"Nantes","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/8r0dab1598797469.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DWDDL","strDescription":"","intPlayed":"18","intWin":"3","intLoss":"6","intDraw":"9","intGoalsFor":"18","intGoalsAgainst":"24","intGoalDifference":"-6","intPoints":"18","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282080","intRank":"15","idTeam":"133709","strTeam":"Montpellier","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/spxtvu1473504783.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LLWDD","strDescription":"","intPlayed":"18","intWin":"5","intLoss":"11","intDraw":"2","intGoalsFor":"28","intGoalsAgainst":"37","intGoalDifference":"-9","intPoints":"17","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282081","intRank":"16","idTeam":"133702","strTeam":"Ajaccio","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/qpxvwy1473505505.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LLWDW","strDescription":"","intPlayed":"18","intWin":"4","intLoss":"11","intDraw":"3","intGoalsFor":"15","intGoalsAgainst":"27","intGoalDifference":"-12","intPoints":"15","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282082","intRank":"17","idTeam":"133704","strTeam":"Brest","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/z69be41598797026.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DLLWL","strDescription":"Relegation - Ligue 2","intPlayed":"18","intWin":"3","intLoss":"10","intDraw":"5","intGoalsFor":"18","intGoalsAgainst":"33","intGoalDifference":"-15","intPoints":"14","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282083","intRank":"18","idTeam":"134788","strTeam":"Auxerre","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/lzdtbf1658753355.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LLLLD","strDescription":"Relegation - Ligue 2","intPlayed":"18","intWin":"3","intLoss":"11","intDraw":"4","intGoalsFor":"16","intGoalsAgainst":"40","intGoalDifference":"-24","intPoints":"13","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282084","intRank":"19","idTeam":"133882","strTeam":"Strasbourg","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/yuxtyy1464540071.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"DLLDL","strDescription":"Relegation - Ligue 2","intPlayed":"18","intWin":"1","intLoss":"8","intDraw":"9","intGoalsFor":"22","intGoalsAgainst":"33","intGoalDifference":"-11","intPoints":"12","dateUpdated":"2023-01-12 23:01:13"}, + {"idStanding":"2282085","intRank":"20","idTeam":"134709","strTeam":"Angers","strTeamBadge":"https://www.thesportsdb.com/images/media/team/badge/445gc21622560255.png/tiny","idLeague":"4334","strLeague":"French Ligue 1","strSeason":"2022-2023","strForm":"LLLLL","strDescription":"Relegation - Ligue 2","intPlayed":"18","intWin":"2","intLoss":"14","intDraw":"2","intGoalsFor":"16","intGoalsAgainst":"39","intGoalDifference":"-23","intPoints":"8","dateUpdated":"2023-01-12 23:01:13"} +]; diff --git a/TP02/EX01/index.html b/TP02/EX01/index.html new file mode 100644 index 0000000..919554a --- /dev/null +++ b/TP02/EX01/index.html @@ -0,0 +1,67 @@ + + + + + + + + + + + + + Classement Ligue 1 + + +
+

+ Classement Ligue 1 de football + +
+ + + + +
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PosTeamPldWDLGFGAGDPts
PosTeamPldWDLGFGAGDPts
+
+ + + + diff --git a/TP02/EX01/script.js b/TP02/EX01/script.js new file mode 100644 index 0000000..0366aa2 --- /dev/null +++ b/TP02/EX01/script.js @@ -0,0 +1,71 @@ +let table = document.getElementsByClassName("table")[0]; +let trieCroissant = false; +let dat = ["intRank","strTeamBadge","strTeam","intPlayed","intWin","intDraw","intLoss","intGoalsFor","intGoalsAgainst","intGoalDifference","intPoints"]; +let recherche = document.getElementById("myInput"); + +recherche.addEventListener('input', function(){ + filtrer(recherche.value.toLowerCase()); +}); + +trier(); + +function viderTable(){ + let listeLigne = table.children; + let i=0; + while (listeLigne.length>i){ + if (listeLigne[i].tagName === 'tr'){ + table.removeChild(listeLigne[i]); + } + else{ + i++; + } + } +} + +function remplirTable(donnee=data){ + for (let i=0; ia.intRank - b.intRank); + } + else{ + data.sort((a,b)=>b.intRank - a.intRank); + } + viderTable(); + remplirTable(); +} + +function filtrer(filtre){ + viderTable(); + let dataFiltrer = data.filter(function(equipe){ + if (equipe.strTeam.toLowerCase().startsWith(filtre)){ + return equipe; + } + }); + remplirTable(dataFiltrer); +} \ No newline at end of file diff --git a/TP02/EX02/css/style.css b/TP02/EX02/css/style.css new file mode 100644 index 0000000..465a430 --- /dev/null +++ b/TP02/EX02/css/style.css @@ -0,0 +1,32 @@ +:focus-visible {outline:none;} + +.strike { + text-decoration-line : line-through; +} + +#loader.is-loading { + position: fixed; + z-index: 999; + overflow: show; + margin: auto; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +#loader.is-loading:after { + animation: spinAround 500ms infinite linear; + border: 2px solid hsl(0deg, 0%, 86%); + border-radius: 9999px; + border-right-color: transparent; + border-top-color: transparent; + content: ""; + display: block; + position: relative; + top: calc(50% - 5em); + left: calc(50% - 5em); + width: 10em; + height: 10em; + border-width: 0.25em; +} diff --git a/TP02/EX02/index.html b/TP02/EX02/index.html new file mode 100644 index 0000000..1a0f2e5 --- /dev/null +++ b/TP02/EX02/index.html @@ -0,0 +1,48 @@ + + + + + + + + Todo + + + + + + +
+ +
+
+
+ + + +
+

+ + + + +

+
+ + + +
+ +
+ +
+
+ + + + + diff --git a/TP02/EX02/js/app.js b/TP02/EX02/js/app.js new file mode 100644 index 0000000..b97d13a --- /dev/null +++ b/TP02/EX02/js/app.js @@ -0,0 +1,6 @@ +import Controller from './controller.js' +import Model from './model.js' +import View from './view.js' + + +const app = new Controller(new Model(),new View()) diff --git a/TP02/EX02/js/controller.js b/TP02/EX02/js/controller.js new file mode 100644 index 0000000..bb027a8 --- /dev/null +++ b/TP02/EX02/js/controller.js @@ -0,0 +1,54 @@ +export default class Controller { + constructor(model, view) { + this.model = model + this.view = view + this.filter = "all" + this.view.bindAddTodo(this.addTodo.bind(this)) + this.view.bindDeleteTodo(this.deleteTodo.bind(this)) + this.view.bindToggleTodo(this.toggleTodo.bind(this)) + this.view.bindEditTodo(this.editTodo.bind(this)) + + /** Routage **/ + this.routes = ['all','active','done']; + + /** Routage **/ + window.addEventListener("load",this.routeChanged.bind(this)); + window.addEventListener("hashchange",this.routeChanged.bind(this)); + + } + + routeChanged(){ + let route = window.location.hash.replace(/^#\//,''); + this.filter = this.routes.find( r => r === route) || 'all'; + this.filterTodoList(); + + } + + + filterTodoList () { + let todos = this.model.getTodos(this.filter) + this.view.renderTodoList(todos) + this.view.setFilterTabs(this.filter) + } + + addTodo(text) { + let todo = this.model.add(text) + this.filterTodoList() + } + + deleteTodo(id) { + this.model.delete(parseInt(id)) + this.filterTodoList() + } + + toggleTodo(id) { + this.model.toggle(parseInt(id)) + this.filterTodoList() + } + + editTodo(id, text) { + this.model.edit(parseInt(id),text) + this.filterTodoList() + } +} + diff --git a/TP02/EX02/js/model.js b/TP02/EX02/js/model.js new file mode 100644 index 0000000..1ec4285 --- /dev/null +++ b/TP02/EX02/js/model.js @@ -0,0 +1,71 @@ +const todos = [ + { + id : 1, + text : "apprendre le javascript", + done : false + + }, + { + id : 2, + text : "Faire des maths", + done : false + + }] + +export default class Model { + constructor() { + //this.todos = JSON.parse(localStorage.getItem('todos')) || [] + this.todos = JSON.parse(localStorage.getItem('todos')) || todos + } + + _commit(todos) { + localStorage.setItem('todos', JSON.stringify(todos)) + } + + getTodos(filter){ + if (filter == "active") + return this.todos.filter(todo => !todo.done) + if (filter == "done") + return this.todos.filter(todo => todo.done) + + return this.todos + } + + add(todoText) { + const todo = { + id: this.todos.length > 0 ? this.todos[this.todos.length - 1].id + 1 : 1, + text: todoText, + done : false, + } + + this.todos.push(todo) + this._commit(this.todos) + return todo + } + + edit(id, updatedText) { + let todo = this.todos.find(t => t.id === id) + todo.text = updatedText + // this.todos = this.todos.map(todo => + // todo.id === id ? { id: todo.id, text: updatedText, done: todo.done} : todo + // ) + + this._commit(this.todos) + } + + delete(id) { + this.todos = this.todos.filter(todo => todo.id !== id) + + this._commit(this.todos) + } + + toggle(id) { + let todo = this.todos.find(t => t.id === id) + todo.done = !todo.done + //this.todos = this.todos.map(todo => + // todo.id === id ? { id: todo.id, text: todo.text, done: !todo.done } : todo + //) + this._commit(this.todos) + } +} + diff --git a/TP02/EX02/js/view.js b/TP02/EX02/js/view.js new file mode 100644 index 0000000..744f870 --- /dev/null +++ b/TP02/EX02/js/view.js @@ -0,0 +1,115 @@ +export default class View { + constructor() { + this.form = document.querySelector("#add_form") + this.input = document.querySelector("#input_todo") + this.list = document.querySelector("#todos_list") + this.tabs = document.querySelector("#todos_filter") + this.loader = document.querySelector("#loader") + } + + _getTodo() { + return this.input.value + } + + _resetInput() { + this.input.value = '' + } + + _getNewTodoElement(todo){ + let div = document.createElement("div") + div.classList.add("box","is-flex","is-align-items-center","m-2") + div.dataset.id = todo.id + + let input = document.createElement("input") + input.type = "checkbox" + input.classList.add("mr-3") + + let span = document.createElement("p") + span.classList.add("mb-0","is-size-3","mr-auto") + span.textContent = todo.text + span.setAttribute("contenteditable",true) + + + let button = document.createElement("button") + button.classList.add("delete","is-large") + + + if (todo.done){ + span.classList.add("strike") + input.checked = true + } + + div.append(input,span,button) + + return div + + } + + setLoader(){ + this.loader.classList.add("is-loading") + } + unsetLoader(){ + this.loader.classList.remove("is-loading") + } + + setFilterTabs(filter){ + let li = this.tabs.querySelectorAll("li") + li.forEach( tab => { + tab.classList.remove("is-active") + }) + let active = this.tabs.querySelector(`#${filter}`) + active.parentNode.classList.add("is-active") + } + + renderTodoList(todos) { + let list = new DocumentFragment() + for (let todo of todos){ + list.appendChild(this._getNewTodoElement(todo)) + } + this.list.replaceChildren(list) + } + + /** Abonnements événements **/ + + bindAddTodo(handler) { + this.form.addEventListener("submit", (e=>{ + e.preventDefault() + let text = this._getTodo() + handler(text) + this._resetInput() + })) + } + + + bindDeleteTodo(handler) { + // TODO + this.list.addEventListener("click", (e) => { + let selection = e.target; + if (selection.tagName === "BUTTON"){ + let id = selection.parentNode.dataset.id; + handler(id); + } + }); + } + + bindEditTodo(handler) { + this.list.addEventListener("keydown", (e) => { + let selection = e.target; + if (selection.tagName === "P" && e.key === "Enter"){ + let id = selection.parentNode.dataset.id; + let texte = selection.textContent; + handler(id, texte); + } + }); + } + + bindToggleTodo(handler) { + this.list.addEventListener("change", (e) => { + let selection = e.target; + if (selection.tagName === "INPUT"){ + let id = selection.parentNode.dataset.id; + handler(id); + } + }); + } +} diff --git a/TP03/EX01/cookie.html b/TP03/EX01/cookie.html new file mode 100644 index 0000000..893679c --- /dev/null +++ b/TP03/EX01/cookie.html @@ -0,0 +1,26 @@ + + + + + + Cookie clicker + + + +
+

Cookie clicker

+
+ cookie + 0 +
+ + + + +
+ + + diff --git a/TP03/EX01/css/img/bg.jpg b/TP03/EX01/css/img/bg.jpg new file mode 100644 index 0000000..1a45fb8 Binary files /dev/null and b/TP03/EX01/css/img/bg.jpg differ diff --git a/TP03/EX01/css/style.css b/TP03/EX01/css/style.css new file mode 100644 index 0000000..558dd08 --- /dev/null +++ b/TP03/EX01/css/style.css @@ -0,0 +1,63 @@ +@import url(https://fonts.googleapis.com/css?family=Kavoon); + +body { + background-image: url("img/bg.jpg"); + background-repeat: repeat; + font-family: Kavoon; + font-size: 24px; + text-align: center; + color: white; +} + +.container { + max-width: 320px; + margin: auto; +} + +h1 { + font-size: 28px; + background-color: rgba(0, 0, 0, 0.25); + padding: 10px 40px 10px 40px; + border-radius: 10px; +} + +figure { + position: relative; + margin: 0; +} + +figure > span { + position: absolute; + top: 25px; + right: 50px; + border-radius: 21px; + height: 42px; + width: 56px; + background-color: #f4d03f; + box-shadow: 4px 4px 4px black; + padding-top: 9px; +} + +button { + display: block; + width: 100%; + font-family: Kavoon; + font-size: 24px; + background-color: white; + padding: 9px; + border-radius: 10px; + border-width: 0; +} + +p { + text-align: left; +} + +img[alt="GrandMa"] { + float: left; +} + +.hidden { + display: none; +} + diff --git a/TP03/EX01/img/bg.jpg b/TP03/EX01/img/bg.jpg new file mode 100644 index 0000000..1a45fb8 Binary files /dev/null and b/TP03/EX01/img/bg.jpg differ diff --git a/TP03/EX01/img/cookie.png b/TP03/EX01/img/cookie.png new file mode 100644 index 0000000..ee14eee Binary files /dev/null and b/TP03/EX01/img/cookie.png differ diff --git a/TP03/EX01/img/memee.png b/TP03/EX01/img/memee.png new file mode 100644 index 0000000..25a9e08 Binary files /dev/null and b/TP03/EX01/img/memee.png differ diff --git a/TP03/EX01/js/game.js b/TP03/EX01/js/game.js new file mode 100644 index 0000000..04d35c9 --- /dev/null +++ b/TP03/EX01/js/game.js @@ -0,0 +1,48 @@ +var btnStart = document.getElementById("btnStart"); +var scoreView = document.getElementById("score"); +var tempsView = document.getElementById("temps"); +var meme = document.getElementById("meme"); +var cookie = document.getElementById("cookie"); +var score; +var temps; +var isPlayed=false; +var texte = " seconds left!"; +var tailleCookieInitiale = cookie.naturalWidth; + +btnStart.addEventListener('click', start); +cookie.addEventListener('click', clicCookie); + +tempsView.style.color = "red"; + +function start(event){ + if (!isPlayed){ + meme.style.display="block"; + cookie.style.width = tailleCookieInitiale+"px"; + temps = 15; + score = 0; + scoreView.textContent = score; + isPlayed = true; + tempsView.textContent = temps+texte; + setTimeout(second,1000); + } +} + +function clicCookie(event){ + if (isPlayed){ + score ++; + cookie.style.width = (tailleCookieInitiale+score)+"px"; + scoreView.textContent = score; + } +} + +function second(){ + temps --; + tempsView.textContent = temps+texte; + if (temps <= 0){ + isPlayed = false; + meme.style.display="none"; + } + else{ + setTimeout(second,1000); + } +} \ No newline at end of file diff --git a/TP03/EX02/css/style.css b/TP03/EX02/css/style.css new file mode 100644 index 0000000..314c60a --- /dev/null +++ b/TP03/EX02/css/style.css @@ -0,0 +1,11 @@ +img{ + cursor:pointer; +} + +#gagne,#perdu,.hidden{ + display : none; +} + +.progress::-webkit-progress-value { + transition: width 0.5s ease; +} diff --git a/TP03/EX02/images/off.png b/TP03/EX02/images/off.png new file mode 100644 index 0000000..693f597 Binary files /dev/null and b/TP03/EX02/images/off.png differ diff --git a/TP03/EX02/images/on.png b/TP03/EX02/images/on.png new file mode 100644 index 0000000..ff59640 Binary files /dev/null and b/TP03/EX02/images/on.png differ diff --git a/TP03/EX02/js/memory.js b/TP03/EX02/js/memory.js new file mode 100644 index 0000000..70b786d --- /dev/null +++ b/TP03/EX02/js/memory.js @@ -0,0 +1 @@ +// TODO diff --git a/TP03/EX02/memory.html b/TP03/EX02/memory.html new file mode 100644 index 0000000..9595776 --- /dev/null +++ b/TP03/EX02/memory.html @@ -0,0 +1,64 @@ + + + + + + + + + + + + Memory + + + +
+

Memory

+
+
+ +
+
+ + + +
+
+ + + +
+
+ + + +
+ +
+
+ +
+

Règles

+

+ Pendant une seconde, vous verrez l'état de l'ensemble + des ampoules, puis elles seront éteintes. Vous devrez + alors cliquer sur celles qui étaient allumées. +

+ + + + + + +
+

Perdu !

+
+
+

Gagné !

+
+
+
+
+ +