面向对象案例
烟花
效果分析
结构分析
- 大盒子做夜空
- 点击的时候生成一个小烟花
- 小烟花升空后生成很多小烟花
- 让很多小烟花移动到一个随机位置
效果分析
- 大盒子点击事件
- 生成小烟花,设置在大盒子最底部,横向位置是鼠标所点的位置。放到大盒子中,调用运动函数移动到鼠标所在高度
- 将小烟花删掉,并生成很多小烟花,设置成圆形,位置就是鼠标所点击的位置,随机颜色
- 让生成的很多小烟花移动到随机位置,移动后将很多小烟花从大盒子删除
代码实现:
html结构
<body>
<div id="box"></div>
<script src="./move.js"></script>
<script src="./fire.js"></script>
</body>
js代码
fire.js
function Fire(){
this.box = document.querySelector('#box')
}
Fire.prototype.init = function(){
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)
this.toUp(div,x,y)
}
Fire.prototype.toUp = function(ele,x,y){
move(ele,{top:y},()=>{
this.box.removeChild(ele)
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)
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
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)
}
}
function getStyle(ele,attr){
if(window.getComputedStyle){
return window.getComputedStyle(ele)[attr];
}else{
return ele.currentStyle(atrr)
}
}
放大镜
效果分析
组成结构分析
- 一个容器大盒子 - div.box
- 一个放中等图片的盒子 - div.middleBox
- 一个放小图片的盒子 - div.smallBox
- 一个放大图的盒子 - div.bigBox
布局分析
- 大盒子box设置相对定位
- 中等盒子middleBox设置相对定位
- 遮罩shade设置绝对定位在中等盒子中,隐藏
- 放大图的盒子bigBox设置绝对定位,定位到大盒子box的右边,大图作为放大图的盒子的背景
效果分析
- 点击小图片,大图随着小图更换
- 鼠标移动大中等盒子上
- 遮罩出现,并可以在中等盒子上移动
- 遮罩移动的过程中大盒子的背景图也跟随移动
- 鼠标离开大盒子
规律分析
- 中等盒子和遮罩的比例,是大图和放大图的盒子的比例
- 遮罩移动过的距离和中等盒子的比例,是大图移动的距离和大图的比例
代码实现
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>
样式代码
*{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 = ()=>{
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
if(x<this.box.offsetLeft+shadeWidthBan){
x = this.box.offsetLeft+shadeWidthBan
}
if(y<this.box.offsetTop+shadeHeightBan){
y = this.box.offsetTop+shadeHeightBan
}
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
}
this.shade.style.left = x - this.box.offsetLeft - shadeWidthBan + 'px'
this.shade.style.top = y - this.box.offsetTop - shadeHeightBan + 'px'
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
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
this.bigBox.style.backgroundPosition = `-${xMove}px -${yMove}px`
}
Enlarge.prototype.tab = function(smallImg){
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})`
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]
}
}