UNPKG

aico-image-editor

Version:

Combine multiple image into and create single combined image

341 lines (304 loc) 12.3 kB
import Cropper from 'cropperjs'; const elementStore = Alpine.store('elements'); Alpine.store('uploadStore', { uploadFilesToServer(uploadObj) { const {files,action, type, imageType, originalFile,cropperData} = uploadObj; const canvasStore = Alpine.store('canvas'); const formData = new FormData(); formData.append('configuratorId', canvasStore.configuratorId) // append productId when configuratorId is null to first time save as create configurator endpoint if(!canvasStore.configuratorId){ formData.append('productId', canvasStore.productId) } imageType && formData.append('imageType', imageType) cropperData && formData.append('cropperData[]', JSON.stringify(cropperData)); originalFile && formData.append('originalFiles[]', originalFile); for (const file of files) { formData.append(type, file) // appending every file to formdata } //console.log(formData.get('backgrounds')) if(type === 'hexCode') { canvasStore.isColorBlockLoaderVisible = true; } else { canvasStore.isServerLoaderTabVisible = true; } return fetch(action, { method: "POST", body: formData, // "timeout": 0, headers: { "Authorization": `Bearer ${canvasStore.apiConfig.apiToken}`, }, redirect: 'follow' }) .then((response) => { return response.json() }) .then((data) => { canvasStore.isServerLoaderTabVisible = canvasStore.isColorBlockLoaderVisible = false; canvasStore.configuratorId = data.data.configuratorId; //console.log(data); return data; }) .catch((error) => { canvasStore.isServerLoaderTabVisible = canvasStore.isColorBlockLoaderVisible = false; console.error(error); }); }, updateImageInServer(editUploadObj) { const {files, action, type, cropperData} = editUploadObj; const canvasStore = Alpine.store('canvas'); const formData = new FormData(); cropperData && formData.append('cropperData', JSON.stringify(cropperData)); for (const file of files) { formData.append(type, file) // appending every file to formdata } canvasStore.isServerLoaderTabVisible = true; return fetch(action, { method: "POST", body: formData, // "timeout": 0, headers: { "Authorization": `Bearer ${canvasStore.apiConfig.apiToken}`, }, redirect: 'follow' }) .then((response) => { return response.json() }) .then((data) => { canvasStore.isServerLoaderTabVisible = false; //console.log(data); return data; }) .catch((error) => { canvasStore.isServerLoaderTabVisible = false; console.error(error); }); }, uploadImageWithoutConfigurator(uploadObj) { const canvasStore = Alpine.store('canvas'); const formData = new FormData(); const {files, action} = uploadObj; for (const file of files) { formData.append('layerFile', file) } canvasStore.isServerLoaderCanvasVisible = true; return fetch(action, { method: "POST", body: formData, // "timeout": 0, headers: { "Authorization": `Bearer ${canvasStore.apiConfig.apiToken}`, }, redirect: 'follow' }) .then((response) => { if (!response.ok) { throw new Error('Network response was not OK'); } return response.json() }) .then((data) => { canvasStore.isServerLoaderCanvasVisible = false; //console.log(data); return data; }) .catch((error) => { canvasStore.isServerLoaderCanvasVisible = false; console.error(error); }); }, deleteFilesFromServer(id, type,fileName) { const canvasStore = Alpine.store('canvas'); const formData = new FormData(); formData.append('productId', this.$store.canvas.buganoProductId) formData.append('fileID', id) formData.append('fileName', fileName) formData.append('type', type) canvasStore.isServerLoaderTabVisible = true; return fetch('http://localhost:6288/delete', { method: "DELETE", body: formData, }) .then((response) => { return response.json() }) .then((data) => { canvasStore.isServerLoaderTabVisible = false; //console.log(data); return data; }) .catch((error) => { console.error(error); }); } }) Alpine.store('bgshapeCropperModalStore', { cropBgImage: null, cropperData: null, originalBackgroundFile: null, editingBackgroundId: null, shouldPushRounded: false, dataURLtoBlob(dataurl) { var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], {type:mime}); }, async getFileFromUrl(url, name, defaultType = 'image/jpeg') { const response = await fetch(url); const data = await response.blob(); return new File([data], name, { type: data.type || defaultType, }); }, async editExistingBackground(background) { //const originalBackgroundFile = await this.getFileFromUrl(background.originalUrl); this.editingBackgroundId = background.id; const cropperInitObj = { fileName: background.name, url: background.cropperData.originalFileDataUrl, //url: background.originalUrl, cropperData: background.cropperData } this.displaySelectedBackground(cropperInitObj); }, async displaySelectedBackground(cropperInitObj) { const input = elementStore.backgroundUploadEL; const img = document.createElement('img'); img.id = 'js-bgimg-cropper'; img.src = cropperInitObj.url; img.alt = cropperInitObj.fileName; const imgbgcrop = elementStore.imgBgCropEL; imgbgcrop.innerHTML = ''; imgbgcrop.appendChild(img); // this represents current background image element which was created from file above this.cropBgImage = img; this.cropperData = cropperInitObj.cropperData; if(cropperInitObj.originalBackgroundFile) { this.originalBackgroundFile = cropperInitObj.originalBackgroundFile; } // open modal if not open and if alreddy open then init background cropper if (elementStore.cropbgModalEL.classList.contains('show')) { this.initBackgroundCropper(img) } else { bootstrap.Modal.getOrCreateInstance(elementStore.cropbgModalEL).show() } }, initBackgroundCropper(img) { let self = this; const input = elementStore.backgroundUploadEL; input.value = ''; this.aspectRatio = '1'; window.dispatchEvent(new CustomEvent('backgrounds-cleard')) //destroy old cropper before initializing new one this.destroyCropper() new Cropper(img, { crop: function (event) { self.cropBoxWidth = Math.round(event.detail.width); self.cropBoxHeight = Math.round(event.detail.height); }, aspectRatio: 1, autoCropArea: 1, preview: elementStore.cropperBgPreviewEL, ready: function () { if(self.cropperData) { this.cropper.setData(self.cropperData); } }, }); }, cropBoxWidth: 0, cropBoxHeight: 0, aspectRatio: '1', clear() { const cropperInstance = this.cropBgImage.cropper; cropperInstance.clear() }, destroyCropper() { this.cropBgImage?.cropper?.destroy(); }, async crop() { return new Promise((resolve, reject) => { const cropperInstance = this.cropBgImage.cropper; const input = elementStore.backgroundUploadEL; let self = this; const croppedCanvas = cropperInstance.getCroppedCanvas(); let finalCanvas = croppedCanvas; if (self.shouldPushRounded) { finalCanvas = self.getRoundedCanvas(croppedCanvas); } finalCanvas.toBlob(blob => { if (blob) { const dt = new DataTransfer(); dt.items.add(new File([blob], self.cropBgImage.alt, { type: blob.type })); input.files = dt.files; window.dispatchEvent(new CustomEvent('background-uploaded', { detail: { name: self.cropBgImage.alt, label: self.cropBgImage.alt, url: URL.createObjectURL(blob), class: self.shouldPushRounded ? 'rounded' : '', type: blob.type, } })); resolve(dt.files); } else { reject("Failed to generate blob"); } }); }); }, async processUpload($store) { let self = this; await this.crop(); const input = elementStore.backgroundUploadEL; const cropperData = Object.assign({originalFileDataUrl: self.cropBgImage.src} ,self.cropBgImage?.cropper.getData()); if(input.files.length) { const uploadObj = { files: input.files, action: `${$store.canvas.apiConfig.apiUrl}/api/v1/product-configurators/${$store.canvas.configuratorId || null}/images`, type: 'backgrounds[]', imageType: 'BACKGROUND', originalFile: this.originalBackgroundFile, cropperData: cropperData } const data = await $store.uploadStore.uploadFilesToServer(uploadObj); data?.data?.images?.forEach((background) => { window.dispatchEvent(new CustomEvent('backgrounds-added-from-api', { detail: { backgrounds: [background] } })); }); //productBlockVisibleMobile = true; } }, async processUpdate($store) { let self = this; await this.crop(); const input = elementStore.backgroundUploadEL; const cropperData = Object.assign({originalFileDataUrl: self.cropBgImage.src} ,self.cropBgImage?.cropper.getData()); if(input.files.length) { const editUploadObj = { files: input.files, action: `${$store.canvas.apiConfig.apiUrl}/api/v1/product-configurators/images/${self.editingBackgroundId}`, type: 'image', cropperData: cropperData } const data = await $store.uploadStore.updateImageInServer(editUploadObj); //here for update case background is directly returned as data.data and no further background property under that if(data?.data) { window.dispatchEvent(new CustomEvent('backgrounds-upated-from-api', { detail: { backgrounds: [data?.data] } })); } //productBlockVisibleMobile = true; } } })