以前唸書時在學長的介紹下接了個case,裡面剛好需要瀏覽解析度高的影像,但網頁版面
是有固定大小的,因此就需要可以放大、縮小、移動來檢視它。當時這個功能是我學長
寫的,那時我不會做XD,因此現在回想起來就自己寫寫看看囉。
這個Web Widget比起之前做的image gallery slider不用去使用CSS來定義版面的擺置,而是
著重在於圖片與區塊間的處理。將圖片類似鑲嵌進div內,如此可以定義圖片在區塊內可視
的長寬,及改變圖片的原點位置來調整放大、縮小後的圖片可視部分等等。
HTML部分
首先自訂一個div區塊,到時透過JavaScript做鑲嵌,而定義兩個按鈕來控制zoom in/out
控制,另外再show出目前圖片可視的原點位置。控制大小的部分,由於一開始是定義
可看到全圖,故首先只能放大,放大之後才可以縮小或拖移。
JavaScript&jQuery部分
一、圖片載入
div是定義為原圖的一半大小,原圖也會以一半的大小來呈現!background-size為可視
的範圍。
二、圖片放大
首先,當zoom in button被按下,此時以10%的大小擴增,並且利用zoom_w, zoom_h紀錄
起增大的長寬。
再來先提到setImgOriginalPosZoomin的功用,目的是計算出放大後圖片的新原點,因此
要放進的參數為現在的原點(0,0)及zoom過程大小的總和、這次以前記錄的zoom總和。
由於這是第一次zoom in,故zoom = 0,以這次放大的10%長寬為之後圖片原點的座標。
再來是會呼叫updateImgposition function改變放大後,可視圖片的原點,基本上會是負的。
舉個例子:
若一開始可視圖為512x386,那麼長寬放大10%後,可視座標的原點會變為(51, 38),至於
為啥是負的,因為要看到的是圖裡面的部分圖。而放大10%,就表示放大後的圖為原圖的
1.2倍長寬(左右延伸、上下增長)囉!
再來當再次zoom in,即zoom = 2時,就可以解釋zoom過程大小的總和、這次以前記錄的
zoom總和的意義。
假設再次放大,那麼原圖大小又會擴增10%,此時圖片可視原點的簡單計算方式如下:
offset_persent = img_pos/offset_pre;
先計算比例,假設放大前為51,offset_pre為51(0+51),那麼比例為1
img_pos = Math.round(offset_persent*offset_sum);
此時將1*offset_sum(0+51+61),即1*122 = 122,即新的可視原點X為122
也許會覺得奇怪為啥要乘比例,因為假設圖片在zoom = 1時,做了移動,此時他就不會是
(-51, -38),所以才乘比例,同理在縮小的地方也是雷同囉!
三、圖片縮小
縮小的概念與放大的概念差不多,在這邊就不另說明囉!
四、圖片移動
圖片的移動概念很簡單,也是去改變可視原點的位置,只不過要限定他移動的範圍,
如下圖:
假設在zoom = 2時,要移動圖片,上面黃色的區塊就是他可以移動的長與寬的距離,即
122, 84,也就是可以往左上、右上、左下、右下等方向各移122, 84。
mou_down_x = e.pageX;
mou_down_y = e.pageY;
點擊區塊時記錄當下位置
drag_img.x = img_ori_x - (e.pageX - mou_down_x);
drag_img.y = img_ori_y - (e.pageY - mou_down_y);
移動時將原點座標減去移動的距離(可能為負或正,若左移則e.pageX - mou_down_x會為負)
PS. 請注意,原點座標雖為負,但img_ori_x、img_ori_y變數值可是正的囉!
因為"background-position" : "-"+(img_ori_x)+"px -"+(img_ori_y)+"px"
如此就可以取得新的原點座標囉
再來像下面這個判斷式只是為了怕移動過界囉!
if(drag_img.x < 0){
drag_img.x = 0;
}else if(($("#img_block").width() + drag_img.x) > img_obj.width){
drag_img.x = img_obj.width - $("#img_block").width();
}
完成畫面如下:
結論
大致上就完成簡易的放大縮小及拖移,測試上應是沒問題,不過在這邊的初始為只能
先放大,您也可以修改成一開始只看到圖片內部部分畫面,此時不僅能縮小,也能放大囉!
而在這邊一開始一開始比較麻煩的為比例的部分,後來就簡單的定義出,假設當zoom =1時
,如往左上移動部分,那麼此時放大,就會去按照剛剛往左上移動移了多少比例來放大,
看起來感覺會比較合理,但也許有其他的定義也說不定XD
是有固定大小的,因此就需要可以放大、縮小、移動來檢視它。當時這個功能是我學長
寫的,那時我不會做XD,因此現在回想起來就自己寫寫看看囉。
這個Web Widget比起之前做的image gallery slider不用去使用CSS來定義版面的擺置,而是
著重在於圖片與區塊間的處理。將圖片類似鑲嵌進div內,如此可以定義圖片在區塊內可視
的長寬,及改變圖片的原點位置來調整放大、縮小後的圖片可視部分等等。
<div id="img_block"></div>
<input id="zoomin" type="button" value="zoom in" />
<input disabled="disabled" id="zoomout" type="button" value="zoom out" />
origin_x, origin_y = <span id="origin_x">0</span>px,
<span id="origin_y">0</span>px
首先自訂一個div區塊,到時透過JavaScript做鑲嵌,而定義兩個按鈕來控制zoom in/out
控制,另外再show出目前圖片可視的原點位置。控制大小的部分,由於一開始是定義
可看到全圖,故首先只能放大,放大之後才可以縮小或拖移。
JavaScript&jQuery部分
一、圖片載入
var img_obj = new Image();
img_obj.src = "Hydrangeas.jpg";
img_obj.onload = function(){
img_obj.width = img_obj.width/2;
img_obj.height = img_obj.height/2;
$("#img_block").css({
"width" : img_obj.width,
"height": img_obj.height,
"background-size" : img_obj.width+"px "+img_obj.height+"px",
"background-image": "url("+img_obj.src+")"
});
};
div是定義為原圖的一半大小,原圖也會以一半的大小來呈現!background-size為可視
的範圍。
二、圖片放大
var zoom_w = new Array();
var zoom_h = new Array();
var img_ori_x = 0;
var img_ori_y = 0;
var img_pre_w = 0;
var img_pre_h = 0;
var zoom = 0;
$("#zoomin").click(function(){
zoom_w.push(Math.round(img_obj.width*0.1));
zoom_h.push(Math.round(img_obj.height*0.1));
offset_pre_x = zoom_w.slice(0, zoom_w.length-1).reduce(arr_sum,0);
offset_pre_y = zoom_h.slice(0, zoom_h.length-1).reduce(arr_sum,0);
offset_sum_x = zoom_w.reduce(arr_sum);
offset_sum_y = zoom_h.reduce(arr_sum);
//new origin pos
img_ori_x = setImgOriginalPosZoomin(img_ori_x, offset_sum_x, offset_pre_x);
img_ori_y = setImgOriginalPosZoomin(img_ori_y, offset_sum_y, offset_pre_y);
//record old length
img_pre_w = img_obj.width;
img_pre_h = img_obj.height;
//new length
img_obj.width = img_obj.width*1.2;
img_obj.height = img_obj.height*1.2;
zoom++;
updateImgposition();
mousecursor();
});
function setImgOriginalPosZoomin(img_pos, offset_sum, offset_pre){
if(zoom == 0){
img_pos = offset_sum;
}else{
offset_persent = img_pos/offset_pre;
img_pos = Math.round(offset_persent*offset_sum);
}
return img_pos;
}
function updateImgposition(){
$("#origin_x").text((0-img_ori_x));
$("#origin_y").text((0-img_ori_y));
$("#img_block").css({
"background-size" : (img_obj.width)+"px "+(img_obj.height)+"px",
"background-position" : "-"+(img_ori_x)+"px -"+(img_ori_y)+"px"
});
}
function mousecursor(){
$("#img_block").css("cursor", "move");
if(zoom == 3){
$("#zoomin").attr("disabled", true);
}else{
$("#zoomin").attr("disabled", false);
}
if(zoom == 0){
$("#img_block").css("cursor", "text");
$("#zoomout").attr("disabled", true);
}else{
$("#zoomout").attr("disabled", false);
}
}
function arr_sum(x,y){
return x+y;
}
首先,當zoom in button被按下,此時以10%的大小擴增,並且利用zoom_w, zoom_h紀錄
起增大的長寬。
再來先提到setImgOriginalPosZoomin的功用,目的是計算出放大後圖片的新原點,因此
要放進的參數為現在的原點(0,0)及zoom過程大小的總和、這次以前記錄的zoom總和。
由於這是第一次zoom in,故zoom = 0,以這次放大的10%長寬為之後圖片原點的座標。
再來是會呼叫updateImgposition function改變放大後,可視圖片的原點,基本上會是負的。
舉個例子:
若一開始可視圖為512x386,那麼長寬放大10%後,可視座標的原點會變為(51, 38),至於
為啥是負的,因為要看到的是圖裡面的部分圖。而放大10%,就表示放大後的圖為原圖的
1.2倍長寬(左右延伸、上下增長)囉!
再來當再次zoom in,即zoom = 2時,就可以解釋zoom過程大小的總和、這次以前記錄的
zoom總和的意義。
假設再次放大,那麼原圖大小又會擴增10%,此時圖片可視原點的簡單計算方式如下:
offset_persent = img_pos/offset_pre;
先計算比例,假設放大前為51,offset_pre為51(0+51),那麼比例為1
img_pos = Math.round(offset_persent*offset_sum);
此時將1*offset_sum(0+51+61),即1*122 = 122,即新的可視原點X為122
也許會覺得奇怪為啥要乘比例,因為假設圖片在zoom = 1時,做了移動,此時他就不會是
(-51, -38),所以才乘比例,同理在縮小的地方也是雷同囉!
三、圖片縮小
$("#zoomout").click(function(){
offset_pre_x = zoom_w.slice(0, zoom_w.length-1).reduce(arr_sum,0);
offset_pre_y = zoom_h.slice(0, zoom_h.length-1).reduce(arr_sum,0);
offset_sum_x = zoom_w.reduce(arr_sum);
offset_sum_y = zoom_h.reduce(arr_sum);
img_ori_x = setImgOriginalPosZoomout(img_ori_x, offset_sum_x, offset_pre_x);
img_ori_y = setImgOriginalPosZoomout(img_ori_y, offset_sum_y, offset_pre_y);
zoom_w.pop();
zoom_h.pop();
img_obj.width = img_pre_w;
img_obj.height = img_pre_h;
img_pre_w = Math.ceil(img_pre_w/1.2);
img_pre_h = Math.ceil(img_pre_h/1.2);
zoom--;
updateImgposition();
mousecursor();
});
function setImgOriginalPosZoomout(img_pos, offset_sum, offset_pre){
offset_persent = img_pos/offset_sum;
img_pos = Math.round(offset_persent*offset_pre);
return img_pos;
}
縮小的概念與放大的概念差不多,在這邊就不另說明囉!
四、圖片移動
var mou_down_x = 0;
var mou_down_y = 0;
var drag_img = {state:false, x : 0, y : 0};
$("#img_block").mousedown(function(e){
drag_img.state = true;
mou_down_x = e.pageX;
mou_down_y = e.pageY;
}).mousemove(function(e){
if(drag_img.state){
drag_img.x = img_ori_x - (e.pageX - mou_down_x);
drag_img.y = img_ori_y - (e.pageY - mou_down_y);
if(drag_img.x < 0){
drag_img.x = 0;
}else if(($("#img_block").width() + drag_img.x) > img_obj.width){
drag_img.x = img_obj.width - $("#img_block").width();
}
if(drag_img.y < 0){
drag_img.y = 0;
}else if(($("#img_block").height() + drag_img.y) > img_obj.height){
drag_img.y = img_obj.height - $("#img_block").height();
}
$("#img_block").css("background-position", "-"+drag_img.x+"px -"+drag_img.y+"px");
}
}).mouseout(drag_img_ini).mouseup(drag_img_ini);
function drag_img_ini(){
if(drag_img.state){
drag_img.state = false;
img_ori_x = drag_img.x;
img_ori_y = drag_img.y;
$("#origin_x").text((0-img_ori_x));
$("#origin_y").text((0-img_ori_y));
}
}
圖片的移動概念很簡單,也是去改變可視原點的位置,只不過要限定他移動的範圍,
如下圖:
假設在zoom = 2時,要移動圖片,上面黃色的區塊就是他可以移動的長與寬的距離,即
122, 84,也就是可以往左上、右上、左下、右下等方向各移122, 84。
mou_down_x = e.pageX;
mou_down_y = e.pageY;
點擊區塊時記錄當下位置
drag_img.x = img_ori_x - (e.pageX - mou_down_x);
drag_img.y = img_ori_y - (e.pageY - mou_down_y);
移動時將原點座標減去移動的距離(可能為負或正,若左移則e.pageX - mou_down_x會為負)
PS. 請注意,原點座標雖為負,但img_ori_x、img_ori_y變數值可是正的囉!
因為"background-position" : "-"+(img_ori_x)+"px -"+(img_ori_y)+"px"
如此就可以取得新的原點座標囉
再來像下面這個判斷式只是為了怕移動過界囉!
if(drag_img.x < 0){
drag_img.x = 0;
}else if(($("#img_block").width() + drag_img.x) > img_obj.width){
drag_img.x = img_obj.width - $("#img_block").width();
}
完成畫面如下:
以下圖片來源為Window 7 (我的圖片),以此程式作為示範之用
初始畫面
zoom = 2且往左上拖移
大致上就完成簡易的放大縮小及拖移,測試上應是沒問題,不過在這邊的初始為只能
先放大,您也可以修改成一開始只看到圖片內部部分畫面,此時不僅能縮小,也能放大囉!
而在這邊一開始一開始比較麻煩的為比例的部分,後來就簡單的定義出,假設當zoom =1時
,如往左上移動部分,那麼此時放大,就會去按照剛剛往左上移動移了多少比例來放大,
看起來感覺會比較合理,但也許有其他的定義也說不定XD
留言
張貼留言