Changeset 111548 in spip-zone


Ignore:
Timestamp:
Sep 11, 2018, 8:10:35 AM (7 months ago)
Author:
bystrano@…
Message:

zoom et sélections fonctionnels, même avec des zooms > 1

Location:
_plugins_/massicot/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/massicot/trunk/css/massicot.css

    r98788 r111548  
    11.image-massicot {
     2  heigth: auto;
    23  text-align: center;
     4}
     5
     6.image-massicot img {
     7  display: block;
     8  height: auto;
     9  margin: auto;
    310}
    411
  • _plugins_/massicot/trunk/javascripts/formulaireMassicoterImage.js

    r111547 r111548  
    1111
    1212        var self = this,
    13                 conteneur = self.parent().find('.image-massicot .conteneur'),
    14                 // l'image
    15                 img = self.parent().find('.image-massicot img'),
     13                conteneur = self.parent().find('.image-massicot'),
     14                img = conteneur.find('img'),
    1615                largeur_image = parseInt(img.attr('width'), 10),
    1716                hauteur_image = parseInt(img.attr('height'), 10),
     
    2019                largeur_forcee = dimensions_forcees ? parseInt(options.forcer_dimensions.largeur, 10) : NaN,
    2120                hauteur_forcee = dimensions_forcees ? parseInt(options.forcer_dimensions.hauteur, 10) : NaN,
    22                 // On garde en mémoire la sélection telle qu'elle serait sans le zoom,
    23                 // pour pouvoir zoomer-dézoomer perdre de la précision à cause d'erreurs
    24                 // d'arrondi.
    25                 selection_nozoom,
     21                // On garde en mémoire la sélection telle qu'elle a été saisie via le
     22                // widget de sélection, en ignorant l'effet d'éventuels zooms à venir.
     23                // Ça permet d'éviter une perte de précision lorsqu'on zoome et dézoome
     24                // avec le slider.
     25                derniere_selection_widget,
    2626                // widgets
    2727                imgAreaSelector,
    2828                slider,
    29                 selecteur_format = self.find('select[name=format]');
     29                selecteur_format = self.find('select[name=format]'),
     30                round = Math.round,
     31                max = Math.max,
     32                min = Math.min;
    3033
    3134        form_init();
    3235        GUI_init();
    33 
    34         selection_nozoom = form_get();
    35         img_set(form_get());
    3636
    3737        /**
     
    4444
    4545                var valeurs_form = form_get();
     46                // console.log('-- form init');
    4647                // console.log(valeurs_form);
    4748
     
    6869                        y1: parseInt(self.find('input[name=y1]').val(), 10),
    6970                        y2: parseInt(self.find('input[name=y2]').val(), 10),
    70                         zoom: self.find('input[name=zoom]').val()
     71                        zoom: parseFloat(self.find('input[name=zoom]').val())
    7172                };
    7273        }
     
    7677         */
    7778        function form_set (valeurs) {
    78                 // console.log('form_set');
     79                // console.log('-- form_set');
    7980                // console.log(valeurs);
    8081
     
    110111                                        imgAreaSelector.setOptions({
    111112                                                aspectRatio: largeur_forcee + ':' + hauteur_forcee,
    112                                                 minWidth: Math.round(largeur_forcee * selection.zoom),
    113                                                 minHeight: Math.round(hauteur_forcee * selection.zoom)
     113                                                minWidth: round(largeur_forcee * selection.zoom),
     114                                                minHeight: round(hauteur_forcee * selection.zoom)
    114115                                        });
    115116
     
    117118                                }
    118119
    119                                 slider_init(selection);
     120                                slider_init(selection, function () {
     121                                        /* Après avoir un initialisé le slider, la mise en page ne
     122                                           bougera plus. On peut alors initialiser la sélection */
     123                                        derniere_selection_widget = form_get();
     124                                        img_set(form_get());
     125                                });
    120126                                // init_selecteur_format();
    121127                                // init_bouton_reinit();
     
    123129                        onSelectChange: function (img, selection) {
    124130
    125                                 selection_nozoom = selection;
     131                                /* Le widget nous donne un objet avec des infos inutiles, on
     132                                 * nettoie un peu… */
     133                                delete selection.width;
     134                                delete selection.height;
     135
     136                                if (isNaN(selection.x1)) { delete selection.x1; }
     137                                if (isNaN(selection.x2)) { delete selection.x2; }
     138                                if (isNaN(selection.y1)) { delete selection.y1; }
     139                                if (isNaN(selection.y2)) { delete selection.y2; }
     140
     141                                /* Quand le wigdet ne donne rien d'utile, on prends les valeurs
     142                                 * enregistrées dans le formulaire. */
     143                                selection = $.extend(form_get(), selection);
     144
     145                                derniere_selection_widget = selection;
    126146                                form_set(selection);
    127147                        }
     
    146166         * Initialisation du slider
    147167         */
    148         function slider_init (selection) {
     168        function slider_init (selection, init_callback) {
    149169
    150170                slider = self.find('#zoom-slider').slider({
     
    154174                        step: 0.01,
    155175                        create: function () {
    156 
    157                                 // if (dimensions_forcees) {
    158                                 //      selection.zoom = zoom_min_get();
    159                                 //      $(this).slider('option', 'value', selection.zoom);
    160                                 //      maj_image(selection.zoom);
    161                                 //      selection_initiale = forcer_dimensions_selection({
    162                                 //              x1: 0,
    163                                 //              x2: Math.round(img.width()),
    164                                 //              y1: 0,
    165                                 //              y2: Math.round(img.height())
    166                                 //      }, zoom);
    167                                 // } else {
    168                                 //      maj_image(zoom);
    169                                 // }
    170                                 // maj_formulaire(selection_initiale, zoom);
     176                                return init_callback();
    171177                        },
    172178                        slide: function (event, ui) {
    173179
    174180                                var selection = form_get();
     181
    175182                                selection.zoom = ui.value;
     183                                selection = zoom_selection(selection);
    176184
    177185                                form_set(selection);
     
    189197                        .css('width', selection.zoom * largeur_image + 'px')
    190198                        .css('height', selection.zoom * hauteur_image + 'px')
    191                         .css('margin-left', '-' + (Math.max((selection.zoom*largeur_image - 780),0) / 2) + 'px' );
     199                        .css('margin-left', '-' + (max((selection.zoom*largeur_image - 780),0) / 2) + 'px' );
    192200
    193201                img
    194                         .css('width', Math.min(1, selection.zoom) * largeur_image + 'px')
    195                         .css('padding-top', (Math.max(1, selection.zoom) - 1) / 2 * hauteur_image);
     202                        .css('width', min(1, selection.zoom) * largeur_image + 'px')
     203                        .css('padding-top', (max(1, selection.zoom) - 1) / 2 * hauteur_image);
    196204
    197205                selector_set(selection);
    198206        }
     207
     208        /**
     209         * Mettre à jour une sélection après un zoom
     210         *
     211         * On recalcule les coordonnées de la sélection en se basant sur la valeur
     212         * du zoom, qu'on applique à la dernière sélection saisie via le widget.
     213         * Cela permet d'éviter toute perte de précision lors de zooms et de
     214         * dé-zooms.
     215         *
     216         * Retourne la sélection avec des coordonnées mises à jour.
     217         */
     218        function zoom_selection (selection) {
     219
     220                var last = derniere_selection_widget,
     221                        zoom = selection.zoom,
     222                        s = { zoom: zoom },
     223                        // La taille des marges autour de l'image
     224                        marge_last = {
     225                                x: (max(1, last.zoom) - 1) / 2 * largeur_image,
     226                                y: (max(1, last.zoom) - 1) / 2 * hauteur_image,
     227                        },
     228                        marge = {
     229                                x: (max(1, zoom) - 1) / 2 * largeur_image,
     230                                y: (max(1, zoom) - 1) / 2 * hauteur_image,
     231                        },
     232                        // L'écart entre la sélection est le bord de l'image
     233                        ecart_last = {
     234                                x1: marge_last.x - last.x1,
     235                                y1: marge_last.y - last.y1,
     236                                x2: last.x2 - (largeur_image + marge_last.x),
     237                                y2: last.y2 - (hauteur_image + marge_last.y)
     238                        };
     239
     240                /* Si le zoom est < 1, on zoome la sélection pour qu'elle reste sur la
     241                 * même portion de l'image. */
     242                if (zoom <= 1) {
     243                        /* Si la dernière sélection à été faite avec un zoom > 0, il faut
     244                         * lui déduire les marges. */
     245                        if (last.zoom > 1) {
     246                                last = {
     247                                        x1: max(0, last.x1 - marge_last.x),
     248                                        x2: max(0, last.x2 - marge_last.x),
     249                                        y1: max(0, last.y1 - marge_last.y),
     250                                        y2: max(0, last.y2 - marge_last.y),
     251                                        zoom: 1
     252                                };
     253                        }
     254
     255                        s = $.extend(s, {
     256                                x1: round(max(
     257                                        0,
     258                                        last.x1 / last.zoom * zoom
     259                                )),
     260                                y1: round(max(
     261                                        0,
     262                                        last.y1 / last.zoom * zoom
     263                                )),
     264                                x2: round(min(
     265                                        largeur_image * zoom,
     266                                        last.x2 / last.zoom * zoom
     267                                )),
     268                                y2: round(min(
     269                                        hauteur_image * zoom,
     270                                        last.y2 / last.zoom * zoom
     271                                )),
     272                        });
     273                }
     274                /* Si le zoom est > 1, l'image n'est pas agrandie, alors on garde la
     275                 * taille de la sélection. Par contre on doit la décaler pour qu'elle
     276                 * reste sur la même portion de l'image. */
     277                else {
     278                        s = $.extend(s, {
     279                                x1: round(max(
     280                                        0,
     281                                        marge.x - (ecart_last.x1 / min(1, last.zoom))
     282                                )),
     283                                y1: round(max(
     284                                        0,
     285                                        marge.y - (ecart_last.y1 / min(1, last.zoom))
     286                                )),
     287                                x2: round(min(
     288                                        largeur_image * zoom,
     289                                        marge.x + ((largeur_image + ecart_last.x2) / min(1, last.zoom))
     290                                )),
     291                                y2: round(min(
     292                                        hauteur_image * zoom,
     293                                        marge.y + ((hauteur_image + ecart_last.y2) / min(1, last.zoom))
     294                                ))
     295                        });
     296                }
     297
     298                return s;
     299        }
    199300};
Note: See TracChangeset for help on using the changeset viewer.