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

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

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

一、实现效果

屏幕录制2023-02-18 下午8.21.50.gif

二、代码实现

代码不多,先看一下 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 = 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:

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

image.png

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

image.png

这样跨域问题就解决了。

本文转载于:

https://juejin.cn/post/7201437314693906491

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

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

原文链接:https://www.cnblogs.com/smileZAZ/p/17337784.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:记录-JS简单实现购物车图片局部放大预览效果 - Python技术站

(0)
上一篇 2023年4月22日
下一篇 2023年4月24日

相关文章

  • 深入理解JavaScript中Ajax

    “深入理解JavaScript中Ajax”的完整攻略如下: 理解Ajax Ajax(Asynchronous JavaScript and XML)即异步JavaScript和XML,可以实现异步服务器调用。它能在不重新加载整个页面的情况下更新页面的部分内容,从而提高网页的交互体验。 Ajax的核心用到了XMLHttpRequest对象,它可以使用XMLHt…

    JavaScript 2023年5月18日
    00
  • JS正则表达式验证数字代码

    下面我将详细讲解 JS 正则表达式验证数字代码的完整攻略。 步骤 1. 构建正则表达式 首先需要构建一个用于验证数字的正则表达式。一般来说,数字可以包含整数和小数,还可能有正负号。 验证整数和小数的正则表达式如下: /^-?\d+(\.\d+)?$/ 其中: ^ 表示字符串开始 -? 表示可以有一个可选的负号 \d+ 表示至少一个数字 (\.\d+)? 表示…

    JavaScript 2023年6月10日
    00
  • JavaScript实现创建自定义对象的常用方式总结

    下面是关于“JavaScript实现创建自定义对象的常用方式总结”这个话题的详细讲解: 自定义对象 在JavaScript中,我们可以通过自定义对象来扩展语言的基础能力。自定义对象非常常见,可以是简单的字面对象,也可以是有方法、继承和构造函数的对象。 字面对象 字面对象是最简单的自定义对象,可以手动定义其属性和值。 let user = { name: ‘T…

    JavaScript 2023年5月27日
    00
  • JS深入浅出Function与构造函数

    JS深入浅出Function与构造函数 什么是Function? 在JavaScript中,函数被看作是对象,函数也可以看作是特殊的对象。每个函数都是Function类型的实例,都有自己的属性和方法。Function类型的构造函数是用来创建函数对象的。 函数的作用是封装一段代码,并可以用来重复使用,降低代码复杂性,方便维护。一个函数可以有0个或多个参数,可以…

    JavaScript 2023年5月27日
    00
  • 浅谈JS数组内置遍历方法有哪些和区别

    让我来详细讲解一下“浅谈JS数组内置遍历方法有哪些和区别”这个话题。 一、JS数组内置遍历方法 JS数组内置了很多遍历方法,其中常用的有以下五种: 1. forEach() forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。forEach() 不会返回任何值。 示例: const arr = [‘apple’, ‘orange’, ‘b…

    JavaScript 2023年5月27日
    00
  • js实现网页防止被iframe框架嵌套及几种location.href的区别

    下面我将详细讲解”JS实现网页防止被iframe框架嵌套及几种location.href的区别”的完整攻略。 JS实现网页防止被iframe框架嵌套 在编写网页时,我们可能希望页面不能被嵌套在iframe框架中,以避免网页的被其他网站直接嵌套到其它站点的页面上,从而保证网站数据的安全性和用户体验。为了实现网页的防止被iframe框架嵌套,我们可以使用以下方法…

    JavaScript 2023年6月11日
    00
  • js预载入和JavaScript Image()对象使用介绍

    让我详细给您讲解“js预载入和JavaScript Image()对象使用介绍”的完整攻略。 什么是js预载入 当一个web页面中有大量的图片、音频等素材需要加载时,页面加载速度会明显减慢,给用户带来不好的体验。而js预载入能够做到在页面需要使用某个资源的时候提前加载资源,这样能够极大的提升用户页面加载体验。如何实现呢?下面我来介绍一下实现的具体步骤: 首先…

    JavaScript 2023年5月27日
    00
  • javascript表单验证 – Parsley.js使用和配置

    JavaScript表单验证是Web开发过程中一个非常重要的环节,可以用于确保用户在提交表单时输入的数据格式正确且符合预期,从而提高应用程序的稳定性和可用性。 Parsley.js是一个轻量级的JavaScript表单验证库,可以有效地帮助开发人员构建和配置表单验证规则。下面是一份Parsley.js的配置攻略: 步骤1:安装Parsley.js 首先,需要…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部