commit 6f868b91cf3e11cd2e59dae1831b870e43339c27 Author: didier amyot Date: Thu Jan 11 19:20:15 2024 -0500 simplify project diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..b73799e --- /dev/null +++ b/src/index.html @@ -0,0 +1,113 @@ + + + + + + + Dessin d'Enfants + + + + + + + + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ + +
+
+ + + + + + + + + + + +
IdDescriptionActions
+
+
+ + +
+
+ +
+
+ + + + \ No newline at end of file diff --git a/src/logo.jpg b/src/logo.jpg new file mode 100644 index 0000000..71a558a Binary files /dev/null and b/src/logo.jpg differ diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..9407b9d --- /dev/null +++ b/src/main.js @@ -0,0 +1,89 @@ + +import {drawCircles, populateTable, Circle, Point, randomColor} from "./tp1.js"; + +const circles = [] + +function getCircleById(circleId){ + for(const circle of circles){ + if(circle.getId() === circleId){ + return circle; + } + } +} + +function onClickUp(circleId){ + const circle = getCircleById(circleId); + const center = circle.getCenter(); + const newCenter = new Point(center.getX(), center.getY() - 10); + circle.setCenter(newCenter); + renderCircles(); +} + +function onClickDown(circleId){ + const circle = getCircleById(circleId); + const center = circle.getCenter(); + const newCenter = new Point(center.getX(), center.getY() + 10); + circle.setCenter(newCenter); + renderCircles(); +} + +function onClickLeft(circleId){ + const circle = getCircleById(circleId); + const center = circle.getCenter(); + const newCenter = new Point(center.getX() - 10, center.getY()); + circle.setCenter(newCenter); + renderCircles(); +} + +function onClickRight(circleId){ + const circle = getCircleById(circleId); + const center = circle.getCenter(); + const newCenter = new Point(center.getX() + 10, center.getY()); + circle.setCenter(newCenter); + renderCircles(); +} + + + +function onClickPaint(circleId){ + const circle = getCircleById(circleId); + circle.setColor(randomColor(Date.now())) + renderCircles(); +} + +function pointToString(point){ + return `(${point.getX()}, ${point.getY()})`; +} + +function drawNewCircle(){ + const x = parseInt(document.getElementById("cx").value) + const y = parseInt(document.getElementById("cy").value) + const r = parseInt(document.getElementById("cr").value) + const p = new Point(x, y); + const circle = new Circle(p, r, Date.now()); + circles.push(circle); + renderCircles(); +} + +function clearCircles(){ + circles.length = 0; + renderCircles(); +} + + +function renderCircles(){ + drawCircles(document.getElementById("canvas"), circles); + populateTable(document.getElementById("table-body"), + circles, + onClickUp, + onClickDown, + onClickLeft, + onClickRight, + onClickPaint); +} + + + +document.getElementById("draw-circle").addEventListener("click", drawNewCircle); +document.getElementById("clear-drawing").addEventListener("click", clearCircles); + diff --git a/src/tp1.js b/src/tp1.js new file mode 100644 index 0000000..e5c99f5 --- /dev/null +++ b/src/tp1.js @@ -0,0 +1,206 @@ +import m from "https://esm.sh/mithril@2.2.2" + +const BLACK = "000000"; +/** + * Classe qui représente un point sur + * un plan cartésien. Le point est donc + * représenté par deux coordonnées x et y. + */ +export class Point{ + #x; + #y; + constructor(x, y) { + this.#x = x; + this.#y = y; + } + getX(){ + return this.#x; + } + + getY(){ + return this.#y; + } +} + +/** + * Classe qui représente un cercle. Le cercle est + * définit par un Point et un rayon. + * + * Par défaut, le cercle est noir. Mais le cercle peut + * changer de couleur. + */ +export class Circle{ + #center; + #radius; + #color; + #id; + + /** + * + * @param {Point} center le point au centre du cercle + * @param {number} radius le rayon du cercle + * @param {number} id l'id unique du cercle. C'est au + * créateur de l'instance de s'assurer de l'unicité + * de l'id. + */ + constructor(center, radius, id) { + this.#center = center; + this.#radius = radius; + this.#color = BLACK; + this.#id = id; + } + + /** + * @returns {Point} le point au centre au cercle + */ + getCenter(){ + return this.#center; + } + + /** + * + * @returns {number} le rayon du cercle + */ + getRadius(){ + return this.#radius; + } + + /** + * + * @returns {string} la couleur (hexadécimal) du cercle + */ + getColor(){ + return this.#color; + } + + /** + * @param {String} color la nouvelle couleur du cercle + */ + setColor(color){ + this.#color = color; + } + + setCenter(center){ + this.#center = center; + } + + /** + * @returns {number} l'id du cercle + */ + getId(){ + return this.#id; + } + + + toString(){ + return `Cercle(${ this.#radius }, ${ this.getCenter().getX() }, ${ this.getCenter().getY() })`; + } +} + +/** + * Dessine tous les cercles dans un svg. Cette fonction + * nettoye le svg avant d'ajouter les cercles. + * + * @param node {HTMLElement} un element svg + * @param circles {Circle[]} Les cercles à dessiner + */ +export function drawCircles(node, circles){ + let svgCircles = []; + for(const circle of circles){ + const attr = { + cx: circle.getCenter().getX(), + cy: circle.getCenter().getY(), + r: circle.getRadius(), + fill: `#${circle.getColor()}`, + + }; + svgCircles.push(m("circle", attr)) + } + m.render(node, svgCircles); +} + +function identity(x){ + return x; +} + +function functionOrDefault(fn){ + if(typeof fn === 'function'){ + return fn; + } + return identity; +} + +function drawIcons(circle, + onClickUp, + onClickDown, + onClickLeft, + onClickRight, + onClickPaint){ + return [ + m("i.fa-solid.fa-arrow-up.is-clickable", {onclick: () => onClickUp(circle.getId())}), + m("i.fa-solid.fa-arrow-down.is-clickable", {onclick: () => onClickDown(circle.getId())}), + m("i.fa-solid.fa-arrow-left.is-clickable", {onclick: () => onClickLeft(circle.getId())}), + m("i.fa-solid.fa-arrow-right.is-clickable", {onclick: () => onClickRight(circle.getId())}), + m("i.fa-solid.fa-paint-roller.is-clickable", {onclick: () => onClickPaint(circle.getId())}), + ] +} + +/** + * @param node {HTMLElement} un element tbody + * @param circles {Circle[]} Les cercles + * @param pointToString Argument optionnel qui doit être une fonction + * qui prend en paramêtre un Point et retourne un String qui + * représente le point. + * @param onClickUp Argument optionnel qui doit être une fonction + * qui sera appelée lorsque la flèche pointant vers le haut + * sera cliquée. L'id du cercle sera passé en argument de + * la fonction. + * @param onClickDown Argument optionnel qui doit être une fonction + * qui sera appelée lorsque la flèche pointant vers le bas + * sera cliquée. L'id du cercle sera passé en argument de + * la fonction. + * @param onClickLeft Argument optionnel qui doit être une fonction + * qui sera appelée lorsque la flèche pointant vers la gauche + * sera cliquée. L'id du cercle sera passé en argument de + * la fonction. + * @param onClickRight Argument optionnel qui doit être une fonction + * qui sera appelée lorsque la flèche pointant vers la droite + * sera cliquée. L'id du cercle sera passé en argument de + * la fonction. + * @param onClickPaint Argument optionnel qui doit être une fonction + * qui sera appelée lorsque l'icone peinture + * sera cliquée. L'id du cercle sera passé en argument de + * la fonction. + */ +export function populateTable(node, + circles, + onClickUp=undefined, + onClickDown=undefined, + onClickLeft=undefined, + onClickRight=undefined, + onClickPaint=undefined){ + const rows = []; + for(const circle of circles){ + const row =[m("td", circle.getId()), + m("td", circle.toString()), + m("td", drawIcons(circle, + functionOrDefault(onClickUp), + functionOrDefault(onClickDown), + functionOrDefault(onClickLeft), + functionOrDefault(onClickRight), + functionOrDefault(onClickPaint)))]; + rows.push(m("tr", row)) + } + m.render(node, rows); + +} + +/** + * Retourne une couleur de gris aléatoire à partir d'un nombre entier. + * @param i {number} (entier) qui sera utilisé comme "seed". + * @returns {string} une couleur hexadécimale + */ +export function randomColor(i){ + const base = (i % 256).toString(16); + return `${base}${base}${base}` +} \ No newline at end of file