烟花
html
<body><div id="box"></div><script src="./move.js"></script><script src="./fire.js"></script>
</body>
js代码
fire.js
function Fire(){// 获取box盒子this.box = document.querySelector('#box')
}
// 火花启动
Fire.prototype.init = function(){// 给box设置样式并绑定点击事件setStyle(this.box,{width:'1000px',height:'600px',background:'#000',border:'10px solid pink',position:'relative'})this.box.onclick = ()=>{// 访问方法创建小烟花this.click()}
}
// 盒子点击创建小烟花
Fire.prototype.click = function(e){// 获取鼠标点击的坐标e = e || window.eventlet x = e.offsetXlet y = e.offsetY// 生成一个小烟花并设置样式let div = document.createElement('div')setStyle(div,{width:'10px',height:'10px',position:'absolute',left:x+'px',bottom:0,background: getColor()})this.box.appendChild(div)// 调用toUP方法让烟花升空this.toUp(div,x,y)
}
Fire.prototype.toUp = function(ele,x,y){move(ele,{top:y},()=>{ this.box.removeChild(ele)// 调用createManyFire方法 在这个位置 生成很多小烟花this.createManyFire(x,y)})
}
// 生成许多小烟花
Fire.prototype.createManyFire = function(x,y){let num = getNum(25,30)// 循环创建多个小烟花for (let i = 0; i < num; i++) {let div = document.createElement('div')// 设置小烟花的样式setStyle(div,{width:'10px',height:'10px',background:getColor(),borderRadius:'50%',position:'absolute',left:x+'px',top:y+'px'})this.box.appendChild(div)// 调用boom方法 让小烟花炸开this.boom(div) }
}
// 烟花炸开
Fire.prototype.boom = function(ele){move(ele,{left:getNum(0,this.box.clientWidth-ele.clientWidth),top:getNum(0,this.box.clientHeight-ele.clientHeight)},()=>{this.box.removeChild(ele)})
}
// 实例化对象
let fire = new Fire()
fire.init()// 设置元素样式函数
function setStyle(ele,obj){for (const attr in obj) {ele.style[attr] = obj[attr]}
}// 生成随机颜色
function getColor(){let rgb1 = getNum(0,255)let rgb2 = getNum(0,255)let rgb3 = getNum(0,255)return `rgb(${rgb1},${rgb2},${rgb3})`
}// 生成随机数
function getNum(a,b){return Math.floor(Math.random()*(b-a+1))+a
}
move.js
/*** @description:封装运动函数 * @param {Object} ele 运动元素* @param {Object} obj 运动目标属性和值 {left:100,top:300,opacity:0.5}* @param {function} fn 运动结束后执行的函数*/
function move(ele,obj,fn=null){let timerObj = {}for(let attr in obj){let currentStyle = parseInt(getStyle(ele,attr))let target = obj[attr]if(attr == 'opacity'){currentStyle = currentStyle*100target = target*100}timerObj[attr] = setInterval(function(){let speed = (target-currentStyle)/10speed = speed>0?Math.ceil(speed):Math.floor(speed)currentStyle += speedif(currentStyle == target){clearInterval(timerObj[attr])delete timerObj[attr]let k = 0for(let i in timerObj){k++}if(k == 0 ){// 运动结束if(fn){fn()}} }else{if(attr == 'opacity'){ele.style[attr] = currentStyle/100}else{ele.style[attr] = currentStyle + 'px'}}},30)}
}
/** * @description: 获取元素属性* @param {Object} ele* @param {string} attr* @return {string}*/
function getStyle(ele,attr){if(window.getComputedStyle){return window.getComputedStyle(ele)[attr];}else{return ele.currentStyle(atrr)}
}
放大镜
html
<div class="box"><div class="middleBox"><img src="./images/middle1.jpg"><div class="shade"></div></div><div class="smallBox"><img src="./images/small1.jpg" middleImg='./images/middle1.jpg' bigImg='./images/big1.jpg' class="active"><img src="./images/small2.jpg" middleImg='./images/middle2.jpg' bigImg='./images/big2.jpg'></div><div class="bigBox"></div></div>
css
*{margin: 0;padding: 0;}
.middleBox{width: 400px;height: 400px;border: 1px solid #000;position: relative;
}
.middleBox img{width: 400px;height: 400px;
}
.shade {width: 200px;height: 200px;background: yellow;position: absolute;left: 0;top: 0;opacity: 0.5;display: none;
}
.shade:hover{cursor: move;
}
.smallBox {margin-top: 10px;
}
.smallBox img {border: 1px solid #000;margin-left: 5px;
}
.smallBox img.active{border-color: red;
}
.box {width: 402px;margin: 50px;position: relative;
}
.bigBox {width: 400px;height: 400px;border: 1px solid #000;position: absolute;top: 0;left: 110%;background-image: url('./images/big1.jpg');background-position: 0 0;background-repeat: no-repeat;background-size: 800px 800px;display: none;
}
js
// 定义一个空构造函数
function Enlarge(){// 获取需要操作的元素并绑定到对象的属性上this.box = document.querySelector('.box')this.middleBox = this.box.querySelector('.middleBox')this.middleImg = this.box.querySelector('.middleBox img')this.shade = this.box.querySelector('.shade')this.smallImgs = this.box.querySelectorAll('.smallBox img')this.bigBox = this.box.querySelector('.bigBox')
}
// 给需要操作的元素绑定事件
Enlarge.prototype.bind = function(){// 中等盒子绑定鼠标移入事件this.middleBox.onmouseover = ()=>{// 鼠标移入显示遮罩层this.shade.style.display = 'block'// 鼠标移动遮罩层移动this.middleBox.onmousemove = ()=>{// 调用移动方法this.move()}}// 中等盒子绑定鼠标移出事件this.middleBox.onmouseleave = ()=>{this.shade.style.display = 'none'this.bigBox.style.display = 'none'this.middleBox.onmousemove = null}// 点击小图切换图片是for (let i = 0; i < this.smallImgs.length; i++) {this.smallImgs[i].onclick = ()=>{// 访问tab方法实现切换图片this.tab(this.smallImgs[i])}}
}// 鼠标在盒子上的移动事件
Enlarge.prototype.move = function(e){e = e || window.event// 鼠标相对于浏览器窗口左上角的坐标let x = e.clientXlet y = e.clientY// 遮罩层的宽高的一半let shadeWidthBan = this.shade.clientWidth/2let shadeHeightBan = this.shade.clientHeight/2// 限定x和y在左上角最小的位置坐标if(x<this.box.offsetLeft+shadeWidthBan){x = this.box.offsetLeft+shadeWidthBan}if(y<this.box.offsetTop+shadeHeightBan){y = this.box.offsetTop+shadeHeightBan}// 限定x和y在右下角最大的位置坐标if(x>this.box.offsetLeft+this.middleBox.clientWidth-shadeWidthBan){x = this.box.offsetLeft+this.middleBox.clientWidth - shadeWidthBan}if(y>this.box.offsetTop+this.middleBox.clientHeight-shadeHeightBan){y = this.box.offsetTop+this.middleBox.clientHeight-shadeHeightBan}// 给遮罩层设置left和top,让遮罩层移动起来this.shade.style.left = x - this.box.offsetLeft - shadeWidthBan + 'px'this.shade.style.top = y - this.box.offsetTop - shadeHeightBan + 'px'// 调用bigMove方法让大图移动this.bigMove()
}// 移动遮罩层让大图移动
Enlarge.prototype.bigMove = function(){this.bigBox.style.display = 'block'// 遮罩层移动的距离/中盒子大小 === 大图移动距离/大图的大小// 计算 遮罩层移动的距离/中盒子大小 的比例let xPercent = this.shade.offsetLeft/this.middleBox.clientWidthlet yPercent = this.shade.offsetTop/this.middleBox.clientHeight// 获取大图的大小// 获取大盒子的背景图的尺寸 background-sizelet bigImgSize = getStyle(this.bigBox,'background-size')// 获取出来是字符串,通过字符串方法获取到背景图的宽高数值let bigImgWidth = parseInt(bigImgSize.split(' ')[0])let bigImgHeight = parseInt(bigImgSize.split(' ')[1])// 计算大图移动的距离let xMove = bigImgWidth*xPercentlet yMove = bigImgHeight*yPercent// 把大图要移动的距离,赋值到大图的背景图定位上 background-positionthis.bigBox.style.backgroundPosition = `-${xMove}px -${yMove}px`
}// 点击小图片切换中图和大图
Enlarge.prototype.tab = function(smallImg){// 获取小图元素中的middleImg和bigImg属性let middleImg = smallImg.getAttribute('middleImg')let bigImg = smallImg.getAttribute('bigImg')console.log(middleImg,bigImg);// 将中图和大图的图片地址替换this.middleImg.setAttribute('src',middleImg)this.bigBox.style.backgroundImage = `url(${bigImg})`// 去除小图片的active类名,给点击的这个加上activefor (let i = 0; i < this.smallImgs.length; i++) {this.smallImgs[i].className = ''}smallImg.className = 'active'
}
// 实例化对象
let enlarge = new Enlarge()
enlarge.bind()// 获取样式函数
function getStyle(ele,attr){if(window.getComputedStyle){return window.getComputedStyle(ele)[attr]}else{return ele.currentStyle[attr]}
}