相关知识
- canvas标签的常用属性:hidden是否隐藏、width画布宽度、height画布高度
- document对象
| 常用方法 | 含义 | 实例 | 备注 |
|---|---|---|---|
| getElementById | 指定id属性的第一个对象 | document.getElementById('pic') | |
| getElementByName | 指定name属性的对象集合 | document.getElementByName('hobbies') | 常用于单行文本框、复选框等具有name属性的元素 |
| getElementByTagName | 指定标签名的元素集合 | document.getElementByTagName('input') | 元素在文档中的顺序即为集合中的顺序;当参数为‘*’,返回页面所有标签 |
| getElementByClassName | 指定class属性的对象集合 | document.getElementByClassName |
- offset(偏移量)
- offsetParent —— 获得被定位的最近的祖先元素
- offsetLeft —— 当前元素相对于 offsetParent节点 左边界的偏移像素值
- offsetTop —— 当前元素相对于 offsetParent节点 上边界的偏移像素值
- 当元素的 style.display 设置为 "none" 时,offsetParent 返回 null
页面效果
共三个板块,左侧为显示的图片,右边图片与左侧等大,为左侧图片放大后的效果,下方为五张可选择放大的图片。
鼠标在左侧图片上移动时,会出现黄色遮罩区,遮罩区覆盖的部分,会在右侧放大,点击下方图片可切换被放大的图片。
放大后的清晰度 取决于原图的像素
注意事项
- canvas画布大小只能通过height、width属性设置,不能在样式中设置height、width
- canvas裁切的是img.src的原图而非img容器的图像,
需要通过img.naturalHeight和img.naturalHeight获取原图的宽高,
和img容器作比,来获取图像缩放的比例()
- img.naturalWidth / canvas_width 原图与画布的宽之比
- img.naturalHeight / canvas_width 原图与画布的高之比
- 绘图的原图坐标 : shadeX × 宽之比,shadeY × 高之比
- 绘制的原图大小 : shade_width × 宽之比, shade_height × 高之比
- 关于shade遮罩区的X坐标如何计算(Y坐标同理)
- ? = e.pageX - boxX - shade_width/2
- ? = e.pageX - boxX - shade_width/2
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>放大镜</title>
<link rel="stylesheet" href="../css/magnifier.css">
<script type="text/javascript" src="../js/magnifier.js"></script>
</head>
<body>
<div class="left_pic">
<div id="box">
<img id="showPicture" src="../images/magnifier/1.jpg" alt="">
<!-- 遮罩层 -->
<div id="shade"></div>
</div>
</div>
<canvas id="mycanvas" width="1000px" height="1000px"></canvas>
<ul class="small_piclist" id="picsList">
<li><img src="../images/magnifier/5.jpg" alt="" onclick="changePic(this)"></li>
<li><img src="../images/magnifier/4.jpg" alt="" onclick="changePic(this)"></li>
<li><img src="../images/magnifier/3.jpg" alt="" onclick="changePic(this)"></li>
<li><img src="../images/magnifier/2.jpg" alt="" onclick="changePic(this)"></li>
<li><img src="../images/magnifier/1.jpg" alt="" onclick="changePic(this)"></li>
</ul>
</body>
</html>
.left_pic{
position: relative;
margin: 50px;
float: left;
}
/* 图片 */
#box{
position: relative;
margin-bottom: 10px;
width: 1000px;
height: 1000px;
}
#showPicture{
width: 100%;
height: 100%;
/* object-fit: fill; */
}
/* 遮罩层 */
#shade{
position: absolute;
top: 0;
z-index: 10;
width: 300px;
height: 300px;
/* 设置透明度 */
/* IE */
filter: alpha(Opacity = 70);
/* 火狐 */
-moz-opacity: 0.7;
/* chrome */
opacity: 0.7;
background-color: #ffc;
display: block;
}
#picsList{
clear:both;
list-style: none;
}
#picsList li{
height: 400px;
width: 400px;
float: left;
margin-left: 50px;
}
#picsList li img{
width: 100%;
height: 100%;
}
#mycanvas{
margin: 50px;
float: left;
display: none;
background-color: #fff;
width: 1000px;
height: 1000px;
}
/*
若修改样式中#box、#shade、#mycanvas的宽高,需要修改以下参数
// 图片大小(box)
var pic_width = 1000;
var pic_height = 1000;
// 遮罩层大小(shade)
var shade_width = 300;
var shade_height = 300;
可优化:动态获取样式或属性的值大小
*/
// 切换展示的图像
function changePic(thumb){
// 获取缩略图在商品展示区对应的大图
var showPic = document.getElementById("showPicture");
showPic.src = thumb.src;
// 获取缩略图对应的li元素,将边框清除
var picsList = document.getElementById("picsList");
var items = picsList.getElementsByTagName("li");
for (var i=0; i<items.length; i++){
var thumbImg = items[i].getElementsByTagName("img");
thumbImg[0].style.border = "";
}
// 设置当前选中图片的边框为红色
thumb.style.border = "4px solid red";
}
// 获取元素顶部与body的距离
function getTop(e){
var offset = e.offsetTop;
// offsetParent为离自身最近且经过定位的父元素
if (e.offsetParent != null)
offset += getTop(e.offsetParent);
return offset;
}
// 获取元素左侧与body的距离
function getLeft(e){
var offset = e.offsetLeft;
if (e.offsetParent != null)
offset += getLeft(e.offsetParent);
return offset;
}
// 图像放大效果
function zoomPicture(){
var box = document.getElementById("box");
var showPicture = document.getElementById("showPicture");
var canvas = document.getElementById("mycanvas");
var shade = document.getElementById("shade");
// 整个.left_pic的margin(复合属性无法直接获取即margin,只能获取单一数值)
var margin = 50;
// 图片大小(box)
var pic_width = 1000;
var pic_height = 1000;
// 遮罩层大小(shade)
var shade_width = 300;
var shade_height = 300;
// 画布大小(mycanvas)
var canvas_width = canvas.width;
var canvas_height = canvas.height;
if (showPicture == null) return false;
// 绑定鼠标移出图片所触发的事件
box.onmouseout = function(){
shade.style.display = "none";
canvas.style.display = "none";
document.body.style.cursor = "default";
};
// 绑定鼠标移入图片所触发的事件
box.onmousemove = function(e){
// 设定鼠标样式
document.body.style.cursor = "move";
// 获取图片容器相对于body的距离(可以理解为容器左上角的坐标)
var boxX = getLeft(box);
var boxY = getTop(box);
// 计算遮罩区域左上角的坐标
var shadeX = e.pageX - boxX - shade_width/2;
var shadeY = e.pageY - boxY - shade_height/2;
// 防止遮罩区移动到图片之外
if (shadeX < 0) shadeX = 0;
else if (shadeX > pic_width-shade_width) shadeX = pic_width-shade_width;
if (shadeY < 0) shadeY = 0;
else if (shadeY > pic_height-shade_height) shadeY = pic_width-shade_height;
// 使用canvas绘制遮罩区
var context = canvas.getContext("2d");
shade.style.display = "block";
shade.style.left = shadeX + "px";
shade.style.top = shadeY + "px";
canvas.style.display = "block";
// 在右侧绘制放大后的图像
var img = showPicture;
var proportion_width = img.naturalWidth / canvas_width;
var proportion_height = img.naturalHeight / canvas_width;
// 清除之前画的图像
context.clearRect(margin, margin, pic_width+margin, pic_height+margin);
// 绘制图像(参数:图片源,绘制的原图坐标,绘制的原图大小,在画布上的坐标,绘制的图片长宽)
context.drawImage(img, shadeX*proportion_width, shadeY*proportion_height,
shade_width*proportion_width, shade_height*proportion_height, 0, 0, canvas_width, canvas_height);
}
}
//去掉像素单位px
function dealPx(pixelStr){
var pixel = pixelStr.substring(0,pixelStr.indexOf('px'));
if (pixel == "") return 0;
return parseInt(pixel);
}
window.onload = function(){
//默认第一个图片为选中状态
var picsList = document.getElementById("picsList");
var thumb_img = picsList.getElementsByTagName("li")[0].getElementsByTagName("img");
changePic(thumb_img[0]);
zoomPicture();
}