当前位置: 首页 > news >正文

做们作业网站重庆seo技术教程博客

做们作业网站,重庆seo技术教程博客,建设门户网站的公司,2023全国疫情爆发时间表扫码关注公众号「政采云前端团队」,获取更多不掺水的原创好文~前言在做电商类应用时,难免会遇到商品主图实现放大镜效果的场景,现有的基于 Vue 的第三方包不多并且无法直接复用,今天,我来分享一种高鲁棒性的…

扫码关注公众号「政采云前端团队」,获取更多不掺水的原创好文~

   referrerpolicy=
   referrerpolicy=

前言

在做电商类应用时,难免会遇到商品主图实现放大镜效果的场景,现有的基于 Vue 的第三方包不多并且无法直接复用,今天,我来分享一种高鲁棒性的基于 Vue 的图片放大镜方法。

实现原理

放大镜的原理用一句话概括,就是根据小图上的鼠标位置去定位大图。

图 1 原理图(以 2 倍放大为例)

   referrerpolicy=

相信原理图已经画的很明白了,图中,左侧框是小图框,其蓝色区域为图片遮罩层(需放大区域),右侧框是整个大图目前所在区域,其蓝色区域是放大区域,设置超出隐藏,就实现了放大遮罩区域的效果。

显然,两块蓝色区域存在着某种对应关系,即遮罩的左上角位置(相对于小图,以下称 X 坐标)和放大区域(相对于大图)的左上角位置是成比例的,即放大倍数。计算出 X 坐标后,适当调整背景图的位置,使大图向反方向移动 scale 倍的 X 坐标即可。

X 坐标为(maskX,maskY),以计算 maskX 为例:

鼠标移动中会产生 e.clientX,标识鼠标与浏览器左侧的距离,小图与浏览器左侧的距离是 left ,由于遮罩始终是一个以鼠标为中心的正方形,所以:

maskX = e.clientX - left - mask/2

同理,

maskY = e.clientY - top - mask/2

大图的对应样式设置为:

{  left: - maskX * scale + 'px';  top: - maskY * scale + 'px';}

效果演示

图 2 长图展示

   referrerpolicy=

图 3 宽图展示

   referrerpolicy=

图 4 两倍放大效果图

   referrerpolicy=

图 5 四倍放大效果图

   referrerpolicy=

核心代码

html

一般放大镜实现的是 1:1 等宽等高的正方形图片,这里兼容了其他比例的图片,设置图片为垂直居中对齐,包括小图,大图。如果小图不够充满整个小图框,余留下的空白部分也可以有放大效果,只不过放大结果依然是空白。 这样只需计算背景图的移动距离,不用过多的关注图片定位问题。

   referrerpolicy=
   referrerpolicy=

js

这里主要有三个事件函数,handOver 鼠标进入到小图框上的事件,此时创建遮罩和放大区域,并计算小图框的位置信息。

handOver() {  this.imgObj = this.$el.getElementsByClassName('small-box')[0];    // 创建遮罩区域  this.mouseMask = document.createElement('div');  this.mouseMask.className = 'magnifier-zoom';  this.mouseMask.style.background = this.configs.maskColor;  this.mouseMask.style.height = this.configs.maskWidth + 'px';  this.mouseMask.style.width = this.configs.maskHeight + 'px';  this.mouseMask.style.opacity = this.configs.maskOpacity;    // 创建预览框样式  this.imgLayer = document.getElementsByClassName('magnifier-layer')[0];  this.imgLayer.style.display = 'block';  this.bigBox = document.getElementsByClassName('big-box')[0];  this.imgObj.appendChild(this.mouseMask);    // 计算小图框在浏览器中的位置  this.imgRectNow = this.imgObj.getBoundingClientRect();}

handMove 鼠标在小图上的移动事件,此事件发生在 handOver 之后,计算数据,移动遮罩以及背景图;

handMove(e) {  // 计算初始的遮罩左上角的坐标  let objX = e.clientX - this.imgRectNow.left;  let objY = e.clientY - this.imgRectNow.top;    // 计算初始的遮罩左上角的坐标  let _maskX = objX - this.mouseMask.offsetHeight/2;  let _maskY = objY - this.mouseMask.offsetWidth/2;    // 判断是否超出界限,并纠正  _maskY = _maskY < 0 ? 0: _maskY;   if(_maskY + this.mouseMask.offsetHeight >= imgRectNow.height){    _maskY = imgRectNow.height - this.mouseMask.offsetHeight;  }  _maskX = _maskX < 0 ? 0: _maskX;   if(_maskX + this.mouseMask.offsetWidth >= imgRectNow.width){    _maskX = imgRectNow.width - this.mouseMask.offsetWidth;  }  let bigImgLeft = _maskX * this.configs.scale;  let bigImgTop = _maskY * this.configs.scale;    // 遮罩移动  this.mouseMask.style.transform=`translate(${_maskX}px, ${_maskY}px)`;    // 背景图移动  this.bigBox.style.left = - bigImgLeft + "px";  this.bigBox.style.top = - bigImgTop + "px";}

handOut 鼠标离开小图事件,此时无放大镜效果,隐藏遮罩和放大区域。

handOut() {  this.imgLayer.style.display = 'none';  this.mouseMask.style.display = 'none';}

以上三个事件基本上就实现了图片的放大镜功能。

但仔细看,你会发现每次移入小图框都会触发一次 handOver 事件,进而创建一份遮罩和放大区域等信息,其实,这些信息只需在页面加载后创建一次,多则浪费。

为了优化此问题,可以用 init 标识是否是页面加载后首次触发 handOver 事件,如果是初始化就创建遮罩和放大区域等,否则只需修改遮罩和放大区域的样式,使其显示即可。

handOver() {  if (!this.init) {    this.init = true;    // 原 handOver 事件    ...  } else {    this.imgLayer.style.display = 'block';    this.mouseMask.style.display = 'block';  }},

在测试的过程中,发现页面滚动后,会出现遮罩定位错误的情况,原来是因为初始化时,我们定死了小图框的位置信息(存放在 this.imgRectNow ),导致 handMove 事件中的移动数据计算错误。

解决这个问题有两种方案,一、监听scroll 事件,更新 this.imgRectNow;二、在 handMove 事件中更新 this.imgRectNow。这里选择了第二种。

handMove(e) {  // 动态获取小图的位置(或者监听 scroll )  let imgRectNow = this.imgObj.getBoundingClientRect();  let objX = e.clientX - imgRectNow.left;  let objY = e.clientY - imgRectNow.top;  // 原 handMove 事件剩余内容  ...},

综合以上,我们已经实现了一个完美的图片放大镜功能。最终的 js 如下所示:

data() {    return {      imgObj:{},      mouseMask:{},      imgLayer:{},      init: false,    };  },  methods: {    handMove(e) {      // 动态获取小图的位置(或者监听 scroll )      let imgRectNow = this.imgObj.getBoundingClientRect();      let objX = e.clientX - imgRectNow.left;      let objY = e.clientY - imgRectNow.top;      // 计算初始的遮罩左上角的坐标      let _maskX = objX - this.mouseMask.offsetHeight/2;      let _maskY = objY - this.mouseMask.offsetWidth/2;      // 判断是否超出界限,并纠正      _maskY = _maskY < 0 ? 0: _maskY;       if(_maskY + this.mouseMask.offsetHeight >= imgRectNow.height){        _maskY = imgRectNow.height - this.mouseMask.offsetHeight;      }      _maskX = _maskX < 0 ? 0: _maskX;       if(_maskX + this.mouseMask.offsetWidth >= imgRectNow.width){        _maskX = imgRectNow.width - this.mouseMask.offsetWidth;      }      let bigImgLeft = _maskX * this.configs.scale;      let bigImgTop = _maskY * this.configs.scale;      // 遮罩移动      this.mouseMask.style.transform=`translate(${_maskX}px, ${_maskY}px)`;      // 背景图移动      this.bigBox.style.left = - bigImgLeft + "px";      this.bigBox.style.top = - bigImgTop + "px";    },    handOut() {      this.imgLayer.style.display = 'none';      this.mouseMask.style.display = 'none';    },    handOver() {      if (!this.init) {        this.init = true;        this.imgObj = this.$el.getElementsByClassName('small-box')[0];        // 创建遮罩区域        this.mouseMask = document.createElement('div');        this.mouseMask.className = 'magnifier-zoom';        this.mouseMask.style.background = this.configs.maskColor;        this.mouseMask.style.height = this.configs.maskWidth + 'px';        this.mouseMask.style.width = this.configs.maskHeight + 'px';        this.mouseMask.style.opacity = this.configs.maskOpacity;        // 创建预览框样式        this.imgLayer = document.getElementsByClassName('magnifier-layer')[0];        this.imgLayer.style.display = 'block';        this.bigBox = document.getElementsByClassName('big-box')[0];        this.imgObj.appendChild(this.mouseMask);      } else {        this.imgLayer.style.display = 'block';        this.mouseMask.style.display = 'block';      }    }  }

CSS

@prefixCls: ~'magnifier';.@{prefixCls} {  position: relative;  font-size: 0;  .small-box {    width: 420px;    height: 420px;    cursor: move;    text-align: center;    display: table-cell;    vertical-align: middle;    border: 1px solid #E6E6E6;    .smallPic {      max-width: 418px;      max-height: 418px;    }  }  .magnifier-layer{    position: absolute;    z-index: 9010;    background: #fff;    display: none;    overflow: hidden;    border: 1px solid #E6E6E6;    box-shadow: 0 6px 20px 0 rgba(0,0,0,.1);    .big-box {      position: absolute;      display: table-cell;      vertical-align: middle;      text-align: center;      &-img {        display: table-cell;        vertical-align: middle;        text-align: center;      }    }  }  .magnifier-zoom{    position: absolute;     top:0;    left:0;     z-index: 20;    pointer-events:none;  }} 

使用方法

本示例中的固定参数:小图框:420 * 420 。

程序可接受参数:

// 小图地址src: {  type: String,},// 大图地址bigSrc: {  type: String,},// 配置项configs: {  type: Object,    default() {    return {    width:420,//放大区域    height:420,//放大区域    maskWidth:210,//遮罩    maskHeight:210,//遮罩    maskColor:'rgba(25,122,255,0.5)',//遮罩样式    maskOpacity:0.6,    scale:2,//放大比例    };  }}

文中图 2 是一张长图,小图的最大边不超过 836px(二倍图) ,大图为了视觉效果,分辨率尽量高点,程序会根据配置项自动设置对应的 height,width,长图与宽图的效果对比可参考图 3。

配置项可根据应用场景自行设置,本文示例的配置项是2倍放大,效果可参考图 4,四倍放大效果可参考图 5。

招贤纳士

政采云前端团队(ZooTeam),一个年轻富有激情和创造力的前端团队,隶属于政采云产品研发部,Base 在风景如画的杭州。团队现有 50 余个前端小伙伴,平均年龄 27 岁,近 3 成是全栈工程师,妥妥的青年风暴团。成员构成既有来自于阿里、网易的“老”兵,也有浙大、中科大、杭电等校的应届新人。团队在日常的业务对接之外,还在物料体系、工程平台、搭建平台、性能体验、云端应用、数据分析及可视化等方向进行技术探索和实战,推动并落地了一系列的内部技术产品,持续探索前端技术体系的新边界。

如果你想改变一直被事折腾,希望开始能折腾事;如果你想改变一直被告诫需要多些想法,却无从破局;如果你想改变你有能力去做成那个结果,却不需要你;如果你想改变你想做成的事需要一个团队去支撑,但没你带人的位置;如果你想改变既定的节奏,将会是“5 年工作时间 3 年工作经验”;如果你想改变本来悟性不错,但总是有那一层窗户纸的模糊… 如果你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的自己。如果你希望参与到随着业务腾飞的过程,亲手推动一个有着深入的业务理解、完善的技术体系、技术创造价值、影响力外溢的前端团队的成长历程,我觉得我们该聊聊。任何时间,等着你写点什么,发给 ZooTeam@cai-inc.com

   referrerpolicy=
http://www.lbrq.cn/news/2387755.html

相关文章:

  • 个人在国外网站做电商培训机构还能开吗
  • 沈阳网站建设多少钱百度sem优化师
  • 湖州长兴县建设局网站北京seo百科
  • 招标代理网站建设网络推广的渠道和方式有哪些
  • 政府网站建设的基本情况优化电池充电什么意思
  • 哈尔滨建站系统报价免费网站推广软文发布
  • 网站上名片如何做湖南网站seo地址
  • 不花钱做网站怎么创建网站
  • 东莞疫情进出最新政策百度seo报价
  • 神东集团网站建设网页搜索快捷键是什么
  • 阿里妈妈网站建设不完整今日最新国际新闻
  • gta5房子网站建设中免费个人网站制作
  • 百度权重2的网站百度平台投诉人工电话
  • wordpress 用iis建站百度seo查询
  • 纯静态网站 维护百度关键词搜索优化
  • 地方型旅游网站上海最大的seo公司
  • 无锡企业建站程序北京seo软件
  • 做音箱木工网站百度搜索引擎下载免费
  • 做网站的需要什么软件专业提升关键词排名工具
  • 做网站不赚钱中国品牌策划公司排名
  • 手机网站切图学编程的正规学校
  • 网站建设开发背景91关键词排名
  • 松江区建设交通委员会网站电脑培训网
  • 网站建设制作免费咨询推广平台 赚佣金
  • 十大免费ppt课件网站石家庄网站建设
  • 做视频网站视频存放问题seo网站内容优化
  • 大连网站建设设计公司哪家好宁国网络推广
  • 电商网站建设教案软文怎么写吸引人
  • 要做网站到哪里做免费b站推广入口2023
  • 做网站需要什么资质查关键词热度的网站
  • 电脑插上u盘不显示怎么回事
  • .NET Core EFCore零基础快速入门简单使用
  • AI安全威胁之MCP Server投毒攻击实践
  • 【SAP SD】跨公司销售、第三方销售、STO采购(公司间合同配件)
  • 【推荐100个unity插件】使用C#或者unity实现爬虫爬取静态网页数据——Html Agility Pack (HAP)库和XPath 语法的使用
  • rLLM:用于LLM Agent RL后训练的创新框架