-
+
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".