canvasframework 0.5.23 → 0.5.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/components/Card.js +151 -123
  2. package/package.json +1 -1
@@ -1,150 +1,167 @@
1
1
  import Component from '../core/Component.js';
2
2
  /**
3
- * Carte avec ombre et contenu
3
+ * Container avec système de layout et effet d'élévation
4
4
  * @class
5
5
  * @extends Component
6
- * @property {Component[]} children - Enfants de la carte
6
+ * @property {Component[]} children - Enfants
7
7
  * @property {number} padding - Padding interne
8
+ * @property {number} gap - Espacement entre enfants
9
+ * @property {string} direction - Direction ('column' ou 'row')
10
+ * @property {string} align - Alignement ('start', 'center', 'end')
8
11
  * @property {string} bgColor - Couleur de fond
9
- * @property {number} elevation - Élévation (ombre)
10
12
  * @property {number} borderRadius - Rayon des coins
11
- * @property {boolean} clipContent - Clip le contenu
12
- * @property {boolean} clickableChildren - Active les clics sur les enfants
13
+ * @property {number} elevation - Niveau d'élévation (ombres)
13
14
  */
14
15
  class Card extends Component {
15
16
  /**
16
17
  * Crée une instance de Card
17
18
  * @param {CanvasFramework} framework - Framework parent
18
19
  * @param {Object} [options={}] - Options de configuration
19
- * @param {number} [options.padding=16] - Padding interne
20
- * @param {string} [options.bgColor='#FFFFFF'] - Couleur de fond
21
- * @param {number} [options.elevation=2] - Élévation (ombre)
22
- * @param {number} [options.borderRadius] - Rayon des coins (auto selon platform)
23
- * @param {boolean} [options.clipContent=true] - Clip le contenu
24
- * @param {boolean} [options.clickableChildren=true] - Active les clics enfants
20
+ * @param {number} [options.padding=0] - Padding interne
21
+ * @param {number} [options.gap=0] - Espacement entre enfants
22
+ * @param {string} [options.direction='column'] - Direction
23
+ * @param {string} [options.align='start'] - Alignement
24
+ * @param {string} [options.bgColor='transparent'] - Couleur de fond
25
+ * @param {number} [options.borderRadius=0] - Rayon des coins
26
+ * @param {number} [options.elevation=0] - Niveau d'élévation (0-5)
25
27
  */
26
28
  constructor(framework, options = {}) {
27
29
  super(framework, options);
28
30
  this.children = [];
29
- this.padding = options.padding || 16;
30
- this.bgColor = options.bgColor || '#FFFFFF';
31
- this.elevation = options.elevation || 2;
32
- this.borderRadius = options.borderRadius || (framework.platform === 'material' ? 4 : 12);
33
- this.clipContent = options.clipContent !== false;
34
- this.clickableChildren = options.clickableChildren !== false; // NOUVEAU: activer/désactiver les enfants cliquables
31
+ this.padding = options.padding || 0;
32
+ this.gap = options.gap || 0;
33
+ this.direction = options.direction || 'column';
34
+ this.align = options.align || 'start';
35
+ this.bgColor = options.bgColor || 'transparent';
36
+ this.borderRadius = options.borderRadius || 0;
37
+ this.elevation = options.elevation || 0; // Nouvelle propriété
35
38
  }
36
39
 
37
40
  /**
38
- * Ajoute un enfant à la carte
41
+ * Ajoute un enfant
39
42
  * @param {Component} child - Composant enfant
40
43
  * @returns {Component} L'enfant ajouté
41
44
  */
42
45
  add(child) {
43
- // Ajuster les coordonnées de l'enfant pour qu'elles soient relatives à la Card
44
- child.x = child.x || 0;
45
- child.y = child.y || 0;
46
46
  this.children.push(child);
47
+ this.layout();
48
+ return child;
49
+ }
50
+
51
+ /**
52
+ * Organise les enfants selon le layout
53
+ * @private
54
+ */
55
+ layout() {
56
+ let currentX = this.x + this.padding;
57
+ let currentY = this.y + this.padding;
47
58
 
48
- // Marquer l'enfant comme appartenant à cette Card
49
- child.parentCard = this;
59
+ for (let child of this.children) {
60
+ if (this.direction === 'column') {
61
+ child.x = currentX;
62
+ child.y = currentY;
63
+ if (this.align === 'center') {
64
+ child.x = this.x + (this.width - child.width) / 2;
65
+ } else if (this.align === 'end') {
66
+ child.x = this.x + this.width - child.width - this.padding;
67
+ }
68
+ currentY += child.height + this.gap;
69
+ } else {
70
+ child.x = currentX;
71
+ child.y = currentY;
72
+ if (this.align === 'center') {
73
+ child.y = this.y + (this.height - child.height) / 2;
74
+ } else if (this.align === 'end') {
75
+ child.y = this.y + this.height - child.height - this.padding;
76
+ }
77
+ currentX += child.width + this.gap;
78
+ }
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Génère les paramètres d'ombre selon le niveau d'élévation
84
+ * @param {number} elevation - Niveau d'élévation (0-5)
85
+ * @returns {Object} Configuration de l'ombre
86
+ * @private
87
+ */
88
+ getShadowConfig(elevation) {
89
+ const shadows = [
90
+ { blur: 0, offsetY: 0, color: 'transparent', spread: 0 }, // 0 - pas d'ombre
91
+ { blur: 2, offsetY: 1, color: 'rgba(0,0,0,0.12)', spread: 0 }, // 1 - léger
92
+ { blur: 3, offsetY: 1, color: 'rgba(0,0,0,0.14)', spread: 0 }, // 2 - léger
93
+ { blur: 4, offsetY: 2, color: 'rgba(0,0,0,0.16)', spread: 0 }, // 3 - moyen
94
+ { blur: 6, offsetY: 3, color: 'rgba(0,0,0,0.18)', spread: 0 }, // 4 - moyen
95
+ { blur: 8, offsetY: 4, color: 'rgba(0,0,0,0.20)', spread: 0 }, // 5 - fort
96
+ ];
50
97
 
51
- return child;
98
+ return shadows[Math.min(elevation, shadows.length - 1)];
52
99
  }
53
100
 
54
101
  /**
55
- * Dessine la carte et ses enfants
102
+ * Dessine l'effet d'ombre selon l'élévation
56
103
  * @param {CanvasRenderingContext2D} ctx - Contexte de dessin
104
+ * @private
57
105
  */
58
- /**
59
- * Dessine la carte et ses enfants
60
- * @param {CanvasRenderingContext2D} ctx - Contexte de dessin
61
- */
62
- draw(ctx) {
63
- ctx.save();
64
-
65
- // Ombre
66
- if (this.elevation > 0) {
67
- ctx.shadowColor = 'rgba(0, 0, 0, 0.15)';
68
- ctx.shadowBlur = this.elevation * 3;
69
- ctx.shadowOffsetY = this.elevation;
70
- }
71
-
72
- // Background
73
- ctx.fillStyle = this.bgColor;
74
- ctx.beginPath();
75
- this.roundRect(ctx, this.x, this.y, this.width, this.height, this.borderRadius);
76
- ctx.fill();
77
-
78
- ctx.shadowColor = 'transparent';
79
-
80
- // Clipping pour empêcher le contenu de déborder
81
- if (this.clipContent) {
82
- ctx.beginPath();
83
- this.roundRect(ctx, this.x, this.y, this.width, this.height, this.borderRadius);
84
- ctx.clip();
85
- }
86
-
87
- // Children - dessinés relativement à la Card
88
- for (let child of this.children) {
89
- if (child.visible) {
90
- // *** FIX : Utiliser ctx.translate au lieu de modifier child.x/y ***
91
- ctx.save();
92
- ctx.translate(this.x + this.padding, this.y + this.padding);
93
-
94
- // Dessiner l'enfant (ses coordonnées sont déjà relatives)
95
- child.draw(ctx);
96
-
97
- ctx.restore();
98
- }
99
- }
100
-
101
- ctx.restore();
102
- }
106
+ drawShadow(ctx) {
107
+ if (this.elevation <= 0) return;
108
+
109
+ const shadow = this.getShadowConfig(this.elevation);
110
+
111
+ // Sauvegarder l'état du contexte
112
+ ctx.save();
113
+
114
+ // Configurer l'ombre
115
+ ctx.shadowColor = shadow.color;
116
+ ctx.shadowBlur = shadow.blur;
117
+ ctx.shadowOffsetX = 0;
118
+ ctx.shadowOffsetY = shadow.offsetY;
119
+
120
+ // Dessiner un rectangle pour l'ombre
121
+ if (this.borderRadius > 0) {
122
+ ctx.beginPath();
123
+ this.roundRect(ctx, this.x, this.y + shadow.offsetY, this.width, this.height, this.borderRadius);
124
+ ctx.fillStyle = this.bgColor === 'transparent' ? 'white' : this.bgColor;
125
+ ctx.fill();
126
+ } else {
127
+ ctx.fillStyle = this.bgColor === 'transparent' ? 'white' : this.bgColor;
128
+ ctx.fillRect(this.x, this.y + shadow.offsetY, this.width, this.height);
129
+ }
130
+
131
+ ctx.restore();
132
+ }
103
133
 
104
134
  /**
105
- * Vérifie les clics sur les enfants
106
- * @param {number} x - Coordonnée X
107
- * @param {number} y - Coordonnée Y
108
- * @returns {boolean} True si un enfant a été cliqué
109
- * @private
110
- */
111
- checkChildClick(x, y) {
112
- // Ajuster y avec le scrollOffset
113
- const adjustedY = y - (this.framework.scrollOffset || 0);
114
-
115
- // Calculer les coordonnées de base de la Card
116
- const baseX = this.x + this.padding;
117
- const baseY = this.y + this.padding;
118
-
119
- // Vérifier chaque enfant (du dernier au premier pour respecter z-index)
120
- for (let i = this.children.length - 1; i >= 0; i--) {
121
- const child = this.children[i];
122
-
123
- if (!child.visible) continue;
124
-
125
- // Coordonnées absolues de l'enfant
126
- const childAbsX = baseX + child.x;
127
- const childAbsY = baseY + child.y;
128
-
129
- // Vérifier si le clic est dans l'enfant
130
- if (adjustedY >= childAbsY &&
131
- adjustedY <= childAbsY + child.height &&
132
- x >= childAbsX &&
133
- x <= childAbsX + child.width) {
134
-
135
- // Déclencher onClick ou onPress
136
- if (child.onClick) {
137
- child.onClick();
138
- return true;
139
- } else if (child.onPress) {
140
- child.onPress(x, adjustedY);
141
- return true;
142
- }
143
- }
144
- }
145
-
146
- return false;
147
- }
135
+ * Dessine la carte et ses enfants
136
+ * @param {CanvasRenderingContext2D} ctx - Contexte de dessin
137
+ */
138
+ draw(ctx) {
139
+ ctx.save();
140
+
141
+ // Dessiner l'ombre si elevation > 0
142
+ if (this.elevation > 0) {
143
+ this.drawShadow(ctx);
144
+ }
145
+
146
+ // Dessiner le fond de la carte
147
+ if (this.bgColor !== 'transparent') {
148
+ ctx.fillStyle = this.bgColor;
149
+ if (this.borderRadius > 0) {
150
+ ctx.beginPath();
151
+ this.roundRect(ctx, this.x, this.y, this.width, this.height, this.borderRadius);
152
+ ctx.fill();
153
+ } else {
154
+ ctx.fillRect(this.x, this.y, this.width, this.height);
155
+ }
156
+ }
157
+
158
+ // Dessiner les enfants
159
+ for (let child of this.children) {
160
+ if (child.visible) child.draw(ctx);
161
+ }
162
+
163
+ ctx.restore();
164
+ }
148
165
 
149
166
  /**
150
167
  * Dessine un rectangle avec coins arrondis
@@ -157,7 +174,6 @@ class Card extends Component {
157
174
  * @private
158
175
  */
159
176
  roundRect(ctx, x, y, width, height, radius) {
160
- ctx.beginPath();
161
177
  ctx.moveTo(x + radius, y);
162
178
  ctx.lineTo(x + width - radius, y);
163
179
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
@@ -167,14 +183,13 @@ class Card extends Component {
167
183
  ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
168
184
  ctx.lineTo(x, y + radius);
169
185
  ctx.quadraticCurveTo(x, y, x + radius, y);
170
- ctx.closePath();
171
186
  }
172
-
187
+
173
188
  /**
174
189
  * Vérifie si un point est dans les limites
175
190
  * @param {number} x - Coordonnée X
176
191
  * @param {number} y - Coordonnée Y
177
- * @returns {boolean} True si le point est dans la carte
192
+ * @returns {boolean} True si le point est dans la vue
178
193
  */
179
194
  isPointInside(x, y) {
180
195
  return x >= this.x &&
@@ -182,14 +197,27 @@ class Card extends Component {
182
197
  y >= this.y &&
183
198
  y <= this.y + this.height;
184
199
  }
185
-
200
+
186
201
  /**
187
- * Gère le clic sur la carte
188
- * @private
202
+ * Définit le niveau d'élévation
203
+ * @param {number} elevation - Nouveau niveau d'élévation (0-5)
204
+ */
205
+ setElevation(elevation) {
206
+ this.elevation = Math.max(0, Math.min(elevation, 5));
207
+ }
208
+
209
+ /**
210
+ * Augmente le niveau d'élévation
211
+ */
212
+ raise() {
213
+ this.setElevation(this.elevation + 1);
214
+ }
215
+
216
+ /**
217
+ * Réduit le niveau d'élévation
189
218
  */
190
- onClick() {
191
- // La Card elle-même peut avoir un onClick, mais on veut aussi vérifier les enfants
192
- // Cette logique est gérée dans le CanvasFramework modifié ci-dessous
219
+ lower() {
220
+ this.setElevation(this.elevation - 1);
193
221
  }
194
222
  }
195
223
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvasframework",
3
- "version": "0.5.23",
3
+ "version": "0.5.25",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/beyons/CanvasFramework.git"