Code Monkey home page Code Monkey logo

vue-croppa's Introduction

vue-croppa

A simple straightforward customizable mobile-friendly image cropper for Vue 2.0.

try it out

Features

  • Straightforward: What you see is what you get
  • Highly customizable: You can almost customize anything except the core functionalities
  • Mobile-friendly: Supports drag to move and pinch with two fingers to zoom on mobile devices
  • EXIF orientation: v0.2.0+ Support correctly show image with EXIF orientation

Browser Support

  • IE 10+
  • Firefox 3.6+
  • Chrome 6+
  • Safari 6+
  • Opera 11.5+
  • iOS Safari 6.1+
  • Android Browser 3+

Template Example

<croppa v-model="myCroppa"
        :width="400"
        :height="400"
        :canvas-color="'default'"
        :placeholder="'Choose an image'"
        :placeholder-font-size="0"
        :placeholder-color="'default'"
        :accept="'image/*'"
        :file-size-limit="0"
        :quality="2"
        :zoom-speed="3"
        :disabled="false"
        :disable-drag-and-drop="false"
        :disable-click-to-choose="false"
        :disable-drag-to-move="false"
        :disable-scroll-to-zoom="false"
        :disable-rotation="false"
        :prevent-white-space="false"
        :reverse-scroll-to-zoom="false"
        :show-remove-button="true"
        :remove-button-color="'red'"
        :remove-button-size="0"
        :initial-image="'path/to/initial-image.png'"
        @init="handleCroppaInit"
        @file-choose="handleCroppaFileChoose"
        @file-size-exceed="handleCroppaFileSizeExceed"
        @file-type-mismatch="handleCroppaFileTypeMismatch"
        @new-image-drawn="handleNewImage"
        @image-remove="handleImageRemove"
        @move="handleCroppaMove"
        @zoom="handleCroppaZoom"></croppa>

NOTE: This is an almost-full-use example. Usually you don't need to specify so many props, because they all have default values. Most simply, you can even do:

<croppa v-model="myCroppa"></croppa>

Method Examples

this.myCroppa.remove();

this.myCroppa.zoomIn();

alert(this.myCroppa.generateDataUrl());

Quick Start

1. Import vue-croppa into your vue.js project.

Using build tools:

npm install --save vue-croppa
import Vue from 'vue';
import Croppa from 'vue-croppa';

Vue.use(Croppa);
// If your build tool supports css module
import 'vue-croppa/dist/vue-croppa.css';

Not using build tools:

<link href="https://unpkg.com/vue-croppa/dist/vue-croppa.min.css" rel="stylesheet" type="text/css">
<script src="https://unpkg.com/vue-croppa/dist/vue-croppa.min.js"></script>
Vue.use(Croppa);

2. Now you have it. The simplest usage:

<croppa v-model="myCroppa"></croppa>
new Vue({
  // ... other vm options omitted
  data: {
    myCroppa: {}
  },

  methods: {
    uploadCroppedImage() {
      this.myCroppa.generateBlob(
        blob => {
          // write code to upload the cropped image file (a file is a blob)
        },
        'image/jpeg',
        0.8
      ); // 80% compressed jpeg file
    }
  }
});

Live example: https://jsfiddle.net/jdcvpvty/2/

NOTE:

  • Since v0.1.0, you can change the default component name to anything you want.
import Vue from 'vue';
import Croppa from 'vue-croppa';

Vue.use(Croppa, { componentName: 'my-image-cropper' });
<my-image-cropper v-model="myCroppa"></my-image-cropper>
  • Since v0.1.1, you can get the component object with Croppa.component. This is useful when you want to register the component by yourself manually.
Vue.component('croppa', Croppa.component);
// Register async component (Webpack 2 + ES2015 Example). More about async component: https://vuejs.org/v2/guide/components.html#Async-Components
Vue.component('croppa', () => import(Croppa.component));
  • Since v1.0.0, the v-modeled value and the ref both point to the same thing - the component itself. So you don't need to set v-model anymore if you have a ref on the component.
<croppa ref="myCroppa"></croppa>
this.$refs.myCroppa.chooseFile();
this.$refs.myCroppa.generateDataUrl();
// ...

Documentation

🌱 Props

v-model

A two-way binding prop. It syncs an object from within the croppa component with a data in parent. We can use this object to call useful methods (Check out "Methods" section). Since v1.0.0, you don't need this anymore, the ref on component can also be used to call methods.

