JS 图片放大镜
程序员文章站
2022-04-13 22:22:29
今天练习一个小demo, 从本地读取图片, 然后实现类似淘宝放大镜的效果, 再加两个需求 1 .可以调节缩放比例,默认放大两倍 2 . 图片宽高自适应, 不固定宽高 话不多说先看效果: 原理:1, 右侧放大区域的大小等于左侧半透明滑块大小乘以缩放倍数 2, 右侧放大区域图片的原始尺寸要和 左侧图片一 ......
今天练习一个小demo, 从本地读取图片,
然后实现类似淘宝放大镜的效果,
再加两个需求
1 .可以调节缩放比例,默认放大两倍
2 . 图片宽高自适应, 不固定宽高
话不多说先看效果:
原理:1, 右侧放大区域的大小等于左侧半透明滑块大小乘以缩放倍数
2, 右侧放大区域图片的原始尺寸要和
左侧图片一样,不能随右侧的宽高变化
3, 计算滑块位置
上代码: 基本每行都有注释
html:
<!--放大镜--> <div class="preview"> <div class="preview-header"> <!--选择本地图片--> <div class="choose-image"> <lable for="fileinput">选择图片</lable> <input type="file" id="fileinput"> </div> <!--调整缩放倍数--> <div class="scale"> <lable for="scalenum">设置放大倍数</lable> <input type="number" id="scalenum" value="2"> </div> </div> <!--预览区域--> <div class="preview-content"> <!--原图--> <div class="origin"> <img src="" alt="" id="origin-image"> <!--滑块--> <div class="scale-section"></div> </div> <!--放大后的图片--> <div class="target"> <img src="" alt="" id="target-image"> </div> </div> </div>
css:
/*图片放大镜*/ /*头部*/ .preview-header{ display: flex; padding: 10px; } /*预览区域*/ .preview-content{ display: none; align-items: flex-start; } /*原始图片*/ .preview-content .origin{ max-width: 350px; margin: 30px 0px 0px 10px; position: relative; box-shadow:3px 3px 10px 0 #111111; /*给图片施加阴影效果 */ -webkit-box-shadow: 3px 3px 10px 0 #111111; /*兼容性处理*/ -moz-box-shadow: 3px 3px 10px 0 #111111; overflow: hidden; } .preview-content .origin img{ width: 100%; } /*滑块*/ .origin .scale-section{ display: none; /*初始隐藏*/ position:absolute; top:0; left:0; width:175px; height:175px; background:#000; opacity: 0.3; cursor:move; /*改变鼠标的形状*/ } /*右侧放大区域的宽高是和滑块成比例的*/ .preview-content .target{ display: none;/*初始隐藏*/ width: 350px; height: 350px; margin: 30px 0px 0px 30px; position: relative; box-shadow:3px 3px 10px 0 #111111; /*给图片施加阴影效果 */ -webkit-box-shadow: 3px 3px 10px 0 #111111; /*兼容性处理*/ -moz-box-shadow: 3px 3px 10px 0 #111111; overflow: hidden; } /*放大后的图片*/ .target img{ position: absolute; top: 0; left: 0; transform-origin: top left; }
js:
// 获取dom // 原始图片 const originimage = document.getelementbyid('origin-image'), // 左侧图片区域 origin = document.getelementsbyclassname('origin')[0], // 放大后的图片 targetimage = document.getelementbyid('target-image'), // 放大图片区域 target = document.getelementsbyclassname('target')[0], // 整个图片区域 previewcontent = document.getelementsbyclassname('preview-content')[0], // 滑块 scalesection = document.getelementsbyclassname('scale-section')[0], // 文件选择框 fileinput = document.getelementbyid('fileinput'), // 放大倍数框 scalenum = document.getelementbyid('scalenum'); // 放大的倍数 let scale = scalenum.value; // 左侧图片的宽高 let originwidth,originheight; // 注册事件 // 选择文件 fileinput.addeventlistener('change',chooseimage,false); // 改变倍数 scalenum.addeventlistener('change',scalechange,false); // 鼠标在左侧区域移动移动 origin.addeventlistener('mousemove',(e) => { // 事件兼容 const event = e || window.event; // 计算滑块以及右边放大图片的位置 calculateposition(event.clientx, event.clienty); scalesection.style.display = 'block'; target.style.display = 'block'; }, false); // 鼠标离开左侧图片区域 origin.addeventlistener('mouseleave',() => { scalesection.style.display = 'none'; target.style.display = 'none'; }, false); // 选择要缩放的图片 function chooseimage(e) { // 使用file reader获取url // 不懂filereader的可以参考我之前写的本地图片预览 if (e.target.files[0].type.indexof('image') === -1) { alert('请选择图片'); return } const reader = new filereader(); reader.onload = () => { // promise是为了等图片加载完毕取宽高 const p1 = () => { return new promise((resolve, reject) => { originimage.onload = () => { resolve(originimage); }; originimage.src = reader.result; }) }; const p2 = () => { return new promise((resolve, reject) => { targetimage.onload = () => { resolve(targetimage); }; targetimage.src = reader.result; }) }; // 获取左侧原图的大小, // 初始化放大区域的图片大小 promise.all([p1(), p2()]).then((data) => { originwidth = data[0].width; originheight = data[0].height; data[1].style.width = originwidth * scale + 'px'; data[1].style.height = originheight * scale + 'px'; }); previewcontent.style.display = 'flex'; }; reader.readasdataurl(e.target.files[0]); } function calculateposition(x,y) { // 设置边界 const mintop = 0, minleft = 0, maxtop = origin.offsetheight - scalesection.offsetheight, maxleft = origin.offsetwidth - scalesection.offsetwidth; // 计算滑块的位置 const sectionx = x - origin.offsetleft - scalesection.offsetwidth/2; const sectiony = y - origin.offsettop - scalesection.offsetheight/2; // 滑块的真实位置 // 用于计算右侧放大图片的位置 let realtop = sectiony, realleft = sectionx; // 左右边界 if (sectionx < minleft) { scalesection.style.left = minleft + 'px'; realleft = minleft; } else if (sectionx >= maxleft) { scalesection.style.left = maxleft + 'px'; realleft = maxleft; } else { scalesection.style.left = sectionx + 'px'; } // 上下边界 if (sectiony <= mintop) { scalesection.style.top = mintop + 'px'; realtop = mintop; } else if (sectiony >= maxtop) { scalesection.style.top = maxtop + 'px'; realtop = maxtop; } else { scalesection.style.top = sectiony + 'px'; } // 计算右侧放大图片的位置 // 滑块移动多少, 右侧图片就向反方向移动scale的倍数 targetimage.style.top = -realtop*scale + 'px'; targetimage.style.left = -realleft*scale + 'px'; } // 缩放比例改变 function scalechange(e) { scale = e.target.value; targetimage.style.width = originwidth * scale + 'px'; targetimage.style.height = originheight * scale + 'px'; target.style.width = 175 * scale + 'px'; target.style.height = 175 * scale + 'px'; }
还是那句话,新手自己多动手写写,
不然容易一看就会,一写就懵逼,
感谢观看!!!
下一篇: JS控制上传文件个数