Skip to content

Commit

Permalink
Hotkeys and major file restructuring (#393)
Browse files Browse the repository at this point in the history
* update dist

* this works

* start restructuring

* restructuring

* small keymapper updates

* mode color UI

* reordering

* port all collection actions to shared actions

* update keybinding to R

* update keybinding to R

* update tests

* reinstate commented out tests

* fix opacity tool

* add new line to file

* rebase and fix lint

* RotateScale -> FreeScale

* free rotate

* update lock mode convntion

* restructures

* add grayscale for disabled icons

* fix implementation

* begin README updates

* a little more lock convention cleaning

* fix disabled keybindings

* more README updates

* bump to 0.8.0

* update readme more

* fix keymapper linting accident

* eymapper fixup

* remove unneccesary class

* final sweep

* updates

* update lint

* update

* fix linting

* spec

* file modifications

* fix one forgotten var

* refacotr

* fix one more bug

* final?

* final
  • Loading branch information
sashadev-sky authored Sep 15, 2019
1 parent 075e335 commit 85520ed
Show file tree
Hide file tree
Showing 44 changed files with 1,770 additions and 1,613 deletions.
3 changes: 1 addition & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
node_modules
test/src/util
test/src/*Spec.js
test/*
Gruntfile.js
dist
71 changes: 35 additions & 36 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,39 @@
module.exports = {
"env": {
"browser": true,
},
"extends": "google",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"env": {
"browser": true,
},
"extends": "google",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
/*
* include rules you want to enforce/suppress/disable here
* they can be set to "off"(0) or "warn"(1) or "error"(2)
* for eg., "semi": "warn" or "semi": 1, that will display
* warnings for all snippets where semicolons aren't used
* but won't throw an error
*/

/*
* include rules you want to enforce/suppress/disable here
* they can be set to "off"(0) or "warn"(1) or "error"(2)
* for eg., "semi": "warn" or "semi": 1, that will display
* warnings for all snippets where semicolons aren't used
* but won't throw an error
*/
/*
* some rules have properties that can be modified for eg.,
* "quotes": ["error", "double"], i.e., display errors(2)
* (see above) ÿhen double quotes aren't used.
*/

/*
* some rules have properties that can be modified for eg.,
* "quotes": ["error", "double"], i.e., display errors(2)
* (see above) when double quotes aren't used.
*/

/* rules */
"curly": ["error", "multi-line"],
"brace-style": ["off", "1tbs", { "allowSingleLine": true }],
"block-spacing": ["error", "always"],
"no-var": 0,
"new-cap": 0,
"guard-for-in": 0,
"max-len": ["warn", { "ignoreComments": true }],
"prefer-const": 1,
"valid-jsdoc": 2
}
/* rules */
"curly": ["error", "multi-line"],
"brace-style": ["off", "1tbs", { "allowSingleLine": true }],
"block-spacing": ["error", "always"],
"no-var": 0,
"new-cap": 0,
"guard-for-in": 0,
"max-len": ["warn", { "ignoreComments": true }],
"prefer-const": 1,
"valid-jsdoc": 0
}
};
15 changes: 6 additions & 9 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,15 @@ module.exports = function(grunt) {
'src/DistortableImageOverlay.js',
'src/DistortableCollection.js',
'src/edit/getEXIFdata.js',
'src/edit/EditHandle.js',
'src/edit/LockHandle.js',
'src/edit/DistortHandle.js',
'src/edit/RotateScaleHandle.js',
'src/edit/RotateHandle.js',
'src/edit/ScaleHandle.js',
'src/edit/handles/EditHandle.js',
'src/edit/handles/*.js',
'src/iconsets/IconSet.js',
'src/iconsets/KeymapperIconSet.js',
'src/iconsets/ToolbarIconSet.js',
'src/edit/tools/EditAction.js',
'src/edit/tools/DistortableImage.PopupBar.js',
'src/edit/tools/DistortableImage.ControlBar.js',
'src/edit/actions/EditAction.js',
'src/edit/actions/*.js',
'src/edit/toolbars/DistortableImage.PopupBar.js',
'src/edit/toolbars/DistortableImage.ControlBar.js',
'src/edit/DistortableImage.Edit.js',
'src/edit/DistortableCollection.Edit.js',
'src/components/DistortableImage.Keymapper.js',
Expand Down
94 changes: 50 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,27 @@ L.tileLayer('https://{s}.tiles.mapbox.com/v3/anishshah101.ipm9j6em/{z}/{x}/{y}.p

### Actions

* `actions` (*optional*, default: [ToggleTransparency, ToggleOutline, ToggleLock, ToggleRotateScale, ToggleOrder, Revert, Export, Delete], value: *array*)
* `actions` (*optional*, default: [`L.ScaleAction`, `L.DistortAction`, `L.RotateAction`, `L.FreeRotateAction`, `L.LockAction`, `L.OpacityAction`, `L.BorderAction`, `L.ExportAction`, `L.DeleteAction`], value: *array*)

If you would like to overrwrite the default toolbar actions available for an individual image's `L.Popup` toolbar, pass an array with the actions you want. Reference the available values [here](#Single-Image-Interface).

For example, to overrwrite the toolbar to only include the `ToggleTransparency` and `Delete` actions, and also add on the additional `ToggleScale` action:
For example, to overrwrite the toolbar to only include `L.OpacityAction` and `L.DeleteAction` , and also add on an additional non-default like `L.RevertAction`:

```js
img = L.distortableImageOverlay('example.jpg', {
actions: [ToggleTransparency, ToggleScale, Delete],
actions: [L.OpacityAction, L.DeleteAction, L.RevertAction],
}).addTo(map);
```

### Corners

* `corners` (*optional*, default: an array of `LatLang`s that position the image on the center of the map, value: *array*)

Allows you to set an image's position on the map manually (somewhere other than center).
Allows you to set an image's position on the map manually (somewhere other than the center default).

They should be passed as an array of `L.latLng` objects in NW, NE, SW, SE order (in a "Z" shape).
Note that this can manipulate shape and dimensions of your image.

This will not have an effect on the map view, but it will determine the shape and dimensions of the rendered image.
The corners should be passed as an array of `L.latLng` objects in NW, NE, SW, SE order (in a "Z" shape).

They will be stored on the image. See the [Quick API Reference](#Quick-API-Reference) for their getter and setter methods.

Expand Down Expand Up @@ -176,14 +176,14 @@ Values available to pass to `mode` are:
* **distort** (*default*): Distortion via individually draggable corners.
* **rotate**: Rotation only.
* **scale**: Resize only.
* **rotateScale**: Free transform. Combines the rotate and scale modes into one.
* **lock**: Locks the image in place. Prevents moving it via user gestures, toolbar actions, and hotkeys until the toolbar action ToggleLock is explicitly triggered (or its hotkey <kbd>l</kbd>).
* **freeRotate**: Combines the rotate and scale modes into one.
* **lock**: Locks the image in place. Disables any user gestures, toolbar actions, or hotkeys that are not associated with mode. Exception: `L.ExportAction` will still be enabled.

In the below example, the image will be initialiazed with "rotateScale" handles:
In the below example, the image will be initialiazed with "freeRotate" handles:

```js
img = L.distortableImageOverlay('example.jpg', {
mode: 'rotateScale',
mode: 'freeRotate',
}).addTo(map);
```

Expand All @@ -207,7 +207,7 @@ Typically, editing actions are triggered through our toolbar interface. If disab

## Multiple Image Interface

Our `DistortableCollection` class allows working with multiple images simultaneously. This interface builds on the single image interface.
Our `DistortableCollection` class builds on the single image interface to allow working with multiple images simultaneously.

The setup is relatively similar.

Expand Down Expand Up @@ -244,7 +244,7 @@ imgGroup.addLayer(img);
imgGroup.addLayer(img2);
```

<blockquote><strong>Note</strong>: You must instantiate a blank collection, then dynamically add layers to it like above. This is because <code>DistortableCollection</code> uses the <code>layeradd</code> event to enable additional editing features on images as they are added, and it is only triggered when they are added dynamically.</blockquote>
<blockquote><strong>Note</strong>: You must instantiate a blank collection, then dynamically add layers to it like above. This is because <code>DistortableCollection</code> internally uses the <code>layeradd</code> event to enable additional editing features on images as they are added, and it is only triggered when they are added dynamically.</blockquote>


Options available to pass during `L.DistortableCollection` initialization:
Expand All @@ -255,15 +255,15 @@ Options available to pass during `L.DistortableCollection` initialization:

### ✤ Actions

* `actions` (*optional*, default: [Exports, Deletes, Locks, Unlocks], value: *array*)
* `actions` (*optional*, default: [`L.ExportAction`, `L.DeleteAction`, `L.LockAction`, `L.UnlocksAction`], value: *array*)

Overrwrite the default toolbar actions for an image collection's `L.Control` toolbar. Reference the available values [here](#Multiple-Image-Interface).

For example, to overrwrite the toolbar to only include the `Deletes` action:
For example, to overrwrite the toolbar to only include the `L.DeleteAction`:

```JS
imgGroup = L.distortableCollection({
actions: [Deletes],
actions: [L.DeleteAction],
}).addTo(map);
```

Expand Down Expand Up @@ -310,18 +310,18 @@ imgGroup = L.distortableCollection({

### UI and functionalities

Currently it supports multiple image selection and translations, and WIP we are working on porting all editing tools to work for it, such as transparency, etc. Image distortions still use the single-image interface.
Currently it supports multiple image selection and translations, and WIP we are working on porting all editing tools to work for it, such as opacity, etc. Image distortions (via modes) still use the single-image interface.

**multi-select:** A single toolbar instance (using `L.control`) renders the set of tools available to use on collections of images.

1. Multi-selection works with <kbd>shift</kbd> + `click` to toggle an individual image's inclusion in this interface.
2. Or <kbd>shift</kbd> + `drag` to use our `BoxSelector` handler to select multiple at once.
2. Or <kbd>shift</kbd> + `drag` to use our `L.Map.BoxSelector` handler to select multiple at once.
3. Or for touch devices, `touch` + `hold` (aka `longpress`).

**un-multi-select:**

* In order to return to the single-image interface, where each `L.popup` toolbar only applies actions on the image it's attached to, you must toggle *all* images out of multi-select or...
* ...Click on the map or hit the <kbd>esc</kbd> key to quickly deselect all images.
* In order to return to the single-image interface, where each `L.popup` toolbar only applies actions on the image it's attached to, you must toggle *all* images out of multi-select with `shift` + click, or...
* ...Click on the map or hit the <kbd>esc</kbd> key to quickly deselect.
* For the aforementioned 3 mutli-select methods, the `BoxSelector` method is the only one that doesn't also toggle _out_ of multi-select mode.

---
Expand All @@ -336,29 +336,27 @@ Currently it supports multiple image selection and translations, and WIP we are

Defaults:

* **ToggleLock (<kbd>l</kbd>)**
* **L.ScaleAction** (<kbd>s</kbd>):
* Sets `scale` mode.
* **L.RotateAction** (<kbd>r</kbd>):
* Sets `rotate` mode.
* **L.FreeRotateAction** (<kbd>f</kbd>)
* Sets `freeRotate` mode.
* **L.LockAction** (<kbd>l</kbd>, <kbd>u</kbd>)
* Toggles between `lock` mode and `distort` mode.
* **ToggleRotateScale (<kbd>r</kbd>, <kbd>d</kbd>)**
* Toggles between `rotateScale` and `distort` mode.
* **ToggleOrder (<kbd>j</kbd>, <kbd>k</kbd>)**
* If you have multiple images, use this to switch an individual image's overlap back and forth into view. Employs [`bringToFront()`](https://leafletjs.com/reference-1.5.0.html\#imageoverlay-bringtofront) and [`bringToBack()`](https://leafletjs.com/reference-1.5.0.html#imageoverlay-bringtoback) from the Leaflet API.
* **ToggleOutline (<kbd>o</kbd>)**
* **ToggleTransparency (<kbd>t</kbd>)**
* **Revert**
* Restores the image to its original proportions and scale, but keeps its current rotation angle and location on the map intact.
* **Export**
* **Delete (<kbd>delete</kbd>, <kbd>backscpace</kbd>)**
* Permanently deletes the image from the map.
* **L.BorderAction** (<kbd>b</kbd>)
* **L.OpacityAction** (<kbd>o</kbd>)
* **L.ExportAction** (<kbd>e</kbd>)
* **L.DeleteAction** (<kbd>backscpace</kbd>, <kbd>delete</kbd>)
* Permanently deletes the image from the map. Uses a `confirm()` modal dialog.
* windows `backspace` / mac `delete`

Addons:

* **ToggleRotate** (<kbd>caps lock</kbd>):
* Toggles between `rotate` mode and `distort` mode.
* Replaced as a default toolbar action by `ToggleRotateScale`, but still accessible via its hotkey, `mode`, and (WIP) custom toolbar actions API.
* **ToggleScale** (<kbd>s</kbd>):
* Toggles between `scale` mode and `distort` mode.
* Replaced as a default toolbar action by `ToggleRotateScale`, but still accessible via its hotkey, `mode`, and (WIP) custom toolbar actions API.
* **EnableEXIF (WIP)**
* **L.StackAction** (<kbd>q</kbd>, <kbd>a</kbd>)
* Switch an image's overlap compared to neighboring images back and forth into view. Employs [`bringToFront()`](https://leafletjs.com/reference-1.5.0.html\#imageoverlay-bringtofront) and [`bringToBack()`](https://leafletjs.com/reference-1.5.0.html#imageoverlay-bringtoback) from the Leaflet API.
* **L.GeolocateAction (WIP)**
* **L.RevertAction (WIP)**
* Restores the image to its original proportions and scale, but keeps its current rotation angle and location on the map intact.

---

Expand All @@ -368,11 +366,13 @@ Defaults:

Defaults:

* **Exports** (WIP)
* **Deletes (<kbd>delete</kbd>, <kbd>backspace</kbd>)**
* Permanently deletes groups of selected images from the map. Uses a `confirm()` modal dialog.
* **Locks** (<kbd>l</kbd>)
* **Unlocks** (<kbd>u</kbd>)
* **L.ExportAction** (<kbd>e</kbd>) (WIP)
* **L.DeleteAction** (<kbd>backscpace</kbd>, <kbd>delete</kbd>)
* Permanently deletes a group of images from the map.
* **L.LockAction** (<kbd>l</kbd>)
* Sets `lock` mode for a group of images.
* **L.UnlocksAction** (<kbd>u</kbd>)
* Unsets `lock` mode for a group of images.

## Quick API Reference

Expand Down Expand Up @@ -539,6 +539,12 @@ A handler that holds the keybindings and toolbar API for an image instance. It i
</ul>
</details>

<details><summary><code><b>getMode()</b>: String</code></summary>
<ul>
<li>Returns the current <code>mode</code> of the image.</li>
</ul>
</details>

---

`L.DistortableCollection`
Expand Down
43 changes: 42 additions & 1 deletion dist/leaflet.distortableimage.css
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,50 @@ input.ldi {
background-color: #efefef;
}

a.leaflet-toolbar-icon.rotate.selected-mode,
a.leaflet-toolbar-icon.freeRotate.selected-mode {
background-color: rgba(251, 18, 14, 0.75);
border: inset 0.5px lightgray;
}

a.leaflet-toolbar-icon.rotate.selected-mode .ldi-icon,
a.leaflet-toolbar-icon.freeRotate.selected-mode .ldi-icon {
fill: white;
}

a.leaflet-toolbar-icon.distort.selected-mode,
a.leaflet-toolbar-icon.scale.selected-mode {
background-color: hsla(239, 97%, 55%, 0.75);
border: inset 0.5px lightgray;
}

a.leaflet-toolbar-icon.distort.selected-mode .ldi-icon,
a.leaflet-toolbar-icon.scale.selected-mode .ldi-icon {
fill: white;
}

a.leaflet-toolbar-icon.lock.selected-mode {
background-color: hsla(0, 0%, 1%, 0.7490196078431373);
border: inset 0.5px lightgray;
}

li.disabled {
cursor: auto;
}

a.leaflet-toolbar-icon.disabled {
filter: grayscale(1);
pointer-events: none;
}

a.leaflet-toolbar-icon.lock.selected-mode .ldi-icon {
fill: white;
}

a.leaflet-toolbar-icon[title='Loading...'] {
background-color: whitesmoke;
pointer-events: none;
cursor: default;
}

.ldi-icon.loader {
Expand All @@ -158,7 +200,6 @@ a.leaflet-toolbar-icon[title='Loading...'] {
fill: black;
width: 22px;
height: 22px;
cursor: default;
}

@keyframes ldi-spin {
Expand Down
Loading

0 comments on commit 85520ed

Please sign in to comment.