今天有时间开始动手,使用css+jqueryshi实现了图片局部放大的组件,首先看看效果图:
界面设计思路如下:
??1.两个div,左边放图片的缩略图
??2.在左边缩略图鼠标移动的时候,区域(效果图中的网格)
??3.右边放大图div,背景为缩略图的大图,在鼠标移入缩略图中,通过获取鼠标的坐标,将右侧背景图片移动到跟鼠标坐标对应的位置
??4.设计时尽量,获取原大图的尺寸,和缩略图视窗计算比例,更大精度的做到左侧缩略图上表示的区域,和右侧放大部分匹配
本示例大部分编码在javascript脚本,以下列出各部分的源码:
<div class="all-region"> ???<div class="image-wrap">
??????<!--缩略图div--> ???????<div class="little-img"> ???????????<img src="./images/show-window/timg.jpg"> ???????</div>
??????<!--图片放大div--> ???????<div class="large-img"> ???????</div>
???????<!--缩略图上展示被放大的区域,网格区域--> ???????<div class="relative-region"></div> ???</div></div>
css:
???.all-region { ???????width: 100%; ???????height: auto; ???} ???.all-region .image-wrap { ???????width: 1300px; ???????margin: 0px auto; ???????height: 300px; ???????line-height: 300px; ???????overflow: hidden; ???????vertical-align: center; ???????background: #FBFBFB; ???????border-left: 1px solid #ebebeb; ???????position: relative; ???} ???.image-wrap .little-img img { ???????width: 600px; ???????height: 300px; ???} ???.image-wrap .large-img { ???????width: 600px; ???????height: 300px; ???????background-image: url("./images/show-window/timg.jpg"); ???????border: 1px solid transparent; ???????background-size: inherit; ???????background-repeat: no-repeat; ???????background-position-x: 0px; ???????background-position-y: 0px; ???????position: relative; ???????top: -301px; ???????left: 605px; ???????float: left; ???????z-index: 10; ???????opacity: 0; ???????display: none; ???????transition: opacity 2s linear; ???????overflow: hidden; ???} ???.relative-region { ???????background: linear-gradient(45deg, rgba(46, 46, 46, 0.5) 50%, transparent 0), ???????linear-gradient(135deg, rgba(200, 200, 200, .5) 70%, transparent 0); ???????display: none; ???????position: relative; ???????z-index: 99; ???????background-size: 5px 5px; ???}
Javascript:
class Elements { ???????constructor() { ???????????//缩略图区域 ???????????this.sourceImage = $(".little-img"); ???????????//放大区域 ???????????this.aimImage = $(".large-img"); ???????????//视图图片,与图片实际尺寸比例 ???????????this.sourceToAimRate = 0.01; ???????????//原图高度 ???????????this.sourceHeight = 0; ???????????//原图宽度 ???????????this.sourceWidth = 0; ???????????//视图高度,div的高度,本例是300px ???????????this.containerHeight = this.sourceImage.children().height(); ???????????this.containerWidth = this.sourceImage.children().width(); ???????????//鼠标在缩略图上的坐标 offsetX ???????????this.cursor_x = 0; ???????????this.cursor_y = 0; ???????????//标志被放大的区域 ???????????this.region = $(".relative-region"); ???????????this.mouseMove = this.mouseMove.bind(this); ???????????this.regionPosition = this.regionPosition.bind(this); ???????????this.regionMove = this.regionMove.bind(this); ???????????this.caculatorRate = this.caculatorRate.bind(this); ???????} ???????//计算原图尺寸,思路是内存加载原图,获得尺寸,并计算容器视图和原图的比例 ???????caculatorRate() { ???????????console.log(this.sourceImage.children().attr("src")); ???????????$("<img/>").attr("src", this.sourceImage.children().attr("src")).load((e) => { ???????????????//let sourceImageWidth=e.target.width; ???????????????this.sourceWidth = e.target.width; ???????????????this.sourceHeight = e.target.height; ???????????????//计算图片和容器的像素比例 ???????????????this.sourceToAimRate = this.sourceWidth / this.containerWidth; ???????????}); ???????} ???????//鼠标在缩略图上移动时计算,放大图的背景位置,并且定位标识被放大的区域 ???????mouseMove(e) { ???????????//console.log(`x:${e.offsetX},y:${e.offsetY}`); ???????????//偏离region的位置 ???????????//由于鼠标实际上是在标识被放大区域(网格区域)的div里面,所以通过e获取的实际上是缩略图内,网格标识的offsetX 要用网格区域的offsetX+offsetLeft-缩略图的offsetleft才是鼠标对应到缩略图上的位置 ???????????let r_x = e.offsetX; ???????????let r_y = e.offsetY; ???????????let s_t = this.sourceImage.offset().top; ???????????let s_l = this.sourceImage.offset().left; ???????????let r_t = this.region.offset().top; ???????????let r_l = this.region.offset().left; ???????????let x = r_l - s_l + r_x; ???????????let y = r_t - s_t + r_y; ???????????//在原图上显示,被放大的区域 ???????????let w = this.region.width(); ???????????let h = this.region.height(); ????????????//由于鼠标在网格区域的中心,所以在计算放大图的top和left的时候,实际是从网格的左上角位置 ???????????this.cursor_x = (x - w / 2) * this.sourceToAimRate; ???????????this.cursor_y = (y - h / 2) * this.sourceToAimRate; ???????????if (this.cursor_x + this.containerWidth > this.sourceWidth) { ???????????????this.cursor_x = this.sourceWidth - this.containerWidth; ???????????} ???????????if (this.cursor_y + this.containerHeight > this.sourceHeight) { ???????????????this.cursor_y = this.sourceHeight - this.containerHeight; ???????????} ???????????if (this.cursor_y < 0) { ???????????????this.cursor_y = 0; ???????????} ???????????if (this.cursor_x < 0) { ???????????????this.cursor_x = 0; ???????????} ???????????this.aimImage.css({ ???????????????"background-position-x": -this.cursor_x + "px", ???????????????"background-position-y": -this.cursor_y + "px" ???????????}); ????????????this.regionMove(w, h, x, y); } ???????regionPosition(r_w, r_h, e) { ???????????let left = e.offsetX - r_w / 2; ???????????let top = e.offsetY - r_h / 2; ????????????if (left < 0) { ???????????????left = 0; ???????????} ???????????if (left + r_w > this.containerWidth) { ???????????????left = this.containerWidth - r_w; ???????????} ???????????if (top < 0) { ???????????????top = 0; ???????????} ???????????if (top + r_h > this.containerHeight) { ???????????????top = this.containerHeight - r_h; ???????????} ???????????this.region.css({ ???????????????"top": (top - this.containerHeight) + "px", ???????????????"left": left+ "px", ???????????????"cursor": "crosshair" ???????????}); ???????} ????????regionMove(r_w, r_h, x, y) { ???????????let left = x - r_w / 2; ???????????let top = y - r_h / 2; ???????????if (left < 0) { ???????????????left = 0; ???????????} ???????????if (left + r_w > this.containerWidth) { ???????????????left = this.containerWidth - r_w; ???????????} ???????????if (top < 0) { ???????????????top = 0; ???????????} ???????????if (top + r_h > this.containerHeight) { ???????????????top = this.containerHeight - r_h; ???????????} ???????????this.region.css({"top": (top - this.containerHeight) + "px", "left": left + "px"}); ???????} ???????init() { ???????????this.caculatorRate(); ???????????//鼠标移入缩略图区域,由缩略图区域的hover事件初始化,将鼠标放入网格区域的中心 ???????????this.sourceImage.children().mouseover((e) => { ???????????????this.aimImage.css({"display": "block", "opacity": "1"}); ???????????????let r_w = this.containerWidth / this.sourceToAimRate; ???????????????let r_h = this.containerHeight / this.sourceToAimRate; ???????????????let x = e.offsetX; ???????????????let y = e.offsetY; ???????????????this.regionPosition(r_w, r_h, e); ???????????????this.region.css({"display": "block", "height": r_h + "px", "width": r_w + "px"}); ???????????}); ???????????//修复鼠标在region上,右侧放大区域闪动 ???????????this.region.mousemove(this.mouseMove); ???????????this.region.mouseleave(() => { ???????????????this.aimImage.css({"display": "none", "opacity": "0"}); ???????????????this.region.css({"display": "none"}); ???????????}); ???????} ???} ????$(function () { ???????var e = new Elements(); ???????e.init(); ???})
由于原图是1920*1080不是缩略视窗严格的2:1,计算中有小数等原因,使网格标识的区域,和放大区域展示的完全匹配
css+jquery 实现图片局部放大预览
原文地址:https://www.cnblogs.com/andayhou/p/9373521.html