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 };
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屬性裡面。