159 lines
5.1 KiB
JavaScript
159 lines
5.1 KiB
JavaScript
|
import { Controller } from '@hotwired/stimulus'
|
||
|
import { Dropzone } from 'dropzone'
|
||
|
import Cropper from 'cropperjs'
|
||
|
|
||
|
export default class extends Controller {
|
||
|
static values = {
|
||
|
avatarImage: String,
|
||
|
userId: Number
|
||
|
}
|
||
|
|
||
|
connect() {
|
||
|
console.log('image', this.avatarImageValue)
|
||
|
console.log('id', this.userIdValue)
|
||
|
|
||
|
/*
|
||
|
const formElement = document.getElementById('avatarDropzone')
|
||
|
const dzMessage = document.getElementsByClassName('dz-message')
|
||
|
formElement.style.backgroundImage = `url('${this.avatarImageValue}')`
|
||
|
formElement.style.backgroundRepeat = 'no-repeat'
|
||
|
formElement.style.backgroundPosition = 'center center'
|
||
|
formElement.style.backgroundSize = 'auto'
|
||
|
formElement.style.borderRadius = '25px'
|
||
|
console.log('formelement', formElement)
|
||
|
*/
|
||
|
|
||
|
console.log('init Dropzone')
|
||
|
let avatarDropzone = new Dropzone('#avatarDropzone', {
|
||
|
url: `/user/upload/avatar/${this.userIdValue}`,
|
||
|
avatarUrl: this.avatarImageValue,
|
||
|
acceptedFiles: '.jpg, .jpeg, .png, gif',
|
||
|
maxFiles: 1,
|
||
|
dictDefaultMessage: '',
|
||
|
init() {
|
||
|
avatarDropzone = this
|
||
|
// If the thumbnail is already in the right size on your server:
|
||
|
const mockFile = { name: 'Filename', size: 12345 }
|
||
|
const callback = null // Optional callback when it's done
|
||
|
const crossOrigin = null // Added to the `img` tag for crossOrigin handling
|
||
|
const resizeThumbnail = false // Tells Dropzone whether it should resize the image first
|
||
|
avatarDropzone.displayExistingFile(mockFile, avatarDropzone.options.avatarUrl, callback, crossOrigin, resizeThumbnail);
|
||
|
avatarDropzone.files.push(mockFile); // line missing in official docs
|
||
|
|
||
|
/*
|
||
|
console.log('url', avatarDropzone.options.foo)
|
||
|
this.hiddenFileInput.removeAttribute('multiple')
|
||
|
this.on('maxfilesexceeded', (file) => {
|
||
|
this.removeAllFiles()
|
||
|
this.addFile(file)
|
||
|
})
|
||
|
this.on('error', (file, data) => {
|
||
|
console.log('error')
|
||
|
if (data.detail) {
|
||
|
this.emit('error', file, data.detail)
|
||
|
}
|
||
|
})
|
||
|
console.log('beforemock')
|
||
|
const mockFile = { name: 'Name Image', size: 12345, type: 'image/jpeg' }
|
||
|
this.emit('addedfile', mockFile)
|
||
|
this.emit('success', mockFile)
|
||
|
console.log('avi', this.avatarImageValue)
|
||
|
this.emit('thumbnail', mockFile, avatarDropzone.options.avatarUrl)
|
||
|
console.log('aftermock')
|
||
|
this.emit('complete', mockFile);
|
||
|
this.files.push(mockFile);
|
||
|
*/
|
||
|
},
|
||
|
transformFile(file, done) {
|
||
|
// Create the image editor overlay
|
||
|
const editor = document.createElement('div')
|
||
|
editor.style.position = 'fixed'
|
||
|
editor.style.left = '25px'
|
||
|
editor.style.right = '25px'
|
||
|
editor.style.top = '25px'
|
||
|
editor.style.bottom = '25px'
|
||
|
editor.style.zIndex = '9999'
|
||
|
editor.style.borderRadius = '15px;'
|
||
|
editor.style.borderColor = '#FF8844'
|
||
|
editor.style.backgroundColor = '#000'
|
||
|
document.body.appendChild(editor)
|
||
|
|
||
|
// Create an image node for Cropper.js
|
||
|
const image = new Image()
|
||
|
image.src = URL.createObjectURL(file)
|
||
|
editor.appendChild(image)
|
||
|
|
||
|
// Create Cropper.js
|
||
|
const cropper = new Cropper(image, {aspectRatio: 1})
|
||
|
|
||
|
// Create confirm button at the top left of the viewport
|
||
|
const buttonCrop = document.createElement('button')
|
||
|
buttonCrop.style.position = 'absolute'
|
||
|
buttonCrop.style.right = '10px'
|
||
|
buttonCrop.style.bottom = '50px'
|
||
|
buttonCrop.style.zIndex = '9999'
|
||
|
buttonCrop.textContent = 'Crop'
|
||
|
buttonCrop.className = 'btn btn-secondary'
|
||
|
editor.appendChild(buttonCrop)
|
||
|
buttonCrop.addEventListener('click', () => {
|
||
|
// clear preview
|
||
|
//formElement.style.backgroundImage = ''
|
||
|
|
||
|
const canvas = cropper.getCroppedCanvas({
|
||
|
width: 256,
|
||
|
height: 256
|
||
|
})
|
||
|
canvas.toBlob((blob) => {
|
||
|
avatarDropzone.createThumbnail(
|
||
|
blob,
|
||
|
avatarDropzone.options.thumbnailWidth,
|
||
|
avatarDropzone.options.thumbnailHeight,
|
||
|
avatarDropzone.options.thumbnailMethod,
|
||
|
false,
|
||
|
(dataURL) => {
|
||
|
avatarDropzone.emit('thumbnail', file, dataURL)
|
||
|
done(blob)
|
||
|
}
|
||
|
)
|
||
|
})
|
||
|
|
||
|
// Remove the editor from the view
|
||
|
document.body.removeChild(editor)
|
||
|
})
|
||
|
|
||
|
// Create keep original button
|
||
|
const buttonKeep = document.createElement('button')
|
||
|
buttonKeep.style.position = 'absolute'
|
||
|
buttonKeep.style.right = '100px'
|
||
|
buttonKeep.style.bottom = '50px'
|
||
|
buttonKeep.style.zIndex = '9999'
|
||
|
buttonKeep.textContent = 'Keep Original'
|
||
|
buttonKeep.className = 'btn btn-primary'
|
||
|
buttonKeep.focus()
|
||
|
editor.appendChild(buttonKeep)
|
||
|
buttonKeep.addEventListener('click', () => {
|
||
|
//formElement.style.backgroundImage = ''
|
||
|
|
||
|
// Remove the editor from the view
|
||
|
this.removeAllFiles()
|
||
|
|
||
|
done(file)
|
||
|
document.body.removeChild(editor)
|
||
|
})
|
||
|
|
||
|
// info text
|
||
|
const infoText = document.createElement('span')
|
||
|
infoText.style.position = 'absolute'
|
||
|
infoText.style.opacity = '0.5'
|
||
|
infoText.style.left = '100px'
|
||
|
infoText.style.bottom = '50px'
|
||
|
infoText.style.display = 'inline:block'
|
||
|
infoText.style.zIndex = '9999'
|
||
|
infoText.textContent = 'Use mouse wheel/touchpad to adapt size'
|
||
|
infoText.className = 'btn btn-secondary'
|
||
|
editor.appendChild(infoText)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|