351 lines
8.6 KiB
JavaScript
351 lines
8.6 KiB
JavaScript
|
|
import {
|
||
|
|
Point,
|
||
|
|
FabricImage,
|
||
|
|
Group,
|
||
|
|
BaseFabricObject,
|
||
|
|
StaticCanvas,
|
||
|
|
} from 'fabric/node';
|
||
|
|
/**
|
||
|
|
* Updates the fromObject function of a class to return a version that can restore old data
|
||
|
|
* with values of originX and originY that are different from 'center', 'center'
|
||
|
|
* Used to upgrade from fabric 6 to fabric 7
|
||
|
|
* @param originalFn the original fromObject function of an object,
|
||
|
|
* @param defaultOriginX optional default value for non exported originX,
|
||
|
|
* @param defaultOriginY optional default value for non exported originY,
|
||
|
|
* @returns a wrapped fromObject function for the object
|
||
|
|
*/
|
||
|
|
export const originUpdaterWrapper = (
|
||
|
|
originalFn,
|
||
|
|
defaultOriginX = 'left',
|
||
|
|
defaultOriginY = 'top',
|
||
|
|
) =>
|
||
|
|
async function (serializedObject, ...args) {
|
||
|
|
// we default to left and top because those are defaults before deprecation
|
||
|
|
const { originX = defaultOriginX, originY = defaultOriginY } =
|
||
|
|
serializedObject;
|
||
|
|
// and we do not want to pass those properties on the object anymore
|
||
|
|
delete serializedObject.originX;
|
||
|
|
delete serializedObject.originY;
|
||
|
|
const originalObject = await originalFn.call(
|
||
|
|
this,
|
||
|
|
serializedObject,
|
||
|
|
...args,
|
||
|
|
);
|
||
|
|
const actualPosition = new Point(originalObject.left, originalObject.top);
|
||
|
|
originalObject.setPositionByOrigin(actualPosition, originX, originY);
|
||
|
|
return originalObject;
|
||
|
|
};
|
||
|
|
|
||
|
|
// @ts-expect-error the _fromObject parameter could be instantiated differently
|
||
|
|
BaseFabricObject._fromObject = originUpdaterWrapper(
|
||
|
|
BaseFabricObject._fromObject,
|
||
|
|
);
|
||
|
|
// FabricImage and Group do not use _fromObject
|
||
|
|
FabricImage.fromObject = originUpdaterWrapper(FabricImage.fromObject);
|
||
|
|
Group.fromObject = originUpdaterWrapper(Group.fromObject);
|
||
|
|
|
||
|
|
const json = {
|
||
|
|
version: '4.5.1',
|
||
|
|
objects: [
|
||
|
|
{
|
||
|
|
type: 'Path',
|
||
|
|
version: '4.5.1',
|
||
|
|
left: 213,
|
||
|
|
top: 163,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
fill: '',
|
||
|
|
stroke: 'red',
|
||
|
|
strokeWidth: 2,
|
||
|
|
path: [
|
||
|
|
['M', 0, 0],
|
||
|
|
['Q', 180, 0, 180, -101.25],
|
||
|
|
['Q', 180, -180, 90, -180],
|
||
|
|
['Q', 0, -180, 0, -112.5],
|
||
|
|
['Q', 0, -45, 78.75, -45],
|
||
|
|
['Q', 135, -45, 146.25, -90],
|
||
|
|
],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
type: 'Path',
|
||
|
|
version: '4.5.1',
|
||
|
|
left: 200,
|
||
|
|
top: 6,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
fill: '',
|
||
|
|
stroke: 'red',
|
||
|
|
strokeWidth: 2,
|
||
|
|
path: [
|
||
|
|
['M', 0, 0],
|
||
|
|
['Q', 180, 0, 180, -101.25],
|
||
|
|
['Q', 180, -180, 90, -180],
|
||
|
|
['Q', 0, -180, 0, -112.5],
|
||
|
|
['Q', 0, -45, 78.75, -45],
|
||
|
|
['Q', 135, -45, 146.25, -90],
|
||
|
|
],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
type: 'Path',
|
||
|
|
version: '4.5.1',
|
||
|
|
left: 18,
|
||
|
|
top: 164,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
fill: '',
|
||
|
|
stroke: 'red',
|
||
|
|
strokeWidth: 2,
|
||
|
|
path: [
|
||
|
|
['M', 0, 0],
|
||
|
|
['Q', 180, 0, 180, -101.25],
|
||
|
|
['Q', 180, -180, 90, -180],
|
||
|
|
['Q', 0, -180, 0, -112.5],
|
||
|
|
['Q', 0, -45, 78.75, -45],
|
||
|
|
['Q', 135, -45, 146.25, -90],
|
||
|
|
],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
type: 'Path',
|
||
|
|
version: '4.5.1',
|
||
|
|
left: 9,
|
||
|
|
top: 14,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
fill: '',
|
||
|
|
stroke: 'red',
|
||
|
|
strokeWidth: 2,
|
||
|
|
path: [
|
||
|
|
['M', 0, 0],
|
||
|
|
['Q', 180, 0, 180, -101.25],
|
||
|
|
['Q', 180, -180, 90, -180],
|
||
|
|
['Q', 0, -180, 0, -112.5],
|
||
|
|
['Q', 0, -45, 78.75, -45],
|
||
|
|
['Q', 135, -45, 146.25, -90],
|
||
|
|
],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
type: 'Text',
|
||
|
|
version: '4.5.1',
|
||
|
|
left: 10,
|
||
|
|
top: 14,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
text: 'Text on a swirl textAlign right',
|
||
|
|
fontSize: 28,
|
||
|
|
textAlign: 'right',
|
||
|
|
charSpacing: 50,
|
||
|
|
path: {
|
||
|
|
type: 'Path',
|
||
|
|
version: '4.5.1',
|
||
|
|
originX: 'left',
|
||
|
|
originY: 'top',
|
||
|
|
left: -0.5,
|
||
|
|
top: -180.5,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
fill: 'rgb(0,0,0)',
|
||
|
|
stroke: null,
|
||
|
|
strokeWidth: 1,
|
||
|
|
strokeDashArray: null,
|
||
|
|
strokeLineCap: 'butt',
|
||
|
|
strokeDashOffset: 0,
|
||
|
|
strokeLineJoin: 'miter',
|
||
|
|
strokeUniform: false,
|
||
|
|
strokeMiterLimit: 4,
|
||
|
|
scaleX: 1,
|
||
|
|
scaleY: 1,
|
||
|
|
angle: 0,
|
||
|
|
flipX: false,
|
||
|
|
flipY: false,
|
||
|
|
opacity: 1,
|
||
|
|
shadow: null,
|
||
|
|
visible: false,
|
||
|
|
backgroundColor: '',
|
||
|
|
fillRule: 'nonzero',
|
||
|
|
paintFirst: 'fill',
|
||
|
|
globalCompositeOperation: 'source-over',
|
||
|
|
skewX: 0,
|
||
|
|
skewY: 0,
|
||
|
|
path: [
|
||
|
|
['M', 0, 0],
|
||
|
|
['Q', 180, 0, 180, -101.25],
|
||
|
|
['Q', 180, -180, 90, -180],
|
||
|
|
['Q', 0, -180, 0, -112.5],
|
||
|
|
['Q', 0, -45, 78.75, -45],
|
||
|
|
['Q', 135, -45, 146.25, -90],
|
||
|
|
],
|
||
|
|
},
|
||
|
|
direction: 'ltr',
|
||
|
|
styles: {},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
type: 'Text',
|
||
|
|
version: '4.5.1',
|
||
|
|
left: 15,
|
||
|
|
top: 165,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
text: 'Text on a swirl textAlign left',
|
||
|
|
fontSize: 28,
|
||
|
|
charSpacing: 50,
|
||
|
|
path: {
|
||
|
|
type: 'Path',
|
||
|
|
version: '4.5.1',
|
||
|
|
originX: 'left',
|
||
|
|
originY: 'top',
|
||
|
|
left: -0.5,
|
||
|
|
top: -180.5,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
fill: 'rgb(0,0,0)',
|
||
|
|
stroke: null,
|
||
|
|
strokeWidth: 1,
|
||
|
|
strokeDashArray: null,
|
||
|
|
strokeLineCap: 'butt',
|
||
|
|
strokeDashOffset: 0,
|
||
|
|
strokeLineJoin: 'miter',
|
||
|
|
strokeUniform: false,
|
||
|
|
strokeMiterLimit: 4,
|
||
|
|
scaleX: 1,
|
||
|
|
scaleY: 1,
|
||
|
|
angle: 0,
|
||
|
|
flipX: false,
|
||
|
|
flipY: false,
|
||
|
|
opacity: 1,
|
||
|
|
shadow: null,
|
||
|
|
visible: false,
|
||
|
|
backgroundColor: '',
|
||
|
|
fillRule: 'nonzero',
|
||
|
|
paintFirst: 'fill',
|
||
|
|
globalCompositeOperation: 'source-over',
|
||
|
|
skewX: 0,
|
||
|
|
skewY: 0,
|
||
|
|
path: [
|
||
|
|
['M', 0, 0],
|
||
|
|
['Q', 180, 0, 180, -101.25],
|
||
|
|
['Q', 180, -180, 90, -180],
|
||
|
|
['Q', 0, -180, 0, -112.5],
|
||
|
|
['Q', 0, -45, 78.75, -45],
|
||
|
|
['Q', 135, -45, 146.25, -90],
|
||
|
|
],
|
||
|
|
},
|
||
|
|
direction: 'ltr',
|
||
|
|
styles: {},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
type: 'Text',
|
||
|
|
version: '4.5.1',
|
||
|
|
left: 201,
|
||
|
|
top: 9,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
text: 'Text on a swirl textAlign center',
|
||
|
|
fontSize: 28,
|
||
|
|
textAlign: 'center',
|
||
|
|
charSpacing: 50,
|
||
|
|
path: {
|
||
|
|
type: 'Path',
|
||
|
|
version: '4.5.1',
|
||
|
|
originX: 'left',
|
||
|
|
originY: 'top',
|
||
|
|
left: -0.5,
|
||
|
|
top: -180.5,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
fill: 'rgb(0,0,0)',
|
||
|
|
stroke: null,
|
||
|
|
strokeWidth: 1,
|
||
|
|
strokeDashArray: null,
|
||
|
|
strokeLineCap: 'butt',
|
||
|
|
strokeDashOffset: 0,
|
||
|
|
strokeLineJoin: 'miter',
|
||
|
|
strokeUniform: false,
|
||
|
|
strokeMiterLimit: 4,
|
||
|
|
scaleX: 1,
|
||
|
|
scaleY: 1,
|
||
|
|
angle: 0,
|
||
|
|
flipX: false,
|
||
|
|
flipY: false,
|
||
|
|
opacity: 1,
|
||
|
|
shadow: null,
|
||
|
|
visible: false,
|
||
|
|
backgroundColor: '',
|
||
|
|
fillRule: 'nonzero',
|
||
|
|
paintFirst: 'fill',
|
||
|
|
globalCompositeOperation: 'source-over',
|
||
|
|
skewX: 0,
|
||
|
|
skewY: 0,
|
||
|
|
path: [
|
||
|
|
['M', 0, 0],
|
||
|
|
['Q', 180, 0, 180, -101.25],
|
||
|
|
['Q', 180, -180, 90, -180],
|
||
|
|
['Q', 0, -180, 0, -112.5],
|
||
|
|
['Q', 0, -45, 78.75, -45],
|
||
|
|
['Q', 135, -45, 146.25, -90],
|
||
|
|
],
|
||
|
|
},
|
||
|
|
direction: 'ltr',
|
||
|
|
styles: {},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
type: 'Text',
|
||
|
|
version: '4.5.1',
|
||
|
|
left: 213,
|
||
|
|
top: 164,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
text: 'full text to understand better a Text on a swirl textAlign',
|
||
|
|
fontSize: 28,
|
||
|
|
charSpacing: 50,
|
||
|
|
path: {
|
||
|
|
type: 'Path',
|
||
|
|
version: '4.5.1',
|
||
|
|
originX: 'left',
|
||
|
|
originY: 'top',
|
||
|
|
left: -0.5,
|
||
|
|
top: -180.5,
|
||
|
|
width: 180,
|
||
|
|
height: 180,
|
||
|
|
fill: 'rgb(0,0,0)',
|
||
|
|
stroke: null,
|
||
|
|
strokeWidth: 1,
|
||
|
|
strokeDashArray: null,
|
||
|
|
strokeLineCap: 'butt',
|
||
|
|
strokeDashOffset: 0,
|
||
|
|
strokeLineJoin: 'miter',
|
||
|
|
strokeUniform: false,
|
||
|
|
strokeMiterLimit: 4,
|
||
|
|
scaleX: 1,
|
||
|
|
scaleY: 1,
|
||
|
|
angle: 0,
|
||
|
|
flipX: false,
|
||
|
|
flipY: false,
|
||
|
|
opacity: 1,
|
||
|
|
shadow: null,
|
||
|
|
visible: false,
|
||
|
|
backgroundColor: '',
|
||
|
|
fillRule: 'nonzero',
|
||
|
|
paintFirst: 'fill',
|
||
|
|
globalCompositeOperation: 'source-over',
|
||
|
|
skewX: 0,
|
||
|
|
skewY: 0,
|
||
|
|
path: [
|
||
|
|
['M', 0, 0],
|
||
|
|
['Q', 180, 0, 180, -101.25],
|
||
|
|
['Q', 180, -180, 90, -180],
|
||
|
|
['Q', 0, -180, 0, -112.5],
|
||
|
|
['Q', 0, -45, 78.75, -45],
|
||
|
|
['Q', 135, -45, 146.25, -90],
|
||
|
|
],
|
||
|
|
},
|
||
|
|
direction: 'ltr',
|
||
|
|
styles: {},
|
||
|
|
},
|
||
|
|
],
|
||
|
|
};
|
||
|
|
|
||
|
|
const canvas = new StaticCanvas();
|
||
|
|
await canvas.loadFromJSON(json);
|
||
|
|
canvas.includeDefaultValues = false;
|
||
|
|
console.log(JSON.stringify(canvas));
|