当前位置:网站首页>小球大小随机,随机运动碰撞
小球大小随机,随机运动碰撞
2022-06-30 17:52:00 【囿于江湖】

<template>
<GZNormalWrap title="建筑工业化" style="position: relative;">
<div class="button-style" @click="handleLink">
决策BI
</div>
<ul id="constructionIndustryMain">
<li v-for="(item, index) in circleData" :key="index" class="ball-style" @click="handleClick(item)">
<div style="width:100%">
<div class="num-style">{
{
item.value }}</div>
<div class="name-style">{
{
item.name}}</div>
</div>
</li>
</ul>
</GZNormalWrap>
</template>
<script>
import GZNormalWrap from '../../common/GZNormalWrapTzq'
export default {
data() {
return {
circleData: [],
circleDom: [],
circleArr: [],
// 初始化运动的最大宽和高,初始定义0
maxW: 0,
maxH: 0,
timer: null,
timerArr: [],
count: 7,
clientWidthValue: 0,
ballWidth: 0,
ballWidthArr: []
};
},
components: {
GZNormalWrap
// NoData
},
mounted() {
this.$nextTick(() => {
this.clientWidthValue = document.querySelector('#constructionIndustryMain').clientWidth
this.ballWidth = Math.floor(this.clientWidthValue / this.count)
this.handleBallWidth(this.ballWidth)
this.getLatest_sign_users('init')
})
},
methods: {
handleLink() {
},
handleBallWidth(ballWidth) {
this.ballWidthArr.push(this.ballWidth)
const cell = ballWidth / (this.count)
const num = (this.count - 1) % 2 + Math.floor((this.count - 1) / 2)
for(let i = 0; i < num; i++) {
const value = Math.floor(ballWidth - (cell * (i + 1)))
const value2 = Math.floor(ballWidth + (cell * (i + 1)))
this.ballWidthArr.push(value)
this.ballWidthArr.unshift(value2)
}
this.ballWidthArr.sort()
console.log(this.ballWidthArr)
},
handleClick(val) {
alert(val)
},
getLatest_sign_users(type = '') {
const data = [
{
name: '装配式智能建造', value: 56 }, {
name: '机器人应用', value: 560 }, {
name: '放样机器人应用', value: 300 }, {
name: '三维激光机器', value: 400 }, {
name: '远程遥控', value: 1 }, {
name: '智慧展馆', value: 200 }, {
name: '倾斜摄影', value: 0 }
]
data.sort((a, b) => {
return a.value - b.value
})
this.circleData = [...data]
this.$nextTick(() => {
if (data.length) {
this.initBubble()
}
})
},
initBubble() {
const main = document.getElementById('constructionIndustryMain');
const divDom = main.querySelectorAll('.ball-style'); // 获取新增加的dom
// 给新增加的dom设置宽高
for (let i = 0; i < divDom.length; i++) {
const textValue = divDom[i].querySelector('.name-style').innerText
const indexValue = this.circleData.findIndex(item => item.name === textValue)
// divDom[i].style.boxShadow = '0 0 20px' + ' ' + colors[this.circleData[i].gender] + ' ' + 'inset';
divDom[i].style.background = 'linear-gradient(123deg, rgba(4, 4, 45, 0.43), rgba(38, 142, 161, 0.43))'
// 10个以上尺寸变小
let sizeValue = this.ballWidthArr[indexValue]
if(sizeValue < 60) {
sizeValue = 60
}
divDom[i].style.width = sizeValue + 'px' // '80px';
divDom[i].style.height = sizeValue + 'px';
divDom[i].style.fontSize = '12px';
divDom[i].style.lineHeight = '16px';
this.circleDom.push(divDom[i])
}
// 根据浏览器窗口的大小自动调节小球的运动空间
window.onresize = () => {
this.maxW = main.clientWidth - divDom[0].clientWidth; // 为了让小球不卡在浏览器边缘
this.maxH = main.clientHeight - divDom[0].clientHeight; // 所以要减去自身的宽高
};
onresize();
// 数组对象的初始化
for (let i = 0; i < this.circleDom.length; i++) {
const obj = {
};
console.log(this.circleDom[i]);
// 增加每个小球自己的maxW 和 maxH
const maxW = main.clientWidth - this.circleDom[i].clientWidth; // 为了让小球不卡在浏览器边缘
const maxH = main.clientHeight - this.circleDom[i].clientHeight;
// if (this.circleDom[i].getAttribute('class') === 'active') {
obj.x = Math.floor(Math.random() * (maxW + 1)); // 初始x坐标
obj.y = Math.floor(Math.random() * (maxH + 1)); // 初始y坐标
obj.cx = obj.x + this.circleDom[i].offsetWidth / 2;// 圆心x坐标
obj.cy = obj.y + this.circleDom[i].offsetHeight / 2;// 圆心y坐标
obj.movex = Math.floor(Math.random() * 2); // x轴移动方向
obj.movey = Math.floor(Math.random() * 2); // y轴移动方向
obj.speed = 0.2; // 随机速度
obj.timer = null; // 计时器
obj.index = i; // 索引值
obj.maxW = maxW; // 每个小球最大宽
obj.maxH = maxH; // 每个小球最大高
obj.offsetWidthValue = this.circleDom[i].offsetWidth
this.circleArr.push(obj)
// 小球位置初始化
this.circleDom[i].style.left = obj.x + 'px';
this.circleDom[i].style.top = obj.y + 'px';
// } else {
// // 保留之前数据得位置信息,不刷新位置
// obj = this.circleArr[i]
// }
this.move(obj);
}
},
// 移动函数
move(balls) {
const self = this
self.timer = requestAnimationFrame(function fn() {
if (balls.movex === 1) {
// 如果往右跑,则一直加速度,碰到边界,改为反方向运动
balls.x += balls.speed;
if (balls.x + balls.speed >= balls.maxW) {
// 防止小球出界
balls.x = balls.maxW;
balls.movex = 0; // 小球运动方向发生改变
}
} else {
balls.x -= balls.speed; // 1和0表示正反方向
if (balls.x - balls.speed <= 0) {
balls.x = 0;
balls.movex = 1;
}
}
if (balls.movey === 1) {
balls.y += balls.speed;
if (balls.y + balls.speed >= balls.maxH) {
balls.y = balls.maxH;
balls.movey = 0;
}
} else {
balls.y -= balls.speed;
if (balls.y - balls.speed <= 0) {
balls.y = 0;
balls.movey = 1;
}
}
if (self.circleDom[balls.index]) {
balls.cx = balls.x + self.circleDom[balls.index].offsetWidth / 2;// 小球圆心等于:运动中x的值加上自身的半径
balls.cy = balls.y + self.circleDom[balls.index].offsetHeight / 2;
self.circleDom[balls.index].style.left = balls.x + 'px'; // 小球相对于屏幕的位置
self.circleDom[balls.index].style.top = balls.y + 'px';
self.crash(balls.index); // 每个小球进行碰撞检测
}
requestAnimationFrame(fn);
});
// // 每个球单独有定时器
// balls.timer = setInterval(() => {
// if (balls.movex === 1) {
// // 如果往右跑,则一直加速度,碰到边界,改为反方向运动
// balls.x += balls.speed;
// if (balls.x + balls.speed >= balls.maxW) {
// // 防止小球出界
// balls.x = balls.maxW;
// balls.movex = 0; // 小球运动方向发生改变
// }
// } else {
// balls.x -= balls.speed; // 1和0表示正反方向
// if (balls.x - balls.speed <= 0) {
// balls.x = 0;
// balls.movex = 1;
// }
// }
// if (balls.movey === 1) {
// balls.y += balls.speed;
// if (balls.y + balls.speed >= balls.maxH) {
// balls.y = balls.maxH;
// balls.movey = 0;
// }
// } else {
// balls.y -= balls.speed;
// if (balls.y - balls.speed <= 0) {
// balls.y = 0;
// balls.movey = 1;
// }
// }
// if (this.circleDom[balls.index]) {
// balls.cx = balls.x + this.circleDom[balls.index].offsetWidth / 2;// 小球圆心等于:运动中x的值加上自身的半径
// balls.cy = balls.y + this.circleDom[balls.index].offsetHeight / 2;
// this.circleDom[balls.index].style.left = balls.x + 'px'; // 小球相对于屏幕的位置
// this.circleDom[balls.index].style.top = balls.y + 'px';
// this.crash(balls.index); // 每个小球进行碰撞检测
// }
// }, 25);
// this.timerArr.push(balls.timer)
},
// 碰撞函数
crash(a) {
const container = [...this.circleArr]
const ball1x = container[a].cx; // 在数组中任意球的圆心坐标
const ball1y = container[a].cy;// 思路:先随便拿一个球,然后遍历所有球,拿这个球和所有球的圆心距离比较
for (let i = 0; i < container.length; i++) {
if (i !== a) {
// 判断取出来的球不是本身,才能和其他球进行距离判断
const ball2x = container[i].cx; // 将其他球的圆心坐标赋值给球2
const ball2y = container[i].cy;
// 圆心距 求两个点之间的距离,开平方
const distence = Math.sqrt((ball1x - ball2x) * (ball1x - ball2x) + (ball1y - ball2y) * (ball1y - ball2y));
if (distence <= ((this.circleDom[a].offsetWidth + container[i].offsetWidthValue) / 2)) {
// 球心距离和求直径比较
if (ball1x > ball2x) {
// 当前位于未知求的右方
if (ball1y > ball2y) {
// 预设未知球撞当前球,然后当前球改变运动
container[a].movex = 1; // 1表示为正值,对应的右和下
container[a].movey = 1;// 0表示为负值,对应的左和上
} else if (ball1y < ball2y) {
container[a].movex = 1;
container[a].movey = 0;
} else {
container[a].movex = 1;
}
} else if (ball1x < ball2x) {
if (ball1y > ball2y) {
container[a].movex = 0;
container[a].movey = 0;
} else if (ball1y < ball2y) {
container[a].movex = 0;
container[a].movey = 1;
} else {
container[a].movex = 0;
}
} else {
if (ball1y > ball2y) {
container[a].movey = 1;
} else if (ball1y < ball2y) {
container[a].movey = 0;
}
}
}
}
}
}
},
beforeDestroy() {
cancelAnimationFrame(this.timer)
}
};
</script>
<style lang='less' scoped>
#constructionIndustryMain {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
padding: 0;
li {
position: absolute;
overflow: hidden;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
cursor: pointer;
&.active {
animation: scaleBox 1s 1;
}
@keyframes scaleBox {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
div {
span {
display: block;
width: 100%;
color: #fff;
text-align: center;
}
}
}
}
.num-style{
font-size: 18px;
font-weight: bold;
color: #20E3E1;
text-align: center;
}
.name-style{
margin-top: 5px;
font-size: 12px;
color: #FFFFFF;
text-align: center;
}
.button-style{
position: absolute;
right: 30px;
top: 30px;
cursor: pointer;
background: rgba(56, 137, 255, 0.6);
width: 80px;
height: 24px;
line-height: 24px;
text-align: center;
color: #FFFFFF;
border-radius: 2px;
border: 1px solid #3889FF;
}
</style>
借鉴于此
https://blog.csdn.net/weixin_39150852/article/details/123825240
边栏推荐
- How to do a good job in software system demand research? Seven weapons make it easy for you to do it
- MySQL function to get the full path
- How to seamlessly transition from traditional microservice framework to service grid ASM
- Evolution of screen display technology
- Swin-transformer --relative positional Bias
- Detailed single case mode
- mysql 递归
- How to improve the three passive situations in data analysis
- Practical application of "experience" crawler in work
- 20220607跌破建议零售价,GPU市场正全面走向供过于求...
猜你喜欢

TCP粘包问题

华兴证券:混合云原生架构下的 Kitex 实践

Digital intelligent supplier management system solution for coal industry: data driven, supplier intelligent platform helps enterprises reduce costs and increase efficiency

PC wechat multi open

Dlib库实现人脸关键点检测(Opencv实现)

教你30分钟快速搭建直播间

20220528【聊聊假芯片】贪便宜往往吃大亏,盘点下那些假的内存卡和固态硬盘

MRO industrial products procurement management system: enable MRO enterprise procurement nodes to build a new digital procurement system

ANSI/UL 94 5-V级垂直燃烧试验

Geoffrey Hinton: my 50 years of in-depth study and Research on mental skills
随机推荐
Can go struct in go question bank · 15 be compared?
Swin-Transformer(2021-08)
Courage to be hated: Adler's philosophy class: the father of self inspiration
Ambient light and micro distance detection system based on stm32f1
Four tips tell you how to use SMS to promote business sales?
Rust 如何实现依赖注入?
Redis入门到精通01
领导:谁再用 Redis 过期监听实现关闭订单,立马滚蛋!
Entry node of link in linked list - linked list topic
How to improve the three passive situations in data analysis
开发那些事儿:如何在视频中添加文字水印?
Huaxing Securities: kitex practice under the original hybrid Cloud Architecture
PC wechat multi open
Nodejs 安装与介绍
Geoffrey Hinton: my 50 years of in-depth study and Research on mental skills
手机股票账号开户安全吗?是靠谱的吗?
mysql修改数据类型_MySQL修改字段类型[通俗易懂]
【社区明星评选】第23期 7月更文计划 | 点滴创作,汇聚成塔!华为FreeBuds 4E等酷爽好礼送不停
RFFE中MIPI协议
At present, the big guys are joining the two streams of flinksql, cdcmysql and Kafka, and the results are put into MySQL or KA