当前位置:网站首页>小球大小随机,随机运动碰撞
小球大小随机,随机运动碰撞
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
边栏推荐
- 基于STM32F1的环境光与微距离检测系统
- Is it safe to open a mobile stock account? Is it reliable?
- PyTorch学习(三)
- Large file transfer software based on UDP protocol
- Swin-transformer --relative positional Bias
- 法国A+ 法国VOC标签最高环保级别
- Where do the guests come from
- Practical application of "experience" crawler in work
- Construction and practice of full stack code test coverage and use case discovery system
- Reading notes of "high EQ means being able to talk"
猜你喜欢

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

全栈代码测试覆盖率及用例发现系统的建设和实践

Nodejs 安装与介绍

链表中环的入口结点-链表专题

Nodejs installation and introduction

How to seamlessly transition from traditional microservice framework to service grid ASM

Opengauss database source code analysis series articles -- detailed explanation of dense equivalent query technology (Part 1)

熵-条件熵-联合熵-互信息-交叉熵

TCP粘包问题

屏幕显示技术进化史
随机推荐
At present, the big guys are joining the two streams of flinksql, cdcmysql and Kafka, and the results are put into MySQL or KA
Full recharge, im+rtc+x full communication service "feedback season" starts
Entry node of link in linked list - linked list topic
【社区明星评选】第23期 7月更文计划 | 点滴创作,汇聚成塔!华为FreeBuds 4E等酷爽好礼送不停
联想YOGA 27 2022,超强配置全面升级
Go Redis连接池
Lenovo Yoga 27 2022, full upgrade of super configuration
视频内容生产与消费创新
传统微服务框架如何无缝过渡到服务网格 ASM
openGauss数据库源码解析系列文章—— 密态等值查询技术详解(上)
How to do a good job in software system demand research? Seven weapons make it easy for you to do it
Nodejs 安装与介绍
德国AgBB VoC有害物质测试
MySQL recursion
【TiDB】TiCDC canal_ Practical application of JSON
sqlserver SQL Server Management Studio和Transact-SQL创建账户、创建访问指定数据库的只读用户
AI chief architect 10-aica-lanxiang, propeller frame design and core technology
删除排序链表中的重复元素 II[链表节点统一操作--dummyHead]
PC端微信多开
Do you really understand the persistence mechanism of redis?