javascript仿新浪微博圖片放大縮小及旋轉效果

龍恩0707發表於2014-07-18

javascript仿新浪微博圖片放大縮小及旋轉效果

     經常看到新浪微博裡有圖片放大縮小旋轉效果,感覺效果還不錯,所以就想試著做一個類似的demo出來,至於旋轉對於IE可以用濾鏡來解決,標準的瀏覽器可以用html5中的canvas畫布來解決。

   思路:1.點選小圖後,小圖隱藏掉,在小圖父級元素後增加一張大圖且顯示出來。

           2.點選往左轉,往右轉觸發旋轉方法。

           3. 點選收起按鈕,把1的步驟反過來 隱藏大圖 顯示小圖。

           4. 點選檢視原圖功能 目前沒有做成js燈箱效果,直接開啟一個新連線。但是如果想做成燈箱效果的話,可以看我這篇部落格,燈箱效果演示

    我們可以先來看看JSFiddler效果吧!

    嘿嘿,看效果請點選我!

實現思路:

    1. 對於第一點 小圖隱藏 大圖顯示這個可以不用說的。

    2. 對於旋轉:IE用濾鏡解決,如:img.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + s + ')'; 標準瀏覽器可以用canvas+旋轉

    程式碼中用了一個圖片預載入,想要了解圖片預載入的話 可以看這篇文章  "圖片預載入"  還用了一個圖片等比例縮放 想了解等比例縮放的話 可以檢視 "等比例縮放圖片"

下面是所有的JS原始碼,大家有空可以看看,如果有更好的思路的話,可以提意見,一起交流下。

