基于Vue怎样使用canvas绘制大小不一且不会重复的圆形
Admin 2022-06-21 群英技术资讯 1117 次浏览
第一张是 随机颜色随机大小聚合 在一起效果
第二张是 随机背景图片随机大小分散 效果(这里我使用的图片都一样所以没展现出不同图片)
<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>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了JS关于for循环中使用setTimeout的四种解决方案,想深入了解JS的同学,一定要继续往下看
今天我们来了解关于JavaScript构造函数的内容,下文会介绍构造函数是什么,构造函数用来做什么,构造函数的执行过程和构造函数的返回值这些,对新手学习和理解JavaScript构造函数有一定的帮助,需要的朋友可以参考。
这篇文章主要为大家详细介绍了微信小程序自定义滚动选择器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
JS利用循环解决的一些常见问题总结 目录 1. 打印0-100中3的倍数 2. 在页面中写入 1000-2000年中的闰年 3. 打印100以内所有偶数的和 4.求出1-1/2+1/3-1/4……1/100的和 5. 打印三角形 5.1 普通三角形 5.2 倒三角 5.3 等腰三角形 6.等腰梯形 7.输出100-200之间所有的质数 9. 有一个棋盘,有64个方格,在第一个方格里面放1粒芝麻重量是0.00001kg,第二个里面放2粒,第三个里面放4,棋盘上放的所有芝麻的重量 10.在页面上完成以一个九九乘法表 11.打印一个3行
这篇文章主要为大家详细介绍了原生JavaScript实现轮播图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008