做一个在屏幕上随机分布泡泡的功能
分类:javascript
最近工作上要做一个功能,就是要在一个平面上随机分布几个大小不一的泡泡,泡泡不能相互覆盖或者只能覆盖小部分。后面泡泡之间会有关系链,其它所有泡泡围着一个泡泡的关系,大概需求就是这样。
需要达到的效果:
开始吧
这里用的小程序里的movable-view
,这个只要设置X,Y和宽高就会有一个不错的效果。
// wxml
<movable-area class="box">
<movable-view wx:for="{{list}}" wx:key="index" direction="all" class="item" x="{{item.x}}" y="{{item.y}}" style="width:{{item.wh}}px;height:{{item.wh}}px;">
{{index}}
</movable-view>
</movable-area>
<button class="btn" bindtap="random">random</button>
// wxss
page{
width: 100%;
height: 100%;
}
.box{
width: 100%;
height: 100%;
}
.item{
border: 1rpx solid red;
border-radius: 50%;
display: flex;
display: -webkit-flex;
justify-content: center;
align-items: center;
}
.btn{
width: 100%;
height: 80rpx;
position: fixed;
bottom: 0rpx;
left: 0rpx;
}
// pages/random/random.js
Page({
data: {
// x ,y 是图形左上角距离屏幕左上角的px
list:[]
},
onLoad: function (options) {
let {windowHeight,windowWidth} = wx.getSystemInfoSync()
this.setData({
windowHeight, // 672
windowWidth, // 414
})
this.random()
},
random(){
const randomNum = (min, max) => {
let randomNum = Math.floor(Math.random() * (max - min + 1) + min);
return randomNum
}
let list = []
for(let i=0;i<5;i++){
// 先把宽高随机出来,因为x ,y 是泡泡左上角距离屏幕左上角的px,所以实际随机的范围要减去这个宽高
let wh = randomNum(50,200)
let obj = {
x:randomNum(0,this.data.windowWidth - wh),
y:randomNum(0,this.data.windowHeight - wh),
wh,
}
list.push(obj)
}
this.setData({
list
})
}
})
这些就可以实现初版效果了。
怎样让它们之间不覆盖呢
我的思路是这样的:每随机一个圆的时候,判断这个圆与之前的所有圆是否互相覆盖,如果互相覆盖,就重新随机。(看起来就很暴力 doge,先做出来之后再优化)
那怎样判断它们互相覆盖呢,其实只有两种情况
- 圆的边相交 (圆心到圆心的距离小于两个圆半径之和)
- 一个圆在另一个圆的肚子里面 (圆心到圆心的距离小于两个圆半径之和)
// 两个圆的圆心
let centerOfCircle = {
x: x+wh/2,
y: y+wh/2,
}
let preCenterOfCircle = {
x: perX+wh/2,
y: preY+wh/2,
}
// 判断方法
let centerOfCircleDistance = this.getDistance(centerOfCircle,preCenterOfCircle)
let longerWh = wh>preWh?wh:preWh
if(centerOfCircleDistance < (wh/2+preWh/2) || centerOfCircleDistance<longerWh){
// 这是相交了,就重新随机再判断
}
// 计算两个点之间的距离
getDistance( circle1, circle2){
let a = circle1.x - circle2.x;
let b = circle1.y - circle2.y;
let c = Math.sqrt(a * a + b * b);
return c;
}
那可以开始创建泡泡啦
贴上全部代码
// pages/random/random.js
Page({
data: {
// x ,y 是图形左上角距离屏幕左上角的px
list:[]
},
onLoad: function (options) {
let {windowHeight,windowWidth} = wx.getSystemInfoSync()
this.setData({
windowHeight, // 672
windowWidth, // 414
})
this.random()
},
random(){
let list = []
for(let i=0;i<10;i++){
let {x,y,wh} = this.createBubble(list,i)
// console.log(`x=${x},y=${y}`)
let obj = {
x,
y,
wh,
}
list.push(obj)
}
this.setData({
list
})
},
createBubble(list,i){
let wh = this.randomNum(50,200)
let x = this.randomNum(0,this.data.windowWidth - wh)
let y = this.randomNum(0,this.data.windowHeight - wh)
if(list.length == 0){
return {x,y,wh}
}
for(let j=0;j<list.length;j++){
let {x:perX,y:preY,wh:preWh} = list[j]
// console.log(perX,preY,preWh)
// 判断有没有相交主要是判断:两个圆心之间的距离有没有大于他们半径之和
let centerOfCircle = {
x: x+wh/2,
y: y+wh/2,
}
let preCenterOfCircle = {
x: perX+wh/2,
y: preY+wh/2,
}
let centerOfCircleDistance = this.getDistance(centerOfCircle,preCenterOfCircle)
console.log(centerOfCircleDistance,wh/2+preWh/2)
let longerWh = wh>preWh?wh:preWh
if(centerOfCircleDistance < (wh/2+preWh/2) || centerOfCircleDistance<longerWh){
// 这是相交了,就重新随机再判断
console.log('香蕉了',i,j)
return this.createBubble(list,i)
}
}
return {x,y,wh}
},
randomNum(min, max){
let randomNum = Math.floor(Math.random() * (max - min + 1) + min);
return randomNum
},
getDistance( circle1, circle2){
let a = circle1.x - circle2.x;
let b = circle1.y - circle2.y;
let c = Math.sqrt(a * a + b * b);
return c;
}
})
之后再看看怎么优化一下。。。