![rjdm](docs/img/rjdm-logo.png?sanitize=true)

# Camedit

A basic vanilla Javascript image editor. It is a wrapper around the [cropperjs](https://github.com/fengyuanchen/cropperjs) library of  [fengyuanchen](https://github.com/fengyuanchen). This project was initiated by [R.J. Design Management](https://www.rjdesignmanagement.ch) and developed by [Christopher Christensen](https://github.com/christopherchristensen).

![editor-showcase-2](docs/img/editor-showcase-6.png?sanitize=true)

## Releases

* camedit@1.2.0: better browser support
* camedit@1.1.0: different output formats
* camedit@1.0.2: first official release

## Getting started

### Installation

#### `npm`

You can install the editor via `npm` :

```bash
npm install camedit
```



Then you can import the editor with one of the following statements:

```javascript
// Commonjs import
import Camedit from 'camedit';

// or Nodejs require
const Camedit = require('camedit');
```



#### `html` reference

You can also download the minified distribution file from the [downloads](www.camedit.rjdesignmanagement.ch/downloads) page and reference it in your `html` like this:

```html
<script type="application/javascript" src="./camedit.min.js"></script>
```

Or you can reference it via **CDN** like this:

```html
<script type="application/javascript" src="https://unpkg.com/camedit@1.0.0"></script>
```

#### `css`

If you want to use the default **CSS** styling of the editor you can easily download the minified ` camedit.min.css` file from the [downloads](www.rjdesignmanagement.ch/websites/camedit) page or from the `./src/dist` directory.

```html
<link rel="stylesheet" href="./camedit.min.css">
```



### Usage

Make sure you add this `div` container in your `html` with a unique selector. 

```html
<div id="my-editor" class="camedit"></div>
```



#### Basic example
```javascript
let editor = new Camedit('#my-editor'); // or .camedit
let image  = document.getElementById('my-image');

editor.launch(image);
```

The default output when saving is a `png` as `dataurl` (base64). You can overrule the default output format like this:

```javascript
editor.setOptions({
    saveFormat: 'png' 		// ('png' or 'jpg'),
    saveType: 'dataurl' 	// ('blob', 'binary' or 'dataurl')
});

editor.launch(image);
```



#### Basic example (with overrule)

When opening the editor it stores the original image source in the dataset of the image element. Once the original image source is stored it will not change for that specific image object, no matter how many times the editor is opened with that image. If you change the source of the image it will still keep the old original image source. In this case you can overrule the default settings when you open the image, so that it uses the new image as its original image source.
Just do this:

```javascript
editor.launch(image, true);
```

You can also store the new image source as original image source like this:

```javascript
editor.storeOriginalImageSource(true);
```



## Advanced Features

In this section you will find additional features for customizing the editor to your needs.



### Open and close the editor

Once you have launched the editor you can either `show ` , `close` or `hide` the editor like this:

```javascript
editor.show();		// without loading GIF
editor.show(true);  // with loading GIF

editor.close(); 	// void
editor.hide();  	// returns boolean
```

> Both closing methods do the same thing, except that the `close` method also hides the loading GIF. 



This **only works** if you use the default css (see the Installation section for more) or if you do this in your css:

```css
.camedit {
    display: none;
}

.camedit.active {
    display: block;
}
```



### Show and hide loading

If you want to use the default loading GIF, you can do this:

```javascript
editor.showLoading();
editor.hideLoading();
```



### Custom events

#### `onAfterSave(callback)`

You can set a callback to execute everytime the editor saves an image:

```javascript
editor.onAfterSave(() => {
    
    /* Do something after saving the image */
    
});
```



#### Override default events

If you are feeling fancy or just need to, you can override the default actions that take place on clicking the editor buttons (close, reset, save). To do this you have to set the `defaultSettings` parameter to `false` when initiating a new Camit object:

```javascript
let customEditor = new Camedit('#my-editor', false);
```

After that you can set your own events like this:



##### `onCloseButtonEvent(eventType, callback)`

```javascript
customEditor.onCloseButtonEvent('click', event => {
    
    /* Do custom things here */
    
    customEditor.close();
    
});

customEditor.on
```

##### `onResetButtonEvent(eventType, callback)`

```javascript
customEditor.onResetButtonEvent('click', event => {
    
    /* Do custom things here */
    
    customEditor.reset();
    
});
```

##### `onSaveButtonEvent(eventType, callback)`

```javascript
customEditor.onSaveButtonEvent('click', event => {
    
    /* Do custom things here */
    
    customEditor.save();
    
});
```



### `data` 

You can get relevant data from the editor through its `data` object. This can be useful to directly access the current values of the editor's sliders, for instance like this:

```js
let brightness = editor.data.input.brightness;
```

* data.input.brightness
* data.input.contrast
* data.input.saturation
* data.input.rotation
* data.input.width
* data.input.height
* data.input.top
* data.input.left



You can also get the stored values of the source image from previous edits like this:

```javascript
let sourceBrightness = editor.data.dataset.brightness
```

* data.input.brightness
* data.input.contrast
* data.input.saturation



### `elements`

You can access all relevant elements of the editor via its `elements` object:

```javascript
let closeButton = editor.elements.closeButton;
```

* elements.closeButton
* elements.contrastInput
* elements.cropperContainer
* elements.cropperViewBox
* elements.cropperBackgroundImage
* elements.cropperBoxImage
* elements.tempHiddenImage
* elements.editor
* elements.sourceImage
* elements.imageView
* elements.loadingGIF
* elements.resetButton
* elements.rotationButtons
* elements.saturationInput
* elements.saveButton


## Next Release (1.1.0)

* Image validation before passing image to Cropper 
    * Check file type .png, .jpeg, etc.
    * Test different image scenarios (e.g. transparent images)
* Click on gray area closes editor
* Option to set return format
* Update Documentation



## Future Ideas

> All ideas written in this section are **not available yet**!

* Add fadeIn: `editor.show(200);`
* Add fadeOut: `editor.hide(500);`
* Click on gray area closes editor (with Modal: are you sure?)
* `Esc` Button also closes editor (with Modal)
* Custom options such as
    * Max image size
    * Cropper options
    * Overrule
    * etc.
    * crop only in image (had to change, because rotation done with cropperjs and not caman => massive performance gain)
    * say restrict to container size (aspect ratio) -> relaunch
    * restrict to image -> relaunch twice with 
    * fallbacks for missing data
    * History (step back and forwards)
    * Scale (flip image)
* Split up Editor in to more meaningful components