width

Display width of the preview container.

  • type: number
  • default: 200
  • valid: val > 0

height

Display height of the preview container.

  • type: number
  • default: 200
  • valid: val > 0

placeholder

Placeholder text of the preview container. It shows up when there is no image.

  • type: string
  • default: 'Choose an image'

placeholder-color

Placeholder text color.

  • type: same as what CanvasRenderingContext2D.fillStyle accepts.
  • default: '#606060'

placeholder-font-size

Placeholder text font size in pixel. When set to 0, the font size will be ajust automatically so that the whole placehoder only takes up 2/3 of the container's width.

  • type: number
  • default: 0

canvas-color

Initial background color and white space color if there is an image.

  • type: same as what CanvasRenderingContext2D.fillStyle accepts.
  • default: before v0.2.0 - '#e6e6e6'; after v0.2.0 - 'transparent'

quality

Specifies how many times larger the actual image is than the container's display size.

  • type: number
  • default: 2
  • valid: val > 0

zoom-speed

Specifies how fast the zoom is reacting to scroll gestures. Default to level 3.

  • type: number
  • default: 3
  • valid: val > 0

accept

Limits the types of files that users can choose.

  • type: same as what accept attribute of HTML input element takes.
  • default: no default value since v1.0.0. Specify it as you need.

file-size-limit

Limits the byte size of file that users can choose. If set to 0, then no limit.

  • type: number
  • default: 0

disabled

Disables user interaction.

  • type: boolean
  • default: false

disable-drag-and-drop

Disables the default "drag and drop a file" user interaction. You can instead �trigger the file chooser window programmatically by "click to choose" functionality or invoking chooseFile() method.

  • type: boolean
  • default: false

disable-click-to-choose

Disables the default "click to choose a file" ("tab" on mobile) user interaction. You can instead �trigger the file chooser window programmatically by "drag and drop" functionality or invoking chooseFile() method.

  • type: boolean
  • default: false

disable-drag-to-move

Disables the default "drag to move" user interaction. You can instead move the image programmatically by invoking moveUpwards() / moveDownwards() / moveLeftwards() / moveRightwards() methods.

  • type: boolean
  • default: false

disable-scroll-to-zoom

Disables the default "scroll to zoom" user interaction. You can instead zoom the image programmatically by invoking zoomIn() / zoomOut() methods.

  • type: boolean
  • default: false

disable-pinch-to-zoom

Disables the default "pinch with two fingers to zoom" user interaction on mobile. You can instead zoom the image programmatically by invoking zoomIn() / zoomOut() methods.

  • type: boolean
  • default: false

disable-rotation

(v0.2.0+) Rotation methods won't work if this is set to true

  • type: boolean
  • default: false

reverse-zooming-gesture

Deprecated Please use reverse-scroll-to-zoom� instead.

Reverses the zoom-in/zoom-out direction when scrolling.

  • type: boolean
  • default: false

reverse-scroll-to-zoom

Reverses the zoom-in/zoom-out direction when scrolling.

  • type: boolean
  • default: false

prevent-white-space

Prevents revealing background white space when moving or zooming the image.

  • type: boolean
  • default: false

show-remove-button

Specifies whether to show the built-in remove-button. You can change the button's color and size using the following two props. If you still find it ugly, hide it and use the remove() method to implement your own trigger.

  • type: boolean
  • default: true

remove-button-color

Changes the default color of the remove-button. Accepts any css color format.

  • type: string
  • default: 'red'

remove-button-size

Specifies the remove-button's width and height (they are equal). If set to 0, then it use the default size.

  • type: number
  • default: default size is ajust accordingly to container's size

initial-image

(v0.1.0+) Set initial image. You can pass a string as the url or an Image object (HTMLImageElement instance). This is an alternative way to set initial image besides using slot. Useful when you want to set cross origin image as initial image.

  • type: string or object (HTMLImageElement instance)
  • default: undefined

initial-size

(v0.2.0+) works similar to css's background-size. It specifies the image's size when it is first loaded on croppa. contain and natural won't work if prevent-white-space is set to true.

  • type: string
  • default: 'cover'
  • valid: one of 'cover', 'contain', 'natural'

initial-position

