Файловый менеджер - Редактировать - /home/lmsyaran/public_html/joomla5/plugins/fabrik_element/fileupload/fileupload.js
Назад
/** * File Upload Element * * @copyright: Copyright (C) 2005-2016 Media A-Team, Inc. - All rights reserved. * @license: GNU/GPL http://www.gnu.org/copyleft/gpl.html */ define(['jquery', 'fab/fileelement'], function (jQuery, FbFileElement) { window.FbFileUpload = new Class({ Extends : FbFileElement, options : { folderSelect: false, ajax_upload: false, ajax_show_widget: true, isCarousel: false }, initialize: function (element, options) { var self = this; this.setPlugin('fileupload'); this.parent(element, options); this.container = jQuery(this.container); this.toppath = this.options.dir; if (this.options.folderSelect === '1' && this.options.editable === true) { this.ajaxFolder(); } this.doBrowseEvent = null; this.watchBrowseButton(); if (this.options.ajax_upload && this.options.editable !== false) { Fabrik.fireEvent('fabrik.fileupload.plupload.build.start', this); this.watchAjax(); if (Object.keys(this.options.files).length !== 0) { this.uploader.trigger('FilesAdded', this.options.files); jQuery.each(this.options.files, function (key, file) { var response = { filepath : file.path, uri : file.url, showWidget: false }, newBar = jQuery(Fabrik.jLayouts['fabrik-progress-bar-success'])[0], bar = jQuery('#' + file.id).find('.bar')[0]; self.uploader.trigger('UploadProgress', file); self.uploader.trigger('FileUploaded', file, { response: JSON.stringify(response) }); jQuery(bar).replaceWith(newBar); }); } this.redraw(); } this.doDeleteEvent = null; this.watchDeleteButton(); this.watchTab(); if (this.options.isCarousel) { jQuery('.slickCarousel').slick(); jQuery('.slickCarouselImage').css('opacity', '1'); } if (this.options.isZoom) { jQuery('.slick-active').find('img').ezPlus({ zoomType: 'lens', lensShape: 'round', lensSize: 200 }); jQuery('.slickCarousel').on('beforeChange', function(event, slick, currentSlide, nextSlide){ jQuery('.zoomWindowContainer,.zoomContainer').remove(); }); jQuery('.slickCarousel').on('afterChange', function(event, slick, currentSlide){ jQuery('.slick-active').find('img').ezPlus({ zoomType: 'lens', lensShape: 'round', lensSize: 200 }); }); } }, /** * Reposition the hidden input field over the 'add' button. Called on initiate and if in a tab * and the tab is activated. Triggered from element.watchTab() */ redraw: function () { var el = jQuery(this.element); if (this.options.editable && this.options.ajax_upload) { var browseButton = jQuery('#' + el.prop('id') + '_browseButton'), c = jQuery('#' + this.options.element + '_container'), diff = browseButton.position().left - c.position().left; // $$$ hugh - working on some IE issues var file_element = c.closest('.fabrikElement').find('input[type=file]'); if (file_element.length > 0) { var fileContainer = file_element.parent(); fileContainer.css({ 'width' : browseButton.width(), 'height': browseButton.height() }); fileContainer.css('top', diff); } } if (this.options.isCarousel) { jQuery('.slickCarousel').slick('resize'); } }, doBrowse: function (evt) { if (window.File && window.FileReader && window.FileList && window.Blob) { var reader, self = this, files = evt.target.files, f = files[0]; // Only process image files. if (f.type.match('image.*')) { reader = new FileReader(); // Closure to capture the file information. reader.onload = (function (theFile) { return function (e) { var c = jQuery(self.getContainer()), b = c.find('img'); b.attr('src', e.target.result); var d = b.closest('.fabrikHide'); d.removeClass('fabrikHide'); var db = c.find('[data-file]'); db.addClass('fabrikHide'); }; }.bind(this))(f); // Read in the image file as a data URL. reader.readAsDataURL(f); } else if (f.type.match('video.*')) { var c = jQuery(this.getContainer()), video = c.find('video'); if (video.length > 0) { video = this.makeVideoPreview(); video.appendTo(c); } reader = new window.FileReader(); var url; reader = window.URL || window.webKitURL; if (reader && reader.createObjectURL) { url = reader.createObjectURL(f); video.attr('src', url); return; } if (!window.FileReader) { console.log('Sorry, not so much'); return; } reader = new window.FileReader(); reader.onload = function (eo) { video.attr('src', eo.target.result); }; reader.readAsDataURL(f); } } }, watchBrowseButton: function () { var el = jQuery(this.element); if (this.options.useWIP && !this.options.ajax_upload && this.options.editable !== false) { el.off('change', this.doBrowseEvent); this.doBrowseEvent = this.doBrowse.bind(this); el.on('change', this.doBrowseEvent); } }, /** * Called from watchDeleteButton * * @param {Event} e */ doDelete: function (e) { e.preventDefault(); var c = jQuery(this.getContainer()), self = this, b = c.find('[data-file]'); if (window.confirm(Joomla.JText._('PLG_ELEMENT_FILEUPLOAD_CONFIRM_SOFT_DELETE'))) { var joinPkVal = b.data('join-pk-val'); new jQuery.ajax({ url : '', data: { 'option' : 'com_fabrik', 'format' : 'raw', 'task' : 'plugin.pluginAjax', 'plugin' : 'fileupload', 'method' : 'ajax_clearFileReference', 'element_id': this.options.id, 'formid' : this.form.id, 'rowid' : this.form.options.rowid, 'joinPkVal' : joinPkVal } }).done(function () { Fabrik.trigger('fabrik.fileupload.clearfileref.complete', self); }); if (window.confirm(Joomla.JText._('PLG_ELEMENT_FILEUPLOAD_CONFIRM_HARD_DELETE'))) { this.makeDeletedImageField(this.groupid, b.data('file')).appendTo(c); Fabrik.fireEvent('fabrik.fileupload.delete.complete', this); } b.remove(); var el = jQuery(this.element); var i = el.closest('.fabrikElement').find('img'); i.attr('src', this.options.defaultImage !== '' ? Fabrik.liveSite + this.options.defaultImage : ''); } }, /** * Single file uploads can allow the user to delete the reference and/or file */ watchDeleteButton: function () { var c = jQuery(this.getContainer()), b = c.find('[data-file]'); b.off('click', this.doDeleteEvent); this.doDeleteEvent = this.doDelete.bind(this); b.on('click', this.doDeleteEvent); }, /** * Sets the element key used in Fabrik.blocks.form_X.formElements overwritten by dbjoin rendered as checkbox * * @since 3.0.7 * * @return string */ getFormElementsKey: function (elId) { this.baseElementId = elId; if (!this.options.inRepeatGroup && this.options.ajax_upload && this.options.ajax_max > 1) { return this.options.listName + '___' + this.options.elementShortName; } else { return this.parent(elId); } }, /** * When in ajax form, on submit the list will call this, so we can remove the submit event if we dont do that, upon a second form submission the * original submitEvent is used causing a js error as it still references the files uploaded in the first form */ removeCustomEvents: function () { // Fabrik.removeEvent('fabrik.form.submit.start', this.submitEvent); }, cloned: function (c) { if (this.options.ajax_upload) { jQuery(this.getContainer()).find('.plupload_container').prop('id', this.element.id + '_container'); jQuery(this.getContainer()).find('.plupload').prop('id', this.element.id + '_dropList_container'); jQuery(this.getContainer()).find('.plupload_filelist').prop('id', this.element.id + '_dropList'); jQuery(this.getContainer()).find('.plupload_browsebutton').prop('id', this.element.id + '_browseButton'); jQuery(this.getContainer()).find('input').remove(); this.watchAjax(); } else { var el = jQuery(this.element); // replaced cloned image with default image if (el.closest('.fabrikElement').length === 0) { return; } var i = el.closest('.fabrikElement').find('img'); i.attr('src', this.options.defaultImage !== '' ? Fabrik.liveSite + this.options.defaultImage : ''); jQuery(this.getContainer()).find('[data-file]').remove(); this.watchBrowseButton(); } this.parent(c); }, decloned: function (groupid) { var i = jQuery('#form_' + this.form.id).find('input[name="fabrik_deletedimages[' + groupid + ']"]'); if (i.length > 0) { this.makeDeletedImageField(groupid, this.options.value).inject(this.form.form); } this.parent(groupid); }, decreaseName: function (delIndex) { var f = this.getOrigField(); if (typeOf(f) !== 'null') { f.name = this._decreaseName(f.name, delIndex); f.id = this._decreaseId(f.id, delIndex); } return this.parent(delIndex); }, getOrigField: function () { var p = this.element.getParent('.fabrikElement'); var f = p.getElement('input[name^=' + this.origId + '_orig]'); if (typeOf(f) === 'null') { f = p.getElement('input[id^=' + this.origId + '_orig]'); } return f; }, /** * Create a hidden input which will tell fabrik, upon form submission, to delete the file * * @param {int} groupId group id * @param {string} value file to delete * * @return Element DOM Node - hidden input */ makeDeletedImageField: function (groupId, value) { return jQuery(document.createElement('input')).attr({ 'type' : 'hidden', 'name' : 'fabrik_fileupload_deletedfile[' + groupId + '][]', 'value': value }); }, makeVideoPreview: function () { var el = jQuery(this.element); return jQuery(document.createElement('video')).attr({ 'id' : el.prop('id') + '_video_preview', 'controls': true }); }, update: function (val) { if (this.element) { var el = jQuery(this.element); if (val === '') { if (this.options.ajax_upload) { this.uploader.files = []; el.parent().find('[id$=_dropList] tr').remove(); } else { el.val(''); } } else { var img = el.closest('div.fabrikSubElementContainer').find('img'); if (img) { img.prop('src', val); } } } }, addDropArea: function () { if (!Fabrik.bootstraped) { return; } var dropTxt = this.container.find('tr.plupload_droptext'), tr; if (dropTxt.length > 0) { dropTxt.show(); } else { tr = jQuery(document.createElementget('tr')).addClass('plupload_droptext').html('<td colspan="4"><i class="icon-move"></i> ' + Joomla.JText ._('PLG_ELEMENT_FILEUPLOAD_DRAG_FILES_HERE') + ' </td>'); this.container.find('tbody').append(tr); } this.container.find('thead').hide(); }, removeDropArea: function () { this.container.find('tr.plupload_droptext').hide(); }, watchAjax: function () { if (this.options.editable === false) { return; } var a, self = this, elementId = jQuery(this.element).prop('id'), el = jQuery(this.getElement()); if (el.length === 0) { return; } var c = el.closest('.fabrikSubElementContainer'); this.container = c; if (this.options.ajax_show_widget && this.options.canvasSupport !== false) { this.widget = new ImageWidget(this.options.modalId, { 'imagedim': { x: 200, y: 200, w: this.options.winWidth, h: this.options.winHeight }, 'cropdim': { w: this.options.cropwidth, h: this.options.cropheight, x: this.options.winWidth / 2, y: this.options.winHeight / 2 }, crop : this.options.crop, modalId : this.options.modalId, quality : this.options.quality }); } this.pluploadContainer = c.find('.plupload_container'); this.pluploadFallback = c.find('.plupload_fallback'); this.droplist = c.find('.plupload_filelist'); var url = 'index.php?option=com_fabrik&format=raw&task=plugin.pluginAjax'; url += '&plugin=fileupload&' + this.options.ajaxToken + '=1'; url += '&method=ajax_upload&element_id=' + this.options.elid; if (this.options.isAdmin) { url = 'administrator/' + url; } var plupopts = { runtimes : this.options.ajax_runtime, browse_button : elementId + '_browseButton', container : elementId + '_container', drop_element : elementId + '_dropList_container', url : url, max_file_size : this.options.max_file_size + 'kb', unique_names : false, flash_swf_url : this.options.ajax_flash_path, silverlight_xap_url: this.options.ajax_silverlight_path, chunk_size : this.options.ajax_chunk_size + 'kb', dragdrop : true, multipart : true, filters : this.options.filters, page_url : this.options.page_url }; this.uploader = new plupload.Uploader(plupopts); // (1) INIT ACTIONS this.uploader.bind('Init', function (up, params) { // FORCEFULLY NUKE GRACEFUL DEGRADING FALLBACK ON INIT self.pluploadFallback.remove(); self.pluploadContainer.removeClass('fabrikHide'); if (up.features.dragdrop && up.settings.dragdrop) { self.addDropArea(); } }); /* */ this.uploader.bind('FilesRemoved', function (up, files) { }); // (2) ON FILES ADDED ACTION this.uploader.bind('FilesAdded', function (up, files) { self.removeDropArea(); var rElement = Fabrik.bootstrapped ? 'tr' : 'li', count; self.lastAddedFiles = files; if (Fabrik.bootstrapped) { self.container.find('thead').css('display', ''); } count = self.droplist.find(rElement).length; jQuery.each(files, function (key, file) { //files.each(function (file, idx) { if (file.size > self.options.max_file_size * 1000) { window.alert(Joomla.JText._('PLG_ELEMENT_FILEUPLOAD_FILE_TOO_LARGE_SHORT')); } else { if (count >= self.options.ajax_max) { window.alert(Joomla.JText._('PLG_ELEMENT_FILEUPLOAD_MAX_UPLOAD_REACHED')); } else { count++; var a, title, innerLi; if (self.isImage(file)) { a = self.editImgButton(); if (self.options.crop) { a.html(self.options.resizeButton); } else { a.html(self.options.previewButton); } title = jQuery(document.createElement('span')).text(file.name); } else { a = jQuery(document.createElement('span')); title = jQuery(document.createElement('a')).attr({ 'href': file.url, 'target': '_blank' }).text(file.name); } innerLi = self.imageCells(file, title, a); self.droplist.append(jQuery(document.createElement(rElement)).attr({ id : file.id, 'class': 'plupload_delete' }).append(innerLi)); } } }); // Automatically start the upload - need delay to ensure up.files is populated setTimeout(function () { up.start(); }, 100); }); // (3) ON FILE UPLOAD PROGRESS ACTION this.uploader.bind('UploadProgress', function (up, file) { var f = jQuery('#' + file.id); if (f.length > 0) { if (Fabrik.bootstrapped) { var bar = f.find('.plupload_file_status .bar'); bar.css('width', file.percent + '%'); if (file.percent === 100) { var newBar = jQuery(Fabrik.jLayouts['fabrik-progress-bar-success']); bar.replaceWith(newBar); } } else { f.find('.plupload_file_status').text(file.percent + '%'); } } }); this.uploader.bind('Error', function (up, err) { self.lastAddedFiles.each(function (file) { var row = jQuery('#' + file.id); if (row.length > 0) { row.remove(); window.alert(err.message); } self.addDropArea(); }); }); this.uploader.bind('ChunkUploaded', function (up, file, response) { response = JSON.parse(response.response); if (typeof(response) === 'object') { if (response.error) { fconsole(response.error.message); } } }); this.uploader.bind('FileUploaded', function (up, file, response) { var name, showWidget, f, resizeButton, idValue, f = jQuery('#' + file.id) response = JSON.parse(response.response); if (response.error) { window.alert(response.error); f.remove(); return; } if (f.length === 0) { fconsole('Filuploaded didnt find: ' + file.id); return; } resizeButton = f.find('.plupload_resize a'); resizeButton.show(); resizeButton.attr({ href: response.uri, id : 'resizebutton_' + file.id }); resizeButton.data('filepath', response.filepath); if (self.widget) { showWidget = response.showWidget === false ? false : true; self.widget.setImage(response.uri, response.filepath, file.params, showWidget); } if (self.options.inRepeatGroup) { name = self.options.elementName.replace(/\[\d*\]/, '[' + self.getRepeatNum() + ']'); } else { name = self.options.elementName; } // Stores the cropparams which we need to reload the crop widget in the correct state (rotation, zoom, etc) jQuery(document.createElement('input')).attr({ 'type' : 'hidden', name : name + '[crop][' + response.filepath + ']', 'id' : 'coords_' + file.id, 'value': JSON.stringify(file.params) }).insertAfter(self.pluploadContainer); // Stores the actual crop image data retrieved from the canvas jQuery(document.createElement('input')).attr({ type: 'hidden', name: name + '[cropdata][' + response.filepath + ']', 'id': 'data_' + file.id }).insertAfter(self.pluploadContainer); // Stores the image id if > 1 fileupload idValue = [file.recordid, '0'].pick(); jQuery(document.createElement('input')).attr({ 'type' : 'hidden', name : name + '[id][' + response.filepath + ']', 'id' : 'id_' + file.id, 'value': idValue }).insertAfter(self.pluploadContainer); f.removeClass('plupload_file_action').addClass('plupload_done'); self.isSubmitDone(); }); // (5) KICK-START PLUPLOAD this.uploader.init(); }, /** * Create an array of the dom elements to inject into a row representing an uploaded file * * @return {array} */ imageCells: function (file, title, a) { var del = this.deleteImgButton(), filename, status, progress, icon; if (Fabrik.bootstrapped) { icon = jQuery(document.createElement('td')).addClass(this.options.spanNames[1] + ' plupload_resize').append(a); progress = Fabrik.jLayouts['fabrik-progress-bar']; status = jQuery(document.createElement('td')).addClass(this.options.spanNames[5] + ' plupload_file_status').html(progress); filename = jQuery(document.createElement('td')).addClass(this.options.spanNames[6] + ' plupload_file_name').append(title); return [filename, icon, status, del]; } else { filename = new Element('div', { 'class': 'plupload_file_name' }).adopt([title, new Element('div', { 'class': 'plupload_resize', style : 'display:none' }).adopt(a)]); status = new Element('div', { 'class': 'plupload_file_status' }).set('text', '0%'); var size = new Element('div', { 'class': 'plupload_file_size' }).set('text', file.size); return [filename, del, status, size, new Element('div', { 'class': 'plupload_clearer' })]; } }, /** * Create edit image button * * @return {jQuery} */ editImgButton: function () { var self = this; if (Fabrik.bootstrapped) { return jQuery(document.createElement('a')).addClass('editImage').attr({ 'href': '#', alt : Joomla.JText._('PLG_ELEMENT_FILEUPLOAD_RESIZE') }).css({ 'display': 'none' }).on('click', function (e) { e.preventDefault(); //var a = e.target.getParent(); self.pluploadResize(jQuery(this)); }); } else { return new Element('a', { 'href': '#', alt : Joomla.JText._('PLG_ELEMENT_FILEUPLOAD_RESIZE'), events: { 'click': function (e) { e.stop(); var a = e.target.getParent(); this.pluploadResize(jQuery(a)); }.bind(this) } }); } }, /** * Create delete image button * * @return {jQuery} */ deleteImgButton: function () { if (Fabrik.bootstrapped) { var icon = Fabrik.jLayouts['fabrik-icon-delete'], self = this; return jQuery(document.createElement('td')).addClass(this.options.spanNames[1] + ' plupload_file_action').append( jQuery(document.createElement('a')) .html(icon) .attr({ 'href' : '#' }) .on('click', function (e) { e.stopPropagation(); self.pluploadRemoveFile(e); }) ); } else { return new Element('div', { 'class': 'plupload_file_action' }).adopt(new Element('a', { 'href' : '#', 'style': 'display:block', events : { 'click': function (e) { this.pluploadRemoveFile(e); }.bind(this) } })); } }, /** * Test if the plupload file object contains an image. * @param {object} file * @returns {*} */ isImage: function (file) { if (file.type !== undefined) { return file.type === 'image'; } var ext = file.name.split('.').pop().toLowerCase(); return ['jpg', 'jpeg', 'png', 'gif'].contains(ext); }, pluploadRemoveFile: function (e) { e.stopPropagation(); if (!window.confirm(Joomla.JText._('PLG_ELEMENT_FILEUPLOAD_CONFIRM_HARD_DELETE'))) { return; } var id = jQuery(e.target).closest('tr').prop('id').split('_').pop();// alreadyuploaded_8_13 // $$$ hugh - removed ' span' from the find(), as this blows up on some templates var f = jQuery(e.target).closest('tr').find('.plupload_file_name').text(); // Get a list of all of the uploaders files except the one to be deleted var newFiles = []; this.uploader.files.each(function (f) { if (f.id !== id) { newFiles.push(f); } }); // Update the uploader's files with the new list. this.uploader.files = newFiles; // Send a request to delete the file from the server. var self = this; var data = { 'option' : 'com_fabrik', 'format' : 'raw', 'task' : 'plugin.pluginAjax', 'plugin' : 'fileupload', 'method' : 'ajax_deleteFile', 'element_id' : this.options.id, 'file' : f, 'recordid' : id, 'repeatCounter': this.options.repeatCounter } data[this.options.ajaxToken] = 1; jQuery.ajax({ url : '', data: data }).done(function (r) { r = JSON.parse(r); if (r.error === '') { Fabrik.trigger('fabrik.fileupload.delete.complete', self); var li = jQuery(e.target).closest('.plupload_delete'); li.remove(); // Remove hidden fields as well jQuery('#id_alreadyuploaded_' + self.options.id + '_' + id).remove(); jQuery('#coords_alreadyuploaded_' + self.options.id + '_' + id).remove(); if (jQuery(self.getContainer()).find('table tbody tr.plupload_delete').length === 0) { self.addDropArea(); } } }); }, /** * * @param {jQuery} a */ pluploadResize: function (a) { if (this.widget) { this.widget.setImage(a.attr('href'), a.data('filepath'), {}, true); } }, /** * Once the upload fires a FileUploaded bound function we test if all images for this element have been * uploaded If they have then we save the * crop widget state and fire the callback - which is handled by FbFormSubmit() */ isSubmitDone: function () { if (this.allUploaded() && typeof (this.submitCallBack) === 'function') { this.saveWidgetState(); this.submitCallBack(true); delete this.submitCallBack; } }, /** * Called from FbFormSubmit.submit() handles testing. If not yet uploaded, triggers the * upload and defers the callback until the upload is * complete. If complete then saves widget state and calls parent onsubmit(). */ onsubmit: function (cb) { this.submitCallBack = cb; if (!this.allUploaded()) { this.uploader.start(); } else { this.saveWidgetState(); this.parent(cb); } }, /** * Save the crop widget state as a json object */ saveWidgetState: function () { if (this.widget !== undefined) { jQuery.each(this.widget.images, function (key, image) { key = key.split('\\').pop(); var f = jQuery('input[name*="' + key + '"]').filter(function (i, fld) { return fld.name.contains('[crop]'); }); f = f.last(); // $$$ rob - seems reloading ajax fileupload element in ajax form (e.g. from db join add record) // is producing odd effects where old fileupload object contains info to previously uploaded image? if (f.length > 0) { // Avoid circular reference in chrome when saving in ajax form var i = image.img; delete (image.img); f.val(JSON.stringify(image)); image.img = i; } }); } }, allUploaded: function () { var uploaded = true; if (this.uploader) { this.uploader.files.each(function (file) { if (file.loaded === 0) { uploaded = false; } }); } return uploaded; } }); var ImageWidget = new Class({ initialize: function (modalId, opts) { this.modalId = modalId; // When element is in modal window it renders fine the first time. But the second time // the original window is still there - so we end up with 2 dom structures and one window object. // To get round this set the first window to be destroyed and close it. if (Fabrik.Windows[this.modalId]) { Fabrik.Windows[this.modalId].options.destroy = true; Fabrik.Windows[this.modalId].close(); } this.imageDefault = { 'rotation': 0, 'scale' : 100, 'imagedim': { x: 200, y: 200, w: 400, h: 400 }, 'cropdim' : { x: 75, y: 25, w: 150, h: 50 } }; jQuery.extend(this.imageDefault, opts); this.windowopts = { 'id' : this.modalId, 'type' : 'modal', loadMethod : 'html', width : parseInt(this.imageDefault.imagedim.w, 10) + 40, height : parseInt(this.imageDefault.imagedim.h, 10) + 170, storeOnClose : true, createShowOverLay: false, crop : opts.crop, destroy : false, modalId : opts.modalId, quality : opts.quality, onClose : function () { this.storeActiveImageData(); }.bind(this), onContentLoaded : function () { this.center(); }, onOpen : function () { this.center(); } }; this.windowopts.title = opts.crop ? Joomla.JText._('PLG_ELEMENT_FILEUPLOAD_CROP_AND_SCALE') : Joomla.JText ._('PLG_ELEMENT_FILEUPLOAD_PREVIEW'); this.showWin(); this.canvas = jQuery(this.window).find('canvas')[0]; this.images = {}; this.CANVAS = new FbCanvas({ canvasElement: this.canvas, enableMouse : true, cacheCtxPos : false }); this.CANVAS.layers.add(new Layer({ id: 'bg-layer' })); this.CANVAS.layers.add(new Layer({ id: 'image-layer' })); if (opts.crop) { this.CANVAS.layers.add(new Layer({ id: 'overlay-layer' })); this.CANVAS.layers.add(new Layer({ id: 'crop-layer' })); } var bg = new CanvasItem({ id : 'bg', scale : 1, events: { onDraw: function (ctx) { if (ctx === undefined) { ctx = this.CANVAS.ctx; } ctx.fillStyle = '#DFDFDF'; ctx.fillRect(0, 0, this.imageDefault.imagedim.w / this.scale, this.imageDefault.imagedim.h / this.scale); }.bind(this) } }); this.CANVAS.layers.get('bg-layer').add(bg); if (opts.crop) { this.overlay = new CanvasItem({ id : 'overlay', events: { onDraw: function (ctx) { if (ctx === undefined) { ctx = this.CANVAS.ctx; } //this.withinCrop = true; if (this.overlay.withinCrop) { var top = { x: 0, y: 0 }; var bottom = { x: this.imageDefault.imagedim.w, y: this.imageDefault.imagedim.h }; ctx.fillStyle = 'rgba(0, 0, 0, 0.3)'; var cropper = this.cropperCanvas; ctx.fillRect(top.x, top.y, bottom.x, cropper.y - (cropper.h / 2));// top ctx.fillRect(top.x - (cropper.w / 2), top.y + cropper.y - (cropper.h / 2), top.x + cropper.x, cropper.h);// left ctx.fillRect(top.x + cropper.x + cropper.w - (cropper.w / 2), top.y + cropper.y - (cropper.h / 2), bottom.x, cropper.h);// right ctx.fillRect(top.x, top.y + (cropper.y + cropper.h) - (cropper.h / 2), bottom.x, bottom.y);// bottom } }.bind(this) } }); this.CANVAS.layers.get('overlay-layer').add(this.overlay); } this.imgCanvas = this.makeImgCanvas(); this.CANVAS.layers.get('image-layer').add(this.imgCanvas); this.cropperCanvas = this.makeCropperCanvas(); if (opts.crop) { // add an item this.CANVAS.layers.get('crop-layer').add(this.cropperCanvas); } this.makeThread(); this.watchZoom(); this.watchRotate(); this.watchClose(); this.win.close(); }, /** * Add or make active an image in the editor * * @param {string} uri Image URI * @param {string} filepath Path to file * @param {object} params Initial parameters * @param {Boolean} showWin */ setImage: function (uri, filepath, params, showWin) { showWin = showWin ? showWin : false; this.activeFilePath = filepath; if (!this.images.hasOwnProperty(filepath)) { // Needed to ensure they are available in onLoad var tmpParams = params; // New image var img = Asset.image(uri, { crossOrigin: 'anonymous', onLoad: function () { var params = this.storeImageDimensions(filepath, jQuery(img), tmpParams); this.img = params.img; this.setInterfaceDimensions(params); this.showWin(); this.storeActiveImageData(filepath); if (!showWin) { this.win.close(); } }.bind(this) }); } else { // Previously set up image params = this.images[filepath]; this.img = params.img; this.setInterfaceDimensions(params); if (showWin) { this.showWin(); } } }, /** * Set rotate, scale, image and crop values for a given image * * @param object params Image parameters */ setInterfaceDimensions: function (params) { if (this.scaleSlide) { this.scaleSlide.set(params.scale); } if (this.rotateSlide) { this.rotateSlide.set(params.rotation); } if (this.cropperCanvas && params.cropdim) { this.cropperCanvas.x = params.cropdim.x; this.cropperCanvas.y = params.cropdim.y; this.cropperCanvas.w = params.cropdim.w; this.cropperCanvas.h = params.cropdim.h; } this.imgCanvas.w = params.mainimagedim.w; this.imgCanvas.h = params.mainimagedim.h; this.imgCanvas.x = params.imagedim !== undefined ? params.imagedim.x : 0; this.imgCanvas.y = params.imagedim !== undefined ? params.imagedim.y : 0; }, /** * One time call to store initial image crop info in this.images * * @param {string} filepath Path to image * @param {jQuery} img Image - just created * @param {object} params object Image parameters * * @return object Update image parameters */ storeImageDimensions: function (filepath, img, params) { // .hide() not working in UIKit img.appendTo(document.body).css({'display': 'none'}); params = params ? params : new CloneObject(this.imageDefault, true, []); var s = img[0].getDimensions(true); if (!params.imagedim) { params.mainimagedim = {}; } else { params.mainimagedim = params.imagedim; } params.mainimagedim.w = s.width; params.mainimagedim.h = s.height; params.img = img[0]; this.images[filepath] = params; return params; }, makeImgCanvas: function () { var parent = this; return new CanvasItem({ id : 'imgtocrop', w : this.imageDefault.imagedim.w, h : this.imageDefault.imagedim.h, x : 200, y : 200, interactive: true, rotation : 0, scale : 1, offset : [0, 0], events : { onMousemove: function (x, y) { if (this.dragging) { var w = this.w * this.scale; var h = this.h * this.scale; this.x = x - this.offset[0] + w * 0.5; this.y = y - this.offset[1] + h * 0.5; } }, onDraw : function (ctx) { ctx = parent.CANVAS.ctx; if (parent.img === undefined) { // console.log('no parent img', parent); return; } var w = this.w * this.scale; var h = this.h * this.scale; var x = this.x - w * 0.5; var y = this.y - h * 0.5; // standard Canvas rotation operation ctx.save(); ctx.translate(this.x, this.y); ctx.rotate(this.rotation * Math.PI / 180); this.hover ? ctx.strokeStyle = '#f00' : ctx.strokeStyle = '#000'; ctx.strokeRect(w * -0.5, h * -0.5, w, h); if (parent.img !== undefined) { try { ctx.drawImage(parent.img, w * -0.5, h * -0.5, w, h); } catch (err) { // only show this for debugging as if we upload a pdf then we get shown lots of these errors. // fconsole(err, parent.img, w * -0.5, h * -0.5, w, h); } } ctx.restore(); if (parent.img !== undefined && parent.images.hasOwnProperty(parent.activeFilePath)) { parent.images[parent.activeFilePath].imagedim = { x: this.x, y: this.y, w: w, h: h }; } this.setDims(x, y, w, h); }, onMousedown: function (x, y) { parent.CANVAS.setDrag(this); this.offset = [x - this.dims[0], y - this.dims[1]]; this.dragging = true; }, onMouseup: function () { parent.CANVAS.clearDrag(); this.dragging = false; }, onMouseover: function () { parent.overImg = true; document.body.style.cursor = "move"; }, onMouseout: function () { parent.overImg = false; if (!parent.overCrop) { document.body.style.cursor = "default"; } } } }); }, makeCropperCanvas: function () { var parent = this; return new CanvasItem({ id : 'item', x : 175, y : 175, w : 150, h : 50, interactive: true, offset : [0, 0], events : { onDraw: function (ctx) { ctx = parent.CANVAS.ctx; if (ctx === undefined) { return; } /* * calculate dimensions locally because they are have to be translated in order to use translate and rotate with the desired * effect: rotate the item around its visual center */ var w = this.w; var h = this.h; var x = this.x - w * 0.5; var y = this.y - h * 0.5; // standard Canvas rotation operation ctx.save(); ctx.translate(this.x, this.y); this.hover ? ctx.strokeStyle = '#f00' : ctx.strokeStyle = '#000'; ctx.strokeRect(w * -0.5, h * -0.5, w, h); ctx.restore(); /* * used to determine the whether the mouse is over an item or not. */ if (parent.img !== undefined && parent.images.hasOwnProperty(parent.activeFilePath)) { parent.images[parent.activeFilePath].cropdim = { x: this.x, y: this.y, w: w, h: h }; } this.setDims(x, y, w, h); }, onMousedown: function (x, y) { parent.CANVAS.setDrag(this); this.offset = [x - this.dims[0], y - this.dims[1]]; this.dragging = true; parent.overlay.withinCrop = true; }, onMousemove: function (x, y) { document.body.style.cursor = "move"; if (this.dragging) { var w = this.w; var h = this.h; this.x = x - this.offset[0] + w * 0.5; this.y = y - this.offset[1] + h * 0.5; } }, onMouseup: function () { parent.CANVAS.clearDrag(); this.dragging = false; parent.overlay.withinCrop = false; }, onMouseover: function () { this.hover = true; parent.overCrop = true; }, onMouseout: function () { if (!parent.overImg) { document.body.style.cursor = 'default'; } parent.overCrop = false; this.hover = false; } } }); }, makeThread: function () { var self = this; this.CANVAS.addThread(new Thread({ id : 'myThread', onExec: function () { if (self.CANVAS !== undefined) { if (self.CANVAS.ctxEl !== undefined) { self.CANVAS.clear().draw(); } } } })); }, /** * watch the close button */ watchClose: function () { var self = this; this.window.find('input[name=close-crop]').on('click', function (e) { self.storeActiveImageData(); self.win.close(); }); }, /** * Takes the current active image and creates cropped image data via a canvas element * * @param {string} filepath File path to image to crop. If blank use this.activeFilePath */ storeActiveImageData: function (filepath) { filepath = filepath ? filepath : this.activeFilePath; if (filepath === undefined) { return; } var x = this.cropperCanvas.x; var y = this.cropperCanvas.y; var w = this.cropperCanvas.w - 2; var h = this.cropperCanvas.h - 2; x = x - (w / 2); y = y - (h / 2); var win = jQuery('#' + this.windowopts.id); if (win.length === 0) { fconsole('storeActiveImageData no window found for ' + this.windowopts.id); return; } var canvas = win.find('canvas'); var target = jQuery(document.createElement('canvas')).attr({ 'width' : w + 'px', 'height': h + 'px' }).appendTo(document.body); var ctx = target[0].getContext('2d'); var file = filepath.split('\\').pop(); var f = jQuery('input[name*="' + file + '"]').filter(function (index, fld) { return fld.name.contains('cropdata'); }); ctx.drawImage(canvas[0], x, y, w, h, 0, 0, w, h); f.val(target[0].toDataURL('image/jpeg', this.windowopts.quality)); target.remove(); }, /** * Set up and watch the zoom slide and input field */ watchZoom: function () { var self = this; if (!this.windowopts.crop) { return; } var scaleField = this.window.find('input[name=zoom-val]'); this.scaleSlide = new Slider(this.window.find('.fabrikslider-line')[0], this.window.find('.knob')[0], { range : [20, 300], onChange: function (pos) { self.imgCanvas.scale = pos / 100; if (self.img !== undefined) { try { self.images[self.activeFilePath].scale = pos; } catch (err) { fconsole('didnt get active file path:' + self.activeFilePath); } } scaleField.val(pos); } }).set(100); scaleField.on('change', function (e) { self.scaleSlide.set(jQuery(this).val()); }); }, /** * Set up and watch the rotate slide and input field */ watchRotate: function () { if (!this.windowopts.crop) { return; } var self = this, r = this.window.find('.rotate'), rotateField = this.window.find('input[name=rotate-val]'); this.rotateSlide = new Slider(r.find('.fabrikslider-line')[0], r.find('.knob')[0], { onChange: function (pos) { self.imgCanvas.rotation = pos; if (self.img !== undefined) { try { self.images[self.activeFilePath].rotation = pos; } catch (err) { fconsole('rorate err' + self.activeFilePath); } } rotateField.val(pos); }, steps : 360 }).set(0); rotateField.on('change', function () { self.rotateSlide.set(jQuery(this).val()); }); }, /** * Show the window - creating it if its not found */ showWin: function () { this.win = Fabrik.getWindow(this.windowopts); this.window = jQuery('#' + this.modalId); if (this.CANVAS === undefined) { return; } if (this.CANVAS.ctxEl !== undefined) { this.CANVAS.ctxPos = document.id(this.CANVAS.ctxEl).getPosition(); } if (this.CANVAS.threads !== undefined) { if (this.CANVAS.threads.get('myThread') !== undefined) { // Fixes issue where sometime canvas thread is not started/running so nothing is drawn this.CANVAS.threads.get('myThread').start(); } } this.win.drawWindow(); this.win.center(); } }); return window.FbFileUpload; });
| ver. 1.4 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка