效果

demo地址
codepen地址
支持功能点
- 放大预览
- 支持自定义放大区域size(矩形)
- 支持动态更新放大设置
- 支持自定义查看区域scale
- 自定义查看区域dom
- 自定义原图size(设置不正确时可能存在溢出不显示的问题)
原理
- 对查看区域的dom进行background-position以及background-size进行动态设置
缺点
- 未提供destroy api
- 未使用canvas,不好进行导出等操作
demo代码展示
<div id="example" style="display: inline-block;"></div>
<div class="piece" style="display: inline-block;"></div>
class ImgScopePreview {
constructor({
el,
imgInfo: [imgW, imgH, imgSrc],
scopeSize: [scopeW, scopeH],
scale,
targetEl
}) {
this.imgSrc = imgSrc;
this.imgW = imgW || 1200;
this.imgH = imgH || 675;
this.scopeW = scopeW || 100;
this.scopeH = scopeH || 100;
this.scale = scale || 2;
this.el = document.querySelector(el);
this.targetEl = document.querySelector(targetEl);
this.innerScopeDom = null;
this.moveListener = null;
this.init();
}
init() {
this.initDom();
this.bindListener();
}
initDom() {
this.el.innerHTML = "";
this.innerScopeDom = document.createElement("div");
Object.assign(this.innerScopeDom.style, {
width: `${this.scopeW}px`,
height: `${this.scopeH}px`,
position: "absolute",
top: 0,
left: 0,
backgroundColor: "#00000066",
pointerEvents: "none"
});
this.el.appendChild(this.innerScopeDom);
Object.assign(this.el.style, {
cursor: "move",
position: "relative",
backgroundImage: `url(${this.imgSrc})`,
backgroundSize: `100%`,
width: `${this.imgW}px`,
height: `${this.imgH}px`
});
Object.assign(this.targetEl.style, {
width: `${this.scopeW * this.scale}px`,
height: `${this.scopeH * this.scale}px`,
backgroundImage: `url(${this.imgSrc})`,
backgroundSize: `${this.imgW * this.scale}px ${this.imgH * this.scale}px`,
backgroundRepeat: `no-repeat`
});
}
bindListener() {
this.el.removeEventListener("mousemove", this.moveListener);
let { imgW, imgH, scopeW, scopeH, scale } = this;
this.moveListener = evnt => {
let { offsetX, offsetY } = evnt;
let scopeLeft =
offsetX < scopeW / 2
? 0
: offsetX > imgW - scopeW / 2
? imgW - scopeW
: offsetX - scopeW / 2;
let scopeTop =
offsetY < scopeH / 2
? 0
: offsetY > imgH - scopeH / 2
? imgH - scopeH
: offsetY - scopeH / 2;
Object.assign(this.innerScopeDom.style, {
left: `${scopeLeft}px`,
top: `${scopeTop}px`
});
Object.assign(this.targetEl.style, {
backgroundPosition: `-${scopeLeft * this.scale}px -${scopeTop * this.scale}px`
});
};
this.el.addEventListener("mousemove", this.moveListener);
}
getOptions() {
return {
imgInfo: [this.imgW, this.imgH, this.imgSrc],
scopeSize: [this.scopeW, this.scopeH],
scale: this.scale
};
}
loadOptions({ imgInfo: [imgW, imgH, imgSrc], scopeSize: [scopeW, scopeH], scale }) {
Object.assign(this, {
imgW,
imgH,
imgSrc,
scopeW,
scopeH,
scale
});
this.init();
}
}
let imgpreviewer = new ImgScopePreview({
el: "#example",
imgInfo: [900, 784, "https://pic2.zhimg.com/80/v2-43db8765a0f2c6cbe55fb785ea538d20_hd.jpeg"],
scopeSize: [200, 400],
scale: 2,
targetEl: ".piece"
});