/**
 * 縮圖
 */
 function ArtZoom(options,callback){
    var self = this;
    self.options = $.extend({},defaults,options || {});
    self._init();
    self.callback = callback;
    this.cache = {
        minStep   :  0,
        maxStep   :  3
    };
 };
 $.extend(ArtZoom.prototype,{

     // 初始化
     _init: function(){
        var self = this,
            cfg = self.options;
        
        if($(cfg.targetCls).length <= 0) {
            return;
        }
        $(cfg.targetCls).each(function(){
            $(this).unbind('click').bind('click',function(e){
                e.preventDefault();
                var maxImage = $(this).attr('href');
                self._imgTool($(this),maxImage);
            });
        });
     },
     /*
      * 點選小圖變大圖 先隱藏小圖 再生成大圖顯示
      * @param {$this,maxImage} 當前點選的元素 當前大圖
      */
     _imgTool: function($this,maxImage) {
        var self = this,
            cfg = self.options;
        var width = 0,
            height = 0,
            maxWidth = $this.closest(cfg.parentCls).outerWidth();

        // 圖片預先載入
        var loadImg = function (url, fn) {
            var img = new Image();
            img.src = url;
            if (img.complete) {
                fn.call(img);
            } else {
                img.onload = function () {
                    fn.call(img);
                };
            };
        };
        loadImg(maxImage, function () {
            width = this.width;
            height = this.height;
            tool();
        });
        function tool(){

            var $thisParent = $($this).closest(cfg.parentCls);
            // 當前圖片隱藏掉
            $this.hide();
            if($('.artZoomBox',$thisParent).length > 0 && $('.artZoomBox',$thisParent).css('display') == "none"){
                $('.artZoomBox',$thisParent).show();
            }
            // 圖片等比例縮放
            if (width > maxWidth) {
                height = maxWidth / width * height;
                width = maxWidth;
            };
            // 頁面只建立一次
            if($('.artZoomBox',$thisParent).length <= 0) {
                var html = '<div class="artZoomBox">'+
                       '<div class="tool">'+
                            '<a class="hideImg" href="#" title="收起">收起</a>'+
                            '<a class="imgRight" href="#" title="向右轉">向右轉</a>'+
                            '<a class="imgLeft" href="#" title="向左轉">向左轉</a>'+
                            '<a class="viewImg" href="' + maxImage + '" title="檢視原圖">檢視原圖</a>'+
                        '</div>'+
                        '<a href="'+maxImage+'" class="maxImgLink">'+
                            '<img class="maxImg" width="'+width+'" height="'+height+'" src="'+maxImage+'"/>'+
                        '</a>'+
                    '</div>';
                $($thisParent).append(html);
            }

            $('.artZoomBox',$thisParent).find('a').unbind('click').bind('click',function(e){
                e.preventDefault();
                var $this = $(this),
                    $parent = $(this).closest(cfg.parentCls);
                var box = $('.artZoomBox',$parent);
                // 收起
                if($($this).hasClass('hideImg') || $($this).hasClass('maxImgLink')) {
                    box.hide();
                    box.prev().show();
                    self.destory($this);
                };
                // 左旋轉
                if($($this).hasClass('imgLeft')) {
                    var target = box.find('.maxImg');
                    self._rotate(target,'left', width)
                };
                // 右旋轉
                if($($this).hasClass('imgRight')) {
                    var target = box.find('.maxImg');
                    self._rotate(target,'right', width);
                };
                // 新視窗開啟
                if($this.hasClass('viewImg')){
                    window.open(maxImage);
                } 
            });
            
        }
     },
     /*
      * 圖片旋轉
      * @param {target,direction,width} 要旋轉的元素,方向, 旋轉元素的寬度
      */
     _rotate: function(target,direction,width){
        var self = this,
            cache = self.cache;

        var img = $(target)[0],
            step = img.getAttribute('step');
        if(img.length <= 0) {
            return;
        }
        if (step == null) {
            step = cache.minStep;
        }
        var width = img.width,
            height = img.height;
        if(direction == 'left') {
            step--;
            if(step < cache.minStep) {
                step = cache.maxStep;
            }
        }else if(direction == 'right') {
            step++;
            if(step > cache.maxStep) {
                step = cache.minStep;
            }
        }
        img.setAttribute('step', step);
        // IE
        if(navigator.userAgent.indexOf('MSIE') >= 0) {
            var s = $(img).attr('step');
            img.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + s + ')';
            img.width = width;
            img.height = height;
        }else {  // 對於現代瀏覽器 使用canvas
             var canvas = $(img).next('canvas')[0];
            if ($(img).next('canvas').length == 0) {
                img.style.display = 'none';
                canvas = document.createElement('canvas');
                canvas.setAttribute('class', 'canvas');
                img.parentNode.appendChild(canvas);
            }
            //旋轉角度以弧度值為引數
            var degree = step * 90 * Math.PI / 180;
            var ctx = canvas.getContext('2d');
            switch (step) {
                case 0:
                    canvas.width = width;
                    canvas.height = height;
                    ctx.drawImage(img, 0, 0);
                    break;
                case 1:
                    canvas.width = height;
                    canvas.height = width;
                    ctx.rotate(degree);
                    ctx.drawImage(img, 0, -height);
                    break;
                case 2:
                    canvas.width = width;
                    canvas.height = height;
                    ctx.rotate(degree);
                    ctx.drawImage(img, -width, -height);
                    break;
                case 3:
                    canvas.width = height;
                    canvas.height = width;
                    ctx.rotate(degree);
                    ctx.drawImage(img, -width, 0);
                    break;
            }
        }
        $(target).attr("step",cache.step);
        self.callback && $.isFunction(self.callback) && self.callback(cache.step);
     },
     /*
      * 銷燬
      */
     destory: function($this){
        var self = this,
            cfg = self.options;
        var curParent = $this.closest(cfg.parentCls),
            canvas = $('.canvas',curParent),
            maxImg = $('.maxImg',curParent);
        
        if(navigator.userAgent.indexOf('MSIE') >= 0) {
            // IE
            $(maxImg)[0].style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=0)';
            $(maxImg).attr('step',0);
        }else{
            if(canvas.length > 0) {
                canvas.remove();
                maxImg.show();
                $(maxImg).attr("step",0);
            }
        }
     }
 });
 var defaults = {
     targetCls            :  '.artZoom',
     parentCls            :  '.parentCls'   // 當前元素最近的父元素的class
 };
View Code

demo下載

HTML程式碼如下:

<li class="parentCls"> 
    <a class="artZoom" href="http://m1.img.srcdd.com/farm5/d/2014/0718/21/EDEF32A674C1217FB6F80851514C124E_B250_400_250_278.jpeg">
    <img src="http://m1.img.srcdd.com/farm4/d/2014/0718/21/31789C10D628913054C9B7F3A11D3519_B250_400_150_108.jpeg" /></a> </li>

其中父類 增加配置元素 parentCls ,當前大圖連結寫在href屬性裡面。

相關文章