溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript如何實現(xiàn)購物車圖片局部放大預覽效果

發(fā)布時間:2023-03-07 14:02:10 來源:億速云 閱讀:124 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹了JavaScript如何實現(xiàn)購物車圖片局部放大預覽效果的相關(guān)知識,內(nèi)容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇JavaScript如何實現(xiàn)購物車圖片局部放大預覽效果文章都會有所收獲,下面我們一起來看看吧。

代碼實現(xiàn)

代碼不多,先看一下 HTML 里面結(jié)構(gòu)很簡單,初始化 MagnifyingGlass 對象來關(guān)聯(lián)一個 IMG 標簽來實現(xiàn)放大。

<!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
    // 區(qū)域小圖
    smallCanvas
    // 保存原圖的像素值
    originalPiexls = []
    // 截流定時器
    interceptionTimer = null

    constructor(el){
        if(el.tagName == 'IMG'){
            this.imgEl = el
            this.listenerImgLoadSucceeded()
        }
    }
    
    // 監(jiān)聽圖片加載完成
    async listenerImgLoadSucceeded(){
        if(!this.imgEl.complete){
            await new Promise((resolve)=>{
            this.imgEl.onload = resolve
        })
    }
    
    // 添加鼠標事件
    this.addMouseEvent()
        // 創(chuàng)建一個放大預覽視圖
        this.createMagnifyingGlassView()
    }

    // 創(chuàng)建一個放大預覽視圖
    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
        //規(guī)定區(qū)域的上下、左右寬度
        let sepX = parseInt(diffusionLength)
        let sepY = parseInt(diffusionLength)
        // 需要開始的點
        let startPoint = {x:(mouseX - parseInt(sepX / 2.0)),y:(mouseY - parseInt(sepY / 2.0))}
        // 需要結(jié)束的點
        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)
        // 當前范圍內(nèi)需要放大的像素
        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);
    }
}

上面的就是全部邏輯,實現(xiàn)方法肯定不是最優(yōu)的,但是其中可以聯(lián)想到通過像素點的操作實現(xiàn)任意效果。

獲取像素信息跨域問題怎么解決

可以啟動一個 node 本地服務(wù),首先見一個包含 index.jspackage.json 的入口文件的文件夾。

package.json 內(nèi)容如下:

{
    "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 內(nèi)容如下:

var express = require('express')
var app = express()
var http = require('http').Server(app)
//公共頁面訪問設(shè)置
app.use(express.static('www'))
//開啟服務(wù)
http.listen(3000,function(){
    console.log('開始了')
})

終端執(zhí)行 npm install 后再執(zhí)行啟動服務(wù)命令 node ./index.js

JavaScript如何實現(xiàn)購物車圖片局部放大預覽效果

注意將前端文件放在目錄里 www 文件夾下

JavaScript如何實現(xiàn)購物車圖片局部放大預覽效果

這樣跨域問題就解決了。

關(guān)于“JavaScript如何實現(xiàn)購物車圖片局部放大預覽效果”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“JavaScript如何實現(xiàn)購物車圖片局部放大預覽效果”知識都有一定的了解,大家如果還想學習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI