บทความนี้จะแนะนำโค้ดการใช้งานของข้อความ Canvas ให้กับเอฟเฟกต์ของอนุภาคและแบ่งปันกับทุกคน ฉันหวังว่าจะเป็นประโยชน์กับทุกคน
การวาดข้อความผ่านอนุภาคให้ความรู้สึกน่าสนใจ และการจับคู่การเคลื่อนไหวของอนุภาคจะทำให้เอฟเฟกต์เย็นลง บทความนี้จะแนะนำวิธีการวาดข้อความผ่านอนุภาคบนผืนผ้าใบ
หลักการปฏิบัติโดยทั่วไปแล้ว การทำให้เอฟเฟกต์ของการเปลี่ยนข้อความเป็นการแสดงอนุภาคนั้นง่ายมาก หลักการนำไปใช้คือการใช้ผืนผ้าใบสองผืน ซึ่งผู้ใช้มองไม่เห็น และอีกผืนหนึ่งคือ สิ่งหนึ่งที่ผู้ใช้สามารถเห็นได้ ผืนผ้าใบ B ที่ได้รับนั้นใช้เพื่อสร้างอนุภาคตามข้อมูลข้อความของ A การแสดงภาพดังแสดงในรูป:
สร้างผืนผ้าใบนอกจอต้องวาง HTML บนผืนผ้าใบหลักเท่านั้น:
<!-- โครงสร้าง HTML--><html><head> ...</head><body> <canvas id=stage></canvas></body></html>
จากนั้นสร้างผืนผ้าใบนอกหน้าจอและวาดข้อความ:
const WIDTH = window.innerWidth; const HEIGHT = window.innerHeight; const offscreenCanvas = document.createElement('canvas'); const offscreenCtx = offscreenCanvas.getContext('2d'); offscreenCtx.font = '100px PingFang SC';offscreenCtx.textAlign = 'center';offscreenCtx.baseline = 'middle';offscreenCtx.fillText('สวัสดี', WIDTH / 2, HEIGHT / 2);ไม่มีอะไรเกิดขึ้นบนเพจในขณะนี้ แต่คุณสามารถจินตนาการได้จริง ๆ บนผืนผ้าใบนอกจอ มันควรจะเป็นดังแสดงในรูป:
เมธอดหลัก getImageData เมื่อใช้วิธีการ getImageData ของ Canvas คุณสามารถรับวัตถุ ImageData ซึ่งใช้เพื่ออธิบายข้อมูลพิกเซลในพื้นที่ที่ระบุของผืนผ้าใบ กล่าวอีกนัยหนึ่ง เราสามารถรับตำแหน่งและสีของแต่ละพิกเซลของข้อความ Hello และเราสามารถสร้างอนุภาคในตำแหน่งที่ระบุได้ ผลลัพธ์สุดท้ายคืออนุภาคจะถูกปะติดปะต่อกันเป็นข้อความ
ในการรับข้อมูลพิกเซลคุณต้องใช้แอตทริบิวต์ data ของวัตถุ ImageData ซึ่งจะกระจายค่า rgba ของพิกเซลทั้งหมดลงในอาร์เรย์ แต่ละพิกเซลมีค่า rgba สี่ค่า จำนวนของอาร์เรย์นี้คือ 像素点数量* 4 .
สมมติว่าฉันเลือกพื้นที่ 3 * 4 แล้วมีทั้งหมด 12 พิกเซล แต่ละพิกเซลมีค่า rgba สี่ค่า ดังนั้นอาร์เรย์ข้อมูลจะมีองค์ประกอบ 12 * 4 = 48
หากคุณพิมพ์ข้อมูลออกมา คุณจะเห็น RGBA ของพิกเซลเหล่านี้จัดเรียงจากซ้ายไปขวาและบนลงล่าง
แน่นอนว่าพื้นที่ที่เราต้องการได้รับจะต้องมีข้อความ ดังนั้นเราควรได้พื้นที่แคนวาสนอกหน้าจอทั้งหมด:
const imgData = offscreenCtx.getImageData(0, 0, WIDTH, HEIGHT).data;สร้างอนุภาค
หลังจากได้รับ ImageData แล้ว โดยการสำรวจอาร์เรย์ข้อมูล คุณสามารถกำหนดได้ว่าจุดใดบนผืนผ้าใบนอกหน้าจอที่มีสี (ตรงกลางข้อความ) และจุดใดที่ไม่มีสี (ไม่ใช่บนข้อความ) และใส่พิกเซลสีเหล่านั้น เขียน ลงจากตำแหน่ง จากนั้นสร้างอนุภาคบนผืนผ้าใบหลัก เท่านี้คุณก็พร้อมแล้ว
ขั้นแรกให้สร้างคลาสอนุภาค:
คลาสอนุภาค { ตัวสร้าง (ตัวเลือก = {}) { const { x = 0, y = 0, color = '#fff', รัศมี = 5} = ตัวเลือก; this.radius = รัศมี; = y; this.color = color; } วาด (ctx) { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false); ctx.fillStyle = this.color; ctx.fill(); ctx.closePath( }}เมื่อสำรวจข้อมูล เราสามารถระบุได้ว่าพิกเซลอยู่ในข้อความหรือไม่โดยพิจารณาจากความโปร่งใส นั่นคือ องค์ประกอบที่สี่ใน rgba ไม่ใช่ 0 หรือไม่
const อนุภาค = []; const ข้าม = 4; สำหรับ (var y = 0; y < HEIGHT; y += ข้าม) { สำหรับ (var x = 0; x < WIDTH; x += ข้าม) { var opacityIndex = (x + y * WIDTH) * 4 + 3; if (imgData[opacityIndex] > 0) { อนุภาค.push(อนุภาคใหม่ ({ x, y, รัศมี: 1, สี: '#2EA9DF' })); เราใช้อาร์เรย์ particles เพื่อจัดเก็บอนุภาคทั้งหมด ฟังก์ชัน skip ที่นี่คือขนาดขั้นตอนของการเคลื่อนที่ผ่าน ถ้าเราสแกนพิกเซลทีละพิกเซล อนุภาคที่จะปะติดปะต่อข้อความจะมีความหนาแน่นมากขึ้น อนุภาคจะถูกสร้างขึ้น
สุดท้าย สร้างผืนผ้าใบหลักแล้ววาด:
const canvas = document.querySelector('#stage');canvas.width = WIDTH;canvas.height = HEIGHT;const ctx = canvas.getContext('2d');for (อนุภาค const ของอนุภาค) { particle.draw(ctx );}เอฟเฟกต์มีดังนี้:
สำหรับโค้ดที่สมบูรณ์ โปรดดูที่ 01-basic-text-to-particles
เพิ่มเอฟเฟกต์หลังจากทำความเข้าใจหลักการใช้งานแล้ว ส่วนที่เหลือคือการเพิ่มเอฟเฟกต์ภาพเคลื่อนไหวให้กับอนุภาค ขั้นแรก คุณสามารถให้อนุภาคมีการกระจัดแบบสุ่มเพื่อหลีกเลี่ยงไม่ให้ดูเรียบร้อยเกินไป
const อนุภาค = []; const ข้าม = 4; สำหรับ (var y = 0; y < HEIGHT; y += ข้าม) { สำหรับ (var x = 0; x < WIDTH; x += ข้าม) { var opacityIndex = (x + y * WIDTH) * 4 + 3; if (imgData[opacityIndex] > 0) { // เพิ่มการกระจัดแบบสุ่มเมื่อสร้างอนุภาค problems.push(ใหม่ อนุภาค({ x: x + Math.random() * 6 - 3, y: y + Math.random() * 6 - 3, รัศมี: 1, สี: '#2EA9DF' }));เอฟเฟกต์มีดังนี้:
หากคุณต้องการบรรลุผลที่มากขึ้น เช่น:
จะดำเนินการอย่างไร ขั้นแรก คุณต้องสุ่มสร้างขนาดของอนุภาค ซึ่งต้องใช้เพียงการสุ่มรัศมีเมื่อสร้างอนุภาค นอกจากนี้ หากคุณต้องการให้รัศมีของอนุภาคเปลี่ยนแปลงแบบไดนามิก คุณต้องแยกแยะรัศมีการแสดงภาพของอนุภาคและรัศมีเริ่มต้น และใช้ requestAnimationFrame สำหรับการแสดงภาพเคลื่อนไหว:
คลาสอนุภาค { ตัวสร้าง (ตัวเลือก = {}) { const { x = 0, y = 0, color = '#fff', รัศมี = 5} = options; this.radius = radius; รัศมี; // เพิ่มคุณสมบัติ dynamicRadius} วาด (ctx) { // ... ctx.arc(this.x, this.y, this.dynamicRadius, 0, 2 * Math.PI, false); // แทนที่ด้วย dynamicRadius // ... } update () { // TODO }}requestAnimationFrame(function loop() { requestAnimationFrame(loop); ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, WIDTH, HEIGHT ); สำหรับ (อนุภาค const) { particle.update(); particle.draw(ctx }}); สิ่งสำคัญอยู่ที่การนำวิธี update ของอนุภาคไปใช้ สมมติว่าเราต้องการให้รัศมีของอนุภาคเปลี่ยนแปลงอย่างราบรื่นและเป็นวงกลมจาก 1 ถึง 5 ฟังก์ชันตรีโกณมิติเป็นเรื่องง่ายที่จะนึกถึง เช่น:
แกนนอนควรสัมพันธ์กับเวลา คุณสามารถรักษาตัวแปรและเพิ่มทุกครั้งที่คุณเรียกใช้การอัปเดต คุณยังสามารถใช้การประทับเวลาเพื่อคำนวณได้ง่ายๆ ตัวอย่างของวิธี update มีดังนี้:
อัปเดต () { this.dynamicRadius = 3 + 2 * Math.sin (วันที่ใหม่ () / 1,000 % 1,000 * this.radius);}สำหรับโค้ดแบบเต็ม โปรดดูที่ 02-text-to-particles-with-size-changeing
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network