From 1bd694d199e77bbbf821ebcaccee97af3e51e42d Mon Sep 17 00:00:00 2001 From: Annie Rheaume Date: Sat, 13 Jan 2024 22:24:50 -0500 Subject: [PATCH] Classes: Rectange,Text; function drawFigures --- src/index.html | 44 ++++++---- src/main.js | 110 ++++++++++++------------ src/tests.js | 79 +++++++++++++++++ src/tp1.js | 226 ++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 377 insertions(+), 82 deletions(-) create mode 100644 src/tests.js diff --git a/src/index.html b/src/index.html index 4d37c3d..64a36f1 100644 --- a/src/index.html +++ b/src/index.html @@ -11,6 +11,7 @@ referrerpolicy="no-referrer" rel="stylesheet"/> + @@ -92,10 +93,10 @@
- +
- +
- +
+
+
+ +
+ +
+
+

@@ -145,10 +159,10 @@
- +
- +
- +
+ placeholder="Saisissez texte" + type="text">

- +
diff --git a/src/main.js b/src/main.js index 9407b9d..6b41952 100644 --- a/src/main.js +++ b/src/main.js @@ -1,8 +1,15 @@ +console.log('MAIN'); -import {drawCircles, populateTable, Circle, Point, randomColor} from "./tp1.js"; +import { + Point, + Circle, + Rectangle, + Text, + drawFigures} from "./tp1.js"; -const circles = [] +const figures = [] +/* function getCircleById(circleId){ for(const circle of circles){ if(circle.getId() === circleId){ @@ -10,80 +17,75 @@ function getCircleById(circleId){ } } } - -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()})`; } +// Sur le bouton 'Ajouter un cercle' function drawNewCircle(){ - const x = parseInt(document.getElementById("cx").value) + console.log('Nouveau cercle') + 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(); + figures.push(circle); + renderFigures(); } -function renderCircles(){ - drawCircles(document.getElementById("canvas"), circles); +// Sur le bouton 'Ajouter un rectangle' +function drawNewRectangle(){ + console.log('Nouveau rectangle'); + const x = parseInt(document.getElementById("x").value) + const y = parseInt(document.getElementById("y").value) + const w = parseInt(document.getElementById("width").value) + const h = parseInt(document.getElementById("height").value) + const p = new Point(x, y); + const rectangle = new Rectangle(p, w, h, Date.now()); + figures.push(rectangle); + renderFigures(); +} + +// Sur le bouton 'Ajouter un cercle' +function drawNewText(){ + console.log('Nouveau texte') + const x = parseInt(document.getElementById("x").value); + const y = parseInt(document.getElementById("y").value); + const t = document.getElementById("text").value; + const p = new Point(x, y); + const text = new Text(p, t, Date.now()); + figures.push(text); + renderFigures(); +} + + +// Sur le bouton 'Tout effacer' +function clearAllFigures(){ + figures.length = 0; + renderFigures(); +} + +function renderFigures(){ + drawFigures(document.getElementById("canvas"), figures); + + /* populateTable(document.getElementById("table-body"), circles, onClickUp, onClickDown, onClickLeft, onClickRight, - onClickPaint); + onClickPaint);*/ + } document.getElementById("draw-circle").addEventListener("click", drawNewCircle); -document.getElementById("clear-drawing").addEventListener("click", clearCircles); +document.getElementById("draw-rectangle").addEventListener("click", drawNewRectangle); +document.getElementById("draw-text").addEventListener("click", drawNewText); +document.getElementById("clear-drawing").addEventListener("click", clearAllFigures); diff --git a/src/tests.js b/src/tests.js new file mode 100644 index 0000000..637e32a --- /dev/null +++ b/src/tests.js @@ -0,0 +1,79 @@ + +import {Point, Rectangle, Circle, Text, drawFigures} from "./tp1.js"; + +function assert(test, message){ + if(test){ + console.log('OK', message) + } else { + console.log('ERREUR', message) + } +} + +function compareStrings(str1, str2){ + return str1 === str2; +} +function compareIntegers(int1, int2){ + return int1 === int2; + } + + console.log('TESTS '); + +function testRectangleClass(){ + console.log('Tests pour la classe Rectangle'); + + const p = new Point(50,50); + const r = new Rectangle(p, 100, 200, Date.now()); + console.log(r.getCorner()); + console.log(r.getWidth()); + console.log(r.getHeight()); + console.log(r.getColor()); + r.setColor('#5F3384'); + console.log('Nouvelle couleur: ', r.getColor()); + const p2 = new Point(r.getCorner().getX() + 5,r.getCorner().getY() + 5) + r.setCorner(p2); + console.log('Nouvelle position du coin:', r.getCorner()); + console.log(r.getId()); + console.log(r.toString()); +} +//testRectangleClass(); + +function testTextClass(){ + console.log('Tests pour la classe Text'); + + const p = new Point(50,50); + const str = 'Hello World !'; + const t = new Text(p, str, Date.now()); + console.log(t.getCorner()); + console.log(t.getText()); + const p2 = new Point(t.getCorner().getX() + 5,t.getCorner().getY() + 5) + t.setCorner(p2); + console.log('Nouvelle position du coin:', t.getCorner()); + console.log(t.getId()); + console.log(t.toString()); + +} +//testTextClass(); + + +function testDrawFigures(){ + console.log('Test pour la fonction drawFigures()'); + + const pc = new Point(100, 100); + const c = new Circle(pc, 50, Date.now()); + + const pr = new Point(300, 200); + const r = new Rectangle(pr, 50, 75, Date.now()); + + const pt = new Point(50, 400); + const str = "TESTS"; + const t = new Text(pt, str, Date.now()); + + const figures = []; + figures.push(c); + figures.push(r); + figures.push(t); + drawFigures(document.getElementById('canvas'), figures); +} +//testDrawFigures(); + + diff --git a/src/tp1.js b/src/tp1.js index e5c99f5..7f2ed87 100644 --- a/src/tp1.js +++ b/src/tp1.js @@ -1,6 +1,9 @@ import m from "https://esm.sh/mithril@2.2.2" const BLACK = "000000"; + +// LES CLASSES: Point, Circle, Rectangle, Text + /** * Classe qui représente un point sur * un plan cartésien. Le point est donc @@ -24,7 +27,7 @@ export class Point{ /** * Classe qui représente un cercle. Le cercle est - * définit par un Point et un rayon. + * définit par un Point, un rayon et un id. * * Par défaut, le cercle est noir. Mais le cercle peut * changer de couleur. @@ -80,6 +83,9 @@ export class Circle{ this.#color = color; } + /** + * @param {Point} center la nouvelle position du centre du cercle + */ setCenter(center){ this.#center = center; } @@ -91,34 +97,226 @@ export class Circle{ return this.#id; } + /** + * @return {Object} balise HTML (clé) et attributs (valeur) + */ + getHtmlTag(){ + const attr = { + cx: this.#center.getX(), + cy: this.#center.getY(), + r: this.#radius, + fill: `#${this.#color}`, + }; + return {"circle": attr}; + } toString(){ return `Cercle(${ this.#radius }, ${ this.getCenter().getX() }, ${ this.getCenter().getY() })`; } } +/** + * Classe qui représente un rectancle. Le rectangle est + * définit par un Point, une largeur, une hauteur et un id. + * + * Par défaut, le rectangle est noir. Mais le restangle peut + * changer de couleur. + */ +export class Rectangle{ + #corner; + #width; + #height; + #color; + #id; + + /** + * + * @param {Point} corner le point du coin supérieur du rectangle + * @param {number} width la largeur du rectangle + * @param {number} height la hauteur du rectangle + * @param {number} id l'id unique du rectangle. C'est au + * créateur de l'instance de s'assurer de l'unicité + * de l'id. + */ + constructor(corner, width, height, id) { + this.#corner = corner; + this.#width = width; + this.#height = height; + this.#color = BLACK; + this.#id = id; + } + + /** + * @returns {Point} le point au coin supérieur gauche du rectangle + */ + getCorner(){ + return this.#corner; + } + + /** + * + * @returns {number} la largeur du rectangle + */ + getWidth(){ + return this.#width; + } + + /** + * + * @returns {number} la hauteur du rectangle + */ + getHeight(){ + return this.#height; + } + + /** + * + * @returns {string} la couleur (hexadécimal) du rectangle + */ + getColor(){ + return this.#color; + } + + /** + * @param {String} color la nouvelle couleur du rectangle + */ + setColor(color){ + this.#color = color; + } + + /** + * @param {Point} corner la nouvelle position du coin supérieur gauche du rectangle + */ + setCorner(corner){ + this.#corner = corner; + } + + /** + * @returns {number} l'id du rectangle + */ + getId(){ + return this.#id; + } + + /** + * @return {Object} balise HTML (clé) et attributs (valeur) + */ + getHtmlTag(){ + const attr = { + x: this.#corner.getX(), + y: this.#corner.getY(), + width: this.#width, + height: this.#height, + fill: `#${this.#color}`, + }; + return {"rect": attr}; + } + + toString(){ + return `Rectangle(${ this.#width }, ${ this.#height }, ${ this.getCorner().getX() }, ${ this.getCorner().getY() })`; + } +} + +/** + * Classe qui représente une boîte de texte. La boîte de texte est + * définie par un Point, un texte et un id. + * + * Par défaut, la boîte texte est sans couleur de remplissage. + */ +export class Text{ + #corner; + #text; + #id; + + /** + * + * @param {Point} corner le point du coin supérieur de la boîte de teste + * @param {string} text le libellé du texte + * @param {number} id l'id unique du texte. C'est au + * créateur de l'instance de s'assurer de l'unicité + * de l'id. + */ + constructor(corner, text, id) { + this.#corner = corner; + this.#text = text; + this.#id = id; + } + + /** + * @returns {Point} le point au coin supérieur gauche du texte + */ + getCorner(){ + return this.#corner; + } + + /** + * @param {Point} corner la nouvelle position du coin supérieur gauche du texte + */ + setCorner(corner){ + this.#corner = corner; + } + + /** + * + * @returns {string} le libellé du texte + */ + getText(){ + return this.#text; + } + + /** + * @returns {number} l'id du texte + */ + getId(){ + return this.#id; + } + + /** + * @return {Object} balise HTML (clé) et attributs (valeur) + */ + getHtmlTag(){ + const attr = { + x: this.#corner.getX(), + y: this.#corner.getY(), + }; + return {"text": attr, "fragment" : this.#text}; + } + + toString(){ + return `Text(${ this.#text }, ${ this.getCorner().getX() }, ${ this.getCorner().getY() })`; + } +} + +// CRÉER LES ÉLÉMENTS HTML , et + /** * 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 + * @param figures {Array[]} Les formes à 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()}`, +export function drawFigures(node, figures){ + //console.log(figures.toString()) - }; - svgCircles.push(m("circle", attr)) + // Liste de vnodes à ajouter comme enfants au SVG (id='canvas') + let svgfig = []; + + for(const figure of figures){ + let figTag = Object.keys(figure.getHtmlTag())[0]; + let attr = Object.values(figure.getHtmlTag())[0]; + let frag = Object.values(figure.getHtmlTag())[1]; + + // ajouter une balise , à la liste des enfants + svgfig.push(m(figTag, attr, frag)); } - m.render(node, svgCircles); + + m.render(node, svgfig); } + +// FONCTIONS POUR CRÉER ET MANIPULER LE TABLEAU DESCRIPTIF DES FORMES + function identity(x){ return x; } @@ -195,6 +393,8 @@ export function populateTable(node, } +// AUTRES FONCTIONS POUR MODIFIER PROPRIÉTÉS DES FORMES + /** * Retourne une couleur de gris aléatoire à partir d'un nombre entier. * @param i {number} (entier) qui sera utilisé comme "seed".