jofftiquez / vue-croppie

Vue wrapper for croppie
https://jofftiquez.github.io/vue-croppie/
MIT License
260 stars 42 forks source link

How to pass a picture and options #4

Closed nicolasvahidzein closed 7 years ago

nicolasvahidzein commented 7 years ago

Hello there, i was wondering if you could help me, how can i pass on a file from an input button instead of from an url.

Also, how can i define the final size and other options?

Thank you very much.

nicolasvahidzein commented 7 years ago

hello again, i was able to find out how to pass the options so no worries about that, but i cannot set the result object to get a proper return of the promise, can you please help me. I tried it many different ways but i know my syntax is wrong. Im not great with es2016 yet.

                       this.$refs.croppieRef.result({
                type: 'base64', //base64, html, blob, rawcanvas
                size: 'viewport', //original , viewport, {width, height}
                format: 'jpeg', //jpeg, png, webp
                quality: 1,
                circle: false
            }, (output) => {
                this.cropped = output
                console.log(output)
            }
        )
nicolasvahidzein commented 7 years ago

index.js?9251:101 Uncaught (in promise) TypeError: cb is not a function at croppie.result.then.output (eval at (app.js:6039), :103:25) at

nicolasvahidzein commented 7 years ago

Tried this way as well, no luck

                  this.$refs.croppieRef.result().then(response => {
            console.log('All is good!')

        }, error => {
            console.log(error)
            console.log('An error happened!')
        })
jofftiquez commented 7 years ago

Hello @nicolasvahidzein sorry for a bit late reply. Let me just look on the issue first.

nicolasvahidzein commented 7 years ago

ok. On the original module i see something close to what i want but i don't know how to do this in vue:

i found it here: https://foliotek.github.io/Croppie/

called: Upload Example (with exif orientation compatability)

$uploadCrop = $('#upload-demo').croppie({ enableExif: true, viewport: { width: 200, height: 200, type: 'circle' }, boundary: { width: 300, height: 300 } });

jofftiquez commented 7 years ago

Hello @nicolasvahidzein based on the code you commented above you are doing this.$refs.croppieRef.result().then() but the result is a callback function not a promise. If you want to wait for the result asynchronously, you can use async await.

Can I see your whole code?

jofftiquez commented 7 years ago

Did you follow my example in the docu?

methods: {
      crop() {
            this.$refs.croppieRef.result((output) => {
                this.cropped = output;
            });
        },
}
nicolasvahidzein commented 7 years ago

I am just learning, so can you tell me how i would pass it the options to get a jpeg back?

Yes i used that example and it's fine but i want a jpeg back or should i just stay with your function and send a base64 to the server (laravel) to convert?

My code is 7000 lines, what part do you want to see?

jofftiquez commented 7 years ago

Just the component code of course. The one with vue-croppie implementation. For the meantime you can pass the enableExif option on the component like 👍

<vue-croppie :enableExif="true"></vue-croppie>
jofftiquez commented 7 years ago

@nicolasvahidzein for the meantime please the do the convertion of the image in your server Ill fix this right away to get a jpeg format. Im sorry for the inconvenience. Ill focus on this for now.

jofftiquez commented 7 years ago

@nicolasvahidzein this should be quick just hang in there for a minute.

jofftiquez commented 7 years ago

@nicolasvahidzein you can now pass result options like :

this.$refs.croppieRef.result({format: 'jpeg', circle:true}, result => {
      this.$emit('imageChanged', result)
      this.dialog = false;
})
nicolasvahidzein commented 7 years ago

Thank you so much Joff, do i need to update the pluggin?

Also does it emit when i upload an image?

Finally i really need to pass on an image via file upload. Is that possible like in the example from croppie?

jofftiquez commented 7 years ago

Yes you need to update the plugin, the version should be 1.2.1 :)

I did not use emit on this component, instead result(options, callback) has a callback function which contains the cropped images.

Yes you can do that. Though it is not native in this plugin. I can show you a snippet on how to do that.

nicolasvahidzein commented 7 years ago

Yes please!! Also i had another question. You use skype? Im looking for a freelancer? nzein19 is mine.

jofftiquez commented 7 years ago

Here's a snippet, it's not a working sample but you should get the idea on how to do it.

  1. Add an input with type of file
  2. Listen to the event change using @change="fileChange"
  3. Handle the file in the fileChange method. See below.
  4. There you should get the file result and then bind it to croppie or show it the image display.
