今天练习一个小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 图片放大镜的更多相关文章

  1. jquery.jqzoom.js图片放大镜

    jqzoom插件实现图片放大镜效果 1. jquery.jqzoom.js //************************************************************ ...

  2. js 图片放大镜功能

    原理:放置两张相同的图片,一张作为主图片(图片1),另一张作为用来裁剪并放大的图片(图片2)          鼠标移动时,计算鼠标在图片1的位置(距离图片1左上角的x,y距离),以此决定在图片2开始 ...

  3. js图片放大镜特效代码

    <script language="JavaScript"> <!-- var srcX = 1024; //原图长宽 var srcY = 768; var b ...

  4. js图片放大镜 可动态更换图片

    现仅已.NET为例,HTML代码如下 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > & ...

  5. js图片放大镜

    <!doctype html><html><head><meta charset="utf-8"><style>#sma ...

  6. [js开源组件开发]图片放大镜

    图片放大镜 一般情况下,手机由于屏幕太小,会有图片上看不清的问题,所以我就做了一个放大镜的js效果,支持pc和移动端.它的原理是利用的backgroundsize来实现的,所以你的浏览器首先要支持这个 ...

  7. Magnifier.js - 支持鼠标滚轮缩放的图片放大镜效果

    Magnifier.js 是一个 JavaScript 库,能够帮助你在图像上实现放大镜效果,支持使用鼠标滚轮放大/缩小功能.放大的图像可以显示在镜头本身或它的外部容器中.Magnifier.js 使 ...

  8. 原生JS实现图片放大镜插件

      前  言 我们大家经常逛各种电商类的网站,商品的细节就需要用到放大镜,这个大家一定不陌生,今天我们就做一个图片放大镜的插件,来看看图片是如何被放大的…… 先看一下我们要是实现的最终效果是怎么样的  ...

  9. JS实现图片放大镜

    将一个小图放置在一个小盒子里,当鼠标在小盒子里移动时,出现一个移动块,右侧出现一个大盒子,显示出小盒子中移动块所在区域的等比例放大的图片内容.需要实现的效果如下: 基本实现思路为:右侧大盒子为一个可视 ...

随机推荐

  1. Wex5执行Class[search.login__do] Method[login]失败

    ====================开发工具版本:WeX5_V3.3======================== 报错背景:大二的时候用这个工具开发了一款APP,备份了项目数据库的SQL文件+ ...

  2. Scala编程入门---函数式编程之集合操作

    集合的函数式编程: 实战常用: //map案例实战:为List中的每个元素都添加一个前缀. List("leo","Jen","peter" ...

  3. 学习JavaScript最佳实践方法

    首先要说明的是,咱现在不是高手,最多还是一个半桶水,算是入了JS的门. 谈不上经验,都是一些教训. 这个时候有人要说,“靠,你丫半桶水,凭啥教我们”.您先别急着骂,先听我说. 你叫一个大学生去教小学数 ...

  4. 20岁少年小伙利用Python_SVM预测股票趋势月入十万!

      在做数据预处理的时候,超额收益率是股票行业里的一个专有名词,指大于无风险投资的收益率,在我国无风险投资收益率即是银行定期存款. pycharm + anaconda3.6开发,涉及到的第三方库有p ...

  5. 使用Myeclipse2015构建SpringMVC项目

    1.新建web project 2.右键项目,给项目添加spring框架如图,不需要勾选任何一个选项. 3.在WebRoot/WEB-INF目录下添加web.xml内容如下: <?xml ver ...

  6. 构建具有用户身份认证的 Ionic 应用

    序言:本文主要介绍了使用 Ionic 和 Cordova 开发混合应用时如何添加用户身份认证.教程简易,对于 Ionic 入门学习有一定帮助.因为文章是去年发表,所以教程内关于 Okta 的一些使用步 ...

  7. django+appium实现UI自动化测试平台---构思版

             背景 UI自动化,在进行的过程中,难免会遇到平台化, 在实际的工作中,有的领导也会想要实现自动化测试的平台化.自动化平台化后,有了更为实际的成果, 在做UI自动化,很想吧现在的自动化 ...

  8. .NET Core使用微软官方类库实现汉字转拼音

    一.NuGet包 拼音:Install-Package SimplifiedChinesePinYinConversion 简体-繁体互转:Install-Package TraditionalChi ...

  9. Spring Boot使用RestTemplate消费REST服务的几个问题记录

    我们可以通过Spring Boot快速开发REST接口,同时也可能需要在实现接口的过程中,通过Spring Boot调用内外部REST接口完成业务逻辑. 在Spring Boot中,调用REST Ap ...

  10. Scrapy爬虫框架第五讲(linux环境)【download middleware用法】

    DOWNLOAD MIDDLEWRE用法详解 通过上面的Scrapy工作架构我们对其功能进行下总结: (1).在Scheduler调度出队列时的Request送给downloader下载前对其进行修改 ...