(v0.2.0+) works similar to css's background-position. It specifies the image's position relative to croppa container when it is first loaded.

  • type: string
  • default: 'center'
  • valid:
    • 'center' (default value)
    • 'top'
    • 'bottom'
    • 'left'
    • 'right'
    • composition of the above words ('top left', 'right top' etc.)
    • '30% 40%' (similar to background-position in css)

input-attrs

(v1.0.0+) to pass attributes to the hidden input[type=file] element.

<croppa :input-attrs="{capture: true, class: 'file-input'}"></croppa>

show-loading

(v1.1.0+) show default loading spinner at the bottom right corner of the container when image is loading (will but not yet be drawn on canvas).

  • type: boolean
  • default: false

loading-size

(v1.1.0+) loading spinner's size in px.

  • type: number
  • default: 20

loading-color

(v1.1.0+) loading spinner's color in css color value formats.

  • type: string
  • default: '#606060'

replace-drop

(v1.1.4+) Replace current image on drag and drop.

  • type: boolean
  • default: false (By default you need to remove the current image to drop a new one)

passive

(1.2.0) Switch to passive mode. Croppa in passive mode will sync state with another croppa if they v-model the same object. Also it will not have self-control - user can't manipulate image on passive croppa. This is useful as a preview component.

These states will be synced:

[
  'imgData',
  'img',
  'imgSet',
  'originalImage',
  'naturalHeight',
  'naturalWidth',
  'orientation',
  'scaleRatio'
];
  • type: boolean
  • default: false
  • Demo

image-border-radius

(1.2.0) Set rounded corders to image. Note that this has effect on the output image. Note that it only works when prevent-white-space is true. (Demo)

  • type: number or string
  • default: 0\

auto-sizing

(1.3.0) If it is set to true, width and height will not work. Instead, croppa will adjust itself to it's container(.croppa-container)'s size. It's useful to make croppa's dimension responsive.

  • type: boolean
  • default: false
  • Demo

video-enabled

(1.3.1) If it is set to true, you can choose a video file. If the video is supported by the browser, the first frame will be drawn on the canvas. You can play/pause the video by dbclick croppa. This feature is not fully developed yet, but you can still play around with it.

  • type: boolean
  • default: false

🌱 Slots

initial

  • You can provide an initial image by putting an <img> node as a named slot initial. For example:
<croppa v-model="myCroppa">
  <img slot="initial" :src="initialImageUrl" />
</croppa>
NOTE:
  • You need to explicitly call .refresh() method after changing inital image.
  • If you provide both the slot and initial-image prop, the slot will be the one that is used.

placeholder

  • If you are not satified with the simple text placeholder. Since v0.3.0, you can apply an <img> slot named placeholder to get an image placeholder! The image will be draw on croppa under the placeholder text.
<croppa v-model="myCroppa">
  <img slot="placeholder" src="static/placeholder-image.png" />
</croppa>
NOTE:
  • It is recommended to use a small-sized image as the placeholder image.
  • The image will be drawn with 100% width and height of croppa container, i.e. it will cover the container. So it is recommended to use a images with the same aspect ratio as the container.
  • Find demo "Image Placeholder" in the demo page

default

  • (v1.1.0+) Default slots (unnamed) will be appended to the container element after the built-in elements.
  • Usually you need to set position: absolute on these slots or it will expand the container.

🌱 Methods

getCanvas()

  • returns the canvas object

getContext()

  • returns the canvas context object

getChosenFile()

getActualImageSize()

  • Return an object { width, height } describing the real image size (preview size * quality)
  • Deprecated Use this.myCroppa.outputWidth and this.myCroppa.outputHeight instead.

moveUpwards( amountInPx: number )

moveDownwards( amountInPx: number )

moveLeftwards( amountInPx: number )

moveRightwards( amountInPx: number )

move({x, y})

  • (v1.0.0+) for more flexibility.

zoomIn()

zoomOut()

zoom(in, timesQuicken)

  • (v1.0.0+) for more flexibility.

rotate(step: number)

  • 1 step = 90 deg
  • positive number: rotates clockwise
  • negative number: rotates counterclockwise.

flipX()

  • Horizontally flip image.

flipY()

  • Vertically flip image.

chooseFile()

  • Opens the file chooser window to Choose an image. Useful when default click-to-choose interaction is disabled.

myCroppa.reset()

  • Deprecated Please use remove() instead.

remove()

  • Removes the current image, can be used to implement your own remove-button.

