目录canvas 相关文档效果图展示案例完整代码父组件代码子组件代码总结canvas 相关文档 Canvas api CANVAS速查简表 效果图展示 第一张是
第一张是 随机颜色随机大小聚合 在一起效果
第二张是 随机背景图片随机大小分散 效果(这里我使用的图片都一样所以没展现出不同图片)
<template>
<div id="home">
<div class="tags" ref="tags">
<circle-box :parentClientWidth="parentClientWidth" :parentClientHeight="parentClientHeight" :dataList="dataList"></circle-box>
</div>
</div>
</template>
<script>
import CircleBox from '@/components/content/circle/Circle.vue'
export default {
components: { CircleBox },
data() {
return {
parentClientWidth: 0,
parentClientHeight: 0,
// canvas 模拟数据
dataList: [
{
follow: 1,
image: 'Http://39.99.139.115/demo/RB5.png'
},
{
follow: 2,
image: 'http://39.99.139.115/demo/RB5.png'
},
{
follow: 3,
image: 'http://39.99.139.115/demo/RB5.png'
},
{
follow: 4,
image: 'http://39.99.139.115/demo/RB5.png'
},
{
follow: 5,
image: 'http://39.99.139.115/demo/RB5.png'
},
{
follow: 6,
image: 'http://39.99.139.115/demo/RB5.png'
},
{
follow: 7,
image: 'http://39.99.139.115/demo/RB5.png'
},
{
follow: 8,
image: 'http://39.99.139.115/demo/RB5.png'
},
{
follow: 9,
image: 'http://39.99.139.115/demo/RB5.png'
},
{
follow: 10,
image: 'http://39.99.139.115/demo/RB5.png'
}
],
};
},
created() {},
mounted() {
this.getWidth();
},
methods: {
// 获取父盒子的宽度和高度
getWidth() {
this.parentClientWidth = this.$refs.tags.clientWidth;
this.parentClientHeight = this.$refs.tags.clientHeight;
console.log(this.$refs.tags.clientWidth);
}
},
};
</script>
<template>
<div>
<canvas id="myCanvas" :width="parentClientWidth + 'px'" :height="parentClientHeight + 'px'"></canvas>
</div>
</template>
<script>
export default {
// 接收数据
props: ['parentClientWidth', 'parentClientHeight', 'dataList'],
data() {
return {
dataListCopy: this.dataList
}
},
created() {
this.$nextTick(() => {
// 初始化
this.circleInfo()
})
},
mounted() {},
methods: {
circleInfo() {
let that = this
class Circle {
constructor(x, y, r, color) {
this.x = x
this.y = y
this.r = r
this.c = color ? color : this.getRandomColor()
}
// 随机颜色
getRandomColor() {
let r = Math.floor(Math.random() * 100) + 155
let g = Math.floor(Math.random() * 100) + 155
let b = Math.floor(Math.random() * 100) + 155
return `rgb(${r},${g},${b})`
}
}
class RandomCircle {
constructor(obj) {
this.c = document.getElementById(obj.id)
console.log(this.c)
this.ctx = this.c.getContext('2d')
this.dWidth = this.c.width
this.dHeight = this.c.height
this.fix = obj.fix || true
this.minMargin = obj.minMargin || 20
this.minRadius = obj.minRadius || 30
this.radiuArr = obj.radiuArr || [30, 30, 30, 30, 30, 30, 30, 30, 30, 30]
this.total = obj.total || 10
this.circleArray = []
this.circleNumber = 1
}
drawOneCircle(c, index) {
// console.log(c, index)
let ctx = this.ctx
ctx.beginPath()
ctx.strokeStyle = c.c
ctx.fillStyle = c.c
// 画圆
ctx.arc(c.x, c.y, c.r, 0, 2 * Math.PI)
ctx.stroke()
ctx.fill()
// ctx.textAlign = 'center'
// ctx.textBaseline = 'middle'
// ctx.fillStyle = 'black'
// ctx.font = '1rem 微软雅黑'
// ctx.fillText(that.dataListCopy[index].follow, c.x, c.y - 10) //圆内文字
let img = new Image()
img.src = that.dataListCopy[index].image
ctx.drawImage(img, c.x - c.r, c.y - c.r, c.r * 2, c.r * 2)
this.circleNumber++
}
check(x, y, r) {
return !(x + r > this.dWidth || x - r < 0 || y + r > this.dHeight || y - r < 0)
}
// 获取一个新圆的半径,主要判断半径与最近的一个圆的距离
getR(x, y) {
if (this.circleArray.length === 0) return Math.floor(Math.random() * 20 + 20)
let lenArr = this.circleArray.map((c) => {
let xSpan = c.x - x
let ySpan = c.y - y
return Math.floor(Math.sqrt(Math.pow(xSpan, 2) + Math.pow(ySpan, 2))) - c.r
})
let minCircleLen = Math.min(...lenArr)
let minC = this.circleArray[lenArr.indexOf(minCircleLen)]
let tempR = this.fix ? this.radiuArr[this.circleArray.length] : minCircleLen - this.minMargin
let bool = this.fix ? tempR <= minCircleLen - minC.r : tempR >= this.minRadius
return bool ? tempR : false
}
// 生成一个圆,随机生成圆心。
// 如果连续生成200次半径都没有合适的话,终止进程
createOneCircle() {
let x, y, r
let createCircleTimes = 0
while (true) {
createCircleTimes++
x = Math.floor(Math.random() * this.dWidth)
y = Math.floor(Math.random() * this.dHeight)
let TR = this.getR(x, y)
if (!TR) {
continue
} else {
r = TR
}
if (this.check(x, y, r) || createCircleTimes > 200) {
break
}
}
this.check(x, y, r) && this.circleArray.push(new Circle(x, y, r))
}
// 如果生成100次新圆都失败的话,终止方案。
// 如果生成100种方案都没有合适可用的话,终止进程。
init() {
let n = 0
while (this.circleArray.length < this.total) {
this.circleArray = []
let i = 0
while (this.circleArray.length < this.total) {
this.createOneCircle()
i++
if (i >= 100) {
break
}
}
n++
if (n > 100) {
break
}
}
// 根据半径从大到小画圆。
this.circleArray
.sort((a, b) => b.r - a.r)
.forEach((c, index) => {
this.drawOneCircle(c, index)
})
}
}
// console.log(this.circle);
const p = new RandomCircle({
id: 'myCanvas',
total: that.dataListCopy.length // 配置数量
})
p.init()
console.log(p)
console.log(p.circleArray)
}
}
}
</script>
到此这篇关于Vue使用Canvas生成随机大小且不重叠圆的文章就介绍到这了,更多相关Vue用Canvas生成随机圆内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: Vue使用Canvas生成随机大小且不重叠圆
本文链接: https://lsjlt.com/news/156344.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0