Changeset 111546 in spip-zone


Ignore:
Timestamp:
Sep 11, 2018, 8:10:30 AM (2 years ago)
Author:
bystrano@…
Message:

On reprend le js à zéro

On aimerait permettre des recadrages plus grands que l'image, pour mieux gérer
le cas des images trop petites pour des dimensions imposées.

Mais le code est trop "spaghetti", on y comprend plus rien, alors on reprend
depuis le début en faisant attention à être plus structuré…

File:
1 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/massicot/trunk/javascripts/formulaireMassicoterImage.js

    r104439 r111546  
    1 /* jshint strict: true, undef: true, unused: true, curly: true,
    2    eqeqeq: true, freeze: true, funcscope: true, futurehostile: true,
    3    nonbsp: true */
    4 /* globals $ */
     1/* global $ */
    52
    63$.fn.formulaireMassicoterImage = function ( options ) {
    7         "use strict";
     4        'use strict';
    85
    9         options = $.extend(true,
    10                                            {
    11                                                    zoom: 1
    12                                            },
    13                                            options
    14                                           );
     6        options = $.extend(
     7                true,
     8                { zoom: 1 },
     9                options
     10        );
    1511
    16         var zoom = options.zoom,
    17                 img = $('.image-massicot img'),
    18                 largeur_image = parseInt(img.attr('width'), 10),
    19                 hauteur_image = parseInt(img.attr('height'), 10),
    20                 premier_chargement = isNaN(parseInt($('input[name=x1]').val(), 10)),
    21                 selection_initiale,
    22                 selection_nozoom,
    23                 slider,
    24                 imgAreaSelector,
    25                 mode_dimensions_forcees = (options.forcer_dimensions !== null),
    26                 forcer_hauteur,
    27                 forcer_largeur,
    28                 select_format = $('#champ_format');
     12        var self = this,
     13                img = self.parent().find('.image-massicot img');
    2914
    30         /* Si le formulaire n'a pas été chargé en php, on s'en occupe ici. */
    31         if (premier_chargement) {
    32                 selection_initiale = {
    33                         x1: 0,
    34                         x2: parseInt(img.attr('width'),10),
    35                         y1: 0,
    36                         y2: parseInt(img.attr('height'),10)
    37                 };
    38         } else {
    39                 selection_initiale = {
    40                         x1: parseInt($('input[name=x1]').val(), 10),
    41                         x2: parseInt($('input[name=x2]').val(), 10),
    42                         y1: parseInt($('input[name=y1]').val(), 10),
    43                         y2: parseInt($('input[name=y2]').val(), 10)
     15        form_init();
     16
     17        /**
     18         * Initialisation du formulaire
     19         *
     20         * Si les saisies n'ont pas de valeurs définies, on les initialise â la taille
     21         * de l'image.
     22         */
     23        function form_init () {
     24
     25                var valeurs_form = form_get();
     26                console.log(valeurs_form);
     27
     28                if (isNaN(valeurs_form.x1)) {
     29                        form_set({
     30                                x1: 0,
     31                                x2: parseInt(img.attr('width'),10),
     32                                y1: 0,
     33                                y2: parseInt(img.attr('height'),10),
     34                                zoom: 1
     35                        });
     36                }
     37        }
     38
     39        /**
     40         * Récupérer les valeurs du formulaire.
     41         */
     42        function form_get () {
     43
     44                console.log('form_get');
     45
     46                return {
     47                        x1: parseInt(self.find('input[name=x1]').val(), 10),
     48                        x2: parseInt(self.find('input[name=x2]').val(), 10),
     49                        y1: parseInt(self.find('input[name=y1]').val(), 10),
     50                        y2: parseInt(self.find('input[name=y2]').val(), 10),
     51                        zoom: self.find('input[name=zoom]').val()
    4452                };
    4553        }
    4654
    47         if (mode_dimensions_forcees) {
    48                 forcer_largeur = parseInt(options.forcer_dimensions.largeur, 10);
    49                 forcer_hauteur = parseInt(options.forcer_dimensions.hauteur, 10);
    50         }
     55        /**
     56         * Mettre à jour les valeurs du formulaire
     57         */
     58        function form_set(valeurs) {
     59                console.log('form_set');
     60                console.log(valeurs);
    5161
    52         /* On garde en mémoire la sélection telle qu'elle serait sans le
    53            zoom, pour pouvoir zoomer-dézoomer perdre de la précision à
    54            cause d'erreurs d'arrondi. */
    55         selection_nozoom = {
    56                 x1: selection_initiale.x1 / zoom,
    57                 x2: selection_initiale.x2 / zoom,
    58                 y1: selection_initiale.y1 / zoom,
    59                 y2: selection_initiale.y2 / zoom
    60         };
    61 
    62         /* On crée le widget de sélection */
    63         imgAreaSelector = img.imgAreaSelect({
    64                 instance: true,
    65                 handles: true,
    66                 show: true,
    67                 x1: selection_initiale.x1,
    68                 x2: selection_initiale.x2,
    69                 y1: selection_initiale.y1,
    70                 y2: selection_initiale.y2,
    71                 /* On fait toutes les initialisations des autres widgets dans ce callback,
    72                  * pour être certain de pouvoir utiliser imgAreaSelector.setOptions sans
    73                  * faire planter le widget. */
    74                 onInit: function () {
    75 
    76                         init_slider();
    77 
    78                         /* Options propres au mode avec dimensions imposées */
    79                         if (mode_dimensions_forcees) {
    80 
    81                                 slider.slider('option', 'min', calculer_zoom_min());
    82 
    83                                 imgAreaSelector.setOptions({
    84                                         aspectRatio: forcer_largeur + ':' + forcer_hauteur,
    85                                         minWidth: Math.round(forcer_largeur * zoom),
    86                                         minHeight: Math.round(forcer_hauteur * zoom)
    87                                 });
    88 
    89                                 imgAreaSelector.update();
    90                         }
    91 
    92                         init_selecteur_format();
    93                         init_bouton_reinit();
    94                 },
    95                 onSelectChange: function (img, selection) {
    96                         selection_nozoom = {
    97                                 x1: selection.x1 / zoom,
    98                                 x2: selection.x2 / zoom,
    99                                 y1: selection.y1 / zoom,
    100                                 y2: selection.y2 / zoom
    101                         };
    102                         maj_formulaire(selection, zoom);
    103                 }
    104         });
    105 
    106         /* Initialisation du slider de zoom */
    107         function init_slider () {
    108                 slider = $('#zoom-slider').slider({
    109                         max: 1,
    110                         min: 0.01,
    111                         value: options.zoom,
    112                         step: 0.01,
    113                         create: function () {
    114 
    115                                 zoom = $('input#champ_zoom').attr('value');
    116 
    117                                 if (premier_chargement && mode_dimensions_forcees) {
    118                                         zoom = calculer_zoom_min();
    119                                         $(this).slider('option', 'value', zoom);
    120                                         maj_image(zoom);
    121                                         selection_initiale = forcer_dimensions_selection({
    122                                                 x1: 0,
    123                                                 x2: Math.round(img.width()),
    124                                                 y1: 0,
    125                                                 y2: Math.round(img.height())
    126                                         }, zoom);
    127                                 } else {
    128                                         maj_image(zoom);
    129                                 }
    130                                 maj_formulaire(selection_initiale, zoom);
    131                         },
    132                         slide: function (event, ui) {
    133 
    134                                 zoom = ui.value;
    135 
    136                                 maj_image(zoom);
    137 
    138                                 var selection = zoomer_selection(selection_nozoom, zoom);
    139 
    140                                 if (mode_dimensions_forcees) {
    141                                         selection = forcer_dimensions_selection(selection, zoom);
    142                                 }
    143 
    144                                 maj_selection(selection);
    145                                 maj_formulaire(selection, zoom);
    146 
    147                                 imgAreaSelector.setOptions({
    148                                         minWidth: Math.round(forcer_largeur * zoom),
    149                                         minHeight: Math.round(forcer_hauteur * zoom)
    150                                 });
    151                         }
    152                 });
    153         }
    154 
    155         /* Gestion du selecteur de format */
    156         function init_selecteur_format () {
    157 
    158                 select_format.change(function (e) {
    159 
    160                         var format = e.target.value;
    161 
    162                         afficher_erreur('');
    163 
    164                         if (format) {
    165                                 mode_dimensions_forcees = true;
    166 
    167                                 format = format.split(':');
    168                                 forcer_largeur = parseInt(format[0], 10);
    169                                 forcer_hauteur = parseInt(format[1], 10);
    170 
    171                                 if ((largeur_image < forcer_largeur) || (hauteur_image < forcer_hauteur)) {
    172                                         afficher_erreur(options.messages.erreur_image_trop_petite);
    173                                 } else {
    174                                         slider.slider('option', 'min', calculer_zoom_min());
    175 
    176                                         imgAreaSelector.setOptions({
    177                                                 aspectRatio: forcer_largeur + ':' + forcer_hauteur,
    178                                                 minWidth: Math.round(forcer_largeur * zoom),
    179                                                 minHeight: Math.round(forcer_hauteur * zoom)
    180                                         });
    181 
    182                                         selection_initiale = forcer_dimensions_selection(
    183                                                 imgAreaSelector.getSelection(),
    184                                                 zoom
    185                                         );
    186 
    187                                         maj_selection(selection_initiale);
    188 
    189                                         maj_formulaire(selection_initiale, zoom);
    190 
    191                                         return;
    192                                 }
    193                         }
    194 
    195                         mode_dimensions_forcees = false;
    196 
    197                         forcer_largeur = null;
    198                         forcer_hauteur = null;
    199 
    200                         slider.slider('option', 'min', 0.01);
    201 
    202                         imgAreaSelector.setOptions({
    203                                 aspectRatio: '',
    204                                 minWidth: 1,
    205                                 minHeight: 1
    206                         });
    207                 })
    208                 .trigger('change');
    209         }
    210 
    211         /* Initialisation du bouton de réinitialisation */
    212         function init_bouton_reinit () {
    213                 $('#formulaire_massicoter_image_reset').click(function (e) {
    214 
    215                         $('#zoom-slider').slider('option', 'value', 1);
    216                         select_format.val('').trigger('change');
    217 
    218                         maj_image(1);
    219 
    220                         var selection = {
    221                                 x1: 0,
    222                                 x2: Math.round(img.width()),
    223                                 y1: 0,
    224                                 y2: Math.round(img.height())
    225                         };
    226                         selection_nozoom = selection;
    227                         maj_selection(selection);
    228                         maj_formulaire(selection, 1);
    229 
    230                         e.preventDefault();
    231                         return false;
    232                 });
    233         }
    234 
    235         /*************/
    236         /* Fonctions */
    237         /*************/
    238 
    239         /* Une fonction pour afficher les erreurs */
    240         function afficher_erreur (msg) {
    241 
    242                 $('#formulaire_massicoter_image .erreur_message').remove();
    243 
    244                 if (msg) {
    245                         $('#formulaire_massicoter_image ul')
    246                                 .before('<div class="erreur_message">' + msg + '</div>');
    247                 }
    248 
    249                 imgAreaSelector.update();
    250         }
    251 
    252         /* Mise à jour du formulaire */
    253         function maj_formulaire (selection, zoom) {
    254 
    255                 /* En mode "dimensions forcées", on permet des sélections plus
    256                    grandes que les dimensions voulues. Il faut alors tout
    257                    remettre à la bonne échelle. */
    258                 if (mode_dimensions_forcees) {
    259                         var zoom_selection = calculer_zoom_selection(selection);
    260                         zoom = zoom * zoom_selection;
    261                         selection = {
    262                                 x1: Math.round(selection.x1 * zoom_selection),
    263                                 x2: Math.round(selection.x1 * zoom_selection) + forcer_largeur,
    264                                 y1: Math.round(selection.y1 * zoom_selection),
    265                                 y2: Math.round(selection.y1 * zoom_selection) + forcer_hauteur
    266                         };
    267                 }
    268 
    269                 $('input#champ_zoom').attr('value', zoom);
    270                 $('input[name=x1]').attr('value', selection.x1);
    271                 $('input[name=x2]').attr('value', selection.x2);
    272                 $('input[name=y1]').attr('value', selection.y1);
    273                 $('input[name=y2]').attr('value', selection.y2);
    274 
    275                 $('.dimensions').html((selection.x2 - selection.x1) + ' x ' + (selection.y2 - selection.y1));
    276         }
    277 
    278         /* Une fonction qui agrandi ou rapetisse l'image */
    279         function maj_image (zoom) {
    280 
    281                 img
    282                         .css('width', zoom * largeur_image + 'px')
    283                         .css('height', 'auto')
    284                         .css('margin-left', '-' + (Math.max((zoom*largeur_image - 780),0) / 2) + 'px' );
    285         }
    286 
    287         /* Une fonction pour mettre à jour la sélection */
    288         function maj_selection (selection) {
    289 
    290                 imgAreaSelector.setSelection(
    291                         selection.x1,
    292                         selection.y1,
    293                         selection.x2,
    294                         selection.y2
    295                 );
    296                 imgAreaSelector.update();
    297         }
    298 
    299         /* Calculer l'effet d'un zoom sur une sélection.
    300            Retourne la sélection zoomée. */
    301         function zoomer_selection (selection, zoom) {
    302 
    303                 var nouvelle_selection = {};
    304 
    305                 nouvelle_selection.x1 = Math.round(selection.x1 * zoom);
    306                 nouvelle_selection.x2 = Math.round(selection.x2 * zoom);
    307                 nouvelle_selection.y1 = Math.round(selection.y1 * zoom);
    308                 nouvelle_selection.y2 = Math.round(selection.y2 * zoom);
    309 
    310                 nouvelle_selection.x1 = Math.max(0, nouvelle_selection.x1);
    311                 nouvelle_selection.y1 = Math.max(0, nouvelle_selection.y1);
    312                 nouvelle_selection.x2 = Math.min(
    313                                 nouvelle_selection.x2,
    314                                 Math.round(img.width())
    315                 );
    316                 nouvelle_selection.y2 = Math.min(
    317                                 nouvelle_selection.y2,
    318                                 Math.round(img.height())
    319                 );
    320 
    321                 return nouvelle_selection;
    322         }
    323 
    324         /* Retourne une sélection aux dimensions reçues en option, en
    325            essayeant de rester le plus proche possible de la sélection
    326            passée en paramètre. On essaie de garder le même centre. */
    327         function forcer_dimensions_selection(selection, zoom) {
    328 
    329                 var x1 = selection.x1,
    330                         x2 = selection.x2,
    331                         y1 = selection.y1,
    332                         y2 = selection.y2,
    333                         zoom_max = Math.min(
    334                                 (largeur_image * zoom) / forcer_largeur,
    335                                 (hauteur_image * zoom) / forcer_hauteur
    336                         ),
    337                         echelle_x = (x2 - x1) / forcer_largeur,
    338                         echelle_y = (y2 - y1) / forcer_hauteur,
    339                         echelle = Math.min(
    340                                 Math.max(zoom, (echelle_x + echelle_y) / 2),
    341                                 zoom_max
    342                         ),
    343                         largeur_selection = forcer_largeur * echelle,
    344                         hauteur_selection = forcer_hauteur * echelle,
    345                         centre = {
    346                                 x: (x2 + x1) / 2,
    347                                 y: (y2 + y1) / 2
    348                         };
    349 
    350                 x1 = Math.round(Math.max(0, centre.x - (largeur_selection / 2)));
    351                 x2 = Math.round(x1 + largeur_selection);
    352                 y1 = Math.round(Math.max(0, centre.y - (hauteur_selection / 2)));
    353                 y2 = Math.round(y1 + hauteur_selection);
    354 
    355                 if (x2 > largeur_image) {
    356                         x1 = x1 - (x2 - largeur_image);
    357                         x2 = largeur_image;
    358                 }
    359                 if (y2 > hauteur_image) {
    360                         y1 = y1 - (y2 - hauteur_image);
    361                         y2 = hauteur_image;
    362                 }
    363 
    364                 return {
    365                         x1: x1,
    366                         x2: x2,
    367                         y1: y1,
    368                         y2: y2
    369                 };
    370         }
    371 
    372         /* La plus grande valeur de zoom possible avant d'être plus petit
    373            que les dimensions forcées */
    374         function calculer_zoom_min() {
    375 
    376                 return Math.min(
    377                         1,
    378                         Math.max(
    379                                 forcer_largeur / largeur_image,
    380                                 forcer_hauteur / hauteur_image
    381                         )
    382                 );
    383         }
    384 
    385         /* Calcul le zoom qu'il faut pour mettre une selection aux
    386            dimensions imposées */
    387         function calculer_zoom_selection(selection) {
    388 
    389                 var zoom_x = forcer_largeur / (selection.x2 - selection.x1),
    390                         zoom_y = forcer_hauteur / (selection.y2 - selection.y1);
    391 
    392                 return Math.max(zoom_x, zoom_y);
     62                self.find('input#champ_zoom').attr('value', valeurs.zoom);
     63                self.find('input[name=x1]').attr('value', valeurs.x1);
     64                self.find('input[name=x2]').attr('value', valeurs.x2);
     65                self.find('input[name=y1]').attr('value', valeurs.y1);
     66                self.find('input[name=y2]').attr('value', valeurs.y2);
    39367        }
    39468};
Note: See TracChangeset for help on using the changeset viewer.