أود أن أشارككم تأثير الصورة أدناه التي قمت بتنفيذها مؤخرًا.
إذا أردنا رسم الرسوم المتحركة للمنحنى أدناه
إذا قمت برسم خط قصير للاتصال في كل مرة، فإن الصورة أدناه مقسمة إلى خمسة أجزاء.
اقرأ عشر فقرات أخرى
إذا كان عدد المقاطع المقسمة كافيًا، فإن رسم قطعة واحدة في كل مرة سيبدو كمسار منحني.
منحنى بيزير التربيعي/** * الرسوم المتحركة لمنحنى بيزييه التربيعي* @param {Array<number>} بداية إحداثيات نقطة البداية* @param {Array<number>} إحداثيات نقطة الانحناء (أي نقطة التحول، وليس الإحداثيات الدقيقة، فقط اتجاه تقريبي) * @param {Array<number>} إحداثيات نقطة النهاية * @param {number} نسبة الرسم المئوية (0-100) */ function drawCurvePath(start, point, end, بالمائة){ ctx.beginPath(); // ابدأ في رسم الخطوط ctx.moveTo(start[0], start[1]); // حرك القلم إلى نقطة البداية for (var t = 0; t <= بالمائة / 100; t += 0.005 ) { // احصل على إحداثيات كل نقطة زمنية var x = QuadraticBezier(start[0], point[0], end[0], t); QuadraticBezier(start[1], point[1], end[1], t); ctx.lineTo(x, y); // ارسم خطًا مستقيمًا من النقطة الزمنية السابقة إلى النقطة الزمنية الحالية} ctx.stroke( ); //السكتة الدماغية} /** * معادلة منحنى بيزيير التربيعي* @param {Array<number>} نقطة بداية البداية* @param {Array<number>} نقطة انحناء* @param {Array<number>} نقطة نهاية النهاية * @param {number} تقدم الرسم (0-1) */ function QuadraticBezier(p0, p1, p2, t) { var k = 1 - t; return k * k * p0 + 2 * (1 - t) * t * ص1 + ر * ر * ص2 }
لمزيد من التفاصيل حول محتوى منحنى بيزيير، يرجى الرجوع إلى هذه المدونة
إلى رمز كامل
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, virtual-scale=1.0> <meta http-equiv=X-UA - المحتوى المتوافق = ie=edge> <title>الرسوم المتحركة لمنحنى بيزيير التربيعي</title> <style> body { الخلفية: #0f1632 } #canvas { border: 1px Solid #ccc; } #img { Display: none; <!--فقط قم بإخفاء الصورة مباشرة، وسيتم اقتباسها مباشرة لاحقًا--> } </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 وفية = 0; بداية: [400, 200], النقطة: [ 300، 100]، النهاية: [100، 400]، القسم: 'بيانات 1'، القيمة: 4321 } الدالة init(){ بالمائة = 0; // إعادة ضبط العملية في كل مرة draw(); } function draw(){ ctx.clearRect(0, 0, 1500, 750); // امسح اللوحة القماشية في كل مرة ctx.strokeStyle = ' # ffffff'; // تعيين نمط الخط drawCurvePath(data.start, data.point, data.end, بالمائة); // مع زيادة العملية، يتحكم هذا في سرعة الرسوم المتحركة if (percent <= 100) { // تابع الاتصال إذا لم يكتمل الرسم، وستتم إعادة تعيين التقدم requestAnimationFrame(draw); }else{ init() } } function drawCurvePath(start, point, end, بالمائة) / /... } الدالة 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 وإعادة تعيين موضع الدائرة.
function createHeadLight(x,y){ ctx.beginPath(); // إنشاء تدرج شعاعي var radialGradient = ctx.createRadialGradient(x, y, 0, x, y, 20); radialGradient.addColorStop(0, rgba(255,255,255, 1); )); radialGradient.addColorStop(.2, rgba(255,255,255,.8)); radialGradient.addColorStop(1,transparent); ctx.fillStyle = radialGradient;//ارسم دائرة ctx.arc(x, y, 20, 0, 2 *) الرياضيات .PI، كاذبة)؛ ctx.fill();}// تحتاج وظيفة drawCurvePath إلى بعض التعديلات function drawCurvePath(start, point, end, بالمائة){ //... ctx.stroke(); // Stroke createHeadLight(x,y) // Draw دائرة تمامًا مثل رسم خط التردد}
للحصول على تفاصيل arc
لرسم الدوائر، يرجى الرجوع إلى MDN
إن إضافة النص يشبه إلى حد كبير إضافة هالة الرأس. كلاهما يستخدم وظيفة drawCurvePath
للحصول على x وy وإعادة تعيين موضع كتلة النص.
/** * إنشاء نص* @param {String} بيانات القسم* @param {Number} بيانات* @param {Number} إحداثيات المحور السيني* @param {Number} إحداثيات المحور الصادي*/function drawText(department, value, x, y) { ctx.fillStyle = '#fff' ctx.font = 22px Microsoft Yahei; y + 20); // لجعل النص في الزاوية اليمنى السفلية من الهالة x، يجب إزاحة المحور y بمسافة معينة var width = ctx.measureText(value).width; للنص ctx.fillStyle = createLinearGradient([x + 30, 0], // نطاق العرض للمحور x لتدرج النص هو [x+30,x+30+text width], [x + 30 + width, 0]، // تم تعيين y هنا على 0 لأنه لا توجد واجهة برمجة تطبيقات للحصول على ارتفاع النص، كما أن كتابة 0 مقبولة '#fffd00', '#ff6d00' ); 50 ); } // تحتاج وظيفة drawCurvePath إلى بعض التعديلات function drawCurvePath(start, point, end, بالمائة, Department, value) { //... createHeadLight(x,y) drawText(department, value, x, y) }أضف نصًا وصورًا في موضع النهاية بعد اكتمال الرسوم المتحركة
يرجى ملاحظة أنه عند إضافة نص وصور بعد اكتمال الرسوم المتحركة، تحتاج إلى تنظيف اللوحة القماشية مباشرة بعد اكتمال الرسوم المتحركة المنحنية، ثم إضافة النص والصور.
/** * إنشاء صورة* @param {Number} إحداثي المحور السيني* @param {Number} إحداثي المحور الصادي*/function drawImg(x, y) { ctx.drawImage(img, x - img.width / 2, y - img.height); }// تحتاج وظيفة الرسم إلى بعض التعديلات draw(){ //... if (percent <= 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() بعد 2000 مللي ثانية },2000) } }ينهي
الكود الكامل لهذا المثال
الكود الكامل للمثال في الصورة الأولى للمقالة
مقالة مرجعية: استخدم اللوحة القماشية لرسم رسم متحرك لمنحنى - فهم متعمق لمنحنيات بيزييه
ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.