UNPKG

fabric

Version:

Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.

266 lines (221 loc) 8.28 kB
import { describe, expect, it } from 'vitest'; import { Circle } from './Circle'; import { FabricObject } from './Object/FabricObject'; import { version } from '../../fabric'; import { createReferenceObject, createSVGElement } from '../../test/utils'; const REFERENCE_CIRCLE = createReferenceObject('Circle', { radius: 0, startAngle: 0, endAngle: 360, counterClockwise: false, }); describe('Circle', () => { it('constructor', () => { const circle = new Circle(); expect(circle, 'should inherit from fabric.Circle').toBeInstanceOf(Circle); expect(circle, 'should inherit from fabric.Object').toBeInstanceOf( FabricObject, ); // @ts-expect-error -- it is a constructor not an ordinary function expect(circle.constructor.type).toBe('Circle'); }); it('constructor with radius', () => { const circle = new Circle({ radius: 20 }); expect(circle.width, 'width is set').toBe(40); expect(circle.height, 'height is set').toBe(40); }); it('getRadiusX, getRadiusY', () => { const circle = new Circle({ radius: 10 }); expect(circle.getRadiusX, 'getRadiusX should exist').toBeTypeOf('function'); expect(circle.getRadiusY, 'getRadiusY should exist').toBeTypeOf('function'); expect(circle.getRadiusX()).toBe(10); expect(circle.getRadiusY()).toBe(10); circle.scale(2); expect(circle.getRadiusX()).toBe(20); expect(circle.getRadiusY()).toBe(20); circle.set('scaleX', 3); expect(circle.getRadiusX()).toBe(30); expect(circle.getRadiusY()).toBe(20); circle.set('scaleY', 4); expect(circle.getRadiusX()).toBe(30); expect(circle.getRadiusY()).toBe(40); }); it('setRadius', () => { const circle = new Circle({ radius: 10, strokeWidth: 0 }); expect(circle.setRadius).toBeTypeOf('function'); expect(circle.getRadiusX()).toBe(10); expect(circle.getRadiusY()).toBe(10); expect(circle.width).toBe(20); expect(circle.height).toBe(20); circle.setRadius(20); expect(circle.getRadiusX()).toBe(20); expect(circle.getRadiusY()).toBe(20); expect(circle.width).toBe(40); expect(circle.height).toBe(40); }); it('set radius', () => { const circle = new Circle({ strokeWidth: 0 }); circle.set('radius', 20); expect(circle.getRadiusX()).toBe(20); expect(circle.getRadiusY()).toBe(20); expect(circle.width).toBe(40); expect(circle.height).toBe(40); }); it('complexity', () => { const circle = new Circle(); expect(circle.complexity).toBeTypeOf('function'); expect(circle.complexity()).toBe(1); }); it('toObject', () => { const circle = new Circle(); expect(circle.toObject).toBeTypeOf('function'); expect(circle.toObject()).toStrictEqual(REFERENCE_CIRCLE); circle.set('left', 100); circle.set('top', 200); circle.set('radius', 15); expect(circle.toObject()).toStrictEqual({ ...REFERENCE_CIRCLE, left: 100, top: 200, width: 30, height: 30, radius: 15, }); }); it('toObject without defaults', () => { const circle = new Circle({ includeDefaultValues: false, }); expect(circle.toObject()).toStrictEqual({ type: 'Circle', version: version, left: 0, top: 0, }); }); it('toSVG with full circle', () => { const circle = new Circle({ width: 100, height: 100, radius: 10, left: 10.5, top: 10.5, }); const svg = circle.toSVG(); const svgClipPath = circle.toClipPathSVG(); expect(svg).toBe( '<g transform="matrix(1 0 0 1 10.5 10.5)" >\n<circle style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" cx="0" cy="0" r="10" />\n</g>\n', ); expect(svgClipPath, 'circle as clipPath').toBe( '\t<circle transform="matrix(1 0 0 1 10.5 10.5)" cx="0" cy="0" r="10" />\n', ); }); it('toSVG with half circle', () => { const circle = new Circle({ width: 100, height: 100, radius: 10, left: 10.5, top: 10.5, endAngle: 180, }); const svg = circle.toSVG(); const svgClipPath = circle.toClipPathSVG(); expect(svg).toBe( '<g transform="matrix(1 0 0 1 10.5 10.5)" >\n<path d="M 10 0 A 10 10 0 0 1 -10 0" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" />\n</g>\n', ); expect(svgClipPath, 'half circle as clipPath').toBe( '\t<path d="M 10 0 A 10 10 0 0 1 -10 0" transform="matrix(1 0 0 1 10.5 10.5)" />\n', ); }); it('toSVG with counterclockwise half circle', () => { const circle = new Circle({ width: 100, height: 100, radius: 10, left: 10.5, top: 10.5, endAngle: 180, counterClockwise: true, }); const svg = circle.toSVG(); const svgClipPath = circle.toClipPathSVG(); expect(svg).toBe( '<g transform="matrix(1 0 0 1 10.5 10.5)" >\n<path d="M 10 0 A 10 10 0 0 0 -10 0" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" />\n</g>\n', ); expect(svgClipPath, 'half circle as clipPath').toBe( '\t<path d="M 10 0 A 10 10 0 0 0 -10 0" transform="matrix(1 0 0 1 10.5 10.5)" />\n', ); }); it('fromElement', async () => { expect(Circle.fromElement).toBeTypeOf('function'); const elCircle = createSVGElement('circle', { r: 10, cx: 12, cy: 15, fill: 'ff5555', opacity: 0.5, 'stroke-width': 2, 'stroke-dasharray': '5, 2', 'stroke-linecap': 'round', 'stroke-linejoin': 'bevel', 'stroke-miterlimit': 5, }); // @ts-expect-error -- svg circle element is not an HTMLElement const oCircle = await Circle.fromElement(elCircle, {}); expect(oCircle).toBeInstanceOf(Circle); expect(oCircle.get('radius')).toBe(10); expect(oCircle.get('left')).toBe(2); expect(oCircle.get('top')).toBe(5); expect(oCircle.get('fill')).toBe('ff5555'); expect(oCircle.get('opacity')).toBe(0.5); expect(oCircle.get('strokeWidth')).toBe(2); expect(oCircle.get('strokeDashArray')).toStrictEqual([5, 2]); expect(oCircle.get('strokeLineCap')).toBe('round'); expect(oCircle.get('strokeLineJoin')).toBe('bevel'); expect(oCircle.get('strokeMiterLimit')).toBe(5); { const elFaultyCircle = createSVGElement('circle', { r: -10 }); // @ts-expect-error -- svg circle element is not an HTMLElement const circle = await Circle.fromElement(elFaultyCircle, {}); expect(circle.radius, 'radius will default to -10').toBe(-10); } { const elFaultyCircle = createSVGElement('circle'); // @ts-expect-error -- svg circle element is not an HTMLElement const circle = await Circle.fromElement(elFaultyCircle, {}); expect(circle.radius, 'radius will default to 0').toBe(0); } }); it('fromObject', async () => { expect(Circle.fromObject).toBeTypeOf('function'); const left = 112, top = 234, radius = 13.45, fill = 'ff5555'; const circle = await Circle.fromObject({ left: left, top: top, radius: radius, fill: fill, }); expect(circle).toBeInstanceOf(Circle); expect(circle.get('left')).toBe(left); expect(circle.get('top')).toBe(top); expect(circle.get('radius')).toBe(radius); expect(circle.get('fill')).toBe(fill); const expected = circle.toObject(); const actual = await Circle.fromObject(expected); expect(actual.toObject()).toStrictEqual(expected); }); it('cloning and radius, width, height', async () => { const circle = new Circle({ radius: 10, strokeWidth: 0 }); circle.scale(2); const clone = await circle.clone(); expect(clone.width).toBe(20); expect(clone.getScaledWidth()).toBe(40); expect(clone.height).toBe(20); expect(clone.getScaledHeight()).toBe(40); expect(clone.radius).toBe(10); }); });