/* SMF Funcard Maker Frontend by Lancel Thaledric */ $( document ).ready(function() { console.log( "Welcome on SMF Funcard Maker 2 !" ); function Funcard(){ /** * Le nom du template */ this.template = ''; /** * La liste des champs remplis par l'utilisateur. * C'est un table d'objets de type Field. * L'exportation transformera donc ça en objet sérialisé. */ this.fields = []; /** * La liste des panneaux permettant à l'utilisateur de modifier les champs */ this.panels = []; /** * Taille de funcard */ this.width = null; this.height = null; this.ratio = null; // width/height this.illusWidth = null; this.illusHeight = null; } /** * type abstrait. * Définit un des paramètres de la funcard associé à un champ html nom=>valeur */ function Field(){ this.name = null; this.value = null; }; /** * écrit le Field dans le champ html du même nom. * Cette fonction doit être surchargée dans chaque nouveau type de Field */ Field.prototype.writeForm = function(){ // Fonction à surcharger } /** * input de type text */ function TextField(){ Field.call(this); }; TextField.prototype = Object.create(Field.prototype); //Override TextField.prototype.writeForm = function(){ Field.prototype.writeForm.apply(this, arguments); // Fonction à surcharger }/** * Gestion de l'affichage des panneaux */ function Panel(n, t){ this.name = n; this.title = t; this.element = null; } Panel.ID_PREFIX = 'fcm-panel-'; Panel.CLASS_TOGGLE = 'active'; Panel.CONTAINER_ELEMENT = $('.fcm-panel-container'); Panel.MENU_ELEMENT = $('#fcm-menu'); Panel.TEMPLATE_CONTAINER_ELEMENT = $('#fcm-template-panel'); Panel.TEMPLATE_MENU_ELEMENT = $('#fcm-template-menu'); Panel.prototype.getId = function(){ return Panel.ID_PREFIX + this.name; } // Retourne l'élément jQuery du panneau /!\Il peut être vide, si le panneau n'a pas été chargé Panel.prototype.get = function(){ return Panel.CONTAINER_ELEMENT.find('#' + this.getId()); } // Appelé quand le panneau est affiché Panel.prototype.onFocus = function(){ // À redéfinir } // Appelé quand le panneau est caché Panel.prototype.onBlur = function(){ // À redéfinir } // Appelé quand le panneau est activé Panel.prototype.onActivate = function(){ // À redéfinir } // Appelé quand le panneau est déchargé Panel.prototype.onDeactivate = function(){ // À redéfinir } /** * Affiche le panneau et met son lien du menu en surbrillance */ Panel.prototype.show = function(){ this.get().addClass(Panel.CLASS_TOGGLE); Panel.MENU_ELEMENT.find('[data-panel="'+this.name+'"]').parent('li').addClass(Panel.CLASS_TOGGLE); this.onFocus(); } /** * Cache le panel */ Panel.prototype.hide = function(){ this.get().removeClass(Panel.CLASS_TOGGLE); Panel.MENU_ELEMENT.find('[data-panel="'+this.name+'"]').parent('li').removeClass(Panel.CLASS_TOGGLE); this.onBlur(); } /** * Ajoute le panel au menu et l'active * (Le contenu du panel doit déjà avoir été ajouté au DOM) */ Panel.prototype.activate = function(){ Panel.TEMPLATE_MENU_ELEMENT.append('
  • '+this.title+'
  • '); this.element = $('#'+Panel.ID_PREFIX+this.name); this.onActivate(); } /** * Appelle la fonction de désactivation du panneaux. * Certains panneaux, comme celui de l'illustration, ont besoin d'effectuer un tache lors de la désactivation. */ Panel.prototype.deactivate = function(){ this.onDeactivate(); } function IllustrationPanel(n, t){ Panel.call(this, n, t); this.cropSelector = null; } IllustrationPanel.prototype = Object.create(Panel.prototype); IllustrationPanel.prototype.onFocus = function(){ // Gestion du plugin ImgAreaSelect if(this.cropSelector != null){ this.cropSelector.setOptions({show:true, hide:false}); this.cropSelector.update(); } } IllustrationPanel.prototype.onBlur = function(){ // Gestion du plugin ImgAreaSelect if(this.cropSelector != null){ this.cropSelector.setOptions({show:false, hide:true}); this.cropSelector.update(); } } IllustrationPanel.prototype.onDeactivate = function(){ // Gestion du plugin ImgAreaSelect if(this.cropSelector != null){ this.cropSelector.remove(); } } IllustrationPanel.prototype.onActivate = function(){ var varthis = this; Panel.CONTAINER_ELEMENT.on('uploadSuccess', '#fcm-form-illustration', function(){ varthis.onImageLoad(); }); Panel.CONTAINER_ELEMENT.on('uploadFailure', '#fcm-form-illustration', function(){ varthis.onImageUnload(); }); Panel.CONTAINER_ELEMENT.on('click', '#fcm-illsutration-center-viewport', function(){ varthis.centerImage(); return false; }); } IllustrationPanel.prototype.onImageLoad = function(){ var image = this.element.find('.file-preview'); var centerbutton = this.element.find('#fcm-illsutration-center-viewport'); centerbutton.addClass('active'); image.load(function(){ // init imgAreaSelect centerbutton.trigger('click'); }); } IllustrationPanel.prototype.onImageUnload = function(){ var image = this.element.find('.file-preview'); var centerbutton = this.element.find('#fcm-illsutration-center-viewport'); centerbutton.removeClass('active'); image.imgAreaSelect({remove:true}); } IllustrationPanel.prototype.centerImage = function(){ // init imgAreaSelect var form = this.element.find('form'); var image = form.find('.file-preview'); var axis = true; // true = X(portait), false = Y(paysage) if(image.width() / image.height() > myFuncard.illusWidth / myFuncard.illusHeight) axis = false; var cx1 = 0, cx2 = 0, cy1 = 0, cy2 = 0; if(axis){ cx2 = image.width(); var height = image.width() / (myFuncard.illusWidth / myFuncard.illusHeight); cy1 = (image.height() - height) / 2; cy2 = cy1 + height; } else { var width = image.height() * (myFuncard.illusWidth / myFuncard.illusHeight); cx1 = (image.width() - width) / 2; cx2 = cx1 + width; cy2 = image.height(); } form.find('#fcm-field-illuscrop-x').val(''); form.find('#fcm-field-illuscrop-y').val(''); form.find('#fcm-field-illuscrop-w').val(''); form.find('#fcm-field-illuscrop-h').val(''); this.cropSelector = image.imgAreaSelect({ instance: true, handles: true, persistent: true, aspectRatio: myFuncard.illusWidth + ':' + myFuncard.illusHeight, x1: cx1, y1: cy1, x2: cx2, y2: cy2, onSelectEnd: function (img, selection) { img = $(img); var px = selection.x1 / img.width(); var py = selection.y1 / img.height(); var pw = selection.width / img.width(); var ph = selection.height / img.height(); form.find('#fcm-field-illuscrop-x').val(px*100); form.find('#fcm-field-illuscrop-y').val(py*100); form.find('#fcm-field-illuscrop-w').val(pw*100); form.find('#fcm-field-illuscrop-h').val(ph*100); } }); } function ModernPW3IllustrationPanel(n, t){ IllustrationPanel.call(this, n, t); } ModernPW3IllustrationPanel.prototype = Object.create(IllustrationPanel.prototype); ModernPW3IllustrationPanel.prototype.onActivate = function(){ IllustrationPanel.prototype.onActivate.call(this); } ModernPW3IllustrationPanel.prototype.centerImage = function(){ IllustrationPanel.prototype.centerImage.call(this); if(this.cropSelector != null){ this.cropSelector.setOptions({classPrefix:'mpw3-imgareaselect', handles:true}); this.cropSelector.update(); } } function ModernPW4IllustrationPanel(n, t){ IllustrationPanel.call(this, n, t); } ModernPW4IllustrationPanel.prototype = Object.create(IllustrationPanel.prototype); ModernPW4IllustrationPanel.prototype.onActivate = function(){ IllustrationPanel.prototype.onActivate.call(this); } ModernPW4IllustrationPanel.prototype.centerImage = function(){ IllustrationPanel.prototype.centerImage.call(this); if(this.cropSelector != null){ this.cropSelector.setOptions({classPrefix:'mpw4-imgareaselect', handles:true}); this.cropSelector.update(); } } function BackgroundPanel(n, t){ Panel.call(this, n, t); } BackgroundPanel.prototype = Object.create(Panel.prototype); BackgroundPanel.prototype.onActivate = function(){ BackgroundPanel.SELECTOR_INNER_ELEMENT = $('#fcm-background-content'); BackgroundPanel.LOADING_ICON = $('#fcm-background-loading-icon'); this.loadBackgrounds(); } BackgroundPanel.prototype.loadBackgrounds = function(){ BackgroundPanel.LOADING_ICON.addClass('active'); //showLoading(); // Call getbackgrounds.php var thisvar = this; $.get( 'getbackgrounds.php', { 'template' : myFuncard.template, 'titles' : myFuncard.titles }, function(data){ BackgroundPanel.SELECTOR_INNER_ELEMENT.html(data); thisvar.get().trigger('backgroundsLoaded'); // Autoselect red skin thisvar.get().find('[id*="base"] button[data-value="r"]').trigger('click'); // And none for skin parts thisvar.get().find('button[data-value=""]').trigger('click'); } ).fail(function() { alert( "error" ); }) .always(function(){ BackgroundPanel.LOADING_ICON.removeClass('active'); //hideLoading(); }); } function ModernBasicBackgroundPanel(n, t){ Panel.call(this, n, t); } ModernBasicBackgroundPanel.prototype = Object.create(Panel.prototype); ModernBasicBackgroundPanel.prototype.onActivate = function(){ ModernBasicBackgroundPanel.FORM_CUSTOM_BG = $('#fcm-form-custom-background'); ModernBasicBackgroundPanel.BUTTONS_GENERATED_BG = $('.fcm-selector-button'); ModernBasicBackgroundPanel.FORM_CUSTOM_BG_ERROR = ModernBasicBackgroundPanel.FORM_CUSTOM_BG.find('.file-error'); ModernBasicBackgroundPanel.FORM_CUSTOM_BG_IMAGE = ModernBasicBackgroundPanel.FORM_CUSTOM_BG.find('.file-preview'); ModernBasicBackgroundPanel.BUTTONS_GENERATED_BG.click(function(){ ModernBasicBackgroundPanel.FORM_CUSTOM_BG.find('#fcm-file-background').val(''); ModernBasicBackgroundPanel.FORM_CUSTOM_BG_ERROR.removeClass('active'); ModernBasicBackgroundPanel.FORM_CUSTOM_BG_IMAGE.removeClass('active'); ModernBasicBackgroundPanel.FORM_CUSTOM_BG.find('#fcm-field-background-custom').val(''); }); } function ExtensionSymbolPanel(n, t){ Panel.call(this, n, t); } ExtensionSymbolPanel.prototype = Object.create(Panel.prototype); ExtensionSymbolPanel.prototype.onActivate = function(){ var varthis = this; ExtensionSymbolPanel.RARITY_SELECTOR = $('#fcm-se-rarity-selector'); ExtensionSymbolPanel.RARITY_SELECTOR_BUTTONS = ExtensionSymbolPanel.RARITY_SELECTOR.find('.fcm-selector-button'); ExtensionSymbolPanel.EXTENSION_SELECTOR = $('#fcm-se-extension-selector'); ExtensionSymbolPanel.EXTENSION_SELECTOR_BUTTONS = ExtensionSymbolPanel.EXTENSION_SELECTOR.find('.fcm-selector-button'); ExtensionSymbolPanel.SE_CLEAR_BUTTON = $('#fcm-se-clear-button'); ExtensionSymbolPanel.FIELD_EXTENSION = $('#fcm-field-se-extension'); ExtensionSymbolPanel.FIELD_RARITY = $('#fcm-field-se-rarity'); ExtensionSymbolPanel.FIELD_CUSTOM = $('#fcm-field-se-custom'); ExtensionSymbolPanel.CUSTOM_PREVIEW = $('#fcm-se-file-preview'); ExtensionSymbolPanel.FILE_SELECTOR = $('#fcm-file-se'); ExtensionSymbolPanel.UPLOAD_FORM = $('#fcm-form-custom-se'); ExtensionSymbolPanel.EXTENSION_SELECTOR_BUTTONS.click(function(){ ExtensionSymbolPanel.RARITY_SELECTOR.addClass('active'); var img; // common img = ExtensionSymbolPanel.RARITY_SELECTOR.find('button[data-value="c"]>img'); img.attr('src', 'resource/seThumb/'+$(this).data('value')+'-c.png'); // uncommon img = ExtensionSymbolPanel.RARITY_SELECTOR.find('button[data-value="u"]>img'); img.attr('src', 'resource/seThumb/'+$(this).data('value')+'-u.png'); // rare img = ExtensionSymbolPanel.RARITY_SELECTOR.find('button[data-value="r"]>img'); img.attr('src', 'resource/seThumb/'+$(this).data('value')+'-r.png'); // mythic img = ExtensionSymbolPanel.RARITY_SELECTOR.find('button[data-value="m"]>img'); img.attr('src', 'resource/seThumb/'+$(this).data('value')+'-m.png'); // shifted img = ExtensionSymbolPanel.RARITY_SELECTOR.find('button[data-value="s"]>img'); img.attr('src', 'resource/seThumb/'+$(this).data('value')+'-s.png'); // auto rarity var field = ExtensionSymbolPanel.RARITY_SELECTOR.find('.fcm-selector-field'); if(!field.val()){ ExtensionSymbolPanel.RARITY_SELECTOR.find('button[data-value="c"]').trigger('click'); } }); ExtensionSymbolPanel.SE_CLEAR_BUTTON.click(function(){ varthis.clearOfficialSE(); varthis.clearCustomSE(); }); ExtensionSymbolPanel.UPLOAD_FORM.on('uploadSuccess', function(){ varthis.clearOfficialSE(); }) ExtensionSymbolPanel.RARITY_SELECTOR_BUTTONS.click(function(){ varthis.clearCustomSE(); }); ExtensionSymbolPanel.EXTENSION_SELECTOR_BUTTONS.click(function(){ varthis.clearCustomSE(); }); } ExtensionSymbolPanel.prototype.clearOfficialSE = function(){ // Clear rarity selector ExtensionSymbolPanel.RARITY_SELECTOR_BUTTONS.filter('.active').removeClass('active'); ExtensionSymbolPanel.RARITY_SELECTOR.removeClass('active'); ExtensionSymbolPanel.EXTENSION_SELECTOR_BUTTONS.filter('.active').removeClass('active'); // hidden fields ExtensionSymbolPanel.FIELD_EXTENSION.val(''); ExtensionSymbolPanel.FIELD_RARITY.val(''); } ExtensionSymbolPanel.prototype.clearCustomSE = function(){ // image ExtensionSymbolPanel.CUSTOM_PREVIEW.removeClass('active'); ExtensionSymbolPanel.CUSTOM_PREVIEW.attr('src', ''); ExtensionSymbolPanel.FILE_SELECTOR.val(''); // hidden field ExtensionSymbolPanel.FIELD_CUSTOM.val(''); } function getPanelByName(name){ return existingPanels[name]; } var existingPanels = []; // Sections du header existingPanels['home'] = new Panel('home', 'Accueil'); existingPanels['newcard'] = new Panel('newCard', 'Nouvelle carte'); existingPanels['help'] = new Panel('help', 'Aide'); existingPanels['credits'] = new Panel('credits', 'Crédits'); existingPanels['changelog'] = new Panel('changelog', 'Changelog'); existingPanels['tools'] = new Panel('tools', 'Outils'); // Sections du menu permanentes existingPanels['template'] = new Panel('template', 'Template'); existingPanels['import-export'] = new Panel('import-export', 'Import / Export'); existingPanels['done'] = new Panel('done', 'Terminé !'); // Sections de génération de fonds existingPanels['modernbasicbackground'] = new ModernBasicBackgroundPanel('modernbasicbackground', 'Fond de carte'); existingPanels['oldbasicbackground'] = new ModernBasicBackgroundPanel('oldbasicbackground', 'Fond de carte'); existingPanels['modernplaneswalkerbackground'] = new ModernBasicBackgroundPanel('modernplaneswalkerbackground', 'Fond de carte'); // Sections de fabrication de carte existingPanels['illustration'] = new IllustrationPanel('illustration', 'Illustration'); existingPanels['mpw3-illustration'] = new ModernPW3IllustrationPanel('mpw3-illustration', 'Illustration'); existingPanels['mpw4-illustration'] = new ModernPW4IllustrationPanel('mpw4-illustration', 'Illustration'); existingPanels['titre-type'] = new Panel('titre-type', 'Titre et type'); existingPanels['cm'] = new Panel('cm', 'Coût de mana'); existingPanels['capa'] = new Panel('capa', 'Capacité
    Texte d\'ambiance'); existingPanels['mpw3-capa'] = new Panel('mpw3-capa', 'Capacité
    Texte d\'ambiance'); existingPanels['mpw4-capa'] = new Panel('mpw4-capa', 'Capacité
    Texte d\'ambiance'); existingPanels['fe'] = new Panel('fe', 'Force / Endurance'); existingPanels['modernbasicfe'] = new Panel('modernbasicfe', 'Force / Endurance'); existingPanels['loyalty'] = new Panel('loyalty', 'Loyauté de base'); existingPanels['se'] = new ExtensionSymbolPanel('se', 'Symbole d\'extension'); existingPanels['illus-copy'] = new Panel('illus-copy', 'Illustrateur
    Copyright'); // Ici, il n'y a pas de classes particulières pour ces panneaux, alors on ne passe pas par le prototype existingPanels['done'].onFocus = function(){ updatePreview(); } existingPanels['titre-type'].onFocus = function(){ $('#fcm-field-title').focus(); } existingPanels['cm'].onFocus = function(){ $('#fcm-field-cm').focus(); } existingPanels['capa'].onFocus = function(){ $('#fcm-field-capa').focus(); } existingPanels['fe'].onFocus = function(){ $('#fcm-field-fe').focus(); } existingPanels['illus-copy'].onFocus = function(){ $('#fcm-field-illustrator').focus(); } // Dictionnaire des templates var existingTemplates = []; // contient tous mes templates de base /** * Modern Basic */ function ModernBasicTemplate(){ Funcard.call(this); this.template = 'modern-basic'; this.panels = [ existingPanels['modernbasicbackground'], existingPanels['illustration'], existingPanels['titre-type'], existingPanels['cm'], existingPanels['capa'], existingPanels['modernbasicfe'], existingPanels['se'], existingPanels['illus-copy'] ]; this.resetSize(); /*this.width = Math.floor(791./2.); this.height = Math.floor(1107./2.);*/ this.illusWidth = 651; this.illusHeight = 480; } ModernBasicTemplate.prototype = Object.create(Funcard.prototype); ModernBasicTemplate.prototype.resetSize = function(){ this.width = 791; this.height = 1107; } existingTemplates['modern-basic'] = new ModernBasicTemplate(); /** * Old Basic */ function OldBasicTemplate(){ Funcard.call(this); this.template = 'old-basic'; this.panels = [ existingPanels['oldbasicbackground'], existingPanels['illustration'], existingPanels['titre-type'], existingPanels['cm'], existingPanels['capa'], existingPanels['fe'], existingPanels['se'], existingPanels['illus-copy'] ]; this.resetSize(); /*this.width = Math.floor(791./2.); this.height = Math.floor(1107./2.);*/ this.illusWidth = 601; this.illusHeight = 485; } OldBasicTemplate.prototype = Object.create(Funcard.prototype); OldBasicTemplate.prototype.resetSize = function(){ this.width = 787; this.height = 1087; } existingTemplates['old-basic'] = new OldBasicTemplate(); /** * Modern Planeswalker 3 capas */ function ModernPlaneswalker3Template(){ Funcard.call(this); this.template = 'modern-planeswalker3'; this.panels = [ existingPanels['modernplaneswalkerbackground'], existingPanels['mpw3-illustration'], existingPanels['titre-type'], existingPanels['cm'], existingPanels['mpw3-capa'], existingPanels['loyalty'], existingPanels['se'], existingPanels['illus-copy'] ]; this.resetSize(); /*this.width = Math.floor(791./2.); this.height = Math.floor(1107./2.);*/ this.illusWidth = 665; // Bounding box of illus-mask this.illusHeight = 890; } ModernPlaneswalker3Template.prototype = Object.create(Funcard.prototype); ModernPlaneswalker3Template.prototype.resetSize = function(){ this.width = 791; this.height = 1107; } existingTemplates['modern-planeswalker3'] = new ModernPlaneswalker3Template(); /** * Modern Planeswalker 4 capas */ function ModernPlaneswalker4Template(){ Funcard.call(this); this.template = 'modern-planeswalker4'; this.panels = [ existingPanels['modernplaneswalkerbackground'], existingPanels['mpw4-illustration'], existingPanels['titre-type'], existingPanels['cm'], existingPanels['mpw4-capa'], existingPanels['loyalty'], existingPanels['se'], existingPanels['illus-copy'] ]; this.resetSize(); /*this.width = Math.floor(791./2.); this.height = Math.floor(1107./2.);*/ this.illusWidth = 665; // Bounding box of illus-mask this.illusHeight = 890; } ModernPlaneswalker4Template.prototype = Object.create(Funcard.prototype); ModernPlaneswalker4Template.prototype.resetSize = function(){ this.width = 791; this.height = 1107; } existingTemplates['modern-planeswalker4'] = new ModernPlaneswalker4Template();/** * Gestion de la funcard de l'uilisateur */ var myFuncard = null; function loadTemplate(template){ if(template in existingTemplates) myFuncard = Object.create(existingTemplates[template]); }var DEBUG = false; // TODO Clean all the code // Elements var generator = $('#fcm-generator'); var loading = $('.loading-wrapper'); var loadingPreview = $('.fcm-preview-loading'); var preview = $('.fcm-preview'); var previewImage = $('.fcm-preview-image'); var previewReloder = $('#fcm-preview-reload'); var previewDebug = $('.fcm-preview-debug'); var previewTime = $('.fcm-preview-generation-time'); // focus element var focusElement = null; // innerLoading var innerLoading = 0; // Panels var currentPanel = null; // Events /** * Changement de panneau lorsqu'on clique sur un bouton étant associé à un panneau */ $('#fcm-menu, #fcm-header').on('click', '[data-panel]', function(e){ // Check if it's a valid link if(!$(this).data('panel')) return true; changePanel($(this).data('panel')); return false; }) // Panel displayer /** * Efface le panneau courant et affiche celui passé en paramètre. */ function changePanel(name){ // hide the current panel if(currentPanel){ currentPanel.hide(); } // Show the new panel var panel = existingPanels[name]; currentPanel = panel; panel.show(); } /** * Retourne le panneau dans lequel est situé un élément du DOM passé en paramètre */ function getElementPanel(elem){ var panelElement = elem.closest('[id^='+Panel.ID_PREFIX+']'); //console.log(panelElement); if(!panelElement.length) return null; var panelName = panelElement.attr('id'); //console.log(panelName); panelName = panelName.substr(Panel.ID_PREFIX.length); //console.log(panelName); if (!(panelName in existingPanels)) return null; return existingPanels[panelName]; } /** * Efface la liste des panneaux et charge les nouveaux panneaux * à partir des données de la funcard passée en paramètre */ function loadPanels(funcard){ showLoading(); var panelsTab = getFuncardPanelNameList(funcard); // Call getpanels.php $.get( 'getpanels.php', { 'panels[]' : panelsTab }, function(data){ // Destroy current pannels clearPanels(); showPanels(funcard, data); changePanel(panelsTab[0]); generator.trigger('panelsLoaded'); setTimeout( function(){ $('.warning-template-changes').addClass('active'); }, 10); } ).fail(function() { alert( 'Erreur au chargement des composantes de la funcard. Veuillez réessayer.' ); }) .always(function(){ hideLoading(); }); } /** * Retourne la liste des noms de panneaux de la funcard */ function getFuncardPanelNameList(funcard){ // On crée un tableau contenant les noms de panneaux à charger var panelsTab = []; if(funcard != null){ for(var panel of funcard.panels){ panelsTab.push(panel.name); } } return panelsTab; } /** * Efface tous les panneaux */ function clearPanels(){ Panel.TEMPLATE_CONTAINER_ELEMENT.html(''); Panel.TEMPLATE_MENU_ELEMENT.html(''); } /** * Show Panels : Affiche les panneaux chargés */ function showPanels(funcard, data){ // On désactive les anciens panneaux s'ils existent if(funcard != null){ for(var panel of funcard.panels){ panel.deactivate(); } } // On ajoute les panneaux chargés Panel.TEMPLATE_CONTAINER_ELEMENT.html(data); // On active les panneaux (ça les ajoute dans le menu notamment) if(funcard != null){ for(var panel of funcard.panels){ panel.activate(); } } } /** * Charge le template dans myFuncard */ Panel.CONTAINER_ELEMENT.on('click', '#fcm-template-selector .fcm-selector-button', function(){ loadTemplate($(this).data('value')); // Une fois le template chargé, on update la preview une fois unique. generator.one('panelsLoaded', updatePreview); loadPanels(myFuncard); }); /** * Affiche/Cache un icone loading sur le generator */ function showLoading(){ ++innerLoading; if(innerLoading > 1) return; loading.addClass('active'); setTimeout( function(elem){ elem.addClass('opaque'); }, 10, loading); } function hideLoading(){ --innerLoading; if(innerLoading > 0) return; loading.removeClass('active'); setTimeout( function(elem){ elem.removeClass('opaque'); }, 10, loading); } /** * Affiche/Cache un icone loading sur la prévisualisation */ function showPreviewLoading(){ loadingPreview.addClass('active'); setTimeout( function(elem){ elem.addClass('opaque'); }, 10, loadingPreview); } function hidePreviewLoading(){ loadingPreview.removeClass('active'); setTimeout( function(elem){ elem.removeClass('opaque'); }, 10, loadingPreview); } /** * Met à jour la prévisualition */ function updatePreview(){ if(!myFuncard) return false; updateFields(myFuncard); myFuncard.resetSize(); showPreviewLoading(); //preview.css('width', myFuncard.width); //preview.css('height', myFuncard.height); // CALL THE GENERATION !!!! HELL YEAH !!!! $.post( "generate.php", { // Data to send to the generation algorithm 'width': myFuncard.width, 'height': myFuncard.height, 'template' : myFuncard.template, 'fields' : myFuncard.fields },function( data ) { // success function if(DEBUG){ previewDebug.html(data); } else { //console.log(data); preview.removeClass('nocard'); previewImage.css('background-image', 'url(data:image/png;base64,'+data.image+')'); previewTime.html('Généré en ' + data.generationTime.toFixed(3) + ' secondes.'); myFuncard.width = data.width; myFuncard.height = data.height; preview.css('width', myFuncard.width); preview.css('height', myFuncard.height); } }) .fail(function(xhr) { if(!isUserAborted(xhr)){ alert( "error" ); } }) .always(function(){ hidePreviewLoading(); }); return false; } previewReloder.click(updatePreview); function isUserAborted(xhr) { return !xhr.getAllResponseHeaders(); } /** * Met à jour la myFuncard d'après les valeurs des inputs HTML */ function updateFields(funcard){ var htmlInputs = Panel.CONTAINER_ELEMENT.find('[name|="fcm-field"]'); funcard.fields = {}; htmlInputs.each(function(){ var fieldname = $(this).attr('name'); fieldname = fieldname.slice(10); // 10 characters in 'fcm-fields-' var fieldvalue= $(this).val(); funcard.fields[fieldname] = fieldvalue; }) } /** * Affiche le panel Home au chargement de la page, et au clic sur le logo */ if($('body').hasClass('index')){ changePanel('home'); } /** * Boutons d'insertion de contenu automatique dans le champ * Utilisé pour les symboles de mna et les caractères spéciaux */ // Il faut constamment enir à jour le dernier champ focussé Panel.CONTAINER_ELEMENT.on('focus', 'input, textarea', function(){ focusElement = $(this); }); Panel.CONTAINER_ELEMENT.on('click', 'button.single-inserter', function(){ var caretPosStart = focusElement[0].selectionStart; var caretPosEnd = focusElement[0].selectionEnd; var textAreaTxt = focusElement.val(); var txtToAdd = $(this).data('insert'); if(txtToAdd === undefined) return; focusElement.val(textAreaTxt.substring(0, caretPosStart) + txtToAdd + textAreaTxt.substring(caretPosEnd) ); focusElement.focus(); setCaretPosition(focusElement[0], caretPosEnd + txtToAdd.length, caretPosEnd + txtToAdd.length); }); Panel.CONTAINER_ELEMENT.on('click', 'button.double-inserter', function(){ var caretPosStart = focusElement[0].selectionStart; var caretPosEnd = focusElement[0].selectionEnd; var textAreaTxt = focusElement.val(); var txtToAdd = $(this).data('insert'); if(txtToAdd === undefined || !$.isArray(txtToAdd) || txtToAdd[0] === undefined || txtToAdd[1] === undefined) return; focusElement.val(textAreaTxt.substring(0, caretPosStart) + txtToAdd[0] + textAreaTxt.substring(caretPosStart, caretPosEnd) + txtToAdd[1] + textAreaTxt.substring(caretPosEnd) ); focusElement.focus(); setCaretPosition(focusElement[0], caretPosStart, caretPosEnd + txtToAdd[0].length + txtToAdd[1].length); }); /** * Code from eternal : http://stackoverflow.com/questions/512528/set-cursor-position-in-html-textbox */ function setCaretPosition(ctrl, pos1, pos2) { if(ctrl.setSelectionRange) { ctrl.focus(); ctrl.setSelectionRange(pos1,pos2); } else if (ctrl.createTextRange) { var range = ctrl.createTextRange(); range.collapse(true); range.moveEnd('character', pos2); range.moveStart('character', pos1); range.select(); } } // Keyboard shortcut to print nbsp $(document).keydown(function (event) { // espace avec Maj if (event.which == 32 && event.shiftKey) { var caretPosStart = focusElement[0].selectionStart; var caretPosEnd = focusElement[0].selectionEnd; var textAreaTxt = focusElement.val(); var txtToAdd = '\u00A0'; focusElement.val(textAreaTxt.substring(0, caretPosStart) + txtToAdd + textAreaTxt.substring(caretPosEnd) ); focusElement.focus(); setCaretPosition(focusElement[0], caretPosEnd + txtToAdd.length, caretPosEnd + txtToAdd.length); event.preventDefault(); } }); // Media Handling Panel.CONTAINER_ELEMENT.on('change', '.fcm-media', function(){ var form = $(this).closest('form'); var formdata = (window.FormData) ? new FormData(form[0]) : null; var data = (formdata !== null) ? formdata : form.serialize(); var loading = form.find('.file-loading-icon'); var error = form.find('.file-error'); var image = form.find('.file-preview'); var field = form.find('.file-field'); function showMediaUploadError(message){ error.html(message); image.removeClass('active'); error.addClass('active'); field.val(''); form.trigger('uploadFailure'); } function showMediaUploadMessage(message){ error.html(message); error.addClass('active'); } loading.addClass('active'); // début des opérations $.ajax({ url: form.attr('action'), type: form.attr('method'), contentType: false, // obligatoire pour de l'upload processData: false, // obligatoire pour de l'upload //dataType: 'json', // selon le retour attendu data: data }).done(function(response){ response = $.parseJSON(response); // On a reçu la réponse du serveur, c'est soit le filepath, soit une erreur. Soit un autre truc inconnu, mais là c'est bizarre. if("filepath" in response){ image.attr('src', 'uploads/'+response.filepath); image.addClass('active'); showMediaUploadMessage('Votre image sera disponible jusqu\'à minuit.'); field.val(response.filepath); form.trigger('uploadSuccess'); } else if("error" in response){ showMediaUploadError(response.error); } else { showMediaUploadError('Erreur inconnue. Merci de nous en parler sur le forum.'); } }).fail(function(){ showMediaUploadError('Erreur lors de l\'envoi du fichier.'); }).always(function(){ loading.removeClass('active'); }); }); /** * Gestion des sélecteurs */ Panel.CONTAINER_ELEMENT.on('click', '.fcm-selector .fcm-selector-button', function(){ var container = $(this).closest('.fcm-selector'); var field = container.find('.fcm-selector-field'); // On décoche le clear button s'il existe container.find('.fcm-selector-clear-button.active').removeClass('active'); //clear previous slected element container.find('.fcm-selector-button.active').removeClass('active'); $(this).addClass('active'); //set hidden field field.val($(this).data('value')); }); Panel.CONTAINER_ELEMENT.on('click', '.fcm-toggle-button', function(){ $(this).toggleClass('active'); }); Panel.CONTAINER_ELEMENT.on('click', '.fcm-toggle-duoselector', function(){ var container = $(this).closest('.fcm-selector, .fcm-duoselector'); container.toggleClass('fcm-duoselector'); container.toggleClass('fcm-selector'); if(container.hasClass('fcm-selector')){ var button = $(container.find('.fcm-selector-button.active')[0]); container.find('.fcm-selector-button.active').removeClass('active first second'); button.trigger('click'); } else if(container.hasClass('fcm-duoselector')){ container.find('.fcm-selector-button.active').addClass('first'); } }); Panel.CONTAINER_ELEMENT.on('click', '.fcm-duoselector .fcm-selector-button', function(){ var container = $(this).closest('.fcm-duoselector'); var field = container.find('.fcm-selector-field'); var str = ''; var separator = false; var checked = container.find('.fcm-selector-button.active'); var nbchecked = checked.length; // On décoche le clear button s'il existe container.find('.fcm-selector-clear-button.active').removeClass('active'); // Si nous avons déjà deux boutons sélectionnés, nous les effaçons if(nbchecked >= 2){ container.find('.fcm-selector-button.active').removeClass('active first second'); $(this).addClass('active first'); } // Coche si premier bouton if(nbchecked == 0){ $(this).addClass('active first'); } // Coche si deuxième bouton différent du premier if(nbchecked == 1 && $(this)[0] != checked[0]){ $(this).addClass('active second'); } // On check quel est le séparateur if(container.data('separator')) separator = container.data('separator'); // On calcule la valeur du champ var first = container.find('.fcm-selector-button.active.first'); if(first.length) str += first.data('value'); var second = container.find('.fcm-selector-button.active.second'); if(separator != false && first.length && second.length) str += separator; if(second.length) str += second.data('value'); field.val(str); }); Panel.CONTAINER_ELEMENT.on('click', '.fcm-selector-clear-button', function(){ var container = $(this).closest('.fcm-selector, .fcm-duoselector'); var field = container.find('.fcm-selector-field'); var buttons = container.find('.fcm-selector-button'); buttons.removeClass('active first second'); field.val(''); $(this).addClass('active'); }); /** * Télécharge le rendu final */ Panel.CONTAINER_ELEMENT.on('click', '#fcm-download-jpg', function(){ if(!myFuncard){ alert('Vous ne voudriez pas créer une funcard, d\'abord ?'); return; } updateFields(myFuncard); // CALL THE GENERATION !!!! HELL YEAH !!!! openWithPostData('generate.php',{ // Data to send to the generation algorithm 'width' : myFuncard.width, 'height' : myFuncard.height, 'template' : myFuncard.template, 'fields' : myFuncard.fields, 'method' : 'thumbnail' }); }); Panel.CONTAINER_ELEMENT.on('click', '#fcm-download', function(){ if(!myFuncard){ alert('Vous ne voudriez pas créer une funcard, d\'abord ?'); return; } updateFields(myFuncard); // CALL THE GENERATION !!!! HELL YEAH !!!! openWithPostData('generate.php',{ // Data to send to the generation algorithm 'width' : myFuncard.width, 'height' : myFuncard.height, 'template' : myFuncard.template, 'fields' : myFuncard.fields, 'method' : 'download' }); }); function openWithPostData(page,data) { var form = document.createElement('form'); form.setAttribute('action', page); form.setAttribute('method', 'post'); recursiveCreateFields(form, data, false); document.body.appendChild(form); form.submit(); document.body.removeChild(form); } function recursiveCreateFields(form, data, field){ for (var n in data) { //console.log(n, data[n]); if(data[n] !== null && typeof data[n] === 'object') recursiveCreateFields(form, data[n], field || (n==='fields')); else createElementField(form, data, n, field); } } function createElementField(form, data, n, field){ var inputvar = document.createElement('input'); inputvar.setAttribute('type', 'hidden'); inputvar.setAttribute('name', field ? 'fields[' + n + ']' : n); inputvar.setAttribute('value', data[n]); form.appendChild(inputvar); } /** * Exporte la funcard dans un fichier json */ Panel.CONTAINER_ELEMENT.on('click', '#fcm-export', function(){ if(!myFuncard) return; updateFields(myFuncard); // CALL THE GENERATION !!!! HELL YEAH !!!! openWithPostData('export.php',{ // Data to send to the generation algorithm 'width' : myFuncard.width, 'height' : myFuncard.height, 'template' : myFuncard.template, 'fields' : myFuncard.fields, 'method' : 'download' }); }); /** * Importe la funcard depuis un fichier json */ Panel.CONTAINER_ELEMENT.on('change', '#fcm-file-import', function(){ if(!$(this).val()) return; var form = $(this).closest('form'); var loading = form.find('.file-loading-icon'); var error = form.find('.file-error'); var inputElement = $(this); loading.addClass('active'); // Code adapted from Trausti Kristjansson's. var input, file, fr, json; if (typeof window.FileReader !== 'function') { alert("Hum... votre navigateur semble un peu vieux, non ? Vous devriez utilisez un navigateur plus récent."); return; } input = $(this)[0]; if (!input) { alert("Um, couldn't find the fileinput element."); loading.removeClass('active'); } else if (!input.files) { alert("Hum... votre navigateur semble un peu vieux, non ? Vous devriez utilisez un navigateur plus récent."); loading.removeClass('active'); } else if (!input.files[0]) { alert("Merci de sélectionner un fichier"); loading.removeClass('active'); } else { file = input.files[0]; fr = new FileReader(); fr.onload = receivedText; fr.readAsText(file); } function receivedText(e) { //loading.removeClass('active'); var lines = e.target.result; //console.log(lines); json = JSON.parse(lines); importFuncard(json); } function importFuncard(json){ // on prend le bon template error.removeClass('active'); if(!json.hasOwnProperty('template') || !json.hasOwnProperty('width') || !json.hasOwnProperty('height') || !json.hasOwnProperty('fields')){ importError('Fichier corrompu. Tentez un autre fichier. (Erreur 1)'); return; } if(!existingTemplates.indexOf(json.template)){ importError('Fichier corrompu. Tentez un autre fichier. (Erreur 2)'); return; } // Une fois les fond chargés, on continue l'importation. // BackgroundsLoaded s'est effectué après panelsLoaded generator.one('backgroundsLoaded', json.fields, function(event){ importFuncardFieldsEvent(event); }); loadTemplate(json.template); loadPanels(myFuncard); myFuncard.width = json.width; myFuncard.height = json.height; myFuncard.fields = json.fields; } function importError(msg){ error.addClass('active').html(msg); loading.removeClass('active'); inputElement.val(''); } function importFuncardFieldsEvent(event){ //console.log(event.data); var fieldsToImport = event.data; for( field in fieldsToImport ) { // on se charge du field var fieldElement = $('#fcm-field-'+field); fieldElement.val(fieldsToImport[field]); //on se charge du bouton s'il existe var selectorElement = $('.fcm-selector[data-field="fcm-field-'+field+'"]'); var buttonElement = selectorElement.find('.fcm-selector-button[data-value="'+fieldsToImport[field]+'"]'); //console.log(buttonElement); buttonElement.trigger('click'); } loading.removeClass('active'); inputElement.val(''); updatePreview(); } }); /** * Afficher/cacher des paragraphes de l'aide */ Panel.CONTAINER_ELEMENT.on('click', '.help-title', function(){ var paragraph = $(this).next('.help-paragraph'); $(this).toggleClass('active'); paragraph.toggleClass('active'); }); /** * Affiche / masque le menu principal sur petites résolutions */ $('#menu-toggle').click(function(){ $('#main-menu').toggleClass('active'); $('#menu-toggle .fa').toggleClass('fa-bars').toggleClass('fa-times'); }); });