@nasser-sw/fabric 7.0.1-beta5 → 7.0.1-beta7
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.
- package/dist/index.js +28 -23
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.min.mjs +1 -1
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +28 -23
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +28 -23
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +28 -23
- package/dist/index.node.mjs.map +1 -1
- package/dist/package.json.min.mjs +1 -1
- package/dist/package.json.mjs +1 -1
- package/dist/src/shapes/Line.d.ts.map +1 -1
- package/dist/src/shapes/Line.min.mjs +1 -1
- package/dist/src/shapes/Line.min.mjs.map +1 -1
- package/dist/src/shapes/Line.mjs +27 -22
- package/dist/src/shapes/Line.mjs.map +1 -1
- package/dist-extensions/src/shapes/Line.d.ts.map +1 -1
- package/fabric-test2.html +91 -0
- package/package.json +1 -1
- package/src/shapes/Line.ts +19 -11
package/fabric-test2.html
CHANGED
|
@@ -54,6 +54,9 @@
|
|
|
54
54
|
<button id="toggleDebugBtn">Toggle Debug</button>
|
|
55
55
|
<button id="exportPngBtn">Export as PNG</button>
|
|
56
56
|
<button id="exportSvgBtn">Export as SVG</button>
|
|
57
|
+
<button id="saveJsonBtn">Save JSON</button>
|
|
58
|
+
<button id="loadJsonBtn">Load JSON</button>
|
|
59
|
+
<input type="file" id="loadJsonFile" accept=".json" style="display: none;">
|
|
57
60
|
</div>
|
|
58
61
|
|
|
59
62
|
<div style="display: flex; gap: 20px;">
|
|
@@ -243,6 +246,94 @@
|
|
|
243
246
|
});
|
|
244
247
|
});
|
|
245
248
|
|
|
249
|
+
// Save JSON functionality
|
|
250
|
+
document.getElementById('saveJsonBtn').addEventListener('click', () => {
|
|
251
|
+
try {
|
|
252
|
+
// Get the canvas as JSON
|
|
253
|
+
const canvasJson = canvas.toJSON();
|
|
254
|
+
|
|
255
|
+
// Create a beautiful formatted JSON string
|
|
256
|
+
const jsonString = JSON.stringify(canvasJson, null, 2);
|
|
257
|
+
|
|
258
|
+
// Create a blob and download link
|
|
259
|
+
const blob = new Blob([jsonString], { type: 'application/json' });
|
|
260
|
+
const url = URL.createObjectURL(blob);
|
|
261
|
+
|
|
262
|
+
const link = document.createElement('a');
|
|
263
|
+
link.download = `fabric-canvas-${Date.now()}.json`;
|
|
264
|
+
link.href = url;
|
|
265
|
+
|
|
266
|
+
// Trigger download
|
|
267
|
+
document.body.appendChild(link);
|
|
268
|
+
link.click();
|
|
269
|
+
document.body.removeChild(link);
|
|
270
|
+
|
|
271
|
+
// Clean up
|
|
272
|
+
URL.revokeObjectURL(url);
|
|
273
|
+
|
|
274
|
+
console.log('Canvas saved as JSON:', canvasJson);
|
|
275
|
+
console.log('JSON string length:', jsonString.length);
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.error('Save JSON failed:', error);
|
|
278
|
+
alert('Save failed: ' + error.message);
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// Load JSON functionality
|
|
283
|
+
document.getElementById('loadJsonBtn').addEventListener('click', () => {
|
|
284
|
+
document.getElementById('loadJsonFile').click();
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
document.getElementById('loadJsonFile').addEventListener('change', (e) => {
|
|
288
|
+
const file = e.target.files[0];
|
|
289
|
+
if (!file) return;
|
|
290
|
+
|
|
291
|
+
const reader = new FileReader();
|
|
292
|
+
reader.onload = function(e) {
|
|
293
|
+
try {
|
|
294
|
+
const jsonData = JSON.parse(e.target.result);
|
|
295
|
+
|
|
296
|
+
console.log('Loading JSON data:', jsonData);
|
|
297
|
+
|
|
298
|
+
// Clear existing canvas
|
|
299
|
+
canvas.clear();
|
|
300
|
+
|
|
301
|
+
// Load the JSON data into the canvas
|
|
302
|
+
canvas.loadFromJSON(jsonData, () => {
|
|
303
|
+
// This callback is called after loading is complete
|
|
304
|
+
canvas.renderAll();
|
|
305
|
+
console.log('Canvas loaded from JSON successfully');
|
|
306
|
+
console.log('Loaded objects:', canvas.getObjects());
|
|
307
|
+
|
|
308
|
+
// Log details about loaded lines
|
|
309
|
+
const lines = canvas.getObjects('line');
|
|
310
|
+
lines.forEach((line, index) => {
|
|
311
|
+
console.log(`Line ${index + 1}:`, {
|
|
312
|
+
type: line.type,
|
|
313
|
+
left: line.left,
|
|
314
|
+
top: line.top,
|
|
315
|
+
x1: line.x1,
|
|
316
|
+
y1: line.y1,
|
|
317
|
+
x2: line.x2,
|
|
318
|
+
y2: line.y2,
|
|
319
|
+
stroke: line.stroke,
|
|
320
|
+
strokeWidth: line.strokeWidth
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// Clear the file input for next use
|
|
326
|
+
e.target.value = '';
|
|
327
|
+
|
|
328
|
+
} catch (error) {
|
|
329
|
+
console.error('Load JSON failed:', error);
|
|
330
|
+
alert('Load failed: ' + error.message);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
reader.readAsText(file);
|
|
335
|
+
});
|
|
336
|
+
|
|
246
337
|
// Add initial line for testing
|
|
247
338
|
const initialLine = new fabric.Line([150, 150, 350, 250], {
|
|
248
339
|
stroke: '#2196F3',
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@nasser-sw/fabric",
|
|
3
3
|
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
|
|
4
4
|
"homepage": "http://fabricjs.com/",
|
|
5
|
-
"version": "7.0.1-
|
|
5
|
+
"version": "7.0.1-beta7",
|
|
6
6
|
"author": "Juriy Zaytsev <kangax@gmail.com>",
|
|
7
7
|
"contributors": [
|
|
8
8
|
{
|
package/src/shapes/Line.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { CENTER, LEFT, TOP } from '../constants';
|
|
|
12
12
|
import type { CSSRules } from '../parser/typedefs';
|
|
13
13
|
import { Control } from '../controls/Control';
|
|
14
14
|
import type { TPointerEvent, Transform } from '../EventTypeDefs';
|
|
15
|
+
import { multiplyTransformMatrices } from '../util/misc/matrix';
|
|
15
16
|
|
|
16
17
|
const coordProps = ['x1', 'x2', 'y1', 'y2'] as const;
|
|
17
18
|
|
|
@@ -99,13 +100,11 @@ export class Line<
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
_p1PositionHandler() {
|
|
102
|
-
|
|
103
|
-
return new Point(this.x1, this.y1).transform(vpt);
|
|
103
|
+
return new Point(this.x1, this.y1).transform(this.getViewportTransform());
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
_p2PositionHandler() {
|
|
107
|
-
|
|
108
|
-
return new Point(this.x2, this.y2).transform(vpt);
|
|
107
|
+
return new Point(this.x2, this.y2).transform(this.getViewportTransform());
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
_renderEndpointControl(
|
|
@@ -176,11 +175,6 @@ export class Line<
|
|
|
176
175
|
|
|
177
176
|
setCoords() {
|
|
178
177
|
if (this._useEndpointCoords) {
|
|
179
|
-
// Set the object's center to the geometric center of the line
|
|
180
|
-
const center = this._findCenterFromElement();
|
|
181
|
-
this.left = center.x;
|
|
182
|
-
this.top = center.y;
|
|
183
|
-
|
|
184
178
|
// Set width and height for hit detection and bounding box
|
|
185
179
|
const effectiveStrokeWidth =
|
|
186
180
|
this.hitStrokeWidth === 'auto'
|
|
@@ -189,6 +183,13 @@ export class Line<
|
|
|
189
183
|
const hitPadding = Math.max(effectiveStrokeWidth / 2 + 5, 10);
|
|
190
184
|
this.width = Math.abs(this.x2 - this.x1) + hitPadding * 2;
|
|
191
185
|
this.height = Math.abs(this.y2 - this.y1) + hitPadding * 2;
|
|
186
|
+
|
|
187
|
+
// Only update left/top if they haven't been explicitly set (e.g., during loading)
|
|
188
|
+
if (this.left === 0 && this.top === 0) {
|
|
189
|
+
const center = this._findCenterFromElement();
|
|
190
|
+
this.left = center.x;
|
|
191
|
+
this.top = center.y;
|
|
192
|
+
}
|
|
192
193
|
}
|
|
193
194
|
super.setCoords();
|
|
194
195
|
}
|
|
@@ -385,8 +386,6 @@ export class Line<
|
|
|
385
386
|
_renderDirectly(ctx: CanvasRenderingContext2D) {
|
|
386
387
|
if (!this.visible) return;
|
|
387
388
|
ctx.save();
|
|
388
|
-
const vpt = this.canvas?.viewportTransform || [1, 0, 0, 1, 0, 0];
|
|
389
|
-
ctx.transform(vpt[0], vpt[1], vpt[2], vpt[3], vpt[4], vpt[5]);
|
|
390
389
|
ctx.globalAlpha = this.opacity;
|
|
391
390
|
ctx.strokeStyle = this.stroke?.toString() || '#000';
|
|
392
391
|
ctx.lineWidth = this.strokeWidth;
|
|
@@ -421,6 +420,15 @@ export class Line<
|
|
|
421
420
|
T extends Omit<Props & TClassProperties<this>, keyof SProps>,
|
|
422
421
|
K extends keyof T = never
|
|
423
422
|
>(propertiesToInclude: K[] = []): Pick<T, K> & SProps {
|
|
423
|
+
if (this._useEndpointCoords) {
|
|
424
|
+
return {
|
|
425
|
+
...super.toObject(propertiesToInclude),
|
|
426
|
+
x1: this.x1,
|
|
427
|
+
y1: this.y1,
|
|
428
|
+
x2: this.x2,
|
|
429
|
+
y2: this.y2,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
424
432
|
return {
|
|
425
433
|
...super.toObject(propertiesToInclude),
|
|
426
434
|
...this.calcLinePoints(),
|