<template>
    <div>
        <!-- Show the output -->
        <img :src="src">
        <!-- The input that will take the image -->
        <input ref=fileInputActivator type="file" @change="fileChange">
        <!-- The vue-croppie -->
        <vue-croppie ref=croppieRef :enableExif="true" :boundary="{width:cropperWidth, height:300}" :viewport="{width:250, height: 250, type: 'square'}"></vue-croppie>
    </div>
</template>

<script>

export default {
    props: {
        default: String,
        cropper: Boolean,
        cropperWidth: {
            type: Number,
            default: 700
        },
        src: String,
    },
    methods: {

        // This method will detect if the image from image input changed
        fileChange(file) {
            // To check if file is an image
            if (!file.target.files[0].name.match(/.(jpg|jpeg|png|gif)$/i)) {
                console.warn('not an image');
                file.target.value = null
                this.$emit('imageChanged', null)
                return;
            }
            var reader = new FileReader();
            reader.readAsDataURL(file.target.files[0]);
            reader.onload = () => {
                this.dialog = true;
                // bind the result of the file 
                // to croppie
                this.$refs.croppieRef.bind({
                    url: reader.result,
                });
                file.target.value = null
            };
            reader.onerror = (error) => {
                console.log('Error: ', error);
            };
        }
    }
}
</script>
jofftiquez commented 7 years ago

@nicolasvahidzein To answer you question, I was a freelancer but I got busy these past months. Am doing this stuff coz I like vuejs and I am experimenting on it. You can also check my other vue project, I have a filter collection for vuejs you might find it useful in your projects, here

But I am planning to get back to freelancing ones my projects are done. So let's keep in touch :) Also if you can give my repos a star I would be glad hehe.

nicolasvahidzein commented 7 years ago

Adding a star now and will review your comment and come back. Add me on skype now if you can that way it will be easier to keep in touch :)

jofftiquez commented 7 years ago

Great! Thanks. Just comment here if you have anymore questions :D

nicolasvahidzein commented 7 years ago

PS this version and last it's not loading the css directly inside the package, i had to do it in vue directly and uncomment the import in your index.js file. Then it works, here is the error in chrome:

./~/css-loader?{"modules":true,"localIdentName":"[name]__[local]___[hash:base64:5]"}!./~/vue-style-loader!./~/css-loader?{"minimize":false,"sourceMap":false}!./~/croppie/croppie.css Module build failed: Unknown word (5:1)

3 | // load the styles 4 | var content = require("!!../css-loader/index.js?{\"minimize\":false,\"sourceMap\":false}!./croppie.css");

5 | if(typeof content === 'string') content = [[module.id, content, '']]; | ^ 6 | if(content.locals) module.exports = content.locals; 7 | // add the styles to the DOM 8 | var update = require("!../vue-style-loader/lib/addStylesClient.js")("1f305612", content, false);

@ ./~/croppie/croppie.css 4:14-133 18:2-22:4 19:20-139 @ ./~/vue-croppie/index.js @ ./~/babel-loader/lib!./~/vue-loader/lib/selector.js?type=script&index=0!./src/pages/CreateIndividual.vue @ ./src/pages/CreateIndividual.vue @ ./src/router/routes.js @ ./src/main.js @ multi ./build/dev-client ./src/main.js

jofftiquez commented 7 years ago

I see. Thanks for noting this. I will create an issue regarding this one.

jofftiquez commented 7 years ago

@nicolasvahidzein that is because your css loader cant understand the css from croppie.css you just have to properly configure your css loader. Did you use vue cli? If so, what template did you use?

jofftiquez commented 7 years ago

@nicolasvahidzein Also if you get an error while building your project please refer here.

nicolasvahidzein commented 7 years ago

I did use vue-cli webpack standard (not simple), aside from that i'm not quite sure.

jofftiquez commented 7 years ago

Thanks for the info. @nicolasvahidzein

nicolasvahidzein commented 7 years ago

I see a this.dialog variable Joff, what is that? it's not referenced anywhere in your example.

Also when i upload many pictures one after an other, after the second one it stops cropping it properly. Is that a known bug?

jofftiquez commented 7 years ago

Hi @nicolasvahidzein That code is just a snippet I copied from one of my apps. I just want to show you how you could work around with input file. Nevermind the this.dialog.

Regarding the

Also when i upload many pictures one after an other, after the second one it stops cropping it properly. Is that a known bug?

It is a known behavior or <input type="file"> you need to clear the input before selecting a new image. You can use file.target.value = null to reset the input.

jofftiquez commented 7 years ago

Re: input problem.

Theses links might help you

https://stackoverflow.com/questions/19643265/second-use-of-input-file-doesnt-trigger-onchange-anymore

https://stackoverflow.com/questions/34531715/click-event-for-input-file-does-not-work-for-2nd-time