Added initial documentation to README, added keyboard shortcuts for import/export

This commit is contained in:
Igor Zinken
2021-01-02 11:06:28 +01:00
parent 47b9228790
commit db143c4906
3 changed files with 39 additions and 10 deletions

View File

@@ -6,7 +6,7 @@ No, I'm building a tool that does the bare minimum what I require and what I don
find in other open source tools. That doesn't mean of course that contributions
related to Photoshop-esque features aren't welcomed.
### All self-written ?
### All hand-written ?
Yep, though it helps having worked in the photo software industry for five years, having
tackled the problems before. Also, Bitmappery is reusing [zCanvas](https://github.com/igorski/zCanvas)
@@ -25,6 +25,23 @@ BitMappery does however make use of the following excellent libraries to speed u
* UI Essentials by [www.wishforge.games](https://freeicons.io/profile/2257)
* Black arrow icons set by [Reda](https://freeicons.io/profile/6156)
## Model
BitMappery works with entities known as _Documents_. A Document contains several _Layer_s, each of
which define their content, transformation, _Effect_s, etc. Each of the nested entity properties
has its own factory (see _@/src/factories/_). The Document is managed by the Vuex _document-module.js_.
## Document rendering and interactions
The Document is rendered one layer at a time onto a Canvas element, using [zCanvas](https://github.com/igorski/zCanvas). Both the rendering and interaction handling is performed by _@/src/components/ui/zcanvas/layer_sprite.js_.
Note that the purpose of the renderer is solely to delegate interactions events to the Layer entity. The
renderer should represent the properties of the Layer, the Layer should never reverse-engineer from the onscreen
content (especially as different window size and scaling factor will greatly complicate these matters when
performed two-way).
Rendering transformations, text and effects is an asynchronous operation handled by _@/src/services/render-service.js_. The purpose of this service is to perform and cache repeated operations and eventually maintain
the source bitmap represented by the _layer-sprite.js_.
## Dropbox integration
Requires you to [register a client id or access token](https://www.dropbox.com/developers/apps).
@@ -56,7 +73,10 @@ npm run lint
# TODO / Roadmap
* Implement iframe based rendering (as more compatible alternative to OffscreenCanvas) for effects
* Implement action queue when drawing, only execute drawing on update() hook
* Implement loaders on document load/save, image export and dropbox import
* Maintain cache for transformations and filters, rendered at the display destination size (invalidate on window resize)
* Drawing masks on a rotated layer that is panned (or mirrored) is broken
* Dragging of masks on rotated/mirror content is kinda broken
* Restoring of document with rotated layers (smaller than document size) restores at incorrect offset

View File

@@ -65,7 +65,7 @@
<button v-t="'exportDocument'"
type="button"
:disabled="noDocumentsAvailable"
@click="requestDocumentSave()"
@click="requestDocumentExport()"
></button>
</li>
<li>
@@ -240,7 +240,7 @@ export default {
requestDocumentResize() {
this.openModal( RESIZE_DOCUMENT );
},
requestDocumentSave() {
requestDocumentExport() {
this.openModal( EXPORT_DOCUMENT );
},
requestSelectionLoad() {

View File

@@ -20,10 +20,11 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { ADD_LAYER } from "@/definitions/modal-windows";
import { LAYER_TEXT } from "@/definitions/layer-types";
import ToolTypes, { MAX_BRUSH_SIZE, MIN_ZOOM, MAX_ZOOM, canDraw } from "@/definitions/tool-types";
import { DROPBOX_FILE_SELECTOR, SAVE_DROPBOX_DOCUMENT } from "@/definitions/modal-windows";
import {
ADD_LAYER, EXPORT_DOCUMENT, DROPBOX_FILE_SELECTOR, SAVE_DROPBOX_DOCUMENT
} from "@/definitions/modal-windows";
import { getCanvasInstance, getSpriteForLayer } from "@/factories/sprite-factory";
let state, getters, commit, dispatch, listener,
@@ -208,7 +209,9 @@ function handleKeyDown( event ) {
break;
case 69: // E
if ( canDraw( getters.activeDocument, getters.activeLayer )) {
if ( hasOption ) {
openModal( EXPORT_DOCUMENT );
} else if ( canDraw( getters.activeDocument, getters.activeLayer )) {
setActiveTool( ToolTypes.ERASER );
}
break;
@@ -220,14 +223,16 @@ function handleKeyDown( event ) {
break;
case 73: // I
if ( getters.activeLayer ) {
if ( hasOption ) {
dispatch( "loadDocument" );
} else if ( getters.activeLayer ) {
setActiveTool( ToolTypes.EYEDROPPER );
}
break;
case 76: // L
if ( hasOption && shiftDown ) {
commit( "openModal", ADD_LAYER );
openModal( ADD_LAYER );
} else {
commit( "setActiveTool", { tool: ToolTypes.LASSO })
setActiveTool( ToolTypes.LASSO );
@@ -251,7 +256,7 @@ function handleKeyDown( event ) {
case 79: // O
if ( hasOption ) {
if ( state.dropboxConnected ) {
commit( "openModal", DROPBOX_FILE_SELECTOR );
openModal( DROPBOX_FILE_SELECTOR );
}
preventDefault( event );
}
@@ -264,7 +269,7 @@ function handleKeyDown( event ) {
case 83: // S
if ( hasOption ) {
if ( getters.activeDocument && state.dropboxConnected ) {
commit( "openModal", SAVE_DROPBOX_DOCUMENT );
openModal( SAVE_DROPBOX_DOCUMENT );
}
preventDefault( event ); // page save
}
@@ -388,3 +393,7 @@ function preventDefault( event ) {
function setActiveTool( tool ) {
commit( "setActiveTool", { tool, activeLayer: getters.activeLayer });
}
function openModal( modal ) {
commit( "openModal", modal );
}