@leapfrog/interactive-canvas 2.0.22-beta-8 → 2.0.23-beta-1
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.
|
@@ -202,11 +202,11 @@ export declare abstract class AbstractInteractiveCanvas implements IInteractiveC
|
|
|
202
202
|
* @inheritDoc
|
|
203
203
|
*/
|
|
204
204
|
sendObjectToBack(target: FabricObject): void;
|
|
205
|
+
addImageObject(imageUrl: string): Promise<IImage>;
|
|
205
206
|
/**
|
|
206
207
|
* @override
|
|
207
208
|
* @inheritDoc
|
|
208
209
|
*/
|
|
209
|
-
addImageObject(imageUrl: string): Promise<IImage>;
|
|
210
210
|
/**
|
|
211
211
|
* @override
|
|
212
212
|
* @inheritDoc
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _, { round, each, values, reduce, clone, max, isEqual } from 'lodash';
|
|
2
2
|
import { BehaviorSubject, Subject } from 'rxjs';
|
|
3
|
+
import { createCanvas, loadImage } from 'canvas';
|
|
3
4
|
import * as fabric from 'fabric';
|
|
4
|
-
import { JSDOM } from 'jsdom';
|
|
5
5
|
|
|
6
6
|
const PIXELS_PER_MM$2 = 3.937;
|
|
7
7
|
class MillimeterDimensions {
|
|
@@ -3034,41 +3034,108 @@ class AbstractInteractiveCanvas {
|
|
|
3034
3034
|
this.fabricCanvas.requestRenderAll();
|
|
3035
3035
|
}
|
|
3036
3036
|
}
|
|
3037
|
-
/**
|
|
3038
|
-
* @override
|
|
3039
|
-
* @inheritDoc
|
|
3040
|
-
*/
|
|
3041
3037
|
addImageObject(imageUrl) {
|
|
3042
3038
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3043
|
-
//Don't let the image be more than half the canvas in size.
|
|
3039
|
+
// Don't let the image be more than half the canvas in size.
|
|
3044
3040
|
const maxSizeScale = 2;
|
|
3045
3041
|
const maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
|
|
3046
3042
|
const options = { crossOrigin: "anonymous" };
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3043
|
+
if (this.headless) {
|
|
3044
|
+
// Server-side logic without mock DOM
|
|
3045
|
+
//const { createCanvas, loadImage } = require("canvas"); // Use node-canvas
|
|
3046
|
+
const canvas = createCanvas(1, 1); // Temporary canvas for image processing
|
|
3047
|
+
canvas.getContext("2d");
|
|
3048
|
+
const image = yield loadImage(imageUrl);
|
|
3049
|
+
const id = this.randomId();
|
|
3050
|
+
let newScale = 1;
|
|
3051
|
+
const curWidth = newScale * image.width;
|
|
3052
|
+
if (curWidth > maxWidth) {
|
|
3053
|
+
newScale = maxWidth / curWidth;
|
|
3054
|
+
}
|
|
3055
|
+
// Set image properties and add to the canvas
|
|
3056
|
+
const fabricImage = new this.fabric.Image(image, {
|
|
3057
|
+
id: id,
|
|
3058
|
+
scaleX: newScale,
|
|
3059
|
+
scaleY: newScale,
|
|
3060
|
+
originX: "left",
|
|
3061
|
+
originY: "top",
|
|
3062
|
+
});
|
|
3063
|
+
this.fabricCanvas.add(fabricImage);
|
|
3064
|
+
const object = new Image(this, fabricImage);
|
|
3065
|
+
this.trackNewObject(object);
|
|
3066
|
+
this.syncObjectList();
|
|
3067
|
+
return object;
|
|
3068
|
+
}
|
|
3069
|
+
else {
|
|
3070
|
+
// Browser-side logic
|
|
3071
|
+
return yield new Promise((resolve) => {
|
|
3072
|
+
this.fabric.Image.fromURL(imageUrl, options).then((fabricImage) => {
|
|
3073
|
+
const id = this.randomId();
|
|
3074
|
+
let newScale = 1;
|
|
3075
|
+
const curWidth = newScale * fabricImage.width;
|
|
3076
|
+
if (curWidth > maxWidth) {
|
|
3077
|
+
newScale = maxWidth / curWidth;
|
|
3078
|
+
}
|
|
3079
|
+
fabricImage.set({
|
|
3080
|
+
id: id,
|
|
3081
|
+
scaleX: newScale,
|
|
3082
|
+
scaleY: newScale,
|
|
3083
|
+
originX: "left",
|
|
3084
|
+
originY: "top",
|
|
3085
|
+
});
|
|
3086
|
+
this.fabricCanvas.add(fabricImage);
|
|
3087
|
+
const object = new Image(this, fabricImage);
|
|
3088
|
+
this.trackNewObject(object);
|
|
3089
|
+
this.selectFabricObject(fabricImage);
|
|
3090
|
+
this.syncObjectList();
|
|
3091
|
+
resolve(object);
|
|
3061
3092
|
});
|
|
3062
|
-
this.fabricCanvas.add(fabricImage);
|
|
3063
|
-
const object = new Image(this, fabricImage);
|
|
3064
|
-
this.trackNewObject(object);
|
|
3065
|
-
this.selectFabricObject(fabricImage);
|
|
3066
|
-
this.syncObjectList();
|
|
3067
|
-
resolve(object);
|
|
3068
3093
|
});
|
|
3069
|
-
}
|
|
3094
|
+
}
|
|
3070
3095
|
});
|
|
3071
3096
|
}
|
|
3097
|
+
/**
|
|
3098
|
+
* @override
|
|
3099
|
+
* @inheritDoc
|
|
3100
|
+
*/
|
|
3101
|
+
/* public async addImageObject(imageUrl: string): Promise<IImage> {
|
|
3102
|
+
//Don't let the image be more than half the canvas in size.
|
|
3103
|
+
const maxSizeScale = 2;
|
|
3104
|
+
const maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
|
|
3105
|
+
|
|
3106
|
+
const options = {crossOrigin: "anonymous"};
|
|
3107
|
+
return await new Promise((resolve) => {
|
|
3108
|
+
this.fabric.Image.fromURL(imageUrl, options).then((fabricImage: FabricImage) => {
|
|
3109
|
+
const id = this.randomId();
|
|
3110
|
+
|
|
3111
|
+
let newScale = 1;
|
|
3112
|
+
|
|
3113
|
+
const curWidth = newScale * fabricImage.width;
|
|
3114
|
+
if (curWidth > maxWidth) {
|
|
3115
|
+
newScale = maxWidth / curWidth;
|
|
3116
|
+
}
|
|
3117
|
+
|
|
3118
|
+
fabricImage.set({
|
|
3119
|
+
id: id,
|
|
3120
|
+
scaleX: newScale,
|
|
3121
|
+
scaleY: newScale,
|
|
3122
|
+
originX: "left",
|
|
3123
|
+
originY: "top"
|
|
3124
|
+
} as any);
|
|
3125
|
+
|
|
3126
|
+
this.fabricCanvas.add(fabricImage);
|
|
3127
|
+
|
|
3128
|
+
const object = new Image(this, fabricImage);
|
|
3129
|
+
this.trackNewObject(object);
|
|
3130
|
+
this.selectFabricObject(fabricImage);
|
|
3131
|
+
|
|
3132
|
+
this.syncObjectList();
|
|
3133
|
+
|
|
3134
|
+
resolve(object);
|
|
3135
|
+
});
|
|
3136
|
+
});
|
|
3137
|
+
}
|
|
3138
|
+
*/
|
|
3072
3139
|
/**
|
|
3073
3140
|
* @override
|
|
3074
3141
|
* @inheritDoc
|
|
@@ -3736,20 +3803,7 @@ class SelectionData {
|
|
|
3736
3803
|
|
|
3737
3804
|
class HeadlessInteractiveCanvas extends AbstractInteractiveCanvas {
|
|
3738
3805
|
constructor() {
|
|
3739
|
-
|
|
3740
|
-
const { window } = new JSDOM('<!DOCTYPE html><html><body></body></html>');
|
|
3741
|
-
global.window = window;
|
|
3742
|
-
global.document = window.document;
|
|
3743
|
-
global.HTMLElement = window.HTMLElement;
|
|
3744
|
-
global.HTMLCanvasElement = window.HTMLCanvasElement;
|
|
3745
|
-
global.window.requestAnimationFrame = (callback) => {
|
|
3746
|
-
return setTimeout(() => callback(Date.now()), 16);
|
|
3747
|
-
};
|
|
3748
|
-
global.window.cancelAnimationFrame = (id) => {
|
|
3749
|
-
clearTimeout(id);
|
|
3750
|
-
};
|
|
3751
|
-
}
|
|
3752
|
-
super(fabric, new fabric.StaticCanvas(undefined, { width: 640, height: 480 }), 1);
|
|
3806
|
+
super(fabric, new fabric.StaticCanvas(undefined, { width: 640, height: 480 }), 0);
|
|
3753
3807
|
this.headless = true;
|
|
3754
3808
|
}
|
|
3755
3809
|
/**
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var _ = require('lodash');
|
|
4
4
|
var rxjs = require('rxjs');
|
|
5
|
+
var canvas = require('canvas');
|
|
5
6
|
var fabric = require('fabric');
|
|
6
|
-
var jsdom = require('jsdom');
|
|
7
7
|
|
|
8
8
|
function _interopNamespaceDefault(e) {
|
|
9
9
|
var n = Object.create(null);
|
|
@@ -3055,41 +3055,108 @@ class AbstractInteractiveCanvas {
|
|
|
3055
3055
|
this.fabricCanvas.requestRenderAll();
|
|
3056
3056
|
}
|
|
3057
3057
|
}
|
|
3058
|
-
/**
|
|
3059
|
-
* @override
|
|
3060
|
-
* @inheritDoc
|
|
3061
|
-
*/
|
|
3062
3058
|
addImageObject(imageUrl) {
|
|
3063
3059
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3064
|
-
//Don't let the image be more than half the canvas in size.
|
|
3060
|
+
// Don't let the image be more than half the canvas in size.
|
|
3065
3061
|
const maxSizeScale = 2;
|
|
3066
3062
|
const maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
|
|
3067
3063
|
const options = { crossOrigin: "anonymous" };
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3064
|
+
if (this.headless) {
|
|
3065
|
+
// Server-side logic without mock DOM
|
|
3066
|
+
//const { createCanvas, loadImage } = require("canvas"); // Use node-canvas
|
|
3067
|
+
const canvas$1 = canvas.createCanvas(1, 1); // Temporary canvas for image processing
|
|
3068
|
+
canvas$1.getContext("2d");
|
|
3069
|
+
const image = yield canvas.loadImage(imageUrl);
|
|
3070
|
+
const id = this.randomId();
|
|
3071
|
+
let newScale = 1;
|
|
3072
|
+
const curWidth = newScale * image.width;
|
|
3073
|
+
if (curWidth > maxWidth) {
|
|
3074
|
+
newScale = maxWidth / curWidth;
|
|
3075
|
+
}
|
|
3076
|
+
// Set image properties and add to the canvas
|
|
3077
|
+
const fabricImage = new this.fabric.Image(image, {
|
|
3078
|
+
id: id,
|
|
3079
|
+
scaleX: newScale,
|
|
3080
|
+
scaleY: newScale,
|
|
3081
|
+
originX: "left",
|
|
3082
|
+
originY: "top",
|
|
3083
|
+
});
|
|
3084
|
+
this.fabricCanvas.add(fabricImage);
|
|
3085
|
+
const object = new Image(this, fabricImage);
|
|
3086
|
+
this.trackNewObject(object);
|
|
3087
|
+
this.syncObjectList();
|
|
3088
|
+
return object;
|
|
3089
|
+
}
|
|
3090
|
+
else {
|
|
3091
|
+
// Browser-side logic
|
|
3092
|
+
return yield new Promise((resolve) => {
|
|
3093
|
+
this.fabric.Image.fromURL(imageUrl, options).then((fabricImage) => {
|
|
3094
|
+
const id = this.randomId();
|
|
3095
|
+
let newScale = 1;
|
|
3096
|
+
const curWidth = newScale * fabricImage.width;
|
|
3097
|
+
if (curWidth > maxWidth) {
|
|
3098
|
+
newScale = maxWidth / curWidth;
|
|
3099
|
+
}
|
|
3100
|
+
fabricImage.set({
|
|
3101
|
+
id: id,
|
|
3102
|
+
scaleX: newScale,
|
|
3103
|
+
scaleY: newScale,
|
|
3104
|
+
originX: "left",
|
|
3105
|
+
originY: "top",
|
|
3106
|
+
});
|
|
3107
|
+
this.fabricCanvas.add(fabricImage);
|
|
3108
|
+
const object = new Image(this, fabricImage);
|
|
3109
|
+
this.trackNewObject(object);
|
|
3110
|
+
this.selectFabricObject(fabricImage);
|
|
3111
|
+
this.syncObjectList();
|
|
3112
|
+
resolve(object);
|
|
3082
3113
|
});
|
|
3083
|
-
this.fabricCanvas.add(fabricImage);
|
|
3084
|
-
const object = new Image(this, fabricImage);
|
|
3085
|
-
this.trackNewObject(object);
|
|
3086
|
-
this.selectFabricObject(fabricImage);
|
|
3087
|
-
this.syncObjectList();
|
|
3088
|
-
resolve(object);
|
|
3089
3114
|
});
|
|
3090
|
-
}
|
|
3115
|
+
}
|
|
3091
3116
|
});
|
|
3092
3117
|
}
|
|
3118
|
+
/**
|
|
3119
|
+
* @override
|
|
3120
|
+
* @inheritDoc
|
|
3121
|
+
*/
|
|
3122
|
+
/* public async addImageObject(imageUrl: string): Promise<IImage> {
|
|
3123
|
+
//Don't let the image be more than half the canvas in size.
|
|
3124
|
+
const maxSizeScale = 2;
|
|
3125
|
+
const maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
|
|
3126
|
+
|
|
3127
|
+
const options = {crossOrigin: "anonymous"};
|
|
3128
|
+
return await new Promise((resolve) => {
|
|
3129
|
+
this.fabric.Image.fromURL(imageUrl, options).then((fabricImage: FabricImage) => {
|
|
3130
|
+
const id = this.randomId();
|
|
3131
|
+
|
|
3132
|
+
let newScale = 1;
|
|
3133
|
+
|
|
3134
|
+
const curWidth = newScale * fabricImage.width;
|
|
3135
|
+
if (curWidth > maxWidth) {
|
|
3136
|
+
newScale = maxWidth / curWidth;
|
|
3137
|
+
}
|
|
3138
|
+
|
|
3139
|
+
fabricImage.set({
|
|
3140
|
+
id: id,
|
|
3141
|
+
scaleX: newScale,
|
|
3142
|
+
scaleY: newScale,
|
|
3143
|
+
originX: "left",
|
|
3144
|
+
originY: "top"
|
|
3145
|
+
} as any);
|
|
3146
|
+
|
|
3147
|
+
this.fabricCanvas.add(fabricImage);
|
|
3148
|
+
|
|
3149
|
+
const object = new Image(this, fabricImage);
|
|
3150
|
+
this.trackNewObject(object);
|
|
3151
|
+
this.selectFabricObject(fabricImage);
|
|
3152
|
+
|
|
3153
|
+
this.syncObjectList();
|
|
3154
|
+
|
|
3155
|
+
resolve(object);
|
|
3156
|
+
});
|
|
3157
|
+
});
|
|
3158
|
+
}
|
|
3159
|
+
*/
|
|
3093
3160
|
/**
|
|
3094
3161
|
* @override
|
|
3095
3162
|
* @inheritDoc
|
|
@@ -3757,20 +3824,7 @@ class SelectionData {
|
|
|
3757
3824
|
|
|
3758
3825
|
class HeadlessInteractiveCanvas extends AbstractInteractiveCanvas {
|
|
3759
3826
|
constructor() {
|
|
3760
|
-
|
|
3761
|
-
const { window } = new jsdom.JSDOM('<!DOCTYPE html><html><body></body></html>');
|
|
3762
|
-
global.window = window;
|
|
3763
|
-
global.document = window.document;
|
|
3764
|
-
global.HTMLElement = window.HTMLElement;
|
|
3765
|
-
global.HTMLCanvasElement = window.HTMLCanvasElement;
|
|
3766
|
-
global.window.requestAnimationFrame = (callback) => {
|
|
3767
|
-
return setTimeout(() => callback(Date.now()), 16);
|
|
3768
|
-
};
|
|
3769
|
-
global.window.cancelAnimationFrame = (id) => {
|
|
3770
|
-
clearTimeout(id);
|
|
3771
|
-
};
|
|
3772
|
-
}
|
|
3773
|
-
super(fabric__namespace, new fabric__namespace.StaticCanvas(undefined, { width: 640, height: 480 }), 1);
|
|
3827
|
+
super(fabric__namespace, new fabric__namespace.StaticCanvas(undefined, { width: 640, height: 480 }), 0);
|
|
3774
3828
|
this.headless = true;
|
|
3775
3829
|
}
|
|
3776
3830
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leapfrog/interactive-canvas",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.23-beta-1",
|
|
4
4
|
"description": "Leapfrog interactive canvas",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -14,13 +14,12 @@
|
|
|
14
14
|
"prepublishOnly": "npm run build"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@types/jsdom": "^28.0.3",
|
|
18
17
|
"@types/lodash": "^4.17.23",
|
|
19
18
|
"typescript": "^6.0.3"
|
|
20
19
|
},
|
|
21
20
|
"dependencies": {
|
|
21
|
+
"canvas": "^3.2.3",
|
|
22
22
|
"fabric": "^7.2.0",
|
|
23
|
-
"jsdom": "^29.0.2",
|
|
24
23
|
"lodash": "^4.18.1",
|
|
25
24
|
"rollup": "^4.60.3",
|
|
26
25
|
"rollup-plugin-typescript2": "^0.37.0",
|