烟花
html
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.event
let x = e.offsetX
let 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*100
target = target*100
}
timerObj[attr] = setInterval(function(){
let speed = (target-currentStyle)/10
speed = speed>0?Math.ceil(speed):Math.floor(speed)
currentStyle += speed
if(currentStyle == target){
clearInterval(timerObj[attr])
delete timerObj[attr]
let k = 0
for(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)
}
}
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.clientX
let y = e.clientY
// 遮罩层的宽高的一半
let shadeWidthBan = this.shade.clientWidth/2
let shadeHeightBan = this.shade.clientHeight/2
// 限定x和y在左上角最小的位置坐标
if(xthis.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.clientWidth
let yPercent = this.shade.offsetTop/this.middleBox.clientHeight
// 获取大图的大小
// 获取大盒子的背景图的尺寸 background-size
let bigImgSize = getStyle(this.bigBox,'background-size')
// 获取出来是字符串,通过字符串方法获取到背景图的宽高数值
let bigImgWidth = parseInt(bigImgSize.split(' ')[0])
let bigImgHeight = parseInt(bigImgSize.split(' ')[1])
// 计算大图移动的距离
let xMove = bigImgWidth*xPercent
let yMove = bigImgHeight*yPercent
// 把大图要移动的距离,赋值到大图的背景图定位上 background-position
this.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类名,给点击的这个加上active
for (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]
}
}