Changeset 77043 in spip-zone


Ignore:
Timestamp:
Oct 7, 2013, 3:35:20 PM (6 years ago)
Author:
cedric@…
Message:

On laisse tomber la piste du conteneur svg qui ne fonctionne pas bien sur les iOS (non respect des proportions), et n'a finalement pas vraiment d'avantage par rapport aux simples backgrounds : si on affiche la page sans style on a pas les images.

On revient sur une stratégie plus simple :

  • img qui contient un src fallback basse-def&basse-qualité en base64 (rendu visuel rapide)
  • media-queries pour afficher à la place l'image de taille adaptée à l'écran : on prend en compte la taille de la fenetre et la resolution du peripherique

On a plus que 2 variantes de HTML, selectionnées selon User-agent : "desktop" pour l'image HD standard et "mobile" pour l'image chargée par media-queries.
Cependant, la version mobile est quasi fonctionnelle sous IE7+, il suffit de definir la constante _RESPIM_PRESERVE_IE7_COMPAT pour ne pas envoyer le fall-back en base64 et retablir la compat IE7 (au prix d'un hit de plus sur les cibles desktop ou mobile haute résolution).

On peut donc choisir d'envoyer le même HTML a tout le monde (si on veut utiliser un CDN ou proxy cache type Varnish) en sacrifiant la compat IE7 ou en acceptant un hit de plus sur l'image petit format pour les consultations depuis desktop

Cette solution (imparfaite) a l'avantage de conserver la balise <img> avec son alt, et d'afficher une image également en consultation sans style. Elle ne requiert pas JS (hormis support media-queries IE7/IE8 si on veut un HTML unique).

A continuer de tester, debug, il reste une passe d'optimisation a faire (regrouper les styles inline notamment), et voir la meilleure stratégie d'appel : affichage_final comme maintenant, ou filtre sur le seul bloc de contenu, ou autre...

Location:
_plugins_/respim/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/respim/trunk/paquet.xml

    r76882 r77043  
    22        prefix="respim"
    33        categorie="multimedia"
    4         version="0.1.0"
     4        version="0.2.0"
    55        etat="dev"
    66        compatibilite="[3.0.12-dev;3.0.*]"
  • _plugins_/respim/trunk/respim_options.php

    r77038 r77043  
    1414
    1515/**
    16  * http://coding.smashingmagazine.com/2013/06/02/clown-car-technique-solving-for-adaptive-images-in-responsive-web-design/
    1716 *
    1817 * @param array $rwd_images
     
    2726 */
    2827function respim_embed($rwd_images, $width, $height, $alt="", $class="", $id=""){
    29         $svg = <<<SVG
    30 <svg viewBox='0 0 $width $height' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg'>
    31 <title>$alt</title>
    32 <style>
    33 svg{background-size:100% 100%;background-repeat:no-repeat;}
    34 SVG;
    3528
    3629        ksort($rwd_images);
     30        $cid = "c".crc32(serialize($rwd_images));
     31        $style =
     32"img.$cid{opacity:0.01;filter:alpha(opacity=1);width:{$width}px;max-width:100%;height:auto;}
     33b.$cid{background-size:100%;background-repeat:no-repeat;display:inline-block;max-width:100%}
     34";
     35
     36        // image de fallback fournie ?
     37        if (isset($rwd_images['fallback'])){
     38                $fallback_file = $rwd_images['fallback'];
     39                unset($rwd_images['fallback']);
     40        }
     41        // sinon on affiche la plus petite image
     42        if (!$fallback_file)
     43                $fallback_file = reset($rwd_images);
     44        /* SI compat IE7 necessaire : pas de base64 dans le src, donc image externe avec un hit de plus... */
     45        if (!defined('_RESPIM_PRESERVE_IE7_COMPAT'))
     46                $fallback_file = filtre_embarque_fichier($fallback_file,"",32000);
     47
    3748        $prev_width = 0;
    3849        $medias = array();
    3950        foreach ($rwd_images as $w=>$file){
    4051                $mw = ($prev_width?"(min-width:{$prev_width}px)":"(max-width:{$w}px)");
    41                 $medias[$w] = "@media screen and $mw{svg{background-image:url($file);}}";
     52                $mw20 = ($prev_width?"(min-width:".round($prev_width/2)."px)":"(max-width:".round($w/2)."px)");
     53                $mw15 = ($prev_width?"(min-width:".round($prev_width/1.5)."px)":"(max-width:".round($w/1.5)."px)");
     54                $medias[$w] = "@media screen and $mw,screen and (-webkit-min-device-pixel-ratio: 2) and $mw20,screen and (-webkit-min-device-pixel-ratio: 1.5) and $mw15,screen and (min--moz-device-pixel-ratio: 2) and $mw20,screen and (min--moz-device-pixel-ratio: 1.5) and $mw15{b.$cid{background-image:url($file);}}";
    4255                $prev_width = $w+1;
    4356        }
    44         $svg .= implode("\n",$medias);
    45         $svg .= "
    46   </style>
    47 </svg>";
    48 
    49         // echapper le $svg
    50         $svg = str_replace("\n","",$svg);
    51         $svg = rawurlencode($svg);
     57        $style .= "b.$cid{background-image:url($file);}";
     58        $style .= implode("\n",$medias);
    5259
    5360        if ($class) $class=" $class";
    54         $class=" class=\"img responsive$class\"";
    55         if ($alt) $alt=" aria-label=\"$alt\"";
     61        $class=" class=\"responsive $cid$class\"";
     62        if ($alt) $alt=" alt=\"$alt\"";
    5663        if ($id) $id=" id=\"$id\"";
    5764
    58         $out = "<object role=\"img\"$alt tab-index=\"0\"
    59 data=\"data:image/svg+xml,$svg\" type=\"image/svg+xml\"
    60 width=\"$width\" height=\"$height\" style=\"max-width: 100%;height:auto;\"
    61 $class$id></object>";
     65        $out = "<b class=\"$cid\"><img
     66$alt
     67src=\"$fallback_file\"
     68width=\"$width\" height=\"$height\"
     69$class$id /></b>
     70<style>$style</style>";
    6271        return $out;
    6372}
     
    6776 * @param string $target
    6877 *   navigateur cible
    69  *   android2 => image petit format
    70  *   mobile => conteneur svg
     78 *   mobile => <img> avec fallback base64 petite taille basse qualite et mediaquerie pour charger la "bonne" image
    7179 *   dektop => image normale
    7280 *   auto => determination en fonction du UA (oui c'est mal)
     
    8088        if (!function_exists("image_reduire"))
    8189                include_spip("inc/filtres_images_mini");
     90        if (!function_exists("image_aplatir"))
     91                include_spip("filtres/images_transforme");
    8292
    8393        list($h,$w) = taille_image($img);
     
    8595
    8696        static $ua_target = null;
    87         if (!in_array($target,array("android2","mobile","desktop"))){
     97        if (!in_array($target,array("mobile","desktop"))){
    8898                if (is_null($ua_target)){
    8999                        include_spip("lib/mobile_detect");
     
    92102                        if ($detect->isMobile()){
    93103                                $ua_target = "mobile";
    94                                 if (strpos($_SERVER['HTTP_USER_AGENT'],"Android 2.")!==false)
    95                                         $ua_target = "android2";
    96104                        }
    97                         if ($t = _request('var_respim'))
     105                        if ($t = _request('var_respim') AND in_array($t,array("mobile","desktop")))
    98106                                $ua_target = $t;
    99107                }
     
    114122                return $img;
    115123
    116         $images = array($w=>url_absolue($src));
     124        $images = array($w=>$src);
    117125        $src=preg_replace(',[?][0-9]+$,','',$src);
    118126
     
    124132                if ($wk>$w) break;
    125133                $i = image_reduire($img,$wk,10000);
    126                 // sur les android2 on renvoie les images dans le plus petit breakpoint
    127                 // (oui c'est arbitraire)
    128                 if ($target=="android2")
    129                         return $i;
    130                 $images[$wk] = url_absolue(extraire_attribut($i,"src"));
     134                $images[$wk] = extraire_attribut($i,"src");
     135        }
     136
     137        if (function_exists("image_aplatir")){
     138                // image de fallback : la plus petite en jpg compresse
     139                $fallback = image_aplatir($images[reset($bkpt)],'jpg','ffffff',51);
     140                $images["fallback"] = extraire_attribut($fallback,"src");
    131141        }
    132142
     
    143153function respim_affichage_final($texte){
    144154        if ($GLOBALS['html']){
     155                #spip_timer();
    145156                $replace = array();
    146157                preg_match_all(",<img\s[^>]*>,Uims",$texte,$matches,PREG_SET_ORDER);
     
    153164                if (count($replace))
    154165                        $texte = str_replace(array_keys($replace),array_values($replace),$texte);
     166                #var_dump(spip_timer());
    155167        }
    156168        return $texte;
Note: See TracChangeset for help on using the changeset viewer.