倔倔死磕Javascript之放大镜

14 Comments

上次我已经预告了下一个要用javascript实现的是放大镜效果~

最开始是在淘宝UED官方博客上看到的.觉得很不错,以为是flash. F12一下才知道是js实现的.当时没具体看,现在开始学javascript了,突然想到这个效果,决定挑战一下哈~开始吧~

Mockup

第一步:HTML&CSS

先不要着急写代码,先要考虑考虑实现这个效果对于代码结构上有什么特别的要求,我想到了两个方案:

1.一个小图容器,一个放大镜容器.原图做为放大镜容器的背景

2.一个小图容器,一个放大镜容器.原图做为放大镜子容器

这两个方案其实实现起来差别不大,但是考虑到将来图片有可能是动态读取出来的,而且大小不定,所以我们不推荐放在CSS背景中来实现,最后选择第二种方案.

HTML代码片段如下:

<div onMouseMove="imgZoomOut(event)" id="smallImgCon">
	<img src="img/airport_small_1.jpg" id="smallImg"/>
	<div id="magnifierCon" style="display:none">
		<img src="img/magnifier.png" id="magnifierBg"/>
		<img src="img/airport_large_1.jpg" id="largeImg"/>
	</div>
</div>

CSS代码片段如下:

#smallImgCon {position:relative;left:0;top:0;}
#magnifierCon {height:276px;width:276px;position:absolute;overflow:hidden;z-index:3}
	#magnifierCon img#magnifierBg {position:absolute;z-index:2}
	#magnifierCon img#largeImg {position:absolute;z-index:1}

第二步:准备好我们需要的信息

我们暂且不去考虑图片大小不定这样一种情况,我们目前可以只针对这其中一张图片.只是放大镜大小固定而已.这里我使用的大小是276*276.
大致思路是可以通过下图来了解:

Step1.得到小图所在位置,即坐标,并将其做为原点.
Step2.得到鼠标当前所在位置,这里是指相对于原点的,所以需要减去上一步得到的坐标值.
Step3.有了这个距离,再减去放大镜长宽的一半就得到了放大镜的坐标.即它相对于原点的距离.
Step4.关键一步大图如何定位呢?
这里需要注意的是这几个容器的层级关系:最外层容器是爷爷,放大镜与小图同是兄弟俩,大图是孙子(哈哈~~不是骂人哈)
说白了就是将光标与原点之间的距离*缩放比例=相对应的大图坐标
再减去放大镜宽高一半就得到了超出放大镜的那段距离 也就是大图相对于其父级容器(放大镜)的距离.将这两个值的赋给大图的left,top就基本搞定了~~
大家晕不?呵呵 我都有点儿晕了…思路及表达能力有待进一步提高 :(

那么按照以上步骤写代码吧:
主要代码如下

	var smallImgCon = document.getElementById("smallImgCon");
	var smallImg = document.getElementById("smallImg");
	var magnifierCon = document.getElementById("magnifierCon");
	var magnifierBg = document.getElementById("magnifierBg");
	var largeImg = document.getElementById("largeImg");

	function imgZoomOut(event) {

		//Step 1得到小图位置,即原点.
		smallImgConLocationX = smallImgCon.offsetLeft;
		smallImgConLocationY = smallImgCon.offsetTop;

		//Step2.得到光标相对于原点的坐标值.
		x = event.clientX - smallImgConLocationX;
		y = event.clientY - smallImgConLocationY;

		//Step3.放大镜相对于原点的距离.
		magnifierCon.style.left = x - magnifierWidth/2 + "px";
		magnifierCon.style.top = y - magnifierHeight/2 + "px";

		//Step4.大图定位
		x = - x*(largeImgWidth/smallImgWidth) + magnifierWidth/2;
		y = - y*(largeImgWidth/smallImgWidth) + magnifierHeight/2;

		largeImg.style.left = x + "px";
		largeImg.style.top = y + "px";

	}

写到这里基本结构有了,但还有一些问题需要考虑:

  1. 鼠标移到图像外面了怎么办?
  2. 如何动态得到各个元素的大小,便于将来扩展呢?

于是我们要添加另外两个函数跟一个条件判断:

	function getImageSize(imageEl) {
		var i = new Image();
		i.src = imageEl.src;
		return new Array(i.width, i.height);
	}
	function dispear() {
		magnifierCon.style.display = "none";
	}
	if ( x < 0 || x > smallImgWidth || y < 0 || y > smallImgHeight) {
		dispear();
	}else {
		...
	}

最终效果演示
小提示:大小图最后比例差别大些 这样效果更好更明显~
再次强调,因为是初学,所以代码还有很多地方需要优化,再小的功能也要不断完善,倔倔会在学习中不断完善之前的练习~希望大家能多多帮助倔倔~~:)

知识点总结:

  1. 函数之间的调用
  2. 数组的定义
  3. 鼠标事件的概念

下期预告:图片浏览+放大镜

14 Comments (+add yours?)

  1. luoxi
    May 09, 2010 @ 22:04:21

    呵呵,还能分出一期那~

    [Reply]

    Ting Reply:

    想分就分,要分得具体~

    [Reply]

  2. 音速
    May 10, 2010 @ 09:22:02

    你总是比我专业!厄~~继续学习~~

    [Reply]

    Ting Reply:

    呵呵 我是想要满足自己的虚荣心 努力装得专业些哈哈

    [Reply]

  3. 张智
    Jun 03, 2010 @ 10:02:26

    恩,不错,顶一个,真爱学习

    [Reply]

    Ting Reply:

    谢谢老伯伯表扬~~哈哈

    [Reply]

  4. hostsoso
    Jun 27, 2010 @ 21:49:57

    看了下。博主真是代码高手啊。各方面都精通,佩服!

    [Reply]

  5. 独孤逸辰
    Jul 18, 2010 @ 22:25:51

    咦!! var i = new Image(); js里哪里的image对象?

    [Reply]

    clovery Reply:

    宿主提供的对象。

    [Reply]

  6. 强哥仔
    Sep 02, 2010 @ 13:46:20

    整个放大镜的代码,要是能组织一下会更好

    [Reply]

  7. clovery
    Sep 02, 2010 @ 14:07:59

    学习了!给点建议,HTML结构的问题,如果多个图片都要使用放大镜效果,那么要在所有的原图前面加一张放大镜的图片,这样移植性就差了点。要么是用js动态生成放大镜的HTML代码,要么在CSS中作为背景图。

    [Reply]

  8. luoxi
    Sep 03, 2010 @ 10:33:14

    恩,是时候review一下以前的代码了,向阿当学习~

    [Reply]

  9. 羊子
    Sep 05, 2010 @ 21:34:34

    这个很实用,学习了,谢谢博主

    [Reply]

Leave a Reply