Canvas related documents
Effect picture displayThe first one is the effect of random colors and random sizes aggregated together The second one is the random background image with random size dispersion effect (the pictures I used here are all the same so different pictures are not shown) Case complete code
Parent component code<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 simulation data 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: { // Get the width and height of the parent box getWidth() { this.parentClientWidth = this.$refs.tags.clientWidth; this.parentClientHeight = this.$refs.tags.clientHeight; console.log(this.$refs.tags.clientWidth); } }, }; </script> Subcomponent code<template> <div> <canvas id="myCanvas" :width="parentClientWidth + 'px'" :height="parentClientHeight + 'px'"></canvas> </div> </template> <script> export default { // Receive data props: ['parentClientWidth', 'parentClientHeight', 'dataList'], data() { return { dataListCopy: this.dataList } }, created() { this.$nextTick(() => { // Initialize 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() } // Random color 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 = cc ctx.fillStyle = cc // Draw a circle ctx.arc(cx, cy, cr, 0, 2 * Math.PI) ctx.stroke() ctx.fill() // ctx.textAlign = 'center' // ctx.textBaseline = 'middle' // ctx.fillStyle = 'black' // ctx.font = '1rem Microsoft YaHei' // ctx.fillText(that.dataListCopy[index].follow, cx, cy - 10) // Text inside the circle let img = new Image() img.src = that.dataListCopy[index].image ctx.drawImage(img, cx - cr, cy - cr, cr * 2, cr * 2) this.circleNumber++ } check(x, y, r) { return !(x + r > this.dWidth || x - r < 0 || y + r > this.dHeight || y - r < 0) } // Get the radius of a new circle, mainly to determine the distance between the radius and the nearest circle getR(x, y) { if (this.circleArray.length === 0) return Math.floor(Math.random() * 20 + 20) let lenArr = this.circleArray.map((c) => { let xSpan = cx - x let ySpan = cy - y return Math.floor(Math.sqrt(Math.pow(xSpan, 2) + Math.pow(ySpan, 2))) - cr }) 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 } // Generate a circle with a randomly generated center. // If the radius is not suitable after 200 consecutive generation, terminate the process 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)) } // If generating new circles fails 100 times, terminate the scheme. // If none of the 100 generated solutions are suitable, terminate the process. 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 } } // Draw circles from large to small according to the radius. this.circleArray .sort((a, b) => br - ar) .forEach((c, index) => { this.drawOneCircle(c, index) }) } } // console.log(this.circle); const p = new RandomCircle({ id: 'myCanvas', total: that.dataListCopy.length //Configuration quantity}) p.init() console.log(p) console.log(p.circleArray) } } } </script> SummarizeThis is the end of this article about how Vue uses Canvas to generate random-sized, non-overlapping circles. For more information about how Vue uses Canvas to generate random circles, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: Realize the CSS loading effect after clicking the button
>>: How to create a table in mysql and add field comments
nohup command: If you are running a process and y...
1. Introduction to Flex Layout Flex is the abbrev...
Table of contents Preface Promise chaining MDN Er...
Question. In the mobile shopping mall system, we ...
Use JOIN instead of sub-queries MySQL supports SQ...
Harbor Harbor is an open source solution for buil...
Table of contents Overview 1. Dependency Injectio...
Without further ado, here is a demo picture. The ...
Install crontab yum install crontabs CentOS 7 com...
question: When I was doing project statistics rec...
Table of contents background Why error handling? ...
The input box always displays the input history wh...
1. What is master-slave replication? The DDL and ...
Table of contents Preface Confusing undefined and...
Table of contents 1. Functional description 2. Pa...