{this.props.displyMode === DisplayMode.Edit && this.getCommandBar()}
);
}
+
+ private imageChanged(url: string): void {
+ this.img = new Image();
+ this.img.src = url;
+ this.img.crossOrigin = 'Anonymous';
+ this.img.onload = () => {
+
+ this.applySettings();
+ };
+ this.img.onerror = (event: Event | string) => {
+ if (this.props.imgLoadError) {
+ this.props.imgLoadError();
+ }
+ };
+ }
+
+ private applySettings(): void {
+ this.canvasRef.width = this.img.width;
+ this.canvasRef.height = this.img.height;
+ this.bufferRef.width = this.img.width;
+ this.bufferRef.height = this.img.height;
+ this.manipulateRef.width = this.img.width;
+ this.manipulateRef.height = this.img.height;
+
+ let currentwidth: number = this.img.width;
+ let currentheight: number = this.img.height;
+ let newwidth: number = currentwidth;
+ let newheight: number = currentheight;
+ this.bufferCtx.clearRect(0, 0, currentwidth, currentheight);
+ this.bufferCtx.drawImage(this.img, 0, 0);
+
+ if (this.props.settings) {
+ this.props.settings.forEach((element, index) => {
+ this.manipulateCtx.clearRect(0, 0, currentwidth, currentheight);
+ this.manipulateRef.width = currentwidth;
+ this.manipulateRef.height = currentheight;
+ this.manipulateCtx.save();
+ let nothingToDo: boolean = false;
+ switch (element.type) {
+ case ManipulationType.Flip:
+ const filp: IFlipSettings = element as IFlipSettings;
+ if (filp.flipY) {
+ this.manipulateCtx.translate(0, currentheight);
+ this.manipulateCtx.scale(1, -1);
+ }
+ if (filp.flipX) {
+ this.manipulateCtx.translate(currentwidth, 0);
+ this.manipulateCtx.scale(-1, 1);
+ }
+ this.manipulateCtx.drawImage(this.bufferRef, 0, 0);
+ break;
+ case ManipulationType.Rotate:
+ const rotate: IRotateSettings = element as IRotateSettings;
+ if (!rotate.rotate || rotate.rotate === 0 || isNaN(rotate.rotate)) {
+ nothingToDo = true;
+ break;
+ }
+ if (rotate.rotate) {
+ const angelcalc: number = rotate.rotate * Math.PI / 180;
+ const oldwidth: number = currentwidth;
+ const oldheight: number = currentheight;
+ let offsetwidth: number = 0;
+ let offsetheight: number = 0;
+
+ const a: number = oldwidth * Math.abs(Math.cos(angelcalc));
+ const b: number = oldheight * Math.abs(Math.sin(angelcalc));
+
+ const p: number = oldwidth * Math.abs(Math.sin(angelcalc));
+ const q: number = oldheight * Math.abs(Math.cos(angelcalc));
+ newwidth = a + b;
+ newheight = p + q;
+
+ offsetwidth = (newwidth - oldwidth) / 2;
+ offsetheight = (newheight - oldheight) / 2;
+
+ this.manipulateRef.width = newwidth;
+ this.manipulateRef.height = newheight;
+
+ this.manipulateCtx.translate(newwidth / 2, newheight / 2);
+ this.manipulateCtx.rotate(angelcalc);
+ this.manipulateCtx.translate(newwidth / 2 * -1, newheight / 2 * -1);
+
+ this.manipulateCtx.drawImage(this.bufferRef, offsetwidth, offsetheight);
+ }
+ break;
+ case ManipulationType.Scale:
+ const scale: IScaleSettings = element as IScaleSettings;
+ if (scale.scale) {
+ this.manipulateCtx.translate(currentwidth / 2, currentheight / 2);
+ this.manipulateCtx.scale(scale.scale, scale.scale);
+ this.manipulateCtx.translate(currentwidth / 2 * -1, currentheight / 2 * -1);
+
+ this.manipulateCtx.drawImage(this.bufferRef, 0, 0);
+ }
+ break;
+ case ManipulationType.Filter:
+ nothingToDo = true;
+ const filter: IFilterSettings = element as IFilterSettings;
+ let imageData: ImageData = this.bufferCtx.getImageData(0, 0, currentwidth, currentheight);
+ switch (filter.filterType) {
+ case FilterType.Grayscale:
+ imageData = new GrayscaleFilter().process(imageData, currentwidth, currentheight, undefined, undefined);
+ break;
+ case FilterType.Sepia:
+ imageData = new SepiaFilter().process(imageData, currentwidth, currentheight, undefined, undefined);
+ break;
+ }
+ this.bufferCtx.putImageData(imageData, 0, 0);
+ break;
+ case ManipulationType.Crop:
+ const last: boolean = this.props.settings.length === index + 1;
+ if (last && this.state.settingPanel === SettingPanelType.Crop) {
+ // Do nothing is last and current edit
+ nothingToDo = true;
+ } else {
+ const crop: ICropSettings = element as ICropSettings;
+ const sourceX: number = crop.sx;
+ const sourceY: number = crop.sy;
+ newwidth = crop.width;
+ newheight = crop.height;
+ this.manipulateRef.width = newwidth;
+ this.manipulateRef.height = newheight;
+ this.manipulateCtx.drawImage(
+ this.bufferRef,
+ sourceX,
+ sourceY,
+ newwidth,
+ newheight,
+ 0,
+ 0,
+ newwidth,
+ newheight);
+ }
+ break;
+
+ case ManipulationType.Resize:
+ const resize: IResizeSettings = element as IResizeSettings;
+ newwidth = resize.width;
+ newheight = resize.height;
+ this.manipulateCtx.drawImage(this.bufferRef, 0, 0);
+ }
+ this.manipulateCtx.restore();
+
+ if (!nothingToDo) {
+ this.bufferCtx.clearRect(0, 0, currentwidth, currentheight);
+
+ this.bufferRef.width = newwidth;
+ this.bufferRef.height = newheight;
+
+ this.bufferCtx.clearRect(0, 0, newwidth, newheight);
+ this.bufferCtx.drawImage(this.manipulateRef, 0, 0, newwidth, newheight);
+
+ currentwidth = newwidth;
+ currentheight = newheight;
+ }
+ });
+ }
+
+ /*this.canvasCtx.clearRect(0, 0, this.canvasRef.width, this.canvasRef.height)
+ // this.canvasCtx.drawImage(this.bufferRef, 0, 0);
+ const sourceX = 400;
+ const sourceY = 200;
+ const sourceWidth = 1200;
+ const sourceHeight = 600;
+ this.canvasCtx.drawImage(
+ this.bufferRef, sourceX, sourceY, sourceWidth,
+ sourceHeight, 0, 0, this.canvasRef.width, this.canvasRef.height);
+*/
+ this.canvasCtx.clearRect(0, 0, currentwidth, currentheight);
+ this.canvasRef.width = currentwidth;
+ this.canvasRef.height = currentheight;
+ this.canvasCtx.drawImage(this.bufferRef, 0, 0);
+ // this.canvasCtx.drawImage(this.bufferRef, 0, 0, currentwidth, currentheight);
+ this.wrapperRef.style.width = currentwidth + 'px';
+ // this.wrapperRef.style.height = currentheight + 'px';
+ // let height = this.canvasRef.height;
+ // let width = this.canvasRef.width;
+
+ // this.canvasctx.translate(this.canvasRef.width / 2 * -1, this.canvasRef.height / 2 * -1);
+ }
+
private getCropGrid(): JSX.Element {
- const lastset = this.getLastManipulation() as ICropSettings;
+ const lastset: ICropSettings = this.getLastManipulation() as ICropSettings;
let lastdata: ICrop = { sx: 0, sy: 0, width: 0, height: 0 };
if (lastset && lastset.type === ManipulationType.Crop) {
@@ -300,7 +330,7 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}
private getResizeGrid(): JSX.Element {
- const lastset = this.getLastManipulation() as IResizeSettings;
+ const lastset: IResizeSettings = this.getLastManipulation() as IResizeSettings;
if (lastset && lastset.type === ManipulationType.Resize) {
return (
this.setResize(size.width, size.height, undefined)}
- //aspect={this.getAspect()}
+ // aspect={this.getAspect()}
width={this.canvasRef.width} height={this.canvasRef.height} />);
}
@@ -323,7 +353,9 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}
private isFilterActive(type: FilterType): boolean {
- return (this.props.settings && this.props.settings.filter((f) => f.type === ManipulationType.Filter && (f as IFilterSettings).filterType === type).length > 0);
+ return (this.props.settings && this.props.settings.filter(
+ (f) => f.type === ManipulationType.Filter
+ && (f as IFilterSettings).filterType === type).length > 0);
}
private closeFilter(): void {
this.setState({
@@ -379,7 +411,7 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}, () => this.toggleEditMode(true));
}
- private toggleEditMode(mode: boolean) {
+ private toggleEditMode(mode: boolean): void {
if (this.props.editMode) {
this.props.editMode(mode);
}
@@ -408,8 +440,6 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
this.props.settingschanged(newhist);
}
}
-
-
}}
onRenderItem={historyItem}
/>);
@@ -431,10 +461,12 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}
private toggleFilter(type: FilterType, nvalue: number = undefined, svalue: string = undefined): void {
- let tmpsettings = clone(this.props.settings);
+ let tmpsettings: IImageManipulationSettings[] = clone(this.props.settings);
if (!tmpsettings) { tmpsettings = []; }
- if (tmpsettings.filter((f) => f.type === ManipulationType.Filter && (f as IFilterSettings).filterType === type).length > 0) {
- const removeindex = findIndex(tmpsettings, (f) => f.type === ManipulationType.Filter && (f as IFilterSettings).filterType === type);
+ if (tmpsettings.filter(
+ (f) => f.type === ManipulationType.Filter && (f as IFilterSettings).filterType === type).length > 0) {
+ const removeindex: number = findIndex(tmpsettings,
+ (f) => f.type === ManipulationType.Filter && (f as IFilterSettings).filterType === type);
tmpsettings.splice(removeindex, 1);
} else {
tmpsettings.push({
@@ -453,12 +485,15 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
return (
{ return (); }}
+ onRenderIcon={() => {
+ // tslint:disable-next-line: react-a11y-img-has-alt
+ return ();
+ }}
title={strings.FlipHorizontal}
ariaLabel={strings.FlipHorizontal}
onClick={() => {
- let last = this.getLastManipulation();
+ const last: IImageManipulationSettings = this.getLastManipulation();
if (last && last.type === ManipulationType.Flip) {
(last as IFlipSettings).flipX = !(last as IFlipSettings).flipX;
if ((last as IFlipSettings).flipX === false &&
@@ -473,11 +508,14 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}}
/>
{ return (); }}
+ onRenderIcon={() => {
+ // tslint:disable-next-line: react-a11y-img-has-alt
+ return ();
+ }}
title={strings.FlipVertical}
ariaLabel={strings.FlipVertical}
onClick={() => {
- let last = this.getLastManipulation();
+ const last: IImageManipulationSettings = this.getLastManipulation();
if (last && last.type === ManipulationType.Flip) {
(last as IFlipSettings).flipY = !(last as IFlipSettings).flipY;
if ((last as IFlipSettings).flipX === false &&
@@ -495,8 +533,8 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
);
}
private getRotateSettings(): JSX.Element {
- const lastvalue = this.getLastManipulation();
- let rotatevalue = 0;
+ const lastvalue: IImageManipulationSettings = this.getLastManipulation();
+ let rotatevalue: number = 0;
if (lastvalue && lastvalue.type === ManipulationType.Rotate) {
rotatevalue = (lastvalue as IRotateSettings).rotate ? (lastvalue as IRotateSettings).rotate : 0;
}
@@ -506,7 +544,6 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
let icon: string = 'CompassNW';
if (value !== 0) { icon = 'Rotate'; }
-
return ( {
@@ -522,7 +559,6 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
{'' + value});
})}
-
{
- //Initial Value has a bug 0 is min value only min value is negative
- const correctBugComponent = component as any;
- if (correctBugComponent && correctBugComponent.state && correctBugComponent.value != correctBugComponent.props.value) {
+ // Initial Value has a bug 0 is min value only min value is negative
+ // tslint:disable-next-line: no-any
+ const correctBugComponent: any = component as any;
+ if (correctBugComponent
+ && correctBugComponent.state
+ && correctBugComponent.value !== correctBugComponent.props.value) {
correctBugComponent.setState({ value: 0, renderedValue: 0 });
}
}}
- //originFromZero
+ // originFromZero
/>
- this.setCrop(parseInt(x), undefined, undefined, undefined, crop.aspect)} />
- this.setCrop(undefined, parseInt(y), undefined, undefined, crop.aspect)} />
- this.setCrop(undefined, undefined, parseInt(w), undefined, crop.aspect)} />
- this.setCrop(undefined, undefined, undefined, parseInt(h), crop.aspect)} />
-
+ this.setCrop(parseInt(x), undefined, undefined, undefined, crop.aspect)} />
+ this.setCrop(undefined, parseInt(y), undefined, undefined, crop.aspect)} />
+ this.setCrop(undefined, undefined, parseInt(w), undefined, crop.aspect)} />
+ this.setCrop(undefined, undefined, undefined, parseInt(h), crop.aspect)} />
);
}
private getResizeSettings(): JSX.Element {
- let resize: IResizeSettings = this.getResizeValues();
+ const resize: IResizeSettings = this.getResizeValues();
return (
@@ -633,7 +695,7 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}
private getResizeValues(): IResizeSettings {
- let state: IImageManipulationSettings = this.getLastManipulation();
+ const state: IImageManipulationSettings = this.getLastManipulation();
let values: IResizeSettings = {
type: ManipulationType.Resize,
height: this.bufferRef.height,
@@ -646,7 +708,7 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}
private setResize(width: number, height: number, aspect: number): void {
- let values: IResizeSettings = this.getResizeValues();
+ const values: IResizeSettings = this.getResizeValues();
if (width) {
values.width = width;
if (aspect) {
@@ -664,7 +726,7 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}
private getCropValues(): ICropSettings {
- let state: IImageManipulationSettings = this.getLastManipulation();
+ const state: IImageManipulationSettings = this.getLastManipulation();
let values: ICropSettings = {
type: ManipulationType.Crop,
sx: 0,
@@ -679,7 +741,7 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}
private setCrop(sx: number, sy: number, width: number, height: number, aspect: number): void {
- let values = this.getCropValues();
+ const values: ICropSettings = this.getCropValues();
const currentheight: number = this.bufferRef.height;
const currentwidth: number = this.bufferRef.width;
if (!isNaN(sx) && sx >= 0) {
@@ -722,22 +784,21 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
}
}
if (isNaN(values.aspect) && !isNaN(aspect)) {
- //aspect added
+ // aspect added
- //limit w
+ // limit w
if ((values.width + values.sx) > currentwidth) {
values.width = currentwidth - values.sx;
}
values.height = values.width / aspect;
- //limit h adn recalulate w
+ // limit h adn recalulate w
if ((values.height + values.sy) > currentheight) {
values.height = currentheight - values.sy;
values.width = values.height * aspect;
}
-
-
}
+
values.aspect = aspect;
if (aspect && (!isNaN(sx) || !isNaN(width))) {
values.height = values.width / aspect;
@@ -762,8 +823,8 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
});
}
private calcRotate(value: number): void {
- const lastVal = this.getLastManipulation();
- let cvalue = 0;
+ const lastVal: IImageManipulationSettings = this.getLastManipulation();
+ let cvalue: number = 0;
if (lastVal && lastVal.type === ManipulationType.Rotate) {
cvalue = (lastVal as IRotateSettings).rotate;
}
@@ -810,18 +871,17 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
return undefined;
}
private addOrUpdateLastManipulation(changed: IImageManipulationSettings): void {
- let state = clone(this.props.settings);
+ let state: IImageManipulationSettings[] = clone(this.props.settings);
if (!state) {
state = [];
}
if (state.length > 0 && state[state.length - 1].type === changed.type) {
state[state.length - 1] = changed;
-
} else {
state.push(changed);
-
}
+
if (this.state.redosettings && this.state.redosettings.length > 0) {
this.setState({ redosettings: [] }, () => {
if (this.props.settingschanged) {
@@ -837,7 +897,7 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
private removeLastManipulation(): void {
if (this.props.settings && this.props.settings.length > 0) {
- let state = clone(this.props.settings);
+ const state: IImageManipulationSettings[] = clone(this.props.settings);
state.splice(state.length - 1, 1);
if (this.props.settingschanged) {
this.props.settingschanged(clone(state));
@@ -850,6 +910,7 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
iconProps={{ iconName: options.iconName }}
onRenderIcon={(p, defaultrenderer) => {
if (options.svgIcon) {
+ // tslint:disable-next-line: react-a11y-img-has-alt
return (
);
}
return defaultrenderer(p);
@@ -875,9 +936,9 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
ariaLabel={strings.CommandBarUndo}
disabled={!this.props.settings || this.props.settings.length < 1}
onClick={() => {
- const settings = clone(this.props.settings);
- const last = settings.pop();
- const redo = clone(this.state.redosettings);
+ const settings: IImageManipulationSettings[] = clone(this.props.settings);
+ const last: IImageManipulationSettings = settings.pop();
+ const redo: IImageManipulationSettings[] = clone(this.state.redosettings);
redo.push(last);
this.setState({ redosettings: redo },
() => {
@@ -894,9 +955,9 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
ariaLabel={strings.CommandBarRedo}
disabled={!this.state.redosettings || this.state.redosettings.length < 1}
onClick={() => {
- const redosettings = clone(this.state.redosettings);
- const redo = redosettings.pop();
- const settings = clone(this.props.settings);
+ const redosettings: IImageManipulationSettings[] = clone(this.state.redosettings);
+ const redo: IImageManipulationSettings = redosettings.pop();
+ const settings: IImageManipulationSettings[] = clone(this.props.settings);
settings.push(redo);
this.setState({ redosettings: redosettings },
() => {
@@ -930,7 +991,7 @@ this.canvasCtx.drawImage(this.bufferRef, sourceX, sourceY, sourceWidth, sourceHe
onClick={() => this.openPanel(SettingPanelType.History)}
/>
{
return ();
- //return ({`X:${item.sx} Y:${item.sy}`});
+ // return ({`X:${item.sx} Y:${item.sy}`});
},
settingPanelType: SettingPanelType.Crop
},
@@ -153,8 +162,5 @@ export const manipulationTypeData: IManipulationTypeData = {
svgIcon: resizeIcon,
toHTML: (item: IResizeSettings) => { return (); },
settingPanelType: SettingPanelType.Resize
- },
-
+ }
};
-
-
diff --git a/samples/react-image-editor/src/components/ImageManipulation/components/ImageCrop.tsx b/samples/react-image-editor/src/components/ImageManipulation/components/ImageCrop.tsx
index bd14ae797..05a854413 100644
--- a/samples/react-image-editor/src/components/ImageManipulation/components/ImageCrop.tsx
+++ b/samples/react-image-editor/src/components/ImageManipulation/components/ImageCrop.tsx
@@ -1,5 +1,3 @@
-import { noWrap } from 'office-ui-fabric-react';
-import { IPosition } from 'office-ui-fabric-react/lib-es2015/utilities/positioning';
import * as React from 'react';
import { ICrop } from '../ImageManipulation.types';
@@ -7,11 +5,10 @@ import { nodePoition } from './Enums';
import styles from './ImageCrop.module.scss';
import { ICropData, IMousePosition } from './Interfaces';
-function clamp(num, min, max) {
+function clamp(num: number, min: number, max: number): number {
return Math.min(Math.max(num, min), max);
}
-
export interface IImageCropProps {
crop: ICrop;
@@ -21,7 +18,8 @@ export interface IImageCropProps {
onDragStart?: (e: MouseEvent) => void;
onComplete?: (crop: ICrop) => void;
onChange?: (crop: ICrop) => void;
- onDragEnd?: (e) => void;
+ // tslint:disable-next-line: no-any
+ onDragEnd?: (e: any) => void;
}
export interface IImageCropState {
@@ -30,17 +28,14 @@ export interface IImageCropState {
reloadtimestamp: string;
}
-
-
-
-
// Feature detection
+// tslint:disable-next-line: max-line-length
// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Improving_scrolling_performance_with_passive_listeners
-let passiveSupported = false;
-export default class ImageCrop extends React.Component {
+export default class ImageCrop extends
+ React.Component {
- private controlRef: HTMLDivElement = null;
+ private controlRef: HTMLDivElement = undefined;
private dragStarted: boolean = false;
private mouseDownOnCrop: boolean = false;
@@ -61,31 +56,24 @@ export default class ImageCrop extends React.Component {
const { crop } = this.props;
- const { cropIsActive, newCropIsBeingDrawn } = this.state;
- const cropSelection = this.isValid(crop) && this.controlRef ? this.createSelectionGrid() : null;
+ const cropSelection: JSX.Element = this.isValid(crop) && this.controlRef ? this.createSelectionGrid() : undefined;
+ // tslint:disable:react-a11y-event-has-role
return (
);
+ // tslint:
}
private createSelectionGrid(): JSX.Element {
const { showRuler } = this.props;
- const style = this.getCropStyle();
+ const style: { top: string, left: string, width: string, height: string } = this.getCropStyle();
+ // tslint:disable:react-a11y-event-has-role
return (
-
@@ -139,7 +128,6 @@ export default class ImageCrop extends React.Component
-
{showRuler && (
@@ -148,6 +136,7 @@ export default class ImageCrop extends React.Component
);
+ // tslint:enable
}
private makeNewCrop(): ICrop {
@@ -155,32 +144,18 @@ export default class ImageCrop extends React.Component | any): void {
const { crop, onChange, onDragStart } = this.props;
if (!this.mouseDownOnCrop) {
@@ -191,15 +166,12 @@ export default class ImageCrop extends React.Component this.props.sourceHeight) {
- calcCrop.height = this.props.sourceHeight - calcCrop.sy;
- calcCrop.width = calcCrop.height * this.props.crop.aspect;
- }
-
- if (calcCrop.sx + calcCrop.width > this.props.sourceWidth) {
- calcCrop.width = this.props.sourceWidth - calcCrop.sx;
- calcCrop.height = calcCrop.width / this.props.crop.aspect;
- }
-
- return calcCrop;
- }
- private resolveCrop(pixelCrop: ICrop) {
- if (this.props.crop.aspect && (!pixelCrop.width || !pixelCrop.height)) {
- return this.makeAspectCrop(pixelCrop);
- }
- return pixelCrop;
- }
-
+ // tslint:disable-next-line: no-any
private onMouseTouchDown(e: MouseEvent | any): void {
const { crop, onChange } = this.props;
e.preventDefault(); // Stop drag selection.
- const mousepos = this.getClientPos(e);
+ const mousepos: IMousePosition = this.getClientPos(e);
- let refpos = this.controlRef.getBoundingClientRect();
- let startx: number = mousepos.x - refpos.left;
- let starty: number = mousepos.y - refpos.top;
- //is mousePos in current pos
+ // tslint:disable-next-line: no-any
+ const refpos: any = this.controlRef.getBoundingClientRect();
+ const startx: number = mousepos.x - refpos.left;
+ const starty: number = mousepos.y - refpos.top;
+ // is mousePos in current pos
if (crop) {
if (crop.sx - 5 <= startx && crop.sx + crop.width + 5 >= startx &&
crop.sy - 5 <= starty && crop.sy + crop.height + 5 >= starty
) {
- //Position in current crop do Nothing
+ // Position in current crop do Nothing
return;
}
}
@@ -479,7 +420,7 @@ export default class ImageCrop extends React.Component void;
onComplete?: (size: IResize) => void;
+ // tslint:disable-next-line: no-any
onDragEnd?: (e: MouseEvent | any) => void;
+ // tslint:disable-next-line: no-any
onDragStart?: (e: MouseEvent | any) => void;
}
@@ -30,7 +31,7 @@ export interface IResizeData {
export default class ImageGrid extends React.Component {
- private evData: IResizeData = null;
+ private evData: IResizeData = undefined;
private dragStarted: boolean = false;
constructor(props: IImageGridProps) {
super(props);
@@ -43,22 +44,23 @@ export default class ImageGrid extends React.Component {
+ // tslint:disable:react-a11y-event-has-role
return (
);
+ // tslint:enable
}
+ // tslint:disable-next-line: no-any
private onStartResizing(e: MouseEvent | any): void {
- const mousePos = this.getClientPos(e);
+ const mousePos: IMousePosition = this.getClientPos(e);
let xInversed: boolean = false;
let yInversed: boolean = false;
const { ord } = e.target.dataset;
@@ -141,8 +145,9 @@ export default class ImageGrid extends React.Component
| any): void {
- const { aspect ,onChange } = this.props;
+ const { aspect, onChange } = this.props;
if (!this.dragStarted) {
return;
}
@@ -151,29 +156,35 @@ export default class ImageGrid extends React.Component;
textProperty?: string;
moveUpIconName: string;
@@ -14,45 +15,47 @@ export interface IItemOrderProps {
disableDragAndDrop: boolean;
removeArrows: boolean;
maxHeight?: number;
+ // tslint:disable-next-line: no-any
valueChanged: (newValue: Array) => void;
+ // tslint:disable-next-line: no-any
onRenderItem?: (item: any, index: number) => JSX.Element;
}
export interface IItemOrderState {
+ // tslint:disable-next-line: no-any
items: Array;
}
-
export default class ItemOrder extends React.Component {
+ // tslint:disable-next-line: no-any
private _draggedItem: any;
private _selection: ISelection;
private _ddHelper: DragDropHelper;
private _refs: Array;
+ // tslint:disable-next-line: no-any
private _ddSubs: Array;
private _lastBox: HTMLElement;
-
constructor(props: IItemOrderProps) {
super(props);
- this._selection = null;
+ this._selection = undefined;
this._ddHelper = new DragDropHelper({
selection: this._selection
});
this._refs = new Array();
+ // tslint:disable-next-line: no-any
this._ddSubs = new Array();
- this._draggedItem = null;
+ this._draggedItem = undefined;
this.state = {
items: []
};
}
-
-
public render(): JSX.Element {
const {
items
@@ -60,9 +63,12 @@ export default class ItemOrder extends React.Component
{this.props.label && }
-
+
{
(items && items.length > 0) && (
+ // tslint:disable-next-line: no-any
items.map((value: any, index: number) => {
return (
- 0) &&
{ this._lastBox = ref; }} />
+ (items && items.length > 0) &&
{ this._lastBox = ref; }} />
}
);
}
- private renderItem(item: any, index: number): JSX.Element {
- return (
-
-
- {this.renderDisplayValue(item, index)}
-
- {!this.props.removeArrows &&
-
{this.renderArrows(index)}
- }
-
- );
- }
-
- private renderDisplayValue(item: any, index: number): JSX.Element {
- if (typeof this.props.onRenderItem === "function") {
- return this.props.onRenderItem(item, index);
- } else {
- return (
-
{this.props.textProperty ? item[this.props.textProperty] : item.toString()}
- );
- }
- }
-
- private renderArrows(index: number): JSX.Element {
- let arrowButtonStyles: Partial
= {
- root: {
- width: '14px',
- height: '100%',
- display: 'inline-block !important'
- },
- rootDisabled: {
- backgroundColor: 'transparent'
- },
- icon: {
- fontSize: "10px"
- }
- };
-
- return (
-
- { this.onMoveUpClick(index); }}
- styles={arrowButtonStyles}
- />
- { this.onMoveDownClick(index); }}
- styles={arrowButtonStyles}
- />
-
- );
- }
-
public componentWillMount(): void {
this.setState({
items: this.props.items || []
@@ -167,6 +119,64 @@ export default class ItemOrder extends React.Component
+
+ {this.renderDisplayValue(item, index)}
+
+ {!this.props.removeArrows &&
+ {this.renderArrows(index)}
+ }
+
+ );
+ }
+
+ // tslint:disable-next-line: no-any
+ private renderDisplayValue(item: any, index: number): JSX.Element {
+ if (typeof this.props.onRenderItem === 'function') {
+ return this.props.onRenderItem(item, index);
+ } else {
+ return (
+ {this.props.textProperty ? item[this.props.textProperty] : item.toString()}
+ );
+ }
+ }
+
+ private renderArrows(index: number): JSX.Element {
+ const arrowButtonStyles: Partial = {
+ root: {
+ width: '14px',
+ height: '100%',
+ display: 'inline-block !important'
+ },
+ rootDisabled: {
+ backgroundColor: 'transparent'
+ },
+ icon: {
+ fontSize: '10px'
+ }
+ };
+
+ return (
+
+ { this.onMoveUpClick(index); }}
+ styles={arrowButtonStyles}
+ />
+ { this.onMoveDownClick(index); }}
+ styles={arrowButtonStyles}
+ />
+
+ );
+ }
+
private registerRef = (ref: HTMLElement): void => {
this._refs.push(ref);
}
@@ -177,7 +187,8 @@ export default class ItemOrder extends React.Component {
+ // tslint:disable-next-line: no-any
+ callback: (context: IDragDropContext, _event?: any) => {
this._draggedItem = context.data;
},
eventName: 'dragstart'
@@ -185,20 +196,22 @@ export default class ItemOrder extends React.Component {
+ updateDropState: (isDropping: boolean, _event: DragEvent) => {
if (isDropping) {
value.classList.add(styles.dragEnter);
} else {
value.classList.remove(styles.dragEnter);
}
},
- canDrop: (dropContext?: IDragDropContext, dragContext?: IDragDropContext) => {
+ canDrop: (_dropContext?: IDragDropContext, _dragContext?: IDragDropContext) => {
return true;
},
- canDrag: (item?: any) => {
+ // tslint:disable-next-line: no-any
+ canDrag: (_item?: any) => {
return true;
},
- onDrop: (item?: any, event?: DragEvent) => {
+ // tslint:disable-next-line: no-any
+ onDrop: (item?: any, _event?: DragEvent) => {
if (this._draggedItem) {
this.insertBeforeItem(item);
}
@@ -207,14 +220,15 @@ export default class ItemOrder extends React.Component {
- this._draggedItem = null;
+ // tslint:disable-next-line: no-any
+ onDragEnd: (_item?: any, _event?: DragEvent) => {
+ this._draggedItem = undefined;
}
}));
});
- //Create dropable area below list to allow items to be dragged to the bottom
- if (this._refs.length && typeof this._lastBox !== "undefined") {
+ // Create droppable area below list to allow items to be dragged to the bottom
+ if (this._refs.length && typeof this._lastBox !== 'undefined') {
this._ddSubs.push(this._ddHelper.subscribe(this._lastBox, new EventGroup(this._lastBox), {
selectionIndex: this._refs.length,
context: { data: {}, index: this._refs.length },
@@ -225,12 +239,13 @@ export default class ItemOrder extends React.Component {
+ canDrop: (_dropContext?: IDragDropContext, _dragContext?: IDragDropContext) => {
return true;
},
- onDrop: (item?: any, event?: DragEvent) => {
+ // tslint:disable-next-line: no-any
+ onDrop: (_item?: any, _event?: DragEvent) => {
if (this._draggedItem) {
- let itemIndex: number = this.state.items.indexOf(this._draggedItem);
+ const itemIndex: number = this.state.items.indexOf(this._draggedItem);
this.moveItemAtIndexToTargetIndex(itemIndex, this.state.items.length - 1);
}
}
@@ -241,13 +256,15 @@ export default class ItemOrder extends React.Component {
while (this._ddSubs.length) {
- let sub: any = this._ddSubs.pop();
+ // tslint:disable-next-line: no-any
+ const sub: any = this._ddSubs.pop();
sub.dispose();
}
}
+ // tslint:disable-next-line: no-any
private insertBeforeItem = (item: any) => {
- let itemIndex: number = this.state.items.indexOf(this._draggedItem);
+ const itemIndex: number = this.state.items.indexOf(this._draggedItem);
let targetIndex: number = this.state.items.indexOf(item);
if (itemIndex < targetIndex) {
targetIndex -= 1;
@@ -255,7 +272,6 @@ export default class ItemOrder extends React.Component {
if (itemIndex > 0) {
this.moveItemAtIndexToTargetIndex(itemIndex, itemIndex - 1);
@@ -269,8 +285,12 @@ export default class ItemOrder extends React.Component {
- if (itemIndex !== targetIndex && itemIndex > -1 && targetIndex > -1 && itemIndex < this.state.items.length && targetIndex < this.state.items.length) {
- let items: Array = this.state.items;
+ if (itemIndex !== targetIndex
+ && itemIndex > -1 && targetIndex > -1
+ && itemIndex < this.state.items.length
+ && targetIndex < this.state.items.length) {
+ // tslint:disable-next-line: no-any
+ const items: Array = this.state.items;
items.splice(targetIndex, 0, ...items.splice(itemIndex, 1)[0]);
this.setState({
diff --git a/samples/react-image-editor/src/components/ImageManipulation/index.ts b/samples/react-image-editor/src/components/ImageManipulation/index.ts
index 4f9d2e702..75a1788e0 100644
--- a/samples/react-image-editor/src/components/ImageManipulation/index.ts
+++ b/samples/react-image-editor/src/components/ImageManipulation/index.ts
@@ -10,4 +10,3 @@ export {
IFilterSettings, IRotateSettings, IScaleSettings, IFlipSettings, ICropSettings, IResizeSettings,
FilterType
} from './ImageManipulation.types';
-
diff --git a/samples/react-image-editor/src/components/ImageManipulation/loc/mystrings.d.ts b/samples/react-image-editor/src/components/ImageManipulation/loc/mystrings.d.ts
index df65f3b6a..0bbb598ed 100644
--- a/samples/react-image-editor/src/components/ImageManipulation/loc/mystrings.d.ts
+++ b/samples/react-image-editor/src/components/ImageManipulation/loc/mystrings.d.ts
@@ -7,7 +7,6 @@ declare interface IImageManipulationStrings {
ManipulationTypeCrop: string;
ManipulationTypeResize: string;
-
FilterTypeGrayscale: string;
FilterTypeSepia: string;
diff --git a/samples/react-image-editor/src/webparts/reactImageEditor/ReactImageEditorWebPart.manifest.json b/samples/react-image-editor/src/webparts/reactImageEditor/ReactImageEditorWebPart.manifest.json
index 4d4a254ef..768987eae 100644
--- a/samples/react-image-editor/src/webparts/reactImageEditor/ReactImageEditorWebPart.manifest.json
+++ b/samples/react-image-editor/src/webparts/reactImageEditor/ReactImageEditorWebPart.manifest.json
@@ -4,17 +4,13 @@
"alias": "ReactImageEditorWebPart",
"componentType": "WebPart",
- // The "*" signifies that the version should be taken from the package.json
"version": "*",
"manifestVersion": 2,
- // If true, the component can only be installed on sites where Custom Script is allowed.
- // Components that allow authors to embed arbitrary script code should set this to true.
- // https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
"requiresCustomScript": false,
"preconfiguredEntries": [{
- "groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
+ "groupId": "5c03119e-3074-46fd-976b-c60198311f70",
"group": { "default": "Other" },
"title": { "default": "react-image-editor" },
"description": { "default": "react-image-editor description" },
diff --git a/samples/react-image-editor/src/webparts/reactImageEditor/ReactImageEditorWebPart.ts b/samples/react-image-editor/src/webparts/reactImageEditor/ReactImageEditorWebPart.ts
index 41a9993c9..89971ca2e 100644
--- a/samples/react-image-editor/src/webparts/reactImageEditor/ReactImageEditorWebPart.ts
+++ b/samples/react-image-editor/src/webparts/reactImageEditor/ReactImageEditorWebPart.ts
@@ -4,7 +4,6 @@ import { Version } from '@microsoft/sp-core-library';
import {
BaseClientSideWebPart,
IPropertyPaneConfiguration,
- PropertyPaneTextField,
PropertyPaneToggle
} from '@microsoft/sp-webpart-base';
@@ -12,8 +11,6 @@ import * as strings from 'ReactImageEditorWebPartStrings';
import ReactImageEditor, { IReactImageEditorBaseProps, IReactImageEditorProps } from './components/ReactImageEditor';
import { IImageManipulationSettings } from '../../components';
-
-
export interface IReactImageEditorWebPartProps extends IReactImageEditorBaseProps {
}
@@ -32,11 +29,12 @@ export default class ReactImageEditorWebPart extends BaseClientSideWebPart {this.properties.title = value;},
+ updateTitleProperty: (value: string) => { this.properties.title = value; },
updateUrlProperty: (value: string) => {
- if(this.properties.url !== value)
+ // tslint:disable-next-line: curly
+ if (this.properties.url !== value)
this.properties.url = value;
- this.properties.settings=[];
+ this.properties.settings = [];
this.render();
},
updateManipulationSettingsProperty: (value: IImageManipulationSettings[]) => {
@@ -58,7 +56,6 @@ export default class ReactImageEditorWebPart extends BaseClientSideWebPart void;
updateUrlProperty: (value: string) => void;
updateManipulationSettingsProperty: (value: IImageManipulationSettings[]) => void;
}
-export interface IReactImageEditorBaseProps {
- showTitle: boolean;
- title: string;
- url?: string
- settings?: IImageManipulationSettings[];
-}
export interface IReactImageEditorState {
- isFilePickerOpen: boolean,
+ isFilePickerOpen: boolean;
statekey: string;
}
@@ -36,7 +34,7 @@ export default class ReactImageEditor extends React.Component {
const { url, settings } = this.props;
const { isFilePickerOpen } = this.state;
- const isConfigured = !!url && url.length > 0;
+ const isConfigured: boolean = !!url && url.length > 0;
return (
@@ -54,16 +52,16 @@ export default class ReactImageEditor extends React.Component {
- this.setState({ isFilePickerOpen: false }, () => this._onUrlChanged(filePickerResult.fileAbsoluteUrl))
+ this.setState({ isFilePickerOpen: false }, () => this._onUrlChanged(filePickerResult.fileAbsoluteUrl));
}}
onCancel={() => {
- this.setState({ isFilePickerOpen: false })
+ this.setState({ isFilePickerOpen: false });
}}
onChanged={(filePickerResult: IFilePickerResult) => {
- this.setState({ isFilePickerOpen: false }, () => this._onUrlChanged(filePickerResult.fileAbsoluteUrl))
+ this.setState({ isFilePickerOpen: false }, () => this._onUrlChanged(filePickerResult.fileAbsoluteUrl));
}}
context={this.props.context}
@@ -92,7 +90,10 @@ export default class ReactImageEditor extends React.Component {
if (Environment.type === EnvironmentType.Local) {
this.setState({ isFilePickerOpen: false }, () => {
- this._onUrlChanged('https://media.gettyimages.com/photos/whitewater-paddlers-descend-vertical-waterfall-in-kayak-picture-id1256321293?s=2048x2048');
+ this._onUrlChanged(
+ 'https://media.gettyimages.com/photos/'
+ + 'whitewater-paddlers-descend-vertical-waterfall-in-kayak-picture-id1256321293?s=2048x2048'
+ );
});
} else {
this.setState({ isFilePickerOpen: true });
diff --git a/samples/react-image-editor/tslint.json b/samples/react-image-editor/tslint.json
index 6bfc75a4c..4fa8d07b3 100644
--- a/samples/react-image-editor/tslint.json
+++ b/samples/react-image-editor/tslint.json
@@ -1,30 +1,31 @@
-{
- "extends": "@microsoft/sp-tslint-rules/base-tslint.json",
- "rules": {
- "class-name": false,
- "export-name": false,
- "forin": false,
- "label-position": false,
- "member-access": true,
- "no-arg": false,
- "no-console": false,
- "no-construct": false,
- "no-duplicate-variable": true,
- "no-eval": false,
- "no-function-expression": true,
- "no-internal-module": true,
- "no-shadowed-variable": true,
- "no-switch-case-fall-through": true,
- "no-unnecessary-semicolons": true,
- "no-unused-expression": true,
- "no-use-before-declare": true,
- "no-with-statement": true,
- "semicolon": true,
- "trailing-comma": false,
- "typedef": false,
- "typedef-whitespace": false,
- "use-named-parameter": true,
- "variable-name": false,
- "whitespace": false
- }
-}
\ No newline at end of file
+{
+ "extends": "@microsoft/sp-tslint-rules/base-tslint.json",
+ "rules": {
+ "class-name": false,
+ "export-name": false,
+ "forin": false,
+ "label-position": false,
+ "member-access": true,
+ "no-arg": false,
+ "no-console": false,
+ "no-construct": false,
+ "no-duplicate-variable": true,
+ "no-eval": false,
+ "no-function-expression": true,
+ "no-internal-module": true,
+ "no-shadowed-variable": true,
+ "no-switch-case-fall-through": true,
+ "no-unnecessary-semicolons": true,
+ "no-unused-expression": true,
+ "no-use-before-declare": true,
+ "no-with-statement": true,
+ "semicolon": true,
+ "trailing-comma": false,
+ "typedef": false,
+ "typedef-whitespace": false,
+ "use-named-parameter": true,
+ "variable-name": false,
+ "whitespace": false,
+ "react-a11y-event-has-role": true
+ }
+}