เมื่อเร็วๆ นี้ เนื่องจากโปรเจ็กต์จำเป็นต้องปรับแต่งฟังก์ชันเขื่อนกั้นน้ำ ฉันจึงพยายามใช้ Canvas เพื่อพัฒนาส่วนประกอบต่างๆ หลังจากการทดสอบกับเครื่องระดับล่างบางรุ่นแล้ว ให้ฉันแชร์กับคุณบ้าง
เอฟเฟกต์เขื่อนกั้นน้ำ การแนะนำฟังก์ชันใช้
npm i vue-barrage
การกำหนดค่าพารามิเตอร์
ชื่อ | พิมพ์ | ค่าเริ่มต้น | รายละเอียด |
---|---|---|---|
รายการสิ่งกีดขวาง | อาร์เรย์ | - | ข้อมูลเขื่อน |
ความเร็ว | ตัวเลข | 4 | ความเร็วในการเลื่อน Barrage |
วนซ้ำ | บูลีน | จริง | ไม่ว่าจะเลื่อนแบบวนซ้ำหรือไม่ |
ช่อง | ตัวเลข | 2 | จำนวนเส้นทางเขื่อนกั้นน้ำ |
สไตล์ HTML
<เทมเพลต> <div class=barrage-container> <div class=container :style={height: barrageHeight/2+'px'}> <canvas id=canvas ref=canvas :width=barrageWidth :height=barrageHeight :style= {'width': barrageWidth/2 + 'px','height': barrageHeight/2 + 'px'}/> </div> </div></template>การใช้งาน js
ฟังแหล่งข้อมูล
ดู: { barrageList (val) { if (val.length !== 0) { this.initData() // การเริ่มต้นข้อมูล this.render() // เริ่มการเรนเดอร์} }}
การเริ่มต้นข้อมูล
barrageArray
ใช้เพื่อจัดเก็บข้อมูลเขื่อน รวมถึงรายการเขื่อนเริ่มต้นและรายการเขื่อนใหม่
/** * การเริ่มต้นข้อมูล*/initData () { สำหรับ (let i = 0; i < this.barrageList.length; i++) { // แสดงเพียง 40 ตัวอักษรที่นี่ ให้เนื้อหา = this.barrageList[i] ความยาว > 40 ? `${this.barrageList[i].content.substring(0, 40)}...` : this.barrageList[i].content this.pushMessage(content, this.barrageList[i].color) }},/** * เพิ่มข้อมูล* @param content * @param color */pushMessage (เนื้อหา, สี) { ให้ตำแหน่ง = this.getPosition() / / กำหนดตำแหน่งทางวิ่ง ให้ x = this.barrageWidth // ตำแหน่งเริ่มต้น ให้ offsetWidth = 0 สำหรับ (ให้ i = 0, len = this.barrageArray.length; i < len; i++) { ให้ item = this.barrageArray[i] if (position === item.position) { // ถ้าพวกมันอยู่ในแทร็กเดียวกัน ให้ย้ายไปที่ด้านหลัง offsetWidth += Math.floor(this.ctx.measureText( item.content) .width * 3 + 60) } } this.barrageArray.push({ เนื้อหา: เนื้อหา // เนื้อหา Barrage x: x + offsetWidth, // กำหนดตำแหน่งเริ่มต้นของแต่ละความคิดเห็น originX: x + offsetWidth, // จัดเก็บตำแหน่งปัจจุบันของความคิดเห็นเพื่อให้สามารถนำไปใช้ในระหว่างตำแหน่งการวนซ้ำ: ตำแหน่ง, ความกว้าง: this.ctx.measureText(content).width * 3, / / สีความกว้างของเนื้อหาการวาดภาพแคนวาส: color ||. this.getColor() // สีที่กำหนดเอง})},
สิ่งที่ต้องประมวลผลในข้อมูลการเริ่มต้นคือการคำนวณเส้นทาง ตำแหน่ง และความกว้างของเขื่อนปัจจุบัน เพื่อให้สามารถนำมาใช้ในการวาด canvas
ได้
วาด canvas
/** * Render*/render () { this.ctx.clearRect(0, 0, this.barrageWidth, this.barrageHeight) this.ctx.font = '30px Microsoft YaHei' this.draw() window.requestAnimationFrame(นี่ .render) // เรนเดอร์ทุกๆ 16.6 มิลลิวินาที หากคุณใช้ setInterval มันจะล่าช้าเล็กน้อยในรุ่นต่ำสุด},** * เริ่มวาดข้อความและพื้นหลัง*/draw () { for (let i = 0, len = this.barrageArray.length; i < len; i++) { la barrage = this.barrageArray[i] try { barrage.x -= this .speed if (barrage.x < -barrage.width - 100) { // กำหนดเวลาที่เขื่อนหายไปที่นี่ถ้า (i === this.barrageArray.length - 1) { // ตรรกะการตัดสินเมื่อเขื่อนกั้นน้ำสุดท้ายหายไปถ้า (!this.loop) { // หากไม่ใช่ลูป ให้ยกเลิกภาพวาดเพื่อพิจารณาว่าเป็นลูปหรือไม่ และดำเนินการ cancelAnimationFrame โดยไม่ต้องวนซ้ำ cancelAnimationFrame(this.render) กลับ } if (this.addArray .length !== 0) { // กำหนดตรรกะของการเพิ่มเขื่อนกั้นน้ำที่นี่ this.barrageArray = this.barrageArray.concat(this.addArray) this.addArray = [] } สำหรับ (ให้ j = 0; j < this.barrageArray.length; j++) { // กำหนดให้แต่ละเขื่อนมีค่าเริ่มต้นเป็น x this.barrageArray[j].x = this.barrageArray[j].originX } } } ถ้า (barrage.x <= 2 * document.body.clientWidth + barrage.width) { // พิจารณาว่าจะเริ่มวาดเมื่อใด ถ้าไม่จะทำให้การเลื่อนเขื่อนค้าง // วาดพื้นหลัง this.drawRoundRect(this.ctx, barrage.x - 15, barrage.position - 30, barrage.width + 30, 40, 20, `rgba(0,0,0,0.75)`) // วาด ส่งข้อความนี้ .ctx.fillStyle = `${barrage.color}` this.ctx.fillText(barrage.content, barrage.x, barrage.position) } } จับ (e) { console.log(e) } }}
ตรรกะการวาดจะตัดสินที่นี่ รวมถึงเวลาที่จะยกเลิก การตัดสินเมื่อเขื่อนเริ่มวาด และการตัดสินเมื่อเขื่อนหายไป
ฟังก์ชั่นอื่นๆ
/** * รับตำแหน่งข้อความ * ใช้ pathWayIndex เพื่อยืนยันแทร็กที่แต่ละเขื่อนตั้งอยู่ * คืนระยะทางจากด้านบน * @TODO นอกจากนี้ยังสามารถปรับให้เหมาะสมเพื่อกำหนดตำแหน่งของเขื่อนถัดไปตามระยะทางของแต่ละแทร็ก */ getPosition () { la range = this.channels la top = (this.pathWayIndex % range) * 50 + 40 this.pathWayIndex++ return top},/** * รับสีสุ่ม*/getColor () { return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);},/** * วาดรูปสี่เหลี่ยมผืนผ้าโค้งมน* @ บริบทพารามิเตอร์ * @param x * @param y * @ความกว้างของพารามิเตอร์ * ความสูง @param * รัศมี @param * สี @param */drawRoundRect (บริบท, x, y, ความกว้าง, ความสูง, รัศมี, สี) { context.beginPath() context.fillStyle = color context.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2) context.lineTo (ความกว้าง - รัศมี + x, y) context.arc(ความกว้าง - รัศมี + x, รัศมี + y, รัศมี, Math.PI * 3/2, Math.PI * 2) context.lineTo(width + x, ความสูง + y - รัศมี) context.arc(ความกว้าง - รัศมี + x, ความสูง - รัศมี + y, รัศมี, 0, Math.PI / 2) context.lineTo(รัศมี + x, ความสูง + y) context.arc (รัศมี + x, ความสูง - รัศมี + y, รัศมี, Math.PI / 2, Math.PI) context.fill() context.closePath()}
นี่คือฟังก์ชั่นบริการเขื่อนกั้นน้ำ
ใช้
<barrage ref=barrage class=barrage :barrage-list=barrageList :speed=speed :loop=loop :channels=channels/> นำเข้า Barrage จาก 'vue-barrage'// การเริ่มต้นข้อมูล Barrage this.barrageList = [{ content: ' ข้อมูลการทดสอบ หมายเลขทดสอบ ข้อมูลการทดสอบ หมายเลข ข้อมูลการทดสอบ', สี: 'สีขาว'}]// เพิ่มเขื่อนกั้นน้ำใหม่ this.$refs.barrage.add({ content: 'เพิ่มเขื่อนกั้นน้ำใหม่เพิ่มเขื่อนกั้นน้ำใหม่', สี: 'สีขาว'})บทสรุป
โดยรวมแล้ว ส่วนประกอบนี้ยังมีพื้นที่สำหรับการเพิ่มประสิทธิภาพ และฉันจะปรับปรุงต่อไปในอนาคต
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network