refresh()

  • Reinitialize the component. Useful when you want to change initial image.

hasImage()

  • Return boolean value indicating whether currently there is a image.

generateDataUrl( type: string, compressionRate: number )

  • Returns a data-URL containing a representation of the image in the format specified by the type parameter (defaults to png).
  • compressionRate (v0.2.0+) defaults to 1, you can pass a number between 0 and 1 to get a compressed output image.

generateBlob( callback: function, mimeType: string, compressionRate: number )

  • Creates a Blob object representing the image contained in the canvas. Look up argument definition here.
  • If there is no image, the first argument of callback function is null.

promisedBlob( mimeType: string, compressionRate: number )

  • This method returns a Promise wrapping around generateBlob(), so that you can use async/await syntax instead of a callback to get blob data, it's simpler.
const blob = await this.myCroppa.promisedBlob()
  • If there is no image, it will resolve null.

getMetadata()

  • Require v0.3.0+
  • Get metadata that describes current user manipulations (moving, zooming, rotating).
var metadata = this.myCroppa.getMetadata();
console.log(metadata);

/* in console
{
  startX:-535.5180530546083,
  startY:-358.0699623303261,
  scale:2.2502626424905396,
  orientation:6
}
*/

applyMetadata(metadata)

  • Require v0.3.0+
  • Apply metadata to get to a certain manipulation state (moving, zooming, rotating).
  • metadata can have one or more of these 4 properties: startX, startY, scale, orientation. Usually you will use the object returned by getMetadata().
var metadata = {
  startX: -535.5180530546083,
  startY: -358.0699623303261,
  scale: 2.2502626424905396,
  orientation: 6
};

this.myCroppa.applyMetadata(metadata);

addClipPlugin(func)

  • Add clip plugin to clip the image. Example:
// Add a clip plugin to make a circle clip on image
onInit(vm) {
  this.croppa.addClipPlugin(function (ctx, x, y, w, h) {
    /*
     * ctx: canvas context
     * x: start point (top-left corner) x coordination
     * y: start point (top-left corner) y coordination
     * w: croppa width
     * h: croppa height
    */
    ctx.beginPath()
    ctx.arc(x + w / 2, y + h / 2, w / 2, 0, 2 * Math.PI, true)
    ctx.closePath()
  })
},
  • Note: in the plugin function you should always start with ctx.beginPath() and end with ctx.closePath().
  • Note: it only works when prevent-white-space is true.
  • Demo

supportDetection()

  • Return an object indicating browser supports. Like this:
{
  basic: true, // supports basic functionality
  dnd: false // does not support drag and drop
}

🌱 Events

init

  • handler(croppa)
    • croppa is the croppa component itself - same as what v-model and ref bind.

file-choose

  • emitted when user choose an image from the poppup window or "drag and drop" a file into the container.
  • handler(file)
    • file is a file object - same as what getChosenFile() returns.

file-size-exceed:

  • emitted when the chosen file's size exceeds the limit specified by prop fileSizeLimit.
  • handler(file)
    • file is a file object - same as what getChosenFile() returns.

file-type-mismatch:

  • emitted when the chosen file does not match the specified type, which btw is specified using prop accept.
  • handler(file)
    • file is a file object - same as what getChosenFile() returns.

new-image

  • emitted when a new valid image is received and read successfully(v0.2.0).

new-image-drawn

  • (v1.0.0+) emitted when a new image is drawn on canvas for the first time.

image-remove

  • emitted when image remove from croppa.

move

zoom

draw

  • emitted on every view update (including init, move, zoom, rotate) when it is not empty. It is useful when you want to add attachment on image.
  • handler(ctx)
    • ctx is the CanvasRenderingContext2D object for you to draw anything you want on the current image. You can also get it with the method getContext().
  • Find demo "Attachments" in the demo page.

initial-image-loaded

  • (v0.3.2+) emitted when initial image loaded. It can be useful when you provide initial image with the initial-image prop.

loading-start

  • (v1.1.0+) emitted when image loading phase starts.

loading-end

  • (v1.1.0+) emitted when image loading phase ends.

🌱 State data

Since v1.0.0, you can access all state data of croppa via the instance. For example,

this.myCroppa.naturalWidth;
this.myCroppa.imgData.startX;
this.myCroppa.scaleRatio;
this.myCroppa.pinching;
//...

All data available:

