Classes: Rectange,Text; function drawFigures

This commit is contained in:
Annie Rheaume committed 2024-01-13 22:24:50 -05:00
1 parent be78b14ad3
commit 1bd694d199
4 files changed
+377 -82

No files matched your search

+29 -15
View File
@@ -11,6 +11,7 @@
referrerpolicy="no-referrer" rel="stylesheet"/> referrerpolicy="no-referrer" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css" rel="stylesheet">
<script src="main.js" type="module"></script> <script src="main.js" type="module"></script>
<script type="module" src="tests.js"></script>
</head> </head>
<body> <body>
@@ -92,10 +93,10 @@
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label">Centre X du Cercle</label> <label class="label">Coin X du Rectangle</label>
<div class="control"> <div class="control">
<input class="input" <input class="input"
id="cx" id="x"
max="500" max="500"
min="1" min="1"
placeholder="250" placeholder="250"
@@ -105,10 +106,10 @@
</div> </div>
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label">Centre Y du Cercle</label> <label class="label">Coin Y du Rectangle</label>
<div class="control"> <div class="control">
<input class="input" <input class="input"
id="cy" id="y"
max="500" max="500"
min="1" min="1"
placeholder="250" placeholder="250"
@@ -118,10 +119,10 @@
</div> </div>
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label">Rayon du Cercle</label> <label class="label">Largeur du Rectangle</label>
<div class="control"> <div class="control">
<input class="input" <input class="input"
id="cr" id="width"
max="500" max="500"
min="1" min="1"
placeholder="100" placeholder="100"
@@ -129,6 +130,19 @@
</div> </div>
</div> </div>
</div> </div>
<div class="column">
<div class="field">
<label class="label">Hauteur du Rectangle</label>
<div class="control">
<input class="input"
id="height"
max="500"
min="1"
placeholder="100"
type="number">
</div>
</div>
</div>
<div class="column"> <div class="column">
<br> <br>
<button class="button mt-2" id="draw-rectangle">Ajouter Rectangle</button> <button class="button mt-2" id="draw-rectangle">Ajouter Rectangle</button>
@@ -145,10 +159,10 @@
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label">Centre X du Cercle</label> <label class="label">Coin X Boîte texte</label>
<div class="control"> <div class="control">
<input class="input" <input class="input"
id="cx" id="x"
max="500" max="500"
min="1" min="1"
placeholder="250" placeholder="250"
@@ -158,10 +172,10 @@
</div> </div>
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label">Centre Y du Cercle</label> <label class="label">Centre Y Boîte texte</label>
<div class="control"> <div class="control">
<input class="input" <input class="input"
id="cy" id="y"
max="500" max="500"
min="1" min="1"
placeholder="250" placeholder="250"
@@ -171,20 +185,20 @@
</div> </div>
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label">Rayon du Cercle</label> <label class="label">Texte</label>
<div class="control"> <div class="control">
<input class="input" <input class="input"
id="cr" id="text"
max="500" max="500"
min="1" min="1"
placeholder="100" placeholder="Saisissez texte"
type="number"> type="text">
</div> </div>
</div> </div>
</div> </div>
<div class="column"> <div class="column">
<br> <br>
<button class="button mt-2" id="draw-circle">Ajouter Cercle</button> <button class="button mt-2" id="draw-text">Ajouter Texte</button>
</div> </div>
</div> </div>
+56 -54
View File
@@ -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){ function getCircleById(circleId){
for(const circle of circles){ for(const circle of circles){
if(circle.getId() === circleId){ 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){ function pointToString(point){
return `(${point.getX()}, ${point.getY()})`; return `(${point.getX()}, ${point.getY()})`;
} }
// Sur le bouton 'Ajouter un cercle'
function drawNewCircle(){ 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 y = parseInt(document.getElementById("cy").value)
const r = parseInt(document.getElementById("cr").value) const r = parseInt(document.getElementById("cr").value)
const p = new Point(x, y); const p = new Point(x, y);
const circle = new Circle(p, r, Date.now()); const circle = new Circle(p, r, Date.now());
circles.push(circle); figures.push(circle);
renderCircles(); renderFigures();
}
function clearCircles(){
circles.length = 0;
renderCircles();
} }
function renderCircles(){ // Sur le bouton 'Ajouter un rectangle'
drawCircles(document.getElementById("canvas"), circles); 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"), populateTable(document.getElementById("table-body"),
circles, circles,
onClickUp, onClickUp,
onClickDown, onClickDown,
onClickLeft, onClickLeft,
onClickRight, onClickRight,
onClickPaint); onClickPaint);*/
} }
document.getElementById("draw-circle").addEventListener("click", drawNewCircle); 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);
+79
View File
@@ -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();
+213 -13
View File
@@ -1,6 +1,9 @@
import m from "https://esm.sh/mithril@2.2.2" import m from "https://esm.sh/mithril@2.2.2"
const BLACK = "000000"; const BLACK = "000000";
// LES CLASSES: Point, Circle, Rectangle, Text
/** /**
* Classe qui représente un point sur * Classe qui représente un point sur
* un plan cartésien. Le point est donc * un plan cartésien. Le point est donc
@@ -24,7 +27,7 @@ export class Point{
/** /**
* Classe qui représente un cercle. Le cercle est * 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 * Par défaut, le cercle est noir. Mais le cercle peut
* changer de couleur. * changer de couleur.
@@ -80,6 +83,9 @@ export class Circle{
this.#color = color; this.#color = color;
} }
/**
* @param {Point} center la nouvelle position du centre du cercle
*/
setCenter(center){ setCenter(center){
this.#center = center; this.#center = center;
} }
@@ -91,34 +97,226 @@ export class Circle{
return this.#id; return this.#id;
} }
/**
* @return {Object} balise HTML <circle> (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(){ toString(){
return `Cercle(${ this.#radius }, ${ this.getCenter().getX() }, ${ this.getCenter().getY() })`; 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 <rect> (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 <text> (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 <circle>, <rectangle> et <text>
/** /**
* Dessine tous les cercles dans un svg. Cette fonction * Dessine tous les cercles dans un svg. Cette fonction
* nettoye le svg avant d'ajouter les cercles. * nettoye le svg avant d'ajouter les cercles.
* *
* @param node {HTMLElement} un element svg * @param node {HTMLElement} un element svg
* @param circles {Circle[]} Les cercles à dessiner * @param figures {Array[]} Les formes à dessiner
*/ */
export function drawCircles(node, circles){ export function drawFigures(node, figures){
let svgCircles = []; //console.log(figures.toString())
for(const circle of circles){
const attr = {
cx: circle.getCenter().getX(),
cy: circle.getCenter().getY(),
r: circle.getRadius(),
fill: `#${circle.getColor()}`,
}; // Liste de vnodes à ajouter comme enfants au SVG (id='canvas')
svgCircles.push(m("circle", attr)) 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 <cercle>, <rect> à 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){ function identity(x){
return 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. * Retourne une couleur de gris aléatoire à partir d'un nombre entier.
* @param i {number} (entier) qui sera utilisé comme "seed". * @param i {number} (entier) qui sera utilisé comme "seed".