> 文章列表 > 记录-JS简单实现购物车图片局部放大预览效果

记录-JS简单实现购物车图片局部放大预览效果

记录-JS简单实现购物车图片局部放大预览效果

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

一、实现效果

记录-JS简单实现购物车图片局部放大预览效果

二、代码实现

代码不多,先看一下 HTML 里面结构很简单,初始化 MagnifyingGlass 对象来关联一个 IMG 标签来实现放大。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<style type="text/css">
*{padding: 0;margin: 0;
}.clothes {width: auto;height: auto;
}
</style><body>
<div><img id="clothes" class="clothes" src="./clothes.jpg" alt="">
</div>
</body><script src="./magnifyingGlass.js"></script>
<script>//针对某个标签进行图片放大处理let magnifyingGlass = new MagnifyingGlass(document.getElementById('clothes'))
</script></html>

再看一下 MagnifyingGlass

class MagnifyingGlass {// 需要放大的图片imgEl// 放大预览视图magnifyingGlassView// 区域小图smallCanvas// 保存原图的像素值originalPiexls = []// 截流定时器interceptionTimer = nullconstructor(el){if(el.tagName == 'IMG'){this.imgEl = elthis.listenerImgLoadSucceeded()}}// 监听图片加载完成async listenerImgLoadSucceeded(){if(!this.imgEl.complete){await new Promise((resolve)=>{this.imgEl.onload = resolve})}// 添加鼠标事件this.addMouseEvent()// 创建一个放大预览视图this.createMagnifyingGlassView()}// 创建一个放大预览视图createMagnifyingGlassView(){if(this.magnifyingGlassView){this.magnifyingGlassView.remove()}this.magnifyingGlassView = document.createElement('canvas')this.magnifyingGlassView.style.cssText = 'position: fixed;background:aliceblue;left:0;top:0;pointer-events:none;display:none'this.magnifyingGlassView.setAttribute('width',`${200}px`)this.magnifyingGlassView.setAttribute('height',`${200}px`)let body = document.getElementsByTagName('body')[0]body.appendChild(this.magnifyingGlassView)}// 添加鼠标事件addMouseEvent(){// 添加鼠标滑过事件this.addMouseMoveToImageEl()// 鼠标滑出事件this.addMouseLeaveToImageEl()}// 添加鼠标滑过事件addMouseMoveToImageEl(){this.imgEl.onmousemove = (event)=>{let x = event.clientX + this.getElementPosition(this.imgEl).left + 20let y = event.clientY + this.getElementPosition(this.imgEl).top + 20let position = { x, y }// 截流this.interceptionFunc(()=>{// 修改放大视图位置this.changeMagnifyingGlassViewPosition(position)// 获取需要放大的像素this.getNeedMasgnifyingGlassPiexl({clientX: (event.clientX - this.getElementPosition(this.imgEl).left),clientY: (event.clientY - this.getElementPosition(this.imgEl).top)})})}}//截流interceptionFunc(cb){if(this.interceptionTimer){return}this.interceptionTimer = setTimeout(() => {cb()this.interceptionTimer = null}, 20);}// 鼠标滑出事件addMouseLeaveToImageEl(){this.imgEl.onmouseleave = ()=>{// 移除放大框this.magnifyingGlassView.style.display = 'none'}}// 修改放大视图位置changeMagnifyingGlassViewPosition(position){this.magnifyingGlassView.style.left = position.x + 'px'this.magnifyingGlassView.style.top = position.y + 'px'this.magnifyingGlassView.style.display = 'block'}// 获取元素在屏幕的位置getElementPosition(element){var top = element.offsetTopvar left = element.offsetLeftvar currentParent = element.offsetParent;while (currentParent !== null) {top += currentParent.offsetTopleft += currentParent.offsetLeftcurrentParent = currentParent.offsetParent}return {top,left}}// 保存原像素(操作像素点时候用)async getOriginalPiexls(){if(this.originalPiexls.length == 0){var image = new Image();image.src = this.imgEl.src;// 等待IMG标签加载完成后保存像素值await new Promise((resolve)=>{image.onload = resolve})let width = image.widthlet height = image.heightlet canvas = document.createElement('canvas')canvas.setAttribute('width',`${width}px`)canvas.setAttribute('height',`${height}px`)var ctx = canvas.getContext("2d")ctx.fillStyle = ctx.createPattern(image, 'no-repeat');ctx.fillRect(0, 0, width, height);try {//保存像素this.originalPiexls = ctx.getImageData(0,0,width,height)} catch (error) {console.log(error)}}}// 获取需要放大的像素async getNeedMasgnifyingGlassPiexl(event){//获取原始像素this.getOriginalPiexls()//如果像素为空,不进行操作if(this.originalPiexls.length == 0){return}//获取待放大IMG的宽度,用来计算像素let imageWidth = this.imgEl.offsetWidth//获取当前鼠标点的范围let diffusionLength = 100//鼠标触点let mouseX = event.clientXlet mouseY = event.clientY//规定区域的上下、左右宽度let sepX = parseInt(diffusionLength)let sepY = parseInt(diffusionLength)// 需要开始的点let startPoint = {x:(mouseX - parseInt(sepX / 2.0)),y:(mouseY - parseInt(sepY / 2.0))}// 需要结束的点let endPoint = {x:(mouseX + parseInt(sepX / 2.0)),y:(mouseY + parseInt(sepY / 2.0))}// 最终要展示的像素集合(乘以4是单一像素值宽度)let finallyOriginalPiexls = new Uint8ClampedArray(sepX * sepY * 4)let currentIndex = 0//操作像素for(let i = startPoint.y;i < endPoint.y;i++){for(let j = startPoint.x; j < endPoint.x;j++){for(let k = 0;k < 4;k++){let index = (i * imageWidth + j) * 4 + kif(index > 0 && index < this.originalPiexls.data.length){// 超过宽度部分需要进行其他色值填充if(j < imageWidth){finallyOriginalPiexls[currentIndex] = this.originalPiexls.data[index]} else {finallyOriginalPiexls[currentIndex] = 199}} else {finallyOriginalPiexls[currentIndex] = 199}currentIndex += 1}}}//先绘制一个100*100单位长的小图if(!this.smallCanvas){this.smallCanvas = document.createElement('canvas')this.smallCanvas.setAttribute('width',`${diffusionLength}px`)this.smallCanvas.setAttribute('height',`${diffusionLength}px`)}let smallCtx = this.smallCanvas.getContext("2d")//初始化ImageDatalet finallyImageData = new ImageData(finallyOriginalPiexls,sepX,sepY)// 当前范围内需要放大的像素smallCtx.putImageData(finallyImageData,0,0,0,0,diffusionLength,diffusionLength)let url = this.smallCanvas.toDataURL('image/jpeg',1)//将小图绘制到200*200的预览图上var image = new Image();image.src = url;await new Promise((resolve)=>{image.onload = resolve})var magnifyingGlassCtx = this.magnifyingGlassView.getContext("2d")magnifyingGlassCtx.drawImage(image, 0,0,200,200);}
}

上面的就是全部逻辑,实现方法肯定不是最优的,但是其中可以联想到通过像素点的操作实现任意效果。

三、获取像素信息跨域问题怎么解决?

可以启动一个 node 本地服务,首先见一个包含 index.jspackage.json 的入口文件的文件夹。

package.json 内容如下:

{"name": "youname","version": "1.0.0","description": "description","main": "index.js","scripts": {"test": "node ./index.js"},"author": "wsl","license": "ISC","dependencies": {"express": "^4.17.3","express-static": "^1.2.6","http": "^0.0.1-security"}
}

index.js 内容如下:

var express = require('express')
var app = express()
var http = require('http').Server(app)
//公共页面访问设置
app.use(express.static('www'))
//开启服务
http.listen(3000,function(){console.log('开始了')
})

终端执行 npm install 后再执行启动服务命令 node ./index.js:

三、获取像素信息跨域问题怎么解决?

记录-JS简单实现购物车图片局部放大预览效果

注意将前端文件放在目录里 www 文件夹下

记录-JS简单实现购物车图片局部放大预览效果

这样跨域问题就解决了。

本文转载于:

https://juejin.cn/post/7201437314693906491

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。