Sorry I'm too lazy to doc about each of them. Please open the vue-devtool to figure out what they mean by yourself.

You can also open an issue to ask me any question about this component.

Note that "computed" and "props" are read-only. Some value on "data" are also not recommended to modify from outside, for example ctx, canvas, img.

  • v1.1.0: loading indicates whether an image is loading (will but not yet be drawn on canvas).

🌱 Customize styles

  • Check out default css styles. You can add more css styles to those selectors to get a different look. Be careful if you try to overwrite existing styles.
  • Note that CSS styles will not have any effect on the output image.

Development

1. Fork and clone the repo.

2. Install dependencies.

$ cd vue-croppa
$ npm install
$ cd docs
$ npm install

3. Start developing.

# under vue-croppa/
$ npm run dev
# under vue-croppa/docs/
$ npm run dev

Edit file ./docs/simple-test.html and open http://localhost:3000/simple-test.html to test while developing.

4. Build

# under vue-croppa/
$ npm run build

To Do

  • Native support for grid #115
  • Auto crop the output image #118
  • Customizable-size preview #68
  • Automatically keeps the output size when container resized due to auto-size=true #122
  • Snapshot the current state and restore. #112
  • Add unit test.
  • Big image rotation optimizations (blob url?).

vue-croppa's People

Contributors

alex-oleksenko avatar chrisnetonline avatar gabrielsosa-stensul avatar injitools avatar zhanziyang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-croppa's Issues

Laravel save image

var app = new Vue({
el: '#app',
data: {
croppa: {}
},
methods: {
upload() {
if (!this.croppa.hasImage()) {
alert('no image to upload')
return
}
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
this.croppa.generateBlob((blob) => {
var fd = new FormData()
fd.append('file', blob)
$.ajax({
url: '/test',
data: fd,
type: 'POST',
processData: false,
contentType: false,
success: function(data) {
console.log(data)
}
})
});
}
}
});

I have method:

public function postImage(Request $request) {
$data = Input::get('file');
$base64_str = substr($data, strpos($data, ",")+1);
$image = base64_decode($base64_str);
$imagename = uniqid('przyrzad_').'.jpg';
file_put_contents(storage_path().'/app/public/'.$imagename, $image);
}

Why save me emty file with correct imagename?

Cross Origin Error

trying to access to a image in a different server gets

Access to Image at from origin 'http://localhost:4500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4500' is therefore not allowed access.

PNG files lose transparency

I noticed that if you use vue-croppa on a PNG file with transparency, that you lose the transparency and the background is the same grey used for the background of the vue-croppa control. If the canvas color is being set to the grey color, could this become the background color for the image.

Calling refresh() doesn't reset zoom

When changing the initial image to another and calling refresh() doesn't reset the zoom level. I have to manually zoom out to have the full sized image (according to prevent-white-space).

Anyways, keep this awesome work up!

Placeholder image taints the canvas [CORS]

Is there a way to load a placeholder image from another origin without being blocked by the security browser policy.
Indeed, it blocks the usage of exporting canvas method like toBlob() by tainting the canvas.

:initial-image is not the expected behavior here as it really loads the image and isn't the best thing for user experience.

I guess it's a request enhancement?

Thanks!

Persisting blob in store

@zhanziyang I'm using a vuex plugin that persists the session state, but the blob output doesn't persist after page refresh. It becomes an empty object. (it's the only one with this behavior). Do you know why?

huge file size

Hello, i really love your module but i was wondering if you can explain to me the quality setting.

On 2 processing is quite long and gives a huge file size, above 3 and 4 it calculates for an insane amount of time and produces a file size that is enormous.

When i upload a 53k image i get back a 1 meg image no setting 2 and 8 megs on setting 5.

What am i doing wrong please?

Clarification on getMetadata()

Was wondering if you could clarify what, exactly, the individual metadata components mean. I'm assuming the following.

  • startX: The first/left x-coordinate of where your crop begins, multiplied by scale.
  • startY: The first/top y-coordinate of where your crop begins, multiplied by scale.
  • scale: The "zoom factor", or "multiplier", revealing how far you've zoomed in from your initial-image.
  • orientation: The rotation of the image? Not sure on this, as it isn't applicable for my project.
    I'm mostly curious about the scale functionality. My Croppa uses prevent-white-space so, as I understand it, scale should never be lower than 1, as you can't zoom out beyond the original/filled ratio.

I must be confused on how scale works...could you shed some light on that, and maybe explain the other components too? Trying to utilize these pieces to apply transformations with Intervention's Image on the back-end. Thanks!

License clarification

Hi, could you clarify the license of Vue-Croppa, please?
Maybe add a LICENSE.md file in the repo?

Async loading

Really great component, thanks. But here is not possible to load component asynchronously.

Vue.component('croppa ', resolve => {
    require.ensure([], function() {
        require('vue-croppa/dist/vue-croppa.css');
        resolve(require('vue-croppa'));
    });
}); 

I need a construction like that. But Vue.component already in it. Can you provide some methods to get exactly component? Like require('vue-croppa').component. Because here is nothing extraordinary in install script. Looking forward. Thanks

Using promisedBlob and reading a blob string

@zhanziyang I'm having trouble with the big base64 strings. It's slowing my entire website after sending the data to vuex store, so I think blob is a better solution for me. Can you write an example using promisedBlob, showing how to read the blob string generated, in a <img> tag? It would be interesting to put in the docs.

HTMLImageElement is not defined

Using the very basic

import Vue from 'vue';
import Croppa from 'vue-croppa';
Vue.use(Croppa);

I'm seeing the following stack trace upon booting the app. Is HTMLImageElement a native object type of Vue or is that something in your library specifically. I can't find much on it and it looks like the only place you use it is the initial-image option. Seems like a great library, would love to get this working.

Call Stack: ReferenceError: HTMLImageElement is not defined
    at .../node_modules/vue-croppa/dist/vue-croppa.js:389:26
    at commonjsGlobal (.../node_modules/vue-croppa/dist/vue-croppa.js:10:82)
    at Object. (.../node_modules/vue-croppa/dist/vue-croppa.js:13:2)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions.(anonymous function) [as .js] (.../node_modules/node-hook/index.js:73:14)
    at Module.load (module.js:545:32)

Changing color

Is that possible to do not delete image when you changing background color? Would be great to have this option. Or for this better to work directly with canvas?

How to resolve initial image via Webpack

I am using vue-croppa in Nuxt.js project which runs webpack to resolve images.

I am trying to setup initial image but it doesn't work for me. I tried:

<croppa initial-image="~/assets/img/profiles/1.png"></croppa>
<croppa initial-image="@/assets/img/profiles/1.png"></croppa>
<croppa initial-image="./assets/img/profiles/1.png"></croppa>
<croppa :initial-image="'./assets/img/profiles/1.png'"></croppa>

Any help is appreciated. Thanks.

Method _init conflicts with an existing Vue instance method

I used croppa in component

	import Croppa from 'vue-croppa';
	import 'vue-croppa/dist/vue-croppa.css';

	export default {
		components: {
			croppa: Croppa.component
		},

There is a warning.

[Vue warn]: Method "_init" conflicts with an existing Vue instance method.

Enhancement - need $emit when user closes image

If you want to keep a "dirty" flag, which gets set to true when the User does a Zoom or Move this is easily accomplished. But, if the User closes the image with (X) then there is no signal emitted to know the image is gone.

New $emit for 'new-image-loaded'

Is it possible to get a new $emit for when a new image is loaded onto the canvas?

The issue i am having is the 'new-image' event gets fired before the file is read so i am unable to get the blob of the image on a new image load manually as i wish to save the image in its original input state on adding to the canvas.

Manipulating stickers

Hi could anyone give me some help regarding to stickers.
I have a logo that can be aligned to the right or left corner with a select input. But when a try to 'remove' the sticker with clearRect the area becomes gray and I don't know how to make it transparent.

I have this code inside onDraw event:

ctx.drawImage(
  document.querySelector(`.${sticker.class}`),
  left * this.quality,
  top * this.quality,
  sticker.width * this.quality,
  sticker.height * this.quality
 );

Thank you

Multiple instances

I was wondering how would you handle multiple croppa instances.
My case: I have 3-4 croppa instances each nested in a tab component, when in the final step, I would like to crop & upload all images from the single tabs.

btw.. I love croppa!! :-)

Use range slider input to set zoom

First of all, thank you for this plugin! It's a great solution our needs. Your hard work is appreciated.

I'm trying to figure out if there's a way to use a range slider input for setting the zoom/scaleRatio .

It would have to bind to the scaleRatio property, but not sure if croppa supports this right now, or if there's possibly a hacky way to do it via the zoomIn() & zoomOut() methods.

NPM Installation Error

When trying to install w/ NPM, getting a "Cannot read property '0' of undefined" error. Here's the log:

999 info lifecycle undefined~uninstall: undefined 1000 verbose unlock done using ....\_locks\staging-29c759a10f8835f9.lock for D:\xampp\htdocs\one\node_modules\.staging 1001 verbose stack TypeError: Cannot read property '0' of undefined 1001 verbose stack at rmStuff (....\npm\lib\unbuild.js:61:24) 1001 verbose stack at tryCatcher (....\npm\node_modules\bluebird\js\release\util.js:16:23) 1001 verbose stack at ret (eval at makeNodePromisifiedEval (....\npm\node_modules\bluebird\js\release\promisify.js:184:12), <anonymous>:13:39) 1001 verbose stack at lifecycle.then.then (....\npm\lib\install\action\unbuild.js:12:12) 1001 verbose stack at tryCatcher (....\npm\node_modules\bluebird\js\release\util.js:16:23) 1001 verbose stack at Promise._settlePromiseFromHandler (....\npm\node_modules\bluebird\js\release\promise.js:512:31) 1001 verbose stack at Promise._settlePromise (....\npm\node_modules\bluebird\js\release\promise.js:569:18) 1001 verbose stack at Promise._settlePromise0 (....\npm\node_modules\bluebird\js\release\promise.js:614:10) 1001 verbose stack at Promise._settlePromises (....\npm\node_modules\bluebird\js\release\promise.js:693:18) 1001 verbose stack at Async._drainQueue (....\npm\node_modules\bluebird\js\release\async.js:133:16) 1001 verbose stack at Async._drainQueues (....\npm\node_modules\bluebird\js\release\async.js:143:10) 1001 verbose stack at Immediate.Async.drainQueues (....\npm\node_modules\bluebird\js\release\async.js:17:14) 1001 verbose stack at runCallback (timers.js:651:20) 1001 verbose stack at tryOnImmediate (timers.js:624:5) 1001 verbose stack at processImmediate [as _immediateCallback] (timers.js:596:5)

dynamic dimensions

any recommendation on how to go regarding dynamic sizes?
Current case:
I have croppa inside a for loop, images (remotely hosted) that are placed as initial-image can be of various dimensions.
<v-flex v-for="(item, key, index) in item.imgfields" :key="key"> <croppa v-model="croppa[key]" :width=this.imgSize.w :height=this.imgSize.h :quality="2" :file-size-limit="5502400" :prevent-white-space="true" accept="image/*" @file-type-mismatch="onFileTypeMismatch" @file-size-exceed="onFileSizeExceed" placeholder="Drag & Drop Image here" :placeholder-font-size="14" :initial-image="item.image" ></croppa> </v-flex>

So I wrote a small method that loads the image and returns the dimensions:

getMeta(url){ var that = this; var img = new Image(); img.addEventListener("load", function(){ that.imgSize.w = this.naturalWidth; that.imgSize.h = this.naturalHeight; }); img.src = url; }

Now how can I apply the imgSize to the alredy created / rendered croppa instance?

Many thanks for your input.

Ability to manually get and set the X/Y position and zoom of initial image

I would like the ability to get the X/Y position and zoom that resulted in the cropped image when saving to the server so that if the user wants to edit the image again I can preload the original image (which I save) as the initial image with those same values so they can pan and zoom again without having to upload the original again.

File Input

I'm trying to get the image that I edited with vue-croppa. I can get Base64 but can't set it to "<input type='file'" input so that I can get it at backend which is Laravel.

I can successfully get dataUrl yet I couldn't find a way to get the edited image as a file input. Is there a way to do it with Vue-Croppa?

promisedBlob compression seems not working properly

@zhanziyang this code:
async imageConfirmed () { const blob = await myCroppa.promisedBlob('image/jpeg', 0.01) }
is returning a not compressed .png image.

But this is working as expected:
async imageConfirmed () { const blob = await myCroppa.promisedBlob('image/jpeg') }

It's a bug?

Unauthentified image request on Safari, iOS and PC

When the initial image is loaded, the request to get its content does not contain the authentication information that my server needs. It may be due to the way the img element is created.

A simple solution may be to have the img element in the Vue template.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.