diff --git a/src/lib/viewers/controls/edit/EditControl.scss b/src/lib/viewers/controls/edit/EditControl.scss
new file mode 100644
index 000000000..de6b51af3
--- /dev/null
+++ b/src/lib/viewers/controls/edit/EditControl.scss
@@ -0,0 +1,5 @@
+@import '../styles';
+
+.bp-EditControl {
+ @include bp-Control;
+}
diff --git a/src/lib/viewers/controls/edit/EditControl.tsx b/src/lib/viewers/controls/edit/EditControl.tsx
new file mode 100644
index 000000000..fc4f60f75
--- /dev/null
+++ b/src/lib/viewers/controls/edit/EditControl.tsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import IconEdit24 from '../icons/IconEdit24';
+import './EditControl.scss';
+
+export type Props = {
+ onEditImageClick: () => void;
+};
+
+export default function EditControl({ onEditImageClick }: Props): JSX.Element {
+ return (
+
+ );
+}
diff --git a/src/lib/viewers/controls/edit/index.ts b/src/lib/viewers/controls/edit/index.ts
new file mode 100644
index 000000000..971d5ea75
--- /dev/null
+++ b/src/lib/viewers/controls/edit/index.ts
@@ -0,0 +1,2 @@
+export * from './EditControl';
+export { default } from './EditControl';
diff --git a/src/lib/viewers/controls/icons/IconEdit24.tsx b/src/lib/viewers/controls/icons/IconEdit24.tsx
new file mode 100644
index 000000000..d7277771c
--- /dev/null
+++ b/src/lib/viewers/controls/icons/IconEdit24.tsx
@@ -0,0 +1,11 @@
+import * as React from 'react';
+
+function IconEdit24(props: React.SVGProps): JSX.Element {
+ return (
+
+ );
+}
+
+export default IconEdit24;
diff --git a/src/lib/viewers/image/ImageControls.tsx b/src/lib/viewers/image/ImageControls.tsx
index 902dd759d..d9ef98142 100644
--- a/src/lib/viewers/image/ImageControls.tsx
+++ b/src/lib/viewers/image/ImageControls.tsx
@@ -4,11 +4,13 @@ import ControlsBar, { ControlsBarGroup } from '../controls/controls-bar';
import DrawingControls, { Props as DrawingControlsProps } from '../controls/annotations/DrawingControls';
import ExperiencesProvider, { Props as ExperiencesProviderProps } from '../controls/experiences';
import FullscreenToggle, { Props as FullscreenToggleProps } from '../controls/fullscreen';
+import EditControl, { Props as EditControlProps } from '../controls/edit';
import RotateControl, { Props as RotateControlProps } from '../controls/rotate';
import ZoomControls, { Props as ZoomControlsProps } from '../controls/zoom';
export type Props = AnnotationsControlsProps &
DrawingControlsProps &
+ EditControlProps &
ExperiencesProviderProps &
FullscreenToggleProps &
RotateControlProps &
@@ -24,6 +26,7 @@ export default function ImageControls({
onAnnotationColorChange,
onAnnotationModeClick,
onAnnotationModeEscape,
+ onEditImageClick,
onFullscreenToggle,
onRotateLeft,
onZoomIn,
@@ -48,6 +51,7 @@ export default function ImageControls({
onAnnotationModeClick={onAnnotationModeClick}
onAnnotationModeEscape={onAnnotationModeEscape}
/>
+
diff --git a/src/lib/viewers/image/ImageViewer.js b/src/lib/viewers/image/ImageViewer.js
index 8b87513d4..8ef5bbe6a 100644
--- a/src/lib/viewers/image/ImageViewer.js
+++ b/src/lib/viewers/image/ImageViewer.js
@@ -29,6 +29,7 @@ class ImageViewer extends ImageBaseViewer {
this.handleAnnotationControlsClick = this.handleAnnotationControlsClick.bind(this);
this.handleAnnotationCreateEvent = this.handleAnnotationCreateEvent.bind(this);
this.handleAssetAndRepLoad = this.handleAssetAndRepLoad.bind(this);
+ this.handleEditImageClick = this.handleEditImageClick.bind(this);
this.handleImageDownloadError = this.handleImageDownloadError.bind(this);
this.handleZoomEvent = this.handleZoomEvent.bind(this);
this.rotateLeft = this.rotateLeft.bind(this);
@@ -400,6 +401,7 @@ class ImageViewer extends ImageBaseViewer {
onAnnotationColorChange={this.handleAnnotationColorChange}
onAnnotationModeClick={this.handleAnnotationControlsClick}
onAnnotationModeEscape={this.handleAnnotationControlsEscape}
+ onEditImageClick={this.handleEditImageClick}
onFullscreenToggle={this.toggleFullscreen}
onRotateLeft={this.rotateLeft}
onZoomIn={this.zoomIn}
@@ -570,6 +572,30 @@ class ImageViewer extends ImageBaseViewer {
}
}
+ /**
+ * Handler for edit image button click event.
+ *
+ * @private
+ * @return {void}
+ */
+ handleEditImageClick() {
+ this.currentRotationAngle = ((this.currentRotationAngle + 90) % 3600) % 360;
+ this.imageEl.setAttribute('data-rotation-angle', this.currentRotationAngle);
+ this.imageEl.style.transform = `rotate(${this.currentRotationAngle}deg)`;
+ this.emit('rotate');
+
+ // Disallow creating annotations on rotated images
+ if (this.currentRotationAngle === 0) {
+ this.enableAnnotationControls();
+ } else {
+ this.disableAnnotationControls();
+ }
+
+ // Re-adjust image position after rotation
+ this.handleOrientationChange();
+ this.setScale(this.imageEl.offsetwidth, this.imageEl.offsetHeight);
+ }
+
updateDiscoverabilityResinTag() {
if (!this.containerEl) {
return;