jofftiquez / vue-croppie

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

how to make multiple instance ? #69

Open spham opened 4 years ago

spham commented 4 years ago

i wish multiple instance (4) from croppies in same page. and wish upload all images loaded.

pintoflager commented 4 years ago

This is what I've come up with since yesterday, you need to modify and change vuetify components to what you use e.g. input, button.. Check out axios for example to upload. Or upload files with the form submit.

<template>
<layout>
    <template v-slot:content>
        <v-row cols="12" class="mt-4 mb-8">
            <template v-for="image in loaded">
                <v-col v-if="image.active" cols="12" sm="6" md="4" xl="3" align-self="center">
                    <vue-croppie
                        :key="image.index"
                        :ref="'croppie' + image.index"
                        :boundary="{ width: 300, height: 300}"
                        :viewport="{ width: 230, height: 230 , type: 'circle'}"
                        :enableResize="false"
                        :enableOrientation="true"
                    >
                    </vue-croppie>
                    <v-icon @click="rotate(image.index, 90)">{{ icon.rotate }}</v-icon>
                    <v-icon @click="remove(image.index)">{{ icon.remove }}</v-icon>

                </v-col>
            </template>
        </v-row>

        <v-row cols="12" align="center" justify="center" class="mt-3 mb-4">
            <v-col cols="12" sm="6">
                <v-file-input
                    multiple
                    accept="image/jpeg, image/png"
                    @change="manager"
                    color="primary"
                    label="File Upload"
                    v-model="files"
                    placeholder="Add files"
                >
                </v-file-input>
            </v-col>
        </v-row>

        <v-btn type="button" @click.stop="crop">crop</v-btn>

        <!-- Live preview of cropped images
        <template v-for="image in cropped">
            <img :key="image.index" v-bind:src="image.file">
        </template>
        -->

    </template>
</layout>

</template>

<script>
import Layout from '@/Shared/Layout'
import { VFileInput } from 'vuetify/lib'

import { mdiTrashCanOutline, mdiRotateRight } from '@mdi/js'

import VueCroppie from 'vue-croppie';
import 'croppie/croppie.css'
import Vue from 'vue'
Vue.use(VueCroppie);

export default {
    components: {
        Layout,
        VFileInput
    },
    data: function() {
        return {
            files: [],
            loaded: [],
            cropped: [],
            icon: {
                remove: mdiTrashCanOutline,
                rotate: mdiRotateRight
            }
        }
    },
    methods: {
        manager() {
            this.files.forEach(file => {
                this.loaded.push({
                    index: this.loaded.length + 1,
                    active: true,
                    loaded: false,
                    file: file
                })
            })
            this.files = []
            this.$nextTick(function () {
                this.init()
            })
        },
        init() {
            this.loaded.forEach(image => {
                if (!image.loaded) {
                    this.$refs['croppie' + image.index][0].bind({
                        url: window.URL.createObjectURL(image.file)
                    })
                    image.loaded = true
                }
            })
        },
        rotate(cid, degrees) {
            this.$refs['croppie' + cid][0].rotate(degrees)
        },
        crop() {
            let options = {
                format: 'png',
                circle: true
            }

            // Loop through loaded, override edits push new.
            this.loaded.forEach(image => {
                if (image.active) {
                    this.$refs['croppie' + image.index][0].result(options, (output) => {
                        if (this.cropped.find(item => item.index === image.index)) {
                            // Photo in loaded with current index is in cropped => Edit.
                            for (let i = 0; i < this.cropped.length; i++) {
                                if (this.cropped[i].index === image.index) {
                                    this.cropped[i] = {
                                        index: image.index,
                                        file: output
                                    }
                                    // For some reason cropped[i] = {edited} is not updating
                                    // preview if you want 'live' preview of cropped images use this:

                                    // this.cropped.splice(i, 1)
                                    // this.cropped.push({
                                    //     index: image.index,
                                    //     file: output
                                    // })
                                }
                            }
                        } else {
                            // Photo index not found in cropped => Add new.
                            this.cropped.push({
                                index: image.index,
                                file: output
                            })
                        }
                    })
                }
            })
        },
        remove(index) {
            // Destroy coppie.
            this.$refs['croppie' + index][0].destroy()

            // Remove from display.
            for (let i = 0; i < this.loaded.length; i++) {
                if (this.loaded[i].index === index) {
                    this.loaded[i].active = false

                }
            }

            // Remove from cropped.
            for (let i = 0; i < this.cropped.length; i++) {
                if (this.cropped[i].index === index) {
                    this.cropped.splice(i, 1)
                }
            }
        }
    }
}
</script>
spham commented 4 years ago

it seems not work. https://jsfiddle.net/spham92/mybutwgo/