当前最新:记录-JS简单实现购物车图片局部放大预览效果
2023-04-21 00:25:20 博客园


(资料图片仅供参考)

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

一、实现效果

二、代码实现

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

<script src="./magnifyingGlass.js"></script><script> //针对某个标签进行图片放大处理 let magnifyingGlass = new MagnifyingGlass(document.getElementById("clothes"))</script>

再看一下MagnifyingGlass

class MagnifyingGlass {    // 需要放大的图片    imgEl    // 放大预览视图    magnifyingGlassView    // 区域小图    smallCanvas    // 保存原图的像素值    originalPiexls = []    // 截流定时器    interceptionTimer = null    constructor(el){        if(el.tagName == "IMG"){            this.imgEl = el            this.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 + 20            let y = event.clientY + this.getElementPosition(this.imgEl).top + 20            let 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.offsetTop        var left = element.offsetLeft        var currentParent = element.offsetParent;        while (currentParent !== null) {            top += currentParent.offsetTop            left += currentParent.offsetLeft            currentParent = 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.width            let height = image.height            let 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.clientX        let 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 + k                    if(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")        //初始化ImageData        let 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:

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

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

这样跨域问题就解决了。

本文转载于:

https://juejin.cn/post/7201437314693906491

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

相关新闻: