JS 图片放大镜
今天练习一个小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 图片放大镜的更多相关文章
- jquery.jqzoom.js图片放大镜
jqzoom插件实现图片放大镜效果 1. jquery.jqzoom.js //************************************************************ ...
- js 图片放大镜功能
原理:放置两张相同的图片,一张作为主图片(图片1),另一张作为用来裁剪并放大的图片(图片2) 鼠标移动时,计算鼠标在图片1的位置(距离图片1左上角的x,y距离),以此决定在图片2开始 ...
- js图片放大镜特效代码
<script language="JavaScript"> <!-- var srcX = 1024; //原图长宽 var srcY = 768; var b ...
- js图片放大镜 可动态更换图片
现仅已.NET为例,HTML代码如下 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > & ...
- js图片放大镜
<!doctype html><html><head><meta charset="utf-8"><style>#sma ...
- [js开源组件开发]图片放大镜
图片放大镜 一般情况下,手机由于屏幕太小,会有图片上看不清的问题,所以我就做了一个放大镜的js效果,支持pc和移动端.它的原理是利用的backgroundsize来实现的,所以你的浏览器首先要支持这个 ...
- Magnifier.js - 支持鼠标滚轮缩放的图片放大镜效果
Magnifier.js 是一个 JavaScript 库,能够帮助你在图像上实现放大镜效果,支持使用鼠标滚轮放大/缩小功能.放大的图像可以显示在镜头本身或它的外部容器中.Magnifier.js 使 ...
- 原生JS实现图片放大镜插件
前 言 我们大家经常逛各种电商类的网站,商品的细节就需要用到放大镜,这个大家一定不陌生,今天我们就做一个图片放大镜的插件,来看看图片是如何被放大的…… 先看一下我们要是实现的最终效果是怎么样的 ...
- JS实现图片放大镜
将一个小图放置在一个小盒子里,当鼠标在小盒子里移动时,出现一个移动块,右侧出现一个大盒子,显示出小盒子中移动块所在区域的等比例放大的图片内容.需要实现的效果如下: 基本实现思路为:右侧大盒子为一个可视 ...
随机推荐
- Wex5执行Class[search.login__do] Method[login]失败
====================开发工具版本:WeX5_V3.3======================== 报错背景:大二的时候用这个工具开发了一款APP,备份了项目数据库的SQL文件+ ...
- Scala编程入门---函数式编程之集合操作
集合的函数式编程: 实战常用: //map案例实战:为List中的每个元素都添加一个前缀. List("leo","Jen","peter" ...
- 学习JavaScript最佳实践方法
首先要说明的是,咱现在不是高手,最多还是一个半桶水,算是入了JS的门. 谈不上经验,都是一些教训. 这个时候有人要说,“靠,你丫半桶水,凭啥教我们”.您先别急着骂,先听我说. 你叫一个大学生去教小学数 ...
- 20岁少年小伙利用Python_SVM预测股票趋势月入十万!
在做数据预处理的时候,超额收益率是股票行业里的一个专有名词,指大于无风险投资的收益率,在我国无风险投资收益率即是银行定期存款. pycharm + anaconda3.6开发,涉及到的第三方库有p ...
- 使用Myeclipse2015构建SpringMVC项目
1.新建web project 2.右键项目,给项目添加spring框架如图,不需要勾选任何一个选项. 3.在WebRoot/WEB-INF目录下添加web.xml内容如下: <?xml ver ...
- 构建具有用户身份认证的 Ionic 应用
序言:本文主要介绍了使用 Ionic 和 Cordova 开发混合应用时如何添加用户身份认证.教程简易,对于 Ionic 入门学习有一定帮助.因为文章是去年发表,所以教程内关于 Okta 的一些使用步 ...
- django+appium实现UI自动化测试平台---构思版
背景 UI自动化,在进行的过程中,难免会遇到平台化, 在实际的工作中,有的领导也会想要实现自动化测试的平台化.自动化平台化后,有了更为实际的成果, 在做UI自动化,很想吧现在的自动化 ...
- .NET Core使用微软官方类库实现汉字转拼音
一.NuGet包 拼音:Install-Package SimplifiedChinesePinYinConversion 简体-繁体互转:Install-Package TraditionalChi ...
- Spring Boot使用RestTemplate消费REST服务的几个问题记录
我们可以通过Spring Boot快速开发REST接口,同时也可能需要在实现接口的过程中,通过Spring Boot调用内外部REST接口完成业务逻辑. 在Spring Boot中,调用REST Ap ...
- Scrapy爬虫框架第五讲(linux环境)【download middleware用法】
DOWNLOAD MIDDLEWRE用法详解 通过上面的Scrapy工作架构我们对其功能进行下总结: (1).在Scheduler调度出队列时的Request送给downloader下载前对其进行修改 ...