ฉันต้องการแบ่งปันกับคุณถึงผลกระทบของภาพด้านล่างที่ฉันเพิ่งนำไปใช้
หากเราต้องการวาดภาพเคลื่อนไหวของเส้นโค้งด้านล่าง
หากลากเส้นสั้นๆ เชื่อมต่อกันในแต่ละครั้ง รูปภาพด้านล่างจะแบ่งออกเป็น 5 ส่วน
อ่านอีกสิบย่อหน้า
หากจำนวนส่วนที่แบ่งเพียงพอ การวาดทีละส่วนจะมีลักษณะเหมือนวิถีโคจรโค้ง
เส้นโค้งเบซีเยร์กำลังสอง/** * ภาพเคลื่อนไหวเส้นโค้ง Quadratic Bezier* @param {Array<number>} เริ่มต้นพิกัดจุดเริ่มต้น* @param {Array<number>} พิกัดจุดโค้ง (นั่นคือจุดเปลี่ยน ไม่ใช่พิกัดที่แน่นอน เป็นเพียงทิศทางโดยประมาณ) * @param {Array<number>} พิกัดจุดสิ้นสุด * @param {number} เปอร์เซ็นต์การวาดเปอร์เซ็นต์ (0-100) */ ฟังก์ชั่น DrawCurvePath(เริ่มต้น จุด สิ้นสุด เปอร์เซ็นต์){ ctx.beginPath(); //เริ่มวาดเส้น ctx.moveTo(start[0], start[1]); //ย้ายปากกาไปยังจุดเริ่มต้นสำหรับ (var t = 0; t <= เปอร์เซ็นต์ / 100; t += 0.005 ) { //รับพิกัดของแต่ละจุดเวลา var x = quadraticBezier(start[0], point[0], end[0], t); var y = กำลังสองBezier (เริ่มต้น [1], จุด [1], สิ้นสุด [1], t); ctx.lineTo (x, y); // วาดเส้นตรงจากจุดเวลาก่อนหน้าไปยังจุดเวลาปัจจุบัน} ctx. stroke ( ); //Stroke} /** * สมการเส้นโค้งกำลังสอง Bezier* @param {Array<number>} จุดเริ่มต้น* @param {Array<number>} จุดโค้ง* @param {Array<number>} จุดสิ้นสุด * @param {number} ความคืบหน้าในการวาด (0-1) */ ฟังก์ชั่นกำลังสอง Bezier(p0, p1, p2, t) { var k = 1 - t; return k * k * p0 + 2 * (1 - t) * t * p1 + เสื้อ * เสื้อ * p2;
สำหรับเนื้อหาเส้นโค้ง Bezier ที่มีรายละเอียดเพิ่มเติม โปรดดูที่บล็อกนี้
ให้เป็นโค้ดที่สมบูรณ์
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, Initial-scale=1.0> <meta http-equiv=X-UA - เนื้อหาที่เข้ากันได้=ie=edge> <title>ภาพเคลื่อนไหวเส้นโค้ง Bezier กำลังสอง</title> <style> body { พื้นหลัง: #0f1632; } #canvas { เส้นขอบ: 1px solid #ccc; } #img { display: none; <!--เพียงซ่อน img โดยตรง มันจะถูกอ้างอิงโดยตรงในภายหลัง--> } </style></head><body> <canvas id=canvas width =1500 ความสูง =750></canvas> <img id=img src=https://s3.imgsha.com/2019/04/22/light.png> <script> var ctx = document.getElementById('canvas').getContext('2d'); var img = document.getElementById('img'); var เปอร์เซ็นต์ = { เริ่มต้น: [400, 200] จุด: [ 300, 100], สิ้นสุด: [100, 400], แผนก: 'ข้อมูล 1', ค่า: 4321 } ฟังก์ชัน init(){ เปอร์เซ็นต์ = 0; // รีเซ็ตกระบวนการแต่ละครั้งที่วาด (); } function Draw(){ ctx.clearRect(0, 0, 1500, 750); // ล้างแคนวาสแต่ละครั้ง ctx. strokeStyle = ' # ffffff'; // ตั้งค่ารูปแบบเส้น DrawCurvePath (data.start, data.point, data.end, เปอร์เซ็นต์); เปอร์เซ็นต์ += 0.8; // เมื่อกระบวนการเพิ่มขึ้น สิ่งนี้จะควบคุมความเร็วของแอนิเมชั่นถ้า (เปอร์เซ็นต์ <= 100) { //เรียกต่อไปหากวาดไม่เสร็จ หากวาดเสร็จแล้ว ความคืบหน้าจะถูกรีเซ็ต requestAnimationFrame(draw); }else{ init() } } /... } ฟังก์ชั่น quadraticBezier( p0, p1, p2, t) { //... } </script></body></html>
แอนิเมชั่นก็ออกมา
ดังที่กล่าวไว้ก่อนหน้านี้ พารามิเตอร์ point
ในฟังก์ชัน drawCurvePath(start, point, end, percent)
ไม่ใช่จุดเฉพาะของความโค้ง แต่เป็นทิศทางทั่วไป
มาดูสถานการณ์เมื่อ point
เปลี่ยนเป็น [200,200]
กัน
หากคุณต้องการบรรลุเอฟเฟกต์ของการล้ม คุณต้องเพิ่มเอฟเฟกต์ไล่ระดับสีให้กับเส้นจากสูงไปต่ำ จากไกลไปใกล้
/** * สร้างการไล่ระดับสีเชิงเส้น* @param {Array<number>} จุดเริ่มต้น* @param {Array<number>} จุดโค้ง* @param {Array<number>} จุดสิ้นสุด จุดสิ้นสุด* @param {number} การวาดภาพ ความคืบหน้า ( 0-1) */function createLinearGradient(start,end,startColor,endColor){ var lineGradient = ctx.createLinearGradient(...start, ...end); lineGradient.addColorStop(0, startColor); // lineGradient.addColorStop(0.3, '#fff'); lineGradient.addColorStop(1, endColor); // ฟังก์ชันการวาดจำเป็นต้องมีการปรับฟังก์ชันบางอย่าง () {// ctx. strokeStyle = '#ffffff'; ctx. strokeStyle = createLinearGradient(data.start, data.end, 'rgba(255,255,255,.2)', '#fff' ); //...}
สำหรับรายละเอียดเกี่ยวกับการไล่ระดับสีแคนวาส โปรดดูที่ MDN
รัศมีหัว หากต้องการเพิ่มรัศมีส่วนหัว คุณต้องวาดวงกลมและตั้งค่าการไล่ระดับสีแบบรัศมี ใช้ฟังก์ชัน drawCurvePath
เพื่อรับ x, y และรีเซ็ตตำแหน่งของวงกลม
ฟังก์ชั่น createHeadLight(x,y){ ctx.beginPath(); //สร้างการไล่ระดับสีแบบรัศมี var radialGradient = ctx.createRadialGradient(x, y, 0, x, y, 20); )); radialGradient.addColorStop(.2, rgba(255,255,255,.8)); radialGradient.addColorStop(1, โปร่งใส); ctx.fillStyle = radialGradient; // วาดวงกลม ctx.arc(x, y, 20, 0, 2 * คณิตศาสตร์ .PI เท็จ); ctx.fill();}//ฟังก์ชัน DrawCurvePath ต้องการฟังก์ชันการปรับเปลี่ยนบางอย่าง DrawCurvePath(เริ่มต้น, จุด, สิ้นสุด, เปอร์เซ็นต์){ //... ctx. stroke(); // Stroke createHeadLight(x,y) // Draw วงกลมเหมือนกับการวาดความถี่เส้น}
สำหรับรายละเอียด arc
สำหรับการวาดวงกลม โปรดดูที่ MDN
การเพิ่มข้อความจะคล้ายกับการเพิ่มรัศมีส่วนหัว ทั้งสองใช้ฟังก์ชัน drawCurvePath
เพื่อรับ x, y และรีเซ็ตตำแหน่งของบล็อกข้อความ
/** * สร้างข้อความ* @param {String} ข้อมูลแผนก* @param {Number} data* @param {Number} พิกัดแกน x* @param {Number} พิกัดแกน y*/ฟังก์ชั่น DrawText (แผนก, ค่า, x, y) { ctx.fillStyle = '#fff' ctx.font = 22px Microsoft Yahei; ctx.fillText(แผนก, x + 30, y + 20); // เพื่อสร้างข้อความที่มุมขวาล่างของรัศมี x แกน y จะต้องถูกชดเชยด้วยระยะทาง var width = ctx.measureText(value).width; //รับความกว้าง ของข้อความ ctx.fillStyle = createLinearGradient([x + 30, 0], //ช่วงการเรนเดอร์ของแกน x ไล่ระดับสีของข้อความคือ [x+30,x+30+ความกว้างข้อความ], [x + 30 + ความกว้าง 0], //ที่นี่ y ถูกตั้งค่าเป็น 0 เนื่องจากไม่มี API สำหรับการรับความสูงของข้อความ การเขียน 0 ก็เป็นที่ยอมรับเช่นกัน '#fffd00', '#ff6d00' ); 50 ); } //ฟังก์ชัน DrawCurvePath ต้องการฟังก์ชันการปรับเปลี่ยนบางอย่าง DrawCurvePath(เริ่มต้น, จุด, สิ้นสุด, เปอร์เซ็นต์, แผนก, ค่า) { //... createHeadLight(x,y) DrawText(แผนก, ค่า, x, y) }เพิ่มข้อความและรูปภาพที่ตำแหน่งสิ้นสุดหลังจากภาพเคลื่อนไหวเสร็จสิ้น
โปรดทราบว่าเมื่อเพิ่มข้อความและรูปภาพหลังจากแอนิเมชั่นเสร็จสิ้น คุณจะต้องทำความสะอาดผืนผ้าใบทันทีหลังจากแอนิเมชั่นเส้นโค้งเสร็จสิ้น จากนั้นจึงเพิ่มข้อความและรูปภาพ
/** * สร้างรูปภาพ* @param {Number} พิกัดแกน x* @param {Number} พิกัดแกน y*/ฟังก์ชั่น DrawImg(x, y) { ctx.drawImage(img, x - img.width / 2, y - img.height); }//ฟังก์ชันการวาดจำเป็นต้องมีการปรับเปลี่ยนบางอย่าง Draw(){ //... if (เปอร์เซ็นต์ <= 100) { requestAnimationFrame(draw); }else{ ctx.clearRect(0, 0, 1500, 750); //ล้างแคนวาสทันทีหลังจากแอนิเมชั่นเส้นโค้งเสร็จสิ้น DrawText(data.department, //Render text data.value, data.end[0], data .end[1 ]) DrawImg(data.end[0], data.end[1]) //เรนเดอร์รูปภาพ setTimeout(function(){ //วาดใหม่ init() หลังจาก 2000ms },2000) -เสร็จ
รหัสที่สมบูรณ์ของตัวอย่างนี้
รหัสที่สมบูรณ์ของตัวอย่างในภาพแรกของบทความ
บทความอ้างอิง: ใช้ Canvas เพื่อวาดแอนิเมชั่นเส้นโค้ง - ความเข้าใจเชิงลึกเกี่ยวกับเส้นโค้ง Bezier
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network