首页>案例集>JavaScript案例集

原生js实现放大镜效果

现在都是手机端,使用放大镜功能的情况很少了,把以前电商网站中的放大镜效果单独拎出来,用原生js写一遍。

6.jpg

点击图片查看具体效果。

放大镜核心功能在于小方块在小图上移动距离的比例和大图移动的比例是一样的。当然,还包括对client、offset等家族的属性比较了解。

给点粗糙的图示看一下。

小方块移动的距离:

moveX.jpg

关键代码:

// 让鼠标的偏移值 - 大盒子的偏移值 - 小方块宽度的一半
var moveX = e.clientX - oBoxOffsetLeft - oZoomOffsetWidth * 0.5;
var moveY = e.clientY - oBoxOffsetTop - oZoomOffsetHeight * 0.5;



当然,小方块不能飞出盒子的边界:

range.jpg

关键代码:

// 判断小方块移动的临界值
// x轴能移动的最小值为0,最大值为小盒子的宽度减去小方块的宽度
if (moveX < 0) {
    moveX = 0;
} else if (moveX > oSmallBoxOffsetWidth - oZoomOffsetWidth) {
    moveX = oSmallBoxOffsetWidth - oZoomOffsetWidth;
}
// y轴小方块能移动的范围
if (moveY < 0) {
    moveY = 0;
} else if (moveY > oSmallBoxOffsetHeight - oZoomOffsetHeight) {
    moveY = oSmallBoxOffsetHeight - oZoomOffsetHeight;
}
oZoom.style.left = moveX + 'px';
oZoom.style.top = moveY + 'px';


最关键的就是,大图片移动的距离:

bigImgmove.jpg

关键代码:

 // 小方块的移动距离:小方块能够移动的最大距离 = 大图片移动的距离:大图片能够移动的最大距离
// moveX : (oSmallBoxOffsetWidth - oZoomOffsetWidth) = 大图的移动距离 : (大图片的宽度 - oBigBoxOffsetWidth)
// 根据公式得出移动的比例
var ratioX = moveX / (oSmallBoxOffsetWidth - oZoomOffsetWidth);
var ratioY = moveY / (oSmallBoxOffsetHeight - oZoomOffsetHeight);
// 大图片移动的距离
oBigImg.style.transform = `translate(-${ratioX * (oBigImgOffsetWidth - oBigBoxOffsetWidth)}px,-${ratioY * (oBigImgOffsetHeight - oBigBoxOffsetHeight)}px)`;

最后还是上完整代码:

        // 准备素材
        const arrImgs = [
            {
                sImg: 'images/small/1.jpg',
                oImg: 'images/big/1.jpg'
            },
            {
                sImg: 'images/small/2.jpg',
                oImg: 'images/big/2.jpg'
            },
            {
                sImg: 'images/small/3.jpg',
                oImg: 'images/big/3.jpg'
            },
            {
                sImg: 'images/small/4.jpg',
                oImg: 'images/big/4.jpg'
            },
            {
                sImg: 'images/small/5.jpg',
                oImg: 'images/big/5.gif'
            }
        ]

        // 获取元素
        const oUl = document.querySelector('.thrumbUl');
        const oImgSmall = document.querySelector('.small-pic');
        const oBigImg = document.querySelector('.big-img');

        // 初始化页面的效果
        oImgSmall.src = arrImgs[0].sImg;
        // 遍历出下方的缩略图
        for (let obj of arrImgs) {
            oUl.innerHTML += `<li class="thrumbLi">
                    <img src="${obj.sImg}" class="thrumb-img">
                </li>`
        }
        // 获取所有的缩略图元素
        const oLis = document.querySelectorAll('.thrumbLi');
        // 初始化高亮元素
        oLis[0].classList.add('active');


        // 保存高亮的元素
        let activeLi = oLis[0];

        // 1、实现点击小图片的切换
        oLis.forEach(function (item, index) {
            item.onclick = function () {
                // 让以前的高亮元素取消高亮
                activeLi.classList.remove('active');
                // 更新小图
                oImgSmall.src = arrImgs[index].sImg;
                // 更新大图
                oBigImg.src = arrImgs[index].oImg;
                // 可以设置大图的初始位置,防止切换之后显示不到大图
                oBigImg.style.transform = 'translate(-25%, -50%)';
                // 让当前被点击的元素有高亮样式
                item.classList.add('active');
                // 更新高亮元素为当前元素
                activeLi = item;
            }
        })
        // 需要页面包括图片加载完毕后执行,因为要获取图片等的宽高
        window.onload = function () {
            const oMask = document.querySelector('.zoomBox');
            const oLeftImgBox = document.querySelector('.smallPicWrapper');
            const oBigImgBox = document.querySelector('.bigPicWrapper');
            // 鼠标移上左侧图片的时候
            oLeftImgBox.addEventListener('mouseover', function () {
                oMask.classList.remove('none');
                const oMaskWidth = oMask.clientWidth;
                const oMaskHeight = oMask.clientHeight;
                const left = oLeftImgBox.getBoundingClientRect().left;
                const top = oLeftImgBox.getBoundingClientRect().top;
                const moveWidth = oLeftImgBox.clientWidth - oMaskWidth;
                const moveHeight = oLeftImgBox.clientHeight - oMaskHeight;
                // console.log(moveWidth,moveHeight)

                // 大图片
                oBigImgBox.classList.remove('none');
                const bigimgWidth = oBigImg.clientWidth;
                const bigimgHeight = oBigImg.clientHeight;
                const oBigBoxWidth = oBigImgBox.clientWidth;
                const oBigBoxHeight = oBigImgBox.clientHeight;
                const bigMoveWidth = bigimgWidth - oBigBoxWidth;
                const bigMoveHeight = bigimgHeight - oBigBoxHeight;
                // console.log(bigMoveHeight);

                // 小方块的鼠标跟随
                oLeftImgBox.addEventListener('mousemove', function (e) {
                    let movex = e.x - left - oMaskWidth / 2;
                    let movey = e.y - top - oMaskHeight / 2;
                    // 小方块不能移出盒子的判断
                    if (movex < 0) {
                        movex = 0;
                    } else if (movex > moveWidth) {
                        movex = moveWidth;
                    }
                    if (movey < 0) {
                        movey = 0;
                    } else if (movey > moveHeight) {
                        movey = moveHeight;
                    }
                    oMask.style.left = movex + 'px';
                    oMask.style.top = movey + 'px';

                    // 大图片的移动,小方块和大图片移动的比例是一样的
                    let moveBigX = movex / moveWidth * bigMoveWidth;
                    let moveBigy = movey / moveHeight * bigMoveHeight;
                    oBigImg.style.transform = `translate(-${moveBigX}px,-${moveBigy}px)`;
                })
            })

            // 鼠标移开,小方块隐藏
            oLeftImgBox.addEventListener('mouseout', function () {
                oMask.classList.add('none');
            })
            // 点击空白处关闭大图
            const oWrapper = document.querySelector('.wrapper');
            document.addEventListener('click', function (e) {
                // 点击除了放大镜容器内部所有子元素,包括父元素本身,都会隐藏大图
                console.log(oWrapper.contains(e.target), e.target)
                if (!oWrapper.contains(e.target)) {
                    oBigImgBox.classList.add('none');
                }
            })
        }


点赞


0
保存到:

相关文章

发表评论:

◎请发表你卖萌撒娇或一针见血的评论,严禁小广告。

Top