From 15b588db282bb457d77f0aabdc5ff6bcfce3a1eb Mon Sep 17 00:00:00 2001 From: Oliver Klemencic Date: Thu, 27 Dec 2012 14:02:56 +0100 Subject: [PATCH] Added fabric.js type definitions --- fabricjs/fabricjs.d.ts | 825 ++++++++++++++++++++++++++++++++++++++ fabricjs/tests/sample1.ts | 33 ++ fabricjs/tests/sample2.ts | 53 +++ fabricjs/tests/sample3.ts | 122 ++++++ fabricjs/tests/sample4.ts | 51 +++ fabricjs/tests/sample5.ts | 66 +++ fabricjs/tests/sample6.ts | 26 ++ fabricjs/tests/sample7.ts | 37 ++ fabricjs/tests/sample8.ts | 667 ++++++++++++++++++++++++++++++ 9 files changed, 1880 insertions(+) create mode 100644 fabricjs/fabricjs.d.ts create mode 100644 fabricjs/tests/sample1.ts create mode 100644 fabricjs/tests/sample2.ts create mode 100644 fabricjs/tests/sample3.ts create mode 100644 fabricjs/tests/sample4.ts create mode 100644 fabricjs/tests/sample5.ts create mode 100644 fabricjs/tests/sample6.ts create mode 100644 fabricjs/tests/sample7.ts create mode 100644 fabricjs/tests/sample8.ts diff --git a/fabricjs/fabricjs.d.ts b/fabricjs/fabricjs.d.ts new file mode 100644 index 0000000000..30b9606c1e --- /dev/null +++ b/fabricjs/fabricjs.d.ts @@ -0,0 +1,825 @@ +// Type definitions for FabricJS +// Project: http://fabricjs.com/ +// Definitions by: Oliver Klemencic + +/* +USAGE +/// +*/ + +declare module fabric { + + function createCanvasForNode(width: number, height: number): ICanvas; + function getCSSRules(doc: SVGDocument); + function getGradientDefs(doc: SVGDocument); + function loadSVGFromString(text: string, callback: (results: IObject[], options) => void , reviver?: (el, obj) => void ); + function loadSVGFromURL(url, callback: (results: IObject[], options) => void , reviver?: (el, obj) => void ); + function log(values); + function parseAttributes(element, attributes: any[]): any; + function parseElements(elements: any[], callback, options, reviver); + function parsePointsAttribute(points: string): any[]; + function parseStyleAttribute(element: SVGElement); + function parseSVGDocument(doc: SVGDocument, callback: (results, options) => void , reviver?: (el, obj) => void ); + function parseTransformAttribute(attributeValue: string); + function warn(values); + + var isLikelyNode: bool; + var isTouchSupported: bool; + + export interface IObservable { + observe(eventCollection: IEventList); + on(eventCollection: IEventList); + + observe(eventName: string, handler: (e) => any); + on(eventName: string, handler: (e) => any); + + fire(eventName: string, options); + stopObserving(eventName: string, handler: (e) => any); + + off(eventName, handler); + } + + export interface IFilter { + new (): IFilter; + new (options: any): IFilter; + } + + export interface IEventList { + [index: string]: (e: Event) => void; + } + + export interface IObjectOptions { + angle?: number; + borderColor?: string; + borderOpacityWhenMoving?: number; + borderScaleFactor?: number; + cornerColor?: string; + cornersize?: number; + fill?: string; + fillRule?: string; + flipX?: bool; + flipY?: bool; + hasBorders?: bool; + hasControls?: bool; + hasRotatingPoint?: bool; + height?: number; + includeDefaultValues?: bool; + left?: number; + lockMovementX?: bool; + lockMovementY?: bool; + lockScalingX?: bool; + lockScalingY?: bool; + lockUniScaling?: bool; + lockRotation?: bool; + opacity?: number; + overlayFill?: string; + padding?: number; + perPixelTargetFind?: bool; + rotatingPointOffset?: number; + scaleX?: number; + scaleY?: number; + selectable?: bool; + stateProperties?: any[]; + stroke?: string; + strokeDashArray?: any[]; + strokeWidth?: number; + top?: number; + transformMatrix?: any[]; + transparentCorners?: bool; + type?: string; + width?: number; + } + + export interface ITextOptions extends IObjectOptions { + fontSize?: number; + fontWeight?: any; + fontFamily?: string; + textDecoration?: string; + textShadow?: string; + textAlign?: string; + fontStyle?: string; + lineHeight?: number; + strokeStyle?: string; + strokeWidth?: number; + backgroundColor?: string; + textBackgroundColor?: string; + path?: string; + type?: string; + useNative?: Boolean; + } + + export interface ICircleOptions extends IObjectOptions { + radius?: number; + } + + export interface IPoint { + add(that: IPoint): IPoint; + addEquals(that: IPoint): IPoint; + distanceFrom(that: IPoint); + divide(scalar: number); + divideEquals(scalar: number); + eq(that: IPoint); + gt(that: IPoint); + gte(that: IPoint); + init(x, y); + lerp(that: IPoint, t); + lt(that: IPoint); + lte(that: IPoint); + max(that: IPoint); + min(that: IPoint); + multiply(scalar); + multiplyEquals(scalar); + scalarAdd(scalar): IPoint; + scalarAddEquals(scalar: number, thisArg: IPoint); + scalarSubtract(scalar: number); + scalarSubtractEquals(scalar); + setFromPoint(that: IPoint); + setXY(x, y); + subtract(that: IPoint): IPoint; + subtractEquals(that: IPoint): IPoint; + swap(that: IPoint); + tostring(): string; + } + + export interface IRect extends IObject { + x: number; + y: number; + rx: number; + ry: number; + + complexity(): number; + initialize(points: number[], options: any): IRect; + toObject(propertiesToInclude: any[]): any; + toSVG(): string; + } + + export interface IText extends IObject { + fontSize: number; + fontWeight: any; + fontFamily: string; + text: string; + textDecoration: string; + textShadow?: string; + textAlign: string; + fontStyle: string; + lineHeight: number; + strokeStyle: string; + strokeWidth: number; + backgroundColor: string; + textBackgroundColor: string; + path?: string; + type: string; + useNative: Boolean; + + initialize(text: string, options: any): IText; + toString(): string; + render(ctx: CanvasRenderingContext2D, noTransform: bool); + toObject(propertiesToInclude: any[]): IObject; + toSVG(): string; + setColor(value: string): IText; + setFontsize(value: number): IText; + getText(): string; + setText(value: string): IText; + } + + export interface ITriangle extends IObject { + complexity(): number; + initialize(options: any): ITriangle; + toSVG(): string; + } + + export interface IEllipse { + initialize(options: any): any; + toObject(propertiesToInclude: any[]): any; + toSVG(): string; + render(ctx: CanvasRenderingContext2D, noTransform: bool); + complexity(): number; + } + + export interface IGradient { + initialize(options): any; + toObject(): any; + toLiveGradient(ctx: CanvasRenderingContext2D): any; + } + + export interface IColor { + getSource(): any[]; + setSource(source: any[]): any; + toRgb(): string; + toRgba(): string; + toHex(): string; + getAlpha(): number; + setAlpha(alpha: number): IColor; + toGrayscale(): IColor; + toBlackWhite(threshold): IColor; + overlayWith(otherColor: string): IColor; + overlayWith(otherColor: IColor): IColor; + } + + export interface IElement { + } + + export interface IObject extends IObservable { + + // constraint properties + lockMovementX: bool; + lockMovementY: bool; + lockScalingX: bool; + lockScalingY: bool; + lockScaling: bool; + lockUniScaling: bool; + lockRotation: bool; + + getCurrentWidth(): number; + getCurrentHeight(): number; + + angle: number; + getAngle(): number; + setAngle(value: number): IObject; + + borderColor: string; + getBorderColor(): string; + setBorderColor(value: string): IObject; + + borderOpacityWhenMoving: number; + borderScaleFactor: number; + getBorderScaleFactor(): number; + + cornerColor: string; + + cornersize: number; + getCornersize(): number; + setCornersize(value: number): IObject; + + fill: string; + getFill(): string; + setFill(value: string): IObject; + + fillRule: string; + getFillRule(): string; + setFillRule(value: string): IObject; + + flipX: bool; + getFlipX(): bool; + setFlipX(value: bool): IObject; + + flipY: bool; + getFlipY(): bool; + setFlipY(value: bool): IObject; + + hasBorders: bool; + + hasControls: bool; + hasRotatingPoint: bool; + + height: number; + getHeight(): number; + setHeight(value: number): IObject; + + includeDefaultValues: bool; + + left: number; + getLeft(): number; + setLeft(value: number): IObject; + + opacity: number; + getOpacity(): number; + setOpacity(value: number): IObject; + + overlayFill: string; + getOverlayFill(): string; + setOverlayFill(value: string): IObject; + + padding: number; + perPixelTargetFind: bool; + rotatingPointOffset: number; + + scaleX: number; + getScaleX(): number; + setScaleX(value: number): IObject; + + scaleY: number; + getScaleY(): number; + setScaleY(value: number): IObject; + + selectable: bool; + stateProperties: any[]; + stroke: string; + strokeDashArray: any[]; + strokeWidth: number; + + top: number; + getTop(): number; + setTop(value: number): IObject; + + transformMatrix: any[]; + transparentCorners: bool; + type: string; + + width: number; + getWidth(): number; + setWidth(value: number): IObject; + + // methods + bringForward(): IObject; + bringToFront(): IObject; + center(): IObject; + centerH(): IObject; + centerV(): IObject; + clone(callback?, propertiesToInclude?): IObject; + cloneAsImage(callback): IObject; + complexity(): number; + drawBorders(context: CanvasRenderingContext2D): IObject; + drawCorners(context: CanvasRenderingContext2D): IObject; + get (property: string): any; + getBoundingRectHeight(): number; + getBoundingRectWidth(): number; + getSvgStyles(): string; + getSvgTransform(): string; + hasStateChanged(): bool; + initialize(options: any); + intersectsWithObject(other: IObject): bool; + intersectsWithRect(selectionTL: any, selectionBR: any): bool; + isActive(): bool; + isContainedWithinObject(other: IObject): bool; + isContainedWithinRect(selectionTL: any, selectionBR: any): bool; + isType(type: string): bool; + remove(): IObject; + render(ctx: CanvasRenderingContext2D, noTransform: bool); + rotate(value: number): IObject; + saveState(): IObject; + scale(value: number): IObject; + scaleToHeight(value: number): IObject; + scaleToWidth(value: number): IObject; + sendBackwards(): IObject; + sendToBack(): IObject; + + set (properties: IObjectOptions): IObject; + set (name: string, value: any): IObject; + setActive(active: bool): IObject; + setCoords(); + setGradientFill(options); + setOptions(options: any); + setSourcePath(value: string): IObject; + toDatalessObject(propertiesToInclude): any; + toDataURL(callback): string; + toggle(property): IObject; + toGrayscale(): IObject; + toJSON(propertiesToInclude): string; + toObject(propertiesToInclude): any; + tostring(): string; + transform(ctx: CanvasRenderingContext2D); + } + + export interface IGroup { + type: string; + + activateAllObjects(): IGroup; + add(object): IGroup; + addWithUpdate(object): IGroup; + complexity(): number; + contains(object): bool; + containsPoint(point): bool; + destroy(): IGroup; + getObjects(): IObject[]; + hasMoved(): bool; + initialize(objects, options): any; + item(index): IObject; + remove(object): IGroup; + removeWithUpdate(object): IGroup; + render(ctx, noTransform): void; + saveCoords(): IGroup; + setObjectsCoords(): IGroup; + size(): number; + toGrayscale(): void; + toObject(propertiesToInclude: any[]): any; + tostring(): string; + toSVG(): string; + } + + + export interface ILine extends IObject { + x1: number; + x2: number; + y1: number; + y2: number; + + complexity(): number; + initialize(points: number[], options: any): ILine; + toObject(propertiesToInclude: any[]): any; + toSVG(): string; + } + + export interface IIntersection { + appendPoint(status: string); + appendPoints(status: string); + init(status: string); + } + + export interface IImage extends IObject { + filters: any; + + applyFilters(callback); + clone(propertiesToInclude, callback); + complexity(): number; + getElement(): HTMLImageElement; + getOriginalSize(): { width: number; height: number; }; + getSrc(): string; + initialize(element: string, options: any); + initialize(element: HTMLImageElement, options: any); + render(ctx: CanvasRenderingContext2D, noTransform: bool); + setElement(element): IImage; + toObject(propertiesToInclude): any; + tostring(): string; + toSVG(): string; + } + + export interface ICircle extends IObject { + // methods + complexity(): number; + getRadiusX(): number; + getRadiusY(): number; + initialize(options: ICircleOptions): ICircle; + setRadius(value: number): number; + toObject(propertiesToInclude): any; + toSVG(): string; + } + + + + export interface IPath extends IObject { + complexity(): number; + initialize(path, options); + render(ctx: CanvasRenderingContext2D, noTransform: bool); + toDatalessObject(propertiesToInclude): any; + toObject(propertiesToInclude): any; + tostring(): string; + toSVG(): string; + } + + export interface IPolygon extends IObject { + complexity(): number; + initialize(points, options); + toObject(propertiesToInclude): any; + toSVG(): string; + } + + export interface IPolyline extends IObject { + complexity(): number; + initialize(points, options); + toObject(propertiesToInclude): any; + toSVG(): string; + } + + export interface IPathGroup extends IObject { + complexity(): number; + initialize(paths, options); + isSameColor(): bool; + render(ctx: CanvasRenderingContext2D); + toDatalessObject(propertiesToInclude): any; + toGrayscale(); + toObject(propertiesToInclude): any; + tostring(): string; + toSVG(): string; + } + + export interface IStaticCanvas extends IObservable { + + // fields + backgroundColor: string; + backgroundImage: string; + backgroundImageOpacity: number; + backgroundImageStretch: number; + clipTo(clipFunction: (context: CanvasRenderingContext2D) => void ); + controlsAboveOverlay: bool; + includeDefaultValues: bool; + overlayImage: string; + overlayImageLeft: number; + overlayImageTop: number; + renderOnAddition: bool; + stateful: bool; + + // static + EMPTY_JSON: string; + supports(methodName: string): bool; + + // methods + add(...object: IObject[]): ICanvas; + bringForward(object: IObject): ICanvas; + calcOffset(): ICanvas; + centerObject(object: IObject): ICanvas; + centerObjectH(object: IObject): ICanvas; + centerObjectV(object: IObject): ICanvas; + clear(): ICanvas; + clearContext(context: CanvasRenderingContext2D): ICanvas; + complexity(): number; + dispose(): ICanvas; + drawControls(); + forEachObject(callback: (object: IObject) => void , context?: CanvasRenderingContext2D): ICanvas; + getActiveGroup(): IGroup; + getActiveObject(): IObject; + getCenter(): IObject; + getContext(): CanvasRenderingContext2D; + getElement(): HTMLCanvasElement; + getHeight(): number; + getWidth(): number; + insertAt(object: IObject, index: number, nonSplicing: bool): ICanvas; + isEmpty(): bool; + item(index: number): IObject; + onBeforeScaleRotate(target: IObject); + remove(object: IObject): IObject; + renderAll(allOnTop?: bool): ICanvas; + renderTop(): ICanvas; + + sendBackwards(object: IObject): ICanvas; + sendToBack(object: IObject): ICanvas; + setBackgroundImage(object: IObject): ICanvas; + setDimensions(object: { width: number; height: number; }): ICanvas; + setHeight(height: number): ICanvas; + setOverlayImage(url: string, callback: () => any, options): ICanvas; + setWidth(width: number): ICanvas; + toDatalessJSON(propertiesToInclude: any[]): string; + toDatalessObject(propertiesToInclude: any[]): string; + toDataURL(format: string, quality?: number): string; + toDataURLWithMultiplier(propertiesToInclude: any[]): string; + toGrayscale(propertiesToInclude: any[]): string; + toJSON(propertiesToInclude: any[]): string; + toObject(propertiesToInclude: any[]): string; + tostring(): string; + toSVG(): string; + } + + export interface ICanvas extends IStaticCanvas { + + // constructors + (element: HTMLCanvasElement): ICanvas; + (element: string): ICanvas; + + // fields + containerClass: string; + defaultCursor: string; + freeDrawingColor: string; + freeDrawingLineWidth: number; + hoverCursor: string; + interactive: bool; + moveCursor: string; + perPixelTargetFind: bool; + rotationCursor: string; + selection: bool; + selectionBorderColor: string; + selectionColor: string; + selectionDashArray: number[]; + selectionLineWidth: number; + targetFindTolerance: number; + + // methods + containsPoint(e: Event, target: IObject): bool; + deactivateAll(): ICanvas; + deactivateAllWithDispatch(): ICanvas; + discardActiveGroup(): ICanvas; + discardActiveObject(): ICanvas; + drawDashedLine(ctx: CanvasRenderingContext2D, x: number, y: number, x2: number, y2: number, dashArray: number[]): ICanvas; + findTarget(e: MouseEvent, skipGroup: bool): ICanvas; + getActiveGroup(): IGroup; + getActiveObject(): IObject; + getPointer(e): { x: number; y: number; }; + getSelectionContext(): CanvasRenderingContext2D; + getSelectionElement(): HTMLCanvasElement; + setActiveGroup(group: IGroup): ICanvas; + setActiveObject(object: IObject, e?): ICanvas; + } + + export interface IBrightnessFilter { + } + export interface IInvertFilter { + } + export interface IRemoveWhiteFilter { + } + export interface IGrayscaleFilter { + } + export interface ISepiaFilter { + } + export interface ISepia2Filter { + } + export interface INoiseFilter { + } + export interface IGradientTransparencyFilter { + } + export interface IPixelateFilter { + } + export interface IConvoluteFilter { + } + + export interface ICanvasOptions { + containerClass?: string; + defaultCursor?: string; + freeDrawingColor?: string; + freeDrawingLineWidth?: number; + hoverCursor?: string; + interactive?: bool; + moveCursor?: string; + perPixelTargetFind?: bool; + rotationCursor?: string; + selection?: bool; + selectionBorderColor?: string; + selectionColor?: string; + selectionDashArray?: number[]; + selectionLineWidth?: number; + targetFindTolerance?: number; + + backgroundColor?: string; + backgroundImage?: string; + backgroundImageOpacity?: number; + backgroundImageStretch?: number; + controlsAboveOverlay?: bool; + includeDefaultValues?: bool; + overlayImage?: string; + overlayImageLeft?: number; + overlayImageTop?: number; + renderOnAddition?: bool; + stateful?: bool; + } + + export interface IRectOptions extends IObjectOptions { + x?: number; + y?: number; + rx?: number; + ry?: number; + } + + export interface ITriangleOptions extends IObjectOptions { + } + + declare var Rect: { + fromElement(element: SVGElement, options: IRectOptions): IRect; + fromObject(object): IRect; + new (options?: IRectOptions): IRect; + prototype: any; + } + + declare var Triangle: { + new (options?: ITriangleOptions): ITriangle; + } + + declare var Canvas: { + new (element: HTMLCanvasElement, options?: ICanvasOptions): ICanvas; + new (element: string, options?: ICanvasOptions): ICanvas; + + EMPTY_JSON: string; + supports(methodName: string): bool; + prototype: any; + } + + declare var Circle: { + ATTRIBUTE_NAMES: string[]; + fromElement(element: SVGElement, options: ICircleOptions): ICircle; + fromObject(object): ICircle; + new (options?: ICircleOptions): ICircle; + prototype: any; + } + + declare var Line: { + ATTRIBUTE_NAMES: string[]; + fromElement(element: SVGElement, options): ILine; + fromObject(object): ILine; + prototype: any; + new (points: number[], objObjects?: IObjectOptions): ILine; + } + + declare var Intersection: { + intersectLineLine(a1, a2, b1, b2); + intersectLinePolygon(a1, a2, points); + intersectPolygonPolygon(points1, points2); + intersectPolygonRectangle(points, r1, r2); + } + + declare var Path: { + fromElement(element: SVGElement, options): IPath; + fromObject(object): IPath; + new (): IPath; + } + + declare var PathGroup: { + fromObject(object): IPathGroup; + new (): IPathGroup; + prototype: any; + } + + declare var Point: { + new (x, y): IPoint; + prototype: any; + } + + declare var Object: { + prototype: any; + } + + declare var Polygon: { + fromObject(object): IPolygon; + fromElement(element: SVGElement, options): IPolygon; + new (): IPolygon; + prototype: any; + } + + declare var Polyline: { + fromObject(object): IPolyline; + fromElement(element: SVGElement, options): IPolyline; + new (): IPolyline; + prototype: any; + } + + declare var Text: { + new (text: string, options?: ITextOptions): IText; + } + + declare var Image: { + fromURL(url: string): IImage; + fromURL(url: string, callback: (image: IImage) => any): IImage; + fromURL(url: string, callback: (image: IImage) => any, objObjects: IObjectOptions): IImage; + prototype: any; + + filters: + { + Grayscale: { + new (): IGrayscaleFilter; + }; + Brightness: { + new (options?: { brightness: number; }): IBrightnessFilter; + }; + RemoveWhite: { + new (options?: { + threshold?: string; // TODO: Check this + distance?: string; // TODO: Check this + }): IRemoveWhiteFilter; + }; + Invert: { + new (): IInvertFilter; + }; + Sepia: { + new (): ISepiaFilter; + }; + Sepia2: { + new (): ISepia2Filter; + }; + Noise: { + new (options?: { + noise?: number; + }): INoiseFilter; + }; + GradientTransparency: { + new (options?: { + threshold?: number; + }): IGradientTransparencyFilter; + }; + Pixelate: { + new (options?: { + color?: any; + }): IPixelateFilter; + }; + Convolute: { + new (options?: { + matrix: any; + }): IConvoluteFilter; + }; + }; + + } + + declare var util: { + addClass(element: HTMLElement, className: string); + addListener(element, eventName: string, handler); + animate(options: { + onChange?: (value: number) => void; + onComplete?: () => void; + startValue?: number; + endValue?: number; + byValue?: number; + easing?: (currentTime, startValue, byValue, duration) => number; + duration?: number; + }); + createClass(parent, properties); + degreesToRadians(degrees: number): number; + falseFunction(): () => bool; + getById(id: HTMLElement): HTMLElement; + getById(id: string): HTMLElement; + getElementOffset(element): { left: number; top: number; }; + getPointer(event: Event); + getRandomInt(min: number, max: number); + getScript(url: string, callback); + groupSVGElements(elements: any[], options, path?: string); + loadImage(url, callback, context); + makeElement(tagName: string, attributes); + makeElementSelectable(element: HTMLElement); + makeElementUnselectable(element: HTMLElement); + populateWithProperties(source, destination, properties): any[]; + radiansToDegrees(radians: number): number; + removeFromArray(array: any[], value); + removeListener(element: HTMLElement, eventName, handler); + request(url, options); + requestAnimFrame(callback, element); + setStyle(element: HTMLElement, styles); + toArray(arrayLike): any[]; + toFixed(number, fractionDigits); + wrapElement(element: HTMLElement, wrapper, attributes); + } +}; \ No newline at end of file diff --git a/fabricjs/tests/sample1.ts b/fabricjs/tests/sample1.ts new file mode 100644 index 0000000000..f494d84cec --- /dev/null +++ b/fabricjs/tests/sample1.ts @@ -0,0 +1,33 @@ +/// + +var canvas = new fabric.Canvas('c', { + hoverCursor: 'pointer', + selection: false, +}); + +canvas.on({ + 'object:moving': function(e) { + e.target.opacity = 0.5; + }, + 'object:modified': function(e) { + e.target.opacity = 1; + } +}); + +for (var i = 0, len = 15; i < len; i++) { + fabric.Image.fromURL('../assets/ladybug.png', function(img) { + img.set({ + left: fabric.util.getRandomInt(0, 600), + top: fabric.util.getRandomInt(0, 500), + angle: fabric.util.getRandomInt(0, 90) + }); + + img.perPixelTargetFind = true; + // img.targetFindTolerance = 4; + img.hasControls = img.hasBorders = false; + + img.scale(fabric.util.getRandomInt(50, 100) / 100); + + canvas.add(img); + }); +} \ No newline at end of file diff --git a/fabricjs/tests/sample2.ts b/fabricjs/tests/sample2.ts new file mode 100644 index 0000000000..a04f2d1b8c --- /dev/null +++ b/fabricjs/tests/sample2.ts @@ -0,0 +1,53 @@ +/// + +var dot, i, + t1, t2, + startTimer = function() { + t1 = new Date().getTime(); + return t1; + }, + stopTimer = function() { + t2 = new Date().getTime(); + return t2 - t1; + }, + getRandomInt = fabric.util.getRandomInt, + rainbow = ["#ffcc66", "#ccff66", "#66ccff", "#ff6fcf", "#ff6666"], + rainbowEnd = rainbow.length - 1; + +// +// Rendering canvas #1 +// +var canvas1 = new fabric.Canvas('c1', { backgroundColor: "#000" }), + results1 = document.getElementById('results-c1'); + +startTimer(); +for (i = 100; i >= 0; i--) { + dot = new fabric.Circle({ + left: getRandomInt(0, 400), + top: getRandomInt(0, 350), + radius: 3, + fill: rainbow[getRandomInt(0, rainbowEnd)] + }); + canvas1.add(dot); +} +results1.innerHTML = 'Regular rendering of 100 elements in ' + stopTimer() + 'ms'; + + +// +// Rendering canvas #2 +// +var canvas2 = new fabric.Canvas('c2', { backgroundColor: "#000", renderOnAddition: false }), + results2 = document.getElementById('results-c2'); + +startTimer(); +for (i = 1000; i >= 0; i--) { + dot = new fabric.Circle({ + left: getRandomInt(0, 400), + top: getRandomInt(0, 350), + radius: 3, + fill: rainbow[getRandomInt(0, rainbowEnd)] + }); + canvas2.add(dot); +} +canvas2.renderAll(); // Note, calling renderAll() is important in this case +results2.innerHTML = 'Rendering 1000 elements using canvas.renderOnAddition = false in ' + stopTimer() + 'ms'; \ No newline at end of file diff --git a/fabricjs/tests/sample3.ts b/fabricjs/tests/sample3.ts new file mode 100644 index 0000000000..5393f6c64e --- /dev/null +++ b/fabricjs/tests/sample3.ts @@ -0,0 +1,122 @@ +/// + +var $ = function(id){return document.getElementById(id)}; + +function applyFilter(index, filter) { + var obj = canvas.getActiveObject(); + obj.filters[index] = filter; + obj.applyFilters(canvas.renderAll.bind(canvas)); +} + +function applyFilterValue(index, prop, value) { + var obj = canvas.getActiveObject(); + if (obj.filters[index]) { + obj.filters[index][prop] = value; + obj.applyFilters(canvas.renderAll.bind(canvas)); + } +} + +var canvas = new fabric.Canvas('c', { backgroundImage: '../lib/bg.png' }), + f = fabric.Image.filters; + +canvas.on({ + 'object:selected': function() { + fabric.util.toArray(document.getElementsByTagName('input')).forEach(function(el){ el.disabled = false; }) + + var filters = ['grayscale', 'invert', 'remove-white', 'sepia', 'sepia2', 'brightness', + 'noise', 'gradient-transparency', 'pixelate', 'blur', 'sharpen']; + + for (var i = 0; i < filters.length; i++) { + var checkBox = $(filters[i]); + var image = canvas.getActiveObject(); + checkBox.checked = !!image.filters[i]; + } + }, + 'selection:cleared': function() { + fabric.util.toArray(document.getElementsByTagName('input')).forEach(function(el){ el.disabled = true; }) + } +}); + +fabric.Image.fromURL('../assets/printio.png', function(img) { + var oImg = img.set({ left: 300, top: 300, angle: -15 }).scale(0.9); + canvas.add(oImg).renderAll(); + canvas.setActiveObject(oImg); +}); + +$('grayscale').onclick = function() { + applyFilter(0, this.checked && new f.Grayscale()); +}; +$('invert').onclick = function() { + applyFilter(1, this.checked && new f.Invert()); +}; +$('remove-white').onclick = function () { + applyFilter(2, this.checked && new f.RemoveWhite({ + threshold: ($('remove-white-threshold')).value, + distance: ($('remove-white-distance')).value + })); +}; +$('remove-white-threshold').onchange = function() { + applyFilterValue(2, 'threshold', this.value); +}; +$('remove-white-distance').onchange = function() { + applyFilterValue(2, 'distance', this.value); +}; +$('sepia').onclick = function() { + applyFilter(3, this.checked && new f.Sepia()); +}; +$('sepia2').onclick = function() { + applyFilter(4, this.checked && new f.Sepia2()); +}; +$('brightness').onclick = function () { + applyFilter(5, this.checked && new f.Brightness({ + brightness: parseInt(($('brightness-value')).value, 10) + })); +}; +$('brightness-value').onchange = function() { + applyFilterValue(5, 'brightness', parseInt(this.value, 10)); +}; +$('noise').onclick = function () { + applyFilter(6, this.checked && new f.Noise({ + noise: parseInt(($('noise-value')).value, 10) + })); +}; +$('noise-value').onchange = function() { + applyFilterValue(6, 'noise', parseInt(this.value, 10)); +}; +$('gradient-transparency').onclick = function () { + applyFilter(7, this.checked && new f.GradientTransparency({ + threshold: parseInt(($('gradient-transparency-value')).value, 10) + })); +}; +$('gradient-transparency-value').onchange = function() { + applyFilterValue(7, 'threshold', parseInt(this.value, 10)); +}; +$('pixelate').onclick = function() { + applyFilter(8, this.checked && new f.Pixelate({ + blocksize: parseInt(($('pixelate-value')).value, 10) + })); +}; +$('pixelate-value').onchange = function() { + applyFilterValue(8, 'blocksize', parseInt(this.value, 10)); +}; +$('blur').onclick = function() { + applyFilter(9, this.checked && new f.Convolute({ + matrix: [ 1/9, 1/9, 1/9, + 1/9, 1/9, 1/9, + 1/9, 1/9, 1/9 ] + })); +}; +$('sharpen').onclick = function() { + applyFilter(10, this.checked && new f.Convolute({ + matrix: [ 0, -1, 0, + -1, 5, -1, + 0, -1, 0 ] + })); +}; +$('emboss').onclick = function() { + applyFilter(11, this.checked && new f.Convolute({ + matrix: [ 1, 1, 1, + 1, 0.7, -1, + -1, -1, -1 ] + })); +}; \ No newline at end of file diff --git a/fabricjs/tests/sample4.ts b/fabricjs/tests/sample4.ts new file mode 100644 index 0000000000..a1cfd0e4c2 --- /dev/null +++ b/fabricjs/tests/sample4.ts @@ -0,0 +1,51 @@ +/// + +var canvas = new fabric.Canvas('c'); +var $ = function (id) { return document.getElementById(id); }; + +var rect = new fabric.Rect({ + width: 100, + height: 100, + top: 150, + left: 150, + fill: 'rgba(255,0,0,0.5)' +}); + +canvas.add(rect); + +var angleControl = $('angle-control'); +angleControl.onchange = function() { + rect.setAngle(this.value).setCoords(); + canvas.renderAll(); +}; + +var scaleControl = $('scale-control'); +scaleControl.onchange = function() { + rect.scale(this.value).setCoords(); + canvas.renderAll(); +}; + +var topControl = $('top-control'); +topControl.onchange = function() { + rect.setTop(this.value).setCoords(); + canvas.renderAll(); +}; + +var leftControl = $('left-control'); +leftControl.onchange = function() { + rect.setLeft(this.value).setCoords(); + canvas.renderAll(); +}; + +function updateControls() { + + scaleControl.value = rect.getScaleX().toString(); + angleControl.value = rect.getAngle().toString(); + leftControl.value = rect.getLeft().toString(); + topControl.value = rect.getTop().toString(); +} +canvas.on({ + 'object:moving': updateControls, + 'object:scaling': updateControls, + 'object:resizing': updateControls +}); diff --git a/fabricjs/tests/sample5.ts b/fabricjs/tests/sample5.ts new file mode 100644 index 0000000000..399f32ad98 --- /dev/null +++ b/fabricjs/tests/sample5.ts @@ -0,0 +1,66 @@ +/// + +module fabric { + export interface CircleWithLineInfos extends ICircle { + line1?: ILine; + line2?: ILine; + line3?: ILine; + line4?: ILine; + } +} + +var makeCircle = function(left: number, top: number, line1?: fabric.ILine, line2?: fabric.ILine, line3?: fabric.ILine, line4?: fabric.ILine): fabric.ICircle { + var c = new fabric.Circle({ + left: left, + top: top, + strokeWidth: 5, + radius: 12, + fill: '#fff', + stroke: '#666' + }); + + c.line1 = line1; + c.line2 = line2; + c.line3 = line3; + c.line4 = line4; + c.hasControls = c.hasBorders = false; + return c; +} + +function makeLine(coords: number[]) { + return new fabric.Line(coords, { + fill: 'red', + strokeWidth: 5, + selectable: false + }); +} + +var canvas = new fabric.Canvas('c', { selection: false }); + +var line = makeLine([ 250, 125, 250, 175 ]), + line2 = makeLine([ 250, 175, 250, 250 ]), + line3 = makeLine([ 250, 250, 300, 350]), + line4 = makeLine([ 250, 250, 200, 350]), + line5 = makeLine([ 250, 175, 175, 225 ]), + line6 = makeLine([ 250, 175, 325, 225 ]); + +canvas.add(line, line2, line3, line4, line5, line6); + +canvas.add( + makeCircle(line.x1, line.y1, null, line), + makeCircle(line.x2, line.y2, line, line2, line5, line6), + makeCircle(line2.x2, line2.y2, line2, line3, line4), + makeCircle(line3.x2, line3.y2, line3), + makeCircle(line4.x2, line4.y2, line4), + makeCircle(line5.x2, line5.y2, line5), + makeCircle(line6.x2, line6.y2, line6) +); + +canvas.on('object:moving', function(e) { + var p = e.target; + p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top }); + p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top }); + p.line3 && p.line3.set({ 'x1': p.left, 'y1': p.top }); + p.line4 && p.line4.set({ 'x1': p.left, 'y1': p.top }); + canvas.renderAll(); +}); \ No newline at end of file diff --git a/fabricjs/tests/sample6.ts b/fabricjs/tests/sample6.ts new file mode 100644 index 0000000000..48123ce626 --- /dev/null +++ b/fabricjs/tests/sample6.ts @@ -0,0 +1,26 @@ +/// + +var canvas = new fabric.Canvas('c'); +fabric.loadSVGFromURL('../assets/135.svg', function (objects) { + var obj = objects[0].scale(0.25); + canvas.centerObject(obj); + canvas.add(obj); + + canvas.add(obj.clone().set({ left: 100, top: 100, angle: -15 })); + canvas.add(obj.clone().set({ left: 480, top: 100, angle: 15 })); + canvas.add(obj.clone().set({ left: 100, top: 400, angle: -15 })); + canvas.add(obj.clone().set({ left: 480, top: 400, angle: 15 })); + + canvas.on('mouse:move', function (options) { + var p = canvas.getPointer(options.e); + + canvas.forEachObject(function (obj) { + var distX = Math.abs(p.x - obj.left), + distY = Math.abs(p.y - obj.top), + dist = Math.round(Math.sqrt(Math.pow(distX, 2) + Math.pow(distY, 2))); + obj.setOpacity(1 / (dist / 20)); + }); + + }); + +}); \ No newline at end of file diff --git a/fabricjs/tests/sample7.ts b/fabricjs/tests/sample7.ts new file mode 100644 index 0000000000..2fe0c74bac --- /dev/null +++ b/fabricjs/tests/sample7.ts @@ -0,0 +1,37 @@ +/// + +module fabric { + export interface ImageWithInfo extends IImage { + movingLeft: bool; + } +} + +var canvas = new fabric.Canvas('c', { selection: false }); + +setInterval(function() { + fabric.Image.fromURL('../assets/ladybug.png', function(obj) { + var img = obj; + img.set('left', fabric.util.getRandomInt(200, 600)).set('top', -50); + img.movingLeft = !!Math.round(Math.random()); + canvas.add(img); + }); +}, 1000); + + +var animate = (function animate() { + canvas.forEachObject(function (obj) { + var img = obj; + img.left += (img.movingLeft ? -1 : 1); + img.top += 1; + if (img.left > 900 || img.top > 500) { + canvas.remove(img); + } + else { + img.setAngle(img.getAngle() + 2); + } + }); + canvas.renderAll(); + window.requestAnimationFrame(animate); +}); + +animate(); \ No newline at end of file diff --git a/fabricjs/tests/sample8.ts b/fabricjs/tests/sample8.ts new file mode 100644 index 0000000000..a8d8ef4812 --- /dev/null +++ b/fabricjs/tests/sample8.ts @@ -0,0 +1,667 @@ +/// + +module fabric { + export interface ImageWithInfo extends IImage { + movingLeft: bool; + } +} + +function pad(str: string, length: number): string { + while (str.length < length) { + str = '0' + str; + } + return str; +}; + +var getRandomInt = fabric.util.getRandomInt; + +function getRandomColor() { + return ( + pad(getRandomInt(0, 255).toString(16), 2) + + pad(getRandomInt(0, 255).toString(16), 2) + + pad(getRandomInt(0, 255).toString(16), 2) + ); +} + +function getRandomNum(min: number, max: number): number { + return Math.random() * (max - min) + min; + } + +if (/(iPhone|iPod|iPad)/i.test(navigator.userAgent)) { + fabric.Object.prototype.cornersize = 30; +} + +var canvas = new fabric.Canvas('canvas'); +// canvas.controlsAboveOverlay = true; + +function updateComplexity() { + setTimeout(function() { + var element = document.getElementById('complexity').childNodes[1]; + element.innerHTML = ' ' + canvas.complexity(); + }, 100); +} + +document.getElementById('commands').onclick = function (ev) { + var ev: any = ev || window.event; + + if (ev.preventDefault) { + ev.preventDefault() + } + else if (ev.returnValue) { + ev.returnValue = false; + } + + var element: any = ev.target || ev.srcElement; + if (element.nodeName.toLowerCase() === 'strong') { + element = element.parentNode; + } + + var className = element.className, + offset = 50, + left = fabric.util.getRandomInt(0 + offset, 700 - offset), + top = fabric.util.getRandomInt(0 + offset, 500 - offset), + angle = fabric.util.getRandomInt(-20, 40), + width = fabric.util.getRandomInt(30, 50), + opacity = (function(min, max){ return Math.random() * (max - min) + min; })(0.5, 1); + + + switch (className) { + case 'rect': + canvas.add(new fabric.Rect({ + left: left, + top: top, + fill: '#' + getRandomColor(), + width: 50, + height: 50, + opacity: 0.8 + })); + break; + + case 'circle': + canvas.add(new fabric.Circle({ + left: left, + top: top, + fill: '#' + getRandomColor(), + radius: 50, + opacity: 0.8 + })); + break; + + case 'triangle': + canvas.add(new fabric.Triangle({ + left: left, + top: top, + fill: '#' + getRandomColor(), + width: 50, + height: 50, + opacity: 0.8 + })); + break; + + case 'image1': + fabric.Image.fromURL('../assets/pug.jpg', function(image) { + image.set({ + left: left, + top: top, + angle: angle, + padding: 10, + cornersize: 10 + }); + image.scale(getRandomNum(0.1, 0.25)).setCoords(); + canvas.add(image); + }); + break; + + case 'image2': + fabric.Image.fromURL('../assets/logo.png', function(image) { + image.set({ + left: left, + top: top, + angle: angle, + padding: 10, + cornersize: 10 + }); + image.scale(getRandomNum(0.1, 1)).setCoords(); + canvas.add(image); + updateComplexity(); + }); + break; + + case 'shape': + var id = element.id, match; + if (match = /\d+$/.exec(id)) { + fabric.loadSVGFromURL('../assets/' + match[0] + '.svg', function(objects, options) { + var loadedObject = fabric.util.groupSVGElements(objects, options); + + loadedObject.set({ + left: left, + top: top, + angle: angle, + padding: 10, + cornersize: 10 + }); + loadedObject/*.scaleToWidth(300)*/.setCoords(); + + // loadedObject.hasRotatingPoint = true; + + canvas.add(loadedObject); + updateComplexity(); + canvas.calcOffset(); + }); + } + break; + + case 'clear': + if (confirm('Are you sure?')) { + canvas.clear(); + } + } + updateComplexity(); +}; + +document.getElementById('execute').onclick = function() { + var code = (document.getElementById('canvas-console')).value; + if (!(/^\s+$/).test(code)) { + eval(code); + } +}; + + +document.getElementById('rasterize').onclick = function() { + if (!fabric.Canvas.supports('toDataURL')) { + alert('This browser doesn\'t provide means to serialize canvas to an image'); + } + else { + window.open(canvas.toDataURL('png')); + } +}; + +var removeSelectedEl = document.getElementById('remove-selected'); + removeSelectedEl.onclick = function() { + var activeObject = canvas.getActiveObject(), + activeGroup = canvas.getActiveGroup(); + if (activeObject) { + canvas.remove(activeObject); + } + else if (activeGroup) { + var objectsInGroup = activeGroup.getObjects(); + canvas.discardActiveGroup(); + objectsInGroup.forEach(function(object) { + canvas.remove(object); + }); + } + }; + +var supportsInputOfType = function(type) { + return function() { + var el = document.createElement('input'); + try { + el.type = type; + } + catch(err) { } + return el.type === type; + }; + }; + + var supportsSlider = supportsInputOfType('range'), + supportsColorpicker = supportsInputOfType('color'); + + if (supportsSlider()) { + (function(){ + var controls = document.getElementById('controls'); + + var sliderLabel = document.createElement('label'); + sliderLabel.htmlFor = 'opacity'; + sliderLabel.innerHTML = 'Opacity: '; + + var slider = document.createElement('input'); + + try { slider.type = 'range'; } catch(err) { } + + slider.id = 'opacity'; + slider.value = "100"; + + controls.appendChild(sliderLabel); + controls.appendChild(slider); + + canvas.calcOffset(); + + slider.onchange = function() { + var activeObject = canvas.getActiveObject(), + activeGroup = canvas.getActiveGroup(); + + if (activeObject || activeGroup) { + (activeObject || activeGroup).setOpacity(parseInt(this.value, 10) / 100); + canvas.renderAll(); + } + }; + })(); + } + +if (supportsColorpicker()) { + (function(){ + var controls = document.getElementById('controls'); + + var label = document.createElement('label'); + label.htmlFor = 'color'; + label.innerHTML = 'Color: '; + label.style.marginLeft = '10px'; + + var colorpicker = document.createElement('input'); + colorpicker.type = 'color'; + colorpicker.id = 'color'; + colorpicker.style.width = '40px'; + + controls.appendChild(label); + controls.appendChild(colorpicker); + + canvas.calcOffset(); + + colorpicker.onchange = function() { + var activeObject = canvas.getActiveObject(), + activeGroup = canvas.getActiveGroup(); + + if (activeObject || activeGroup) { + (activeObject || activeGroup).setFill(this.value); + canvas.renderAll(); + } + }; + })(); + } + + var lockHorizontallyEl = document.getElementById('lock-horizontally'); + lockHorizontallyEl.onclick = function() { + var activeObject: any = canvas.getActiveObject(); + if (activeObject) { + activeObject.lockMovementX = !activeObject.lockMovementX; + lockHorizontallyEl.innerHTML = activeObject.lockMovementX + ? 'Unlock horizontal movement' + : 'Lock horizontal movement'; + } + }; + + var lockVerticallyEl = document.getElementById('lock-vertically'); + lockVerticallyEl.onclick = function() { + var activeObject: any = canvas.getActiveObject(); + if (activeObject) { + activeObject.lockMovementY = !activeObject.lockMovementY; + lockVerticallyEl.innerHTML = activeObject.lockMovementY + ? 'Unlock vertical movement' + : 'Lock vertical movement'; + } + }; + + var lockScalingXEl = document.getElementById('lock-scaling-x'); + lockScalingXEl.onclick = function() { + var activeObject: any = canvas.getActiveObject(); + if (activeObject) { + activeObject.lockScalingX = !activeObject.lockScalingX; + lockScalingXEl.innerHTML = activeObject.lockScalingX + ? 'Unlock horizontal scaling' + : 'Lock horizontal scaling'; + } + }; + + var lockScalingYEl = document.getElementById('lock-scaling-y'); + lockScalingYEl.onclick = function() { + var activeObject: any = canvas.getActiveObject(); + if (activeObject) { + activeObject.lockScalingY = !activeObject.lockScalingY; + lockScalingYEl.innerHTML = activeObject.lockScalingY + ? 'Unlock vertical scaling' + : 'Lock vertical scaling'; + } + }; + + var lockRotationEl = document.getElementById('lock-rotation'); + lockRotationEl.onclick = function() { + var activeObject: any = canvas.getActiveObject(); + if (activeObject) { + activeObject.lockRotation = !activeObject.lockRotation; + lockRotationEl.innerHTML = activeObject.lockRotation + ? 'Unlock rotation' + : 'Lock rotation'; + } + }; + + var gradientifyBtn = document.getElementById('gradientify'); + + var activeObjectButtons = [ + lockHorizontallyEl, + lockVerticallyEl, + lockScalingXEl, + lockScalingYEl, + lockRotationEl, + removeSelectedEl, + gradientifyBtn + ]; + + var opacityEl = document.getElementById('opacity'); + if (opacityEl) { + activeObjectButtons.push(opacityEl); + } + var colorEl = document.getElementById('color'); + if (colorEl) { + activeObjectButtons.push(colorEl); + } + + for (var i = activeObjectButtons.length; i--; ) { + activeObjectButtons[i].disabled = true; + } + + canvas.on('object:selected', onObjectSelected); + canvas.on('group:selected', onObjectSelected); + + function onObjectSelected(e) { + var selectedObject = e.target; + + for (var i = activeObjectButtons.length; i--; ) { + activeObjectButtons[i].disabled = false; + } + + lockHorizontallyEl.innerHTML = (selectedObject.lockMovementX ? 'Unlock horizontal movement' : 'Lock horizontal movement'); + lockVerticallyEl.innerHTML = (selectedObject.lockMovementY ? 'Unlock vertical movement' : 'Lock vertical movement'); + lockScalingXEl.innerHTML = (selectedObject.lockScalingX ? 'Unlock horizontal scaling' : 'Lock horizontal scaling'); + lockScalingYEl.innerHTML = (selectedObject.lockScalingY ? 'Unlock vertical scaling' : 'Lock vertical scaling'); + lockRotationEl.innerHTML = (selectedObject.lockRotation ? 'Unlock rotation' : 'Lock rotation'); + } + + canvas.on('selection:cleared', function(e) { + for (var i = activeObjectButtons.length; i--; ) { + activeObjectButtons[i].disabled = true; + } + }); + + var drawingModeEl = document.getElementById('drawing-mode'), + drawingOptionsEl = document.getElementById('drawing-mode-options'), + drawingColorEl = document.getElementById('drawing-color'), + drawingLineWidthEl = document.getElementById('drawing-line-width'); + + drawingModeEl.onclick = function() { + var canvasWithDrawingMode: any = canvas; + canvasWithDrawingMode.isDrawingMode = !canvasWithDrawingMode.isDrawingMode; + if (canvasWithDrawingMode.isDrawingMode) { + drawingModeEl.innerHTML = 'Cancel drawing mode'; + drawingModeEl.className = 'is-drawing'; + drawingOptionsEl.style.display = ''; + } + else { + drawingModeEl.innerHTML = 'Enter drawing mode'; + drawingModeEl.className = ''; + drawingOptionsEl.style.display = 'none'; + } + }; + + canvas.on('path:created', function() { + updateComplexity(); + }); + + drawingColorEl.onchange = function() { + canvas.freeDrawingColor = drawingColorEl.value; + }; + drawingLineWidthEl.onchange = function() { + canvas.freeDrawingLineWidth = parseInt(drawingLineWidthEl.value, 10) || 1; // disallow 0, NaN, etc. + }; + + canvas.freeDrawingColor = drawingColorEl.value; + canvas.freeDrawingLineWidth = parseInt(drawingLineWidthEl.value, 10) || 1; + + + var text = 'Lorem ipsum dolor sit amet,\nconsectetur adipisicing elit,\nsed do eiusmod tempor incididunt\nut labore et dolore magna aliqua.\n' + + 'Ut enim ad minim veniam,\nquis nostrud exercitation ullamco\nlaboris nisi ut aliquip ex ea commodo consequat.'; + + document.getElementById('add-text').onclick = function() { + var textSample = new fabric.Text(text.slice(0, getRandomInt(0, text.length)), { + left: getRandomInt(350, 400), + top: getRandomInt(350, 400), + fontFamily: 'helvetica', + angle: getRandomInt(-10, 10), + fill: '#' + getRandomColor(), + scaleX: 0.5, + scaleY: 0.5, + fontWeight: '' + }); + canvas.add(textSample); + updateComplexity(); + }; + + + document.onkeydown = function(e) { + var obj = canvas.getActiveObject() || canvas.getActiveGroup(); + if (obj && e.keyCode === 8) { + // this is horrible. need to fix, so that unified interface can be used + if (obj.type === 'group') { + // var groupObjects = obj.getObjects(); + // canvas.discardActiveGroup(); + // groupObjects.forEach(function(obj) { + // canvas.remove(obj); + // }); + } + else { + //canvas.remove(obj); + } + canvas.renderAll(); + // return false; + } + }; + + setTimeout(function() { + canvas.calcOffset(); + }, 100); + + if (document.location.search.indexOf('guidelines') > -1) { + initCenteringGuidelines(canvas); + initAligningGuidelines(canvas); + } + + gradientifyBtn.onclick = function() { + var obj = canvas.getActiveObject(); + if (obj) { + obj.setGradientFill({ + x2: (getRandomInt(0, 1) ? 0 : obj.width), + y2: (getRandomInt(0, 1) ? 0 : obj.height), + colorStops: { + 0: '#' + getRandomColor(), + 1: '#' + getRandomColor() + } + }); + canvas.renderAll(); + } + }; + + var textEl = document.getElementById('text'); + if (textEl) { + textEl.onfocus = function() { + var activeObject = canvas.getActiveObject(); + + if (activeObject && activeObject.type === 'text') { + this.value = (activeObject).text; + } + }; + textEl.onkeyup = function(e) { + var activeObject = canvas.getActiveObject(); + if (activeObject) { + if (!this.value) { + canvas.discardActiveObject(); + } + else { + (activeObject).text = this.value; + } + canvas.renderAll(); + } + }; + } + + var cmdUnderlineBtn = document.getElementById('text-cmd-underline'); + if (cmdUnderlineBtn) { + activeObjectButtons.push(cmdUnderlineBtn); + cmdUnderlineBtn.disabled = true; + cmdUnderlineBtn.onclick = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.textDecoration = (activeObject.textDecoration == 'underline' ? '' : 'underline'); + this.className = activeObject.textDecoration ? 'selected' : ''; + canvas.renderAll(); + } + }; + } + + var cmdLinethroughBtn = document.getElementById('text-cmd-linethrough'); + if (cmdLinethroughBtn) { + activeObjectButtons.push(cmdLinethroughBtn); + cmdLinethroughBtn.disabled = true; + cmdLinethroughBtn.onclick = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.textDecoration = (activeObject.textDecoration == 'line-through' ? '' : 'line-through'); + this.className = activeObject.textDecoration ? 'selected' : ''; + canvas.renderAll(); + } + }; + } + + var cmdOverlineBtn = document.getElementById('text-cmd-overline'); + if (cmdOverlineBtn) { + activeObjectButtons.push(cmdOverlineBtn); + cmdOverlineBtn.disabled = true; + cmdOverlineBtn.onclick = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.textDecoration = (activeObject.textDecoration == 'overline' ? '' : 'overline'); + this.className = activeObject.textDecoration ? 'selected' : ''; + canvas.renderAll(); + } + }; + } + + var cmdBoldBtn = document.getElementById('text-cmd-bold'); + if (cmdBoldBtn) { + activeObjectButtons.push(cmdBoldBtn); + cmdBoldBtn.disabled = true; + cmdBoldBtn.onclick = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.fontWeight = (activeObject.fontWeight == 'bold' ? '' : 'bold'); + this.className = activeObject.fontWeight ? 'selected' : ''; + canvas.renderAll(); + } + }; + } + + var cmdItalicBtn = document.getElementById('text-cmd-italic'); + if (cmdItalicBtn) { + activeObjectButtons.push(cmdItalicBtn); + cmdItalicBtn.disabled = true; + cmdItalicBtn.onclick = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.fontStyle = (activeObject.fontStyle == 'italic' ? '' : 'italic'); + this.className = activeObject.fontStyle ? 'selected' : ''; + canvas.renderAll(); + } + }; + } + + var cmdShadowBtn = document.getElementById('text-cmd-shadow'); + if (cmdShadowBtn) { + activeObjectButtons.push(cmdShadowBtn); + cmdShadowBtn.disabled = true; + cmdShadowBtn.onclick = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.textShadow = !activeObject.textShadow ? 'rgba(0,0,0,0.2) 2px 2px 10px' : ''; + this.className = activeObject.textShadow ? 'selected' : ''; + canvas.renderAll(); + } + }; + } + + var textAlignSwitch = document.getElementById('text-align'); + if (textAlignSwitch) { + activeObjectButtons.push(textAlignSwitch); + textAlignSwitch.disabled = true; + textAlignSwitch.onchange = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.textAlign = this.value.toLowerCase(); + canvas.renderAll(); + } + }; + } + + var fontFamilySwitch = document.getElementById('font-family'); + if (fontFamilySwitch) { + activeObjectButtons.push(fontFamilySwitch); + fontFamilySwitch.disabled = true; + fontFamilySwitch.onchange = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.fontFamily = this.value; + canvas.renderAll(); + } + }; + } + + var bgColorField = document.getElementById('text-bg-color'); + if (bgColorField) { + bgColorField.onchange = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.backgroundColor = this.value; + canvas.renderAll(); + } + }; + } + + var strokeColorField = document.getElementById('text-stroke-color'); + if (strokeColorField) { + strokeColorField.onchange = function() { + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.strokeStyle = this.value; + canvas.renderAll(); + } + }; + } + + if (supportsSlider) { + (function(){ + var container = document.getElementById('text-controls'); + var slider = document.createElement('input'); + var label = document.createElement('label'); + label.innerHTML = 'Line height: '; + try { slider.type = 'range'; } catch(err) { } + slider.min = "0"; + slider.max = "10"; + slider.step = "0.1"; + slider.value = "1.5"; + container.appendChild(label); + label.appendChild(slider); + slider.title = "Line height"; + slider.onchange = function(){ + var activeObject = canvas.getActiveObject(); + if (activeObject && activeObject.type === 'text') { + activeObject.lineHeight = this.value; + canvas.renderAll(); + } + }; + + canvas.on('object:selected', function(e) { + slider.value = e.target.lineHeight; + }); + })(); + } + + document.getElementById('load-svg').onclick = function() { + var svg = (document.getElementById('svg-console')).value; + fabric.loadSVGFromString(svg, function(objects, options) { + var obj = fabric.util.groupSVGElements(objects, options); + canvas.add(obj).centerObject(obj).renderAll(); + obj.setCoords(); + }); + }; + + if (typeof Cufon !== 'undefined') { + Cufon.fonts.delicious.offsetLeft = 75; + Cufon.fonts.delicious.offsetTop = 25; + } \ No newline at end of file