用 JS 控制网页中 GIF 图片播放特效

起步

Opsof4ln5zbGLt87Lr1gFwT9JZKWHSXVpD8kt8bcmQgqgHi1oGsgoC6Kktkt8M+NEyj7gxClQIvy/9JRvt1XjNC977b23x/idNfiA0pgsM/N2O794PysECHBpcI8aPea2Y0nUTS5z1h/ihr/o9WfbNsNCEnFsJOm6ohUltEilvg0p8TS++wNTwruY3uOegU1uu2CZU/S0AGPorU7OLPHlYvZcFpnVuXjksHVtwUu1n4=

8Wm/hbKydmQtg0eUEVjQUeJy1M5wvYnvnnm5bl6cCpt36cQqyyTk2B4iQBDxsWjGJV1BFPui5tBz6jpphXARWARPFiqBIOXRZBlyHFQN3iI=

bkT7LhzYwKlRZSazi+vJzRLVv3zZnGiJwVGHixsM8ULD1VqF80LFx6ZWajL1M7kqf9CpQiHy0A7rdnhKqyYHSdnyRleChqTMGvkQE3c/T9zyhwylgdrWHt0PuBRg1zQw

思路

uT+bevTBY7VUMO0rc0hbsnKrDtnFS9o/1pJurWN3oKAqPisAZJyc/ri51zYipNzrxXbxUbtCLhuNASWJLY6PA0LUg2BnAlXCrvG2SqmmanqQneDh06idXQw32mfvl+g5FVdNdc6tutC1EogUeKkIfOH/06TwFQ/2s7el3Izj7W+CNmu1txJfy6cQjzEQs8YWuCz7LDy0U6OK+soWoTzhb70p04GcajS+nJ21caWvzCM/Spb8QcsbmVYF16iXlLS+

<img src="http://xxx.gif" />

# 替换成
<img src="data:image/png,base64,xxxx" />

GIlc3rDTHo3v19n4yi15UAhZdwoMDHqAZc4D5IWfFvz6sZA/3w469PLPd6t21NIYuIhBAAbSS3yv5ohqV4YVYw2PjVaaUhCEoU10oP30xMEtJb/MLZxO1fkllE+Drl8cRX/YtIKMjFsjKUA3viRsKuXoUqqIJ80dJHoGmthkA0S/jMLPnlU7KU+V/GbbnNPAtwT1m4FYGJpCxFilStPaoJBlM8SS3AUfiYdCc99LlX3Jaq1EbSMYOmIjq6IkoRI6YRpJV9eCcoZo482rhvm9gAjPu+m9NSwJDGsjRKIBDfJsZXO4uOLz1NAp9KHqeBwk2u06LJWwoMaSB6Pq7QBTL79jrjJbl3HvJGQ+ArwndwlNdhfQY2LT9swWnFfnXXMKlKHLAooqNd9WP05fHthWAwnWrZQDX2KdGcEscPj/Oo8=

let obj = $('#id img');
let src = obj.attr('src');   // 初始的 gif 图片地址
let width = obj.width();
let height = obj.height();
let gif_cache = {            // 保存所需要的数据
  gif_src: '',               // 保存初始的 gif 图片地址
  blob_src: '',              // 保存转码后的base64数据
  loaded: false,             // 保存当前需要显示动图还是静图
};
let img = new Image();
img.setAttribute("crossOrigin",'Anonymous');  // 潜在的图片跨域问题
gif_cache.gif_src = img.src = src;            // 加载gif图片
img.onload = function () {
    var canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

    // 设置 gif 所需要的数据源
    gif_cache.blob_src = canvas.toDataURL("image/png");  // 转为base64
    gif_cache.gif_src = src;
    obj.attr('src', gif_cache.blob_src);   // 替换
};
obj.click(function () {      // 图片的点击事件监听
    gif.loaded = !gif.loaded;
    obj.attr('src', gif.loaded ? gif.gif_src : gif.blob_src);
});

aQSOffQ4NgYLLlen3WrUwMQ9QLqYFUeFjDHtCx5Gwe6tRa4Sm+kAqqHkxOTXiEsO8NMwanLW9EnzKP1OGULD+C13aIUCgJ5M8nFv9Aj5xMXOU0/ikpcwsIrw0ySLph12

小图标 Tip

W+UG6beqLS0fjD3e0zmYh+e2YO/I5x6A+UV40MDDXSUeaIMlFkAVTdUmn2dDlg3Fm/MRynA2NiVFq7LYc74+0A60t/l4iU0x2uE6RACkIbxEpWxa+aEXSGmEHKAoQYPt6vXazh6hO4xpxhir0qKtYOSQsR8QSv+fK3iytqSedQ/VISqaUonQoi2Ak4evO0RC1dr8OMfLSGL4+Sn8QLkvbMa1q5JRuddjr4ADAchf8bQ9hn3+xyysv0qGmp/OSy3Agkg+jI9BsYVqzqPTUfK1qA==

4rBbFGM6zRKzy8XpSgJYzEeRI05dCBTt44HZ9QrzXQo=

ins.play-gif{
    position: absolute;
    font-family: Arial, sans serif;
    width: 50px;
    height: 50px;
    line-height: 2.8rem;
    text-align: center;
    background: #222;
    font-size: 1em;
    color: #fff;
    border-radius: 50%;
    opacity: .8;
    border: 4px solid #fff;
    cursor:pointer;
    text-decoration: none;
}

ins.play-gif:hover{
    opacity:.5;
}

w4z7ObiFaE/XL6pRwWBZZOmimxcUoIHK3gBO+p0un0zKUQgFdjJxy4ll0rPOfa2bj3SWJ+6xnlxNCEsb7n7cHVAAPPGUXgvwQEBtSUERhzE=

/**
 * author: hongweipeng
 */
(function($) {
    "use strict";

    let GIF = function() {
        this.gif_src = '';
        this.blob_src = '';
        this.loaded  = false;
        this.tip = $("<ins class='play-gif'>GIF</ins>");
    };

    $.fn.gif = function() {
        let obj = $(this);
        let src = obj.attr('src');
        let width = obj.width();
        let height = obj.height();
        let gif = new GIF();
        let img = new Image();
        img.setAttribute("crossOrigin",'Anonymous');
        gif.gif_src = img.src = src;
        img.onload = function () {
            var canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

            // 设置 gif 所需要的数据源
            gif.blob_src = canvas.toDataURL("image/gif");
            gif.gif_src = src;
            obj.attr('src', gif.blob_src);
            gif.tip.css({
                'top' : height / 2 - gif.tip.height() / 2,
                'left' : width / 2 - gif.tip.width() / 2,
            });
            gif.tip.click(function() {
                obj.trigger('click');
            });
            gif.tip.insertAfter(obj);

            canvas = null;  // 回收
            img = null;
        };

        obj.click(function () {
            gif.loaded = !gif.loaded;
            obj.attr('src', gif.loaded ? gif.gif_src : gif.blob_src);
            if (gif.loaded) {
                gif.tip.hide();
            } else {
                gif.tip.show();
            }
        });

    };
})(jQuery);

使用

CXscTQju/SadcUBLoO5oBQ4/YFiCbK+GUT9qcjtu/6t4geuDVmCkWvDjxIP0gqnB/uFKaMnjvmfGyYRW3PIqZ9lt+PYZKxML/kqwclhPUlBMX0NcMU0XzQD/MU4yxi4MmSwr4iYTTjG8q65GnGzPlQ==

$('.container img').each(function(_, obj) {
    let $obj = $(obj);
    let src = $obj.attr('src');
    if (!src || src.indexOf('.gif') < 0) {  // 忽略非 gif 的图片
        return;
    }
    $obj.gif();
});

总结

gr3JtWXCc27RFiB7SCcVAenu/QRdbjghOMuYo6krWljcwuaOEjILn76y724PKTvS1xVPSx5mpejqPzgIUz1EZF+L46xfY5Qc7ISOAw3fWBMCTfgOq+a5BGK1hU8dpy530o6mkvk1Q8bgkuURB+vk3Zf2tjN032nirQi3oNozT8A0QcgIEGDjapg4EVDUUr27gmCUoFtkFmmKut9QY2xJSqGi8u3pwdoYoG6KUAg0BGXuNBsWyabLUaooO7IkfqhK6Uzv5zTH81fIkJj7kdisEF+v3f3lqNEXW4DBYNtRIEAQs/OyGq2zecLBkpz4c4RtO7Gh3yCNM+z0CHGXkwSt4U/no2d/LGsZM/+UYnkhiH2rUBEsF+TVin+5Kpa4VH/dkHyIL6J1jfe+boi02Bz4EQ==

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章