قبل أن نتمكن من البدء في الرسم ، نحتاج إلى التحدث عن شبكة قماش أو تنسيق مساحة . كان قالب HTML في الصفحة السابقة عنصر قماش 150 بكسل و 150 بكسل. لقد رسمت هذه الصورة مع الشبكة الافتراضية المتراكبة. عادةً وحدة واحدة في الشبكة تتوافق مع 1 بكسل على القماش. يتم وضع أصل هذه الشبكة في الركن الأيسر العلوي (إحداثي (0،0)). يتم وضع جميع العناصر بالنسبة إلى هذا الأصل. لذلك يصبح موضع الزاوية العلوية اليسرى من المربع الأزرق X بكسل من اليسار والبكسل y من الأعلى (إحداثيات (x ، y)). في وقت لاحق في هذا البرنامج التعليمي ، سنرى كيف يمكننا ترجمة الأصل إلى موضع مختلف ، وتدوير الشبكة وحتى قم بتوسيع نطاقه. في الوقت الحالي ، سنلتزم بالافتراضي.
قبل أن نبدأ حقًا ، نحتاج إلى استكشاف الشبكة أو تنسيق مساحة القماش. يوجد ارتفاع 150 بكسل و 150 بكسل في قالب HTML في الصفحة السابقة. أتراكب الشبكة الافتراضية على الشاشة ، كما هو موضح في الصورة على اليمين. عادة ما تتوافق خلية واحدة من الشبكة مع بكسل واحد على القماش. يتم وضع أصل الشبكة في الزاوية اليسرى العليا (إحداثيات (0،0)). مواقع جميع الكائنات في الصورة هي نسبة إلى هذا الأصل. وبهذه الطريقة ، فإن موضع المربع الأزرق في الزاوية اليسرى العلوية هو X بكسل من اليسار والبكسل y من الجانب العلوي (الإحداثيات (x ، y)). في البرنامج التعليمي التالي ، سوف نتعلم كيفية تحريك الأصل وتدوير الشبكة وتوسيع نطاقها. ولكن الآن سوف نستخدم الحالة الافتراضية.
على عكس SVG ، يدعم القماش فقط شكلًا بدائيًا واحدًا - مستطيلات. يجب إنشاء جميع الأشكال الأخرى من خلال الجمع بين مسار واحد أو أكثر. محظوظ ، لدينا مجموعة من وظائف رسم المسار مما يجعل من الممكن تكوين أشكال معقدة للغاية.
على عكس SVG ، تدعم القماش فقط شكلًا أساسيًا واحدًا - مستطيل ، لذلك تتكون الأشكال الأخرى من مسار واحد أو أكثر. لحسن الحظ ، هناك مجموعة من وظائف رسم المسار التي تسمح لنا برسم أشكال معقدة إلى حد ما.
أولاً دعونا نلقي نظرة على المستطيل. هناك ثلاث وظائف ترسم مستطيلات على القماش:
دعونا نلقي نظرة أولاً على المستطيل. هناك ثلاث وظائف لرسم المستطيلات:
FillRect (x ، y ، العرض ، الارتفاع): يرسم مستطيل مملوء strokerect (x ، y ، العرض ، الارتفاع): يرسم مخططًا مستطيلًا ClearRect (X ، Y ، العرض ، الارتفاع): مسح المنطقة المحددة ويجعلها شفافة تمامًاكل من هذه الوظائف الثلاث تأخذ نفس المعلمات. حدد x و y الموضع على القماش (نسبة إلى أصل) الزاوية العلوية اليسرى من المستطيل. العرض والارتفاع واضح جدا. دعونا نرى هذه الوظائف في العمل.
يقبلون جميعًا أربعة معلمات ، تحدد x و y موضع الزاوية اليسرى العلوية للمستطيل (نسبة إلى الأصل) ، والعرض والارتفاع هما عرض وارتفاع المستطيل. حسنًا ، دعنا نواجه بعض المعارك العملية.
فيما يلي وظيفة Draw () من الصفحة السابقة ، لكن الآن أضفت الوظائف الثلاث أعلاه.
فيما يلي وظيفة Draw () في القالب في الصفحة السابقة ، ولكن تتم إضافة الوظائف الثلاثة أعلاه.
عرض المثال
دالة draw () {var canvas = document.getElementById ('Tutorial') ؛ if (canvas.getContext) {var ctx = canvas.getContext ('2d') ؛ CTX.FillRect (25،25،100،100) ؛ CTX.ClearRect (45،45،60،60) ؛ CTX.StrokeCt (50،50،50،50) ؛ }}يجب أن تبدو النتيجة شيئًا مثل الصورة على اليمين. تُوجه وظيفة FillRect مربعًا أسود 100 × 100 بكسل كبير. تزيل وظيفة ClearRect مربع 60 × 60 بكسل من المركز ، وأخيراً ترسم Strokerect مخططًا مستطيلاً 50 × 50 بكسل داخل المربع الذي تم تطهيره. في الصفحات التالية ، سنرى طريقتين بديلين لوظيفة ClearRect ، وسنرى أيضًا كيفية تغيير نمط اللون والسكتة الدماغية للأشكال المقدمة.
يجب أن تكون النتيجة هي نفسها على اليمين. تقوم وظيفة FillRect برسم مستطيل أسود كبير (100x100) ، وتمسح وظيفة ClearRect المربع بحجم 60 × 60 في الوسط ، ثم تحدد وظيفة strokerect حدود مستطيل 50 × 50 في المساحة التي تم مسحها. في الصفحة التالية ، سنرى طريقتين أخريين مشابهة لوظيفة ClearRect ، وكذلك كيفية تغيير الملء واللون الحدودي للشكل.
على عكس وظائف المسار التي سنراها في القسم التالي ، ترسم جميع وظائف المستطيل الثلاث على الفور إلى اللوحة.
على عكس وظيفة المسار في القسم التالي ، ستنعكس تأثيرات هذه الوظائف الثلاث على الفور على قماش.
لصنع الأشكال باستخدام المسارات ، نحتاج إلى بضع خطوات إضافية.
على عكس رسم مستطيل ، يتطلب رسم المسار بعض الخطوات الإضافية.
BeginPath () Closepath () سكتة دماغية () يملأ ()الخطوة الأولى لإنشاء مسار هي استدعاء طريقة البداية. داخليًا ، يتم تخزين المسارات كقائمة من المسارات الفرعية (الخطوط ، الأقواس ، إلخ) التي تشكل شكلًا. في كل مرة تسمى هذه الطريقة ، يتم إعادة تعيين القائمة ويمكننا البدء في رسم أشكال جديدة.
الخطوة الأولى هي إنشاء مسار مع BeginPath. في الذاكرة ، يتم تخزين المسارات في شكل مجموعة من المسارات الفرعية (الخطوط ، الأقواس ، إلخ) ، والتي تشكل رسمًا بيانيًا. في كل مرة يتم فيها استدعاء BeginPath ، يتم إعادة تعيين مجموعة SubPath ويمكن رسم رسم بياني جديد.
الخطوة الثانية هي استدعاء الطرق التي تحدد بالفعل المسارات المراد رسمها. سنرى هذه قريبا.
الخطوة الثانية هي رسم جزء من المسار ، الذي سنراه قريبًا.
تتمثل الخطوة الثالثة ، والخطوة الاختيارية ، في استدعاء طريقة ClosePath. تحاول هذه الطريقة إغلاق الشكل عن طريق رسم خط مستقيم من النقطة الحالية إلى البداية. إذا كان الشكل قد تم إغلاقه بالفعل أو لم يكن هناك سوى نقطة واحدة في القائمة ، فإن هذه الوظيفة لا تفعل شيئًا.
والخطوة الثالثة هي استدعاء طريقة ClosePath ، والتي ستحاول توصيل نقطة النهاية الحالية بنقطة النهاية البداية بخط مستقيم لإغلاق المسار ، ولكن إذا كان الرسم البياني مغلقًا بالفعل أو لم يكن هناك سوى نقطة واحدة ، فلن تفعل شيئًا. هذه الخطوة ليست ضرورية.
ستكون الخطوة الأخيرة هي استدعاء أساليب السكتة الدماغية و/أو ملء. استدعاء واحدة من هذه سوف ترسم في الواقع الشكل إلى قماش. يتم استخدام السكتة الدماغية لرسم شكل محدد ، بينما يتم استخدام التعبئة لطلاء شكل صلب.
الخطوة الأخيرة هي استدعاء طريقة السكتة الدماغية أو ملء ، وفي هذا الوقت ، يتم رسم الرسم البياني فعليًا على القماش. السكتة الدماغية هي الحدود التي ترسم الشكل ، وسوف تملأها بشخصية صلبة.
ملاحظة: عند استدعاء طريقة التعبئة ، سيتم إغلاق أي أشكال مفتوحة تلقائيًا وليس من الضروري استخدام طريقة ClosePath. ملاحظة: عندما يتم استدعاء التعبئة ، سيتم إغلاق المسار المفتوح تلقائيًا دون استدعاء ClosePath.رمز الرسم البسيط (مثلث) سيبدو شيئًا كهذا.
رمز رسم شخصية بسيطة (مثل مثلث) كما يلي.
ctx.beginpath () ؛ ctx.moveto (75،50) ؛ ctx.lineto (100،75) ؛ ctx.lineto (100،25) ؛
وظيفة واحدة مفيدة للغاية ، والتي لا ترسم أي شيء بالفعل ، ولكنها جزء من قائمة المسار الموضحة أعلاه ، هي وظيفة Moveto. من المحتمل أن تفكر في هذا على أفضل وجه على أنه رفع قلمًا أو قلم رصاص من بقعة واحدة على قطعة من الورق ووضعه في اليوم التالي.
Moveto هي طريقة مفيدة للغاية. على الرغم من أنه لا يمكن استخدامه لرسم أي شيء ، إلا أنه جزء من طريقة عملية لرسم المسارات. يمكنك التفكير في الأمر كعملية لرفع القلم ونقله من نقطة إلى أخرى.
Moveto (x ، y)تأخذ وظيفة Moveto وسيطتين - X و Y ، - وهما إحداثيات نقطة البداية الجديدة.
يقبل x و y (مواضع إحداثيات جديدة) كمعلمات.
عند تهيئة اللوحة القماشية أو يتم استدعاء طريقة BeginPath ، يتم ضبط نقطة البداية على الإحداثيات (0،0). في معظم الحالات ، سنستخدم طريقة Moveto لوضع نقطة البداية في مكان آخر. يمكننا أيضًا استخدام طريقة Moveto لرسم مسارات غير متصلة. ألق نظرة على الوجه المبتسم على اليمين. لقد قمت بتمييز الأماكن التي استخدمت فيها طريقة Moveto (الخطوط الحمراء).
عند تهيئة القماش أو يتم استدعاء PTHONDPART ، يكون إعداد إحداثيات البدء هو الأصل (0،0). في معظم الحالات ، نستخدم طريقة Moveto لنقل إحداثيات البداية إلى أماكن أخرى ، أو لرسم مسارات متقطعة. انظر إلى الوجه المبتسم على اليمين ، الخط الأحمر هو مسار التحرك باستخدام Moveto.
لتجربة هذا بنفسك ، يمكنك استخدام مقتطف الرمز أدناه. ما عليك سوى الصق في وظيفة السحب التي رأيناها في وقت سابق.
جرب الكود التالي وقم بصقه في وظيفة السحب التي استخدمتها من قبل لرؤية التأثير.
CTX.BeginPath () ؛ CTX.ARC (75،75،50،0 ، Math.pi*2 ، true) ؛ // Outer Circuitx.Moveto (110،75) ؛ CTX.ARC (75،75،35،0 ، Math.PI ، false) ؛ // الفم (في اتجاه الساعة) ctx.moveto (65،65) ؛ ctx.arc (60،65،5،0 ، Math.Pi*2 ، true) ؛ // eyectx.moveto (95،65) ؛ ctx.arc (90،65،5،0 ، Math.Pi*2 ، true) ؛ // eyectx.stroke () ؛ملاحظة : قم بإزالة طرق Moveto لرؤية خطوط التوصيل. ملاحظة : للحصول على وصف لوظيفة ARC وتبدو المعلمات أدناه. ملاحظة: يمكنك التعليق على طريقة Moveto لمراقبة الخطوط المتصلة. ملاحظة: يظهر استخدام طريقة ARC أدناه.
لرسم خطوط مستقيمة نستخدم طريقة LineTo.
نستخدم طريقة LineTo لرسم خطوط مستقيمة.
lineto (x ، y)تأخذ هذه الطريقة وسيطتين - X و Y ، - وهما إحداثيات نقطة نهاية الخط. تعتمد نقطة البداية على مسارات مرسومة سابقة ، حيث تكون نقطة نهاية المسار السابق هي نقطة الانطلاق لما يلي ، وما إلى ذلك. يمكن أيضًا تغيير نقطة البداية باستخدام طريقة Moveto.
تقبل طريقة LineTo الإحداثيات (x ، y) لنقطة النهاية كمعلمة. يعتمد تنسيق البدء على المسار السابق. نقطة نهاية المسار السابق هي نقطة انطلاق المسار الحالي. يمكن أيضًا تعيين إحداثيات البدء من خلال طريقة Moveto.
في المثال أدناه ، يتم رسم اثنين من المثلثين ، واحد ملء وواحد محدد. (يمكن رؤية النتيجة في الصورة على اليمين). أولاً ، يتم استدعاء طريقة BeginPath لبدء مسار شكل جديد. نستخدم بعد ذلك طريقة Moveto لنقل نقطة البداية إلى الموضع المطلوب. أسفل هذا الخطين يتم رسمهما يشكلان جانبين من المثلث.
المثال (كما هو موضح في الصورة على اليمين) هو مثلثتين ، واحد مليء بالألوان الصلبة وحافة واحدة مرسومة. أولاً ، استدعاء طريقة BeginPath لإنشاء مسار جديد ، ثم استخدم طريقة Moveto لنقل إحداثيات البداية إلى الموضع المطلوب ، ثم ارسم خطين مستقيمين لتشكيل جانبي المثلث.
ستلاحظ الفرق بين المثلث المملوء والضرب. هذا ، كما ذكر أعلاه ، لأنه يتم إغلاق الأشكال تلقائيًا عند ملء المسار. إذا كنا قد فعلنا هذا من أجل المثلث المضطرب ، لكان قد تم رسم سطرين فقط ، وليس مثلثًا كاملاً.
يمكنك أن تلاحظ الفرق بين مثلثات التعبئة والستروك. كما ذكر أعلاه ، سيتم إغلاق المسار باستخدام Fill تلقائيًا ، لكنه لن يكون بالسكتة الدماغية. إذا لم يتم إغلاق المسار ، فسيتم رسم جانبين فقط.
عرض المثال
. ctx.beginpath () ؛ ctx.moveto (125،125) ؛ ctx.lineto (125،45) ؛ ctx.lineto (45،125) ؛ ctx.closepath () ؛ ctx.stroke () ؛
لرسم الأقواس أو الدوائر نستخدم طريقة ARC. تصف المواصفات أيضًا طريقة Arcto ، والتي تدعمها Safari ولكن لم يتم تنفيذها في متصفحات Gecko الحالية.
نستخدم طريقة القوس لرسم الأقواس أو الدوائر. يتم تضمين طريقة Arcto أيضًا في الوصف القياسي. يتم دعم Safari حاليًا ، لكن المتصفحات المستندة إلى Gecko لم تنفذ بعد.
قوس (x ، y ، نصف قطرها ، startnangle ، indangle ، عكس اتجاه عقارب الساعة)تأخذ هذه الطريقة خمسة معلمات: X و Y هي إحداثيات مركز الدائرة. دائرة نصف قطرها هو التفسير الذاتي. تحدد معلمات STARTANGLE و ENDANGLE نقاط البداية والنهاية للقوس في RADIANS. يتم قياس زاوية البداية والإغلاق من المحور X. المعلمة عكس اتجاه عقارب الساعة هي قيمة منطقية والتي عندما ترسم القوس عكس اتجاه عقارب الساعة ، وإلا في اتجاه عقارب الساعة.
تقبل الطريقة خمسة معلمات: x ، y هي الإحداثيات المركزية ، والنصف القطر هو نصف القطر ، والبدء والصفنة هي الراديان البداية والنهاية (استنادًا إلى المحور السيني كمرجع) ، عكس اتجاه عقارب الساعة ، مما يعني عكس اتجاه عقارب الساعة ، وعلى مدار الساعة.
تحذير : في بناء BITA Firefox ، فإن المعلمة الأخيرة هي في اتجاه عقارب الساعة. سوف يدعم الإصدار النهائي الوظيفة كما هو موضح أعلاه. يجب تحديث جميع البرامج النصية التي تستخدم هذه الطريقة في شكلها الحالي بمجرد إصدار الإصدار النهائي.تحذير: في الإصدار التجريبي من Firefox ، فإن المعلمة الأخيرة هي في اتجاه عقارب الساعة ، والنسخة النهائية ليست كذلك. لذلك ، إذا كنت تقوم بالترقية من بيتا إلى التوزيع ، فأنت بحاجة إلى إجراء تغييرات مماثلة.
ملاحظة : يتم قياس الزوايا في وظيفة القوس في الراديان ، وليس الدرجات. لتحويل الدرجات إلى الراديان ، يمكنك استخدام تعبير JavaScript التالي: var radians = (Math.PI/180)*الدرجات.ملاحظة: الزاوية المستخدمة في طريقة القوس هي في وحدات من الراديان بدلاً من الدرجات. يمكن استخدام التحويل المباشر للدرجات والراديان مع هذا التعبير: var radians = (Math.PI/180)*درجات ؛.
المثال التالي أكثر تعقيدًا قليلاً من تلك التي رأيناها أعلاه. لقد رسمت 12 أقواس مختلفة جميعها بزوايا وملء مختلفة. إذا كنت قد كتبت هذا المثال تمامًا مثل الوجه المبتسم أعلاه ، فقد أصبح هذا أولاً قائمة طويلة جدًا من العبارات وثانياً ، عند رسم الأقواس ، سأحتاج إلى معرفة كل نقطة انطلاق واحدة. بالنسبة للأقواس التي تبلغ 90 و 180 و 270 درجة ، مثل تلك التي استخدمتها هنا ، لن يكون هذا الأمر مشكلة كبيرة ، ولكن بالنسبة إلى تلك الأكثر تعقيدًا ، يصبح هذا الأمر صعبًا للغاية.
هذا المثال أكثر تعقيدًا مما رأيته من قبل. يرسم 12 أقواس مختلفة مع زوايا مختلفة وحالات ملء. إذا رسمت هذه الأقواس بالطريقة أعلاه لرسم الوجوه المبتسمة ، فستكون جزءًا كبيرًا من الكود ، وعند رسم كل قوس ، أحتاج إلى معرفة موضع مركز الدائرة. على سبيل المثال ، تعتبر أقواس رسم 90 و 180 و 270 درجة هنا مشكلة أيضًا. إذا كانت الرسومات أكثر تعقيدًا ، فكلما كان تنفيذها أكثر صعوبة.
الاثنان للحلقات هي للحلق من خلال صفوف وأعمدة الأقواس. لكل قوس أبدأ مسارًا جديدًا باستخدام BeginPath. أدناه هذا كتبت جميع المعلمات كمتغيرات ، لذلك من الأسهل قراءة ما يجري. عادة سيكون هذا مجرد بيان واحد. يجب أن تكون إحداثيات X و Y واضحة بما فيه الكفاية. يتم إصلاح نصف القطر والبدء. يبدأ Endangle من 180 درجة (العمود الأول) ويتم زيادة مع خطوات 90 درجة لتشكيل دائرة كاملة (العمود الأخير). ينتج عن بيان المعلمة في اتجاه عقارب الساعة في الصف الأول والثالث يتم رسمها كقوس في اتجاه عقارب الساعة والصف الثاني والرابع كقوس عكس اتجاه عقارب الساعة. أخيرًا ، يجعل البيان IF أقواس النصف العلوي والأقواس المملوءة بالنصف السفلي.
هنا نستخدم اثنين للحلقات لرسم أقواس مع صفوف وأعمدة متعددة. يقوم كل قوس بإنشاء مسار جديد باستخدام طريقة BeginPath. بعد ذلك ، من أجل القراءة والتفاهم السهلة ، كتبت جميع المعلمات في أشكال متغيرة. من الواضح أن X و Y هما الإحداثيات المركزية. يتم إصلاح كل من نصف القطر والبدء ، ويبدأ ENDANGLE من نصف دائرة 180 درجة وزيادات إلى الدائرة في الوضع 90 درجة. يعتمد عكس اتجاه عقارب الساعة على عدد الصفوف الغريبة وحتى. أخيرًا ، يتم استخدام البيان IF للحكم على أن أول سطرين يتم عرضهما كحواف ، ويتم ملء آخر سطرين بالتأثير.
لـ (i = 0 ؛ i <4 ؛ i ++) {for (j = 0 ؛ j <3 ؛ j ++) {ctx.beginpath () ؛ var x = 25+j*50 ؛ // x إحداثي var y = 25+i*50 ؛ // y إحداثيات var radius = 20 ؛ // arc radius var startNangle = 0 ؛ // نقطة انطلاق على دائرة var endangle = math.pi+(math.pi*j)/2 ؛ // نقطة نهاية على دائرة var anticlockwise = i ٪ 2 == 0؟ خطأ: صحيح // في اتجاه عقارب الساعة أو CTX.ARC (x ، y ، نصف قطرها ، بداية ، indangle ، عكس اتجاه عقارب الساعة) ؛ if (i> 1) {ctx.fill () ؛ } آخر {ctx.stroke () ؛ }}}النوع التالي من المسارات المتاحة هو منحنيات Bézier ، المتوفرة في التنوع المكعب والتربيعي. وتستخدم هذه بشكل عام لرسم الأشكال العضوية المعقدة.
المسار التالي الذي سيتم تقديمه هو منحنى Bezier ، والذي يمكن أن يكون في أشكال تربيعية ومكعبة ، ويستخدم عمومًا لرسم الأشكال المعقدة والمنتظمة.
QuadraticCurveto (CP1X ، CP1Y ، X ، Y) // Broken in Firefox 1.5 (انظر العمل أدناه) Beziercurveto (CP1X ، CP1Y ، CP2X ، CP2Y ، X ، Y)يمكن وصف الفرق بين هذه بشكل أفضل باستخدام الصورة على اليمين. إن منحنى Bézier التربيعي له بداية ونقطة نهاية (نقاط زرقاء) ونقطة تحكم واحدة فقط (نقاط حمراء) بينما يستخدم منحنى Bézier مكعب نقطتين تحكم.
انظر الشكل على اليمين للفرق بين سطرين من الكود أعلاه. لديهم جميعًا نقطة انطلاق ونقطة نهاية (نقطة زرقاء في الشكل) ، لكن منحنى Bezier التربيعي يحتوي على نقطة تحكم واحدة فقط (أحمر)) ومنحنى Bezier المكعب لهان.
معلمات X و Y في كلتا الطريقتين هي إحداثيات نقطة النهاية. CP1X و CP1Y هما إحداثيات نقطة التحكم الأولى ، و CP2X و CP2Y هي إحداثيات نقطة التحكم الثانية.
المعلمات X و Y هما إحداثيات نقطة النهاية ، CP1X و CP1Y هي إحداثيات نقطة التحكم الأولى ، و CP2X و CP2Y هي الثانية.
يمكن أن يكون استخدام منحنيات Bézier التربيعية والمكعبة أمرًا صعبًا للغاية ، لأنه على عكس برامج رسم المتجهات مثل Adobe Illustrator ، ليس لدينا ردود فعل مرئية مباشرة حول ما نقوم به. هذا يجعل من الصعب جدا رسم الأشكال المعقدة. في المثال التالي ، سنقوم برسم بعض الأشكال العضوية البسيطة ، ولكن إذا كان لديك الوقت ، والأهم من ذلك كله ، يمكن إنشاء الصبر ، وأشكال أكثر تعقيدًا.
يعد استخدام منحنيات Bezier التربيعية والمكعبة أمرًا صعبًا للغاية لأنه لا توجد ردود فعل مرئية فورية كما في برنامج رسم المتجه Adobe Illustrator. لأنه أكثر إثارة للقلق لرسم رسومات معقدة. ولكن إذا كان لديك وقت والأهم من ذلك ، يمكنك رسم أي رسومات معقدة. دعنا نرسم شخصية بسيطة ومنتظمة أدناه.
لا يوجد شيء صعب للغاية في هذه الأمثلة. في كلتا الحالتين ، نرى سلسلة من المنحنيات يتم رسمها والتي تؤدي أخيرًا إلى شكل كامل.
هذه الأمثلة بسيطة نسبيا. كل ما نرسمه هو رسومات كاملة.
// منحنيات رباعية examplex.beginpath () ؛ 120،30،125) ؛ CTX.QuadraticCurveto (60،120،65،100) ؛ CTX.QuadraticCurveto (125،100،125،62.5) ؛
من الممكن تحويل أي منحنى Bézier التربيعي إلى منحنى Bézier مكعب عن طريق حساب كل من نقاط التحكم Bézier المكعبة من نقطة التحكم في Bézier التربيعية ، على الرغم من أن العكس غير صحيح. من الممكن تحويل دقيق لمنحنى Bézier المكعب إلى منحنى Bézier التربيعي فقط إذا كان المصطلح المكعب صفرًا ، ويتم استخدام طريقة التقسيم الفرعية بشكل أكثر شيوعًا لتقريب Bézier مكعب باستخدام منحنيات Bézier التربيعية المتعددة.
من خلال الحساب ، يمكن اشتقاق نقطتين تحكمين للمنحنى المكعب المقابل من نقطة تحكم واحدة من المنحنى التربيعي ، لذلك من الممكن تحويل التربيع إلى مكعب ، ولكن على خلاف ذلك. من الممكن التحويل إلى منحنى Bezier التربيعي فقط إذا كان المصطلح المكعب في معادلة مكعبة صفراً. بشكل عام ، يمكن استخدام منحنيات تربيعية متعددة لتقريب محاكاة منحنيات بيزيير المكعبة من خلال خوارزميات التقسيم الفرعي.
// bezier curves examplex.beginpath () ؛ ctx.moveto (75،40) ؛ ctx.beziercurveto (75،37،70،25،50،25) ؛ ، 102،75،120) ؛ ctx.beziercurveto (110،102،130،80،130،62.5) ؛
هناك خطأ في تنفيذ Firefox 1.5 لـ Quadatriccurveto (). لا يرسم منحنى تربيعي ، لأنه يطلق فقط على مكالمات المنحنى المكعب Beziercurveto () ، وتكرار إحداثيات نقطة التحكم التربيعية (X ، Y) مرتين. لهذا السبب سوف QuadraticCurveto () نتائج غير صحيحة. إذا كنت بحاجة إلى استخدام QuadraticCurveto () ، فيجب عليك تحويل منحنى Bézier التربيعي إلى منحنى Bézier مكعب ، حتى تتمكن من استخدام طريقة Beziercurveto () العاملة.
في Firefox 1.5 ، يكون تنفيذ adadatriccurveto () عربات التي تجرها الدواب. لا يرسم منحنى تربيعي مباشرة ، ولكن يطلق على Beziercurveto () ، حيث كلا نقطتين التحكم هما نقطة التحكم الفردية للمنحنى التربيعي. لذلك ، فإنه يرسم منحنيات غير صحيحة. إذا كان عليك استخدام QuadraticCurveto () ، فأنت بحاجة إلى تحويل المنحنى التربيعي إلى قوة مكعب بنفسك ، حتى تتمكن من استخدام طريقة Beziercurveto ().
var currentx ، currenty ؛ // ضبط على آخر x ، y تم إرسالها إلى lineto/moveto/beziercurveto أو quadraticcurvetofixed () function QuadraticCurvetofixed (cpx ، cpy ، x ، y) Beziercurveto ()). QP1 هي نقطة التحكم في المنحنى الرباعي (هذه هي CPX ، CPY التي كنت قد أرسلتها إلى QuadraticCurveto ()). QP2 هي نقطة إنهاء المنحنى التربيعي (هذه هي الوسائط x ، y التي كنت قد أرسلتها إلى QuadraticCurveto ()). سنقوم بتحويل هذه النقاط إلى حساب نقطتي التحكم المكعبة المطلوبة (نقاط البداية/النهاية هي نفسها لكل من المنحنيات التربيعية والمكعبة. المعادلات لنقطتي التحكم المكعبة هي: CP0 = QP0 و CP3 = QP2 CP1 = QP0 + 2/3 *(QP1-QP0) و y لكل نقطة بشكل منفصل أ) استبدل متغيرات qp0x و qp0y بـ currentx و currenty (والتي يجب عليك * * تخزينها لكل moveto/lineto/beziercurveto) b) استبدال متغيرات qp1x و qp1y مع cpx و cpy (والتي كنا قد انتقلنا إلى pultraticcurveto) c) استبدال qp2x مع qp2y مع yplabling مع x و ys. الذي يتركنا مع: */ var cp1x = currentx + 2.0/ 3.0 *(cpx - currentx) ؛ var cp1y = currenty + 2.0/3.0*(cpy - currenty) ؛ var cp2x = cp1x + (x - currentx) /3.0 ؛ var cp2y = cp1y + (y - currenty) /3.0 ؛ // والآن استدعاء منحنى bezier المكعب لتعمل beziercurveto (CP1X ، CP1Y ، CP2X ، CP2Y ، X ، Y) ؛ CurrentX = x ؛ currenty = y ؛}
إلى جانب الطرق الثلاثة التي رأيناها أعلاه والتي ترسم الأشكال المستطيلة مباشرة إلى القماش ، لدينا أيضًا طريقة مستقيمة تضيف مسارًا مستطيلًا إلى قائمة المسار.
بالإضافة إلى الطرق الثلاثة المذكورة أعلاه والتي يمكن أن ترسم المستطيلات مباشرة ، لدينا أيضًا طريقة مستقيمة تستخدم لرسم مسارات المستطيل.
المستقيم (x ، y ، العرض ، الارتفاع)هذه الطريقة تأخذ أربع وسيطات. تحدد معلمات X و Y إحداثيات الزاوية اليسرى العلوية من المسار المستطيل الجديد. يحدد العرض والارتفاع عرض وارتفاع المستطيل.
يقبل أربعة معلمات ، X و Y هما إحداثياتها اليسرى العليا ، والعرض والارتفاع هما عرضه وارتفاعه.
عند تنفيذ هذه الطريقة ، يتم استدعاء طريقة MOVETO تلقائيًا باستخدام المعلمات (0،0) (أي إعادة تعيين نقطة البداية إلى موقعها الافتراضي).
عندما يتم استدعاؤه ، سيتم استدعاء طريقة Moveto تلقائيًا ، لذلك يتم استعادة إحداثيات البدء إلى الأصل.
في جميع الأمثلة على هذه الصفحة ، استخدمت نوعًا واحدًا فقط من وظائف المسار لكل شكل. ومع ذلك ، لا يوجد أي الحد من كمية أو نوع المسارات التي يمكنك استخدامها لإنشاء شكل. لذلك في هذا المثال الأخير ، حاولت الجمع بين جميع وظائف المسار لصنع مجموعة من شخصيات اللعبة الشهيرة للغاية.
تستخدم الأمثلة المستخدمة أعلاه نوعًا واحدًا فقط من المسار ، بالطبع لن يحد القماش من عدد أنواع المسارات المستخدمة. لذلك ، دعونا نلقي نظرة على مسار hodgepodge.
لن أجري هذا البرنامج النصي الكامل ، ولكن أهم الأشياء التي يجب ملاحظتها هي الوظيفة المستديرة واستخدام خاصية FillStyle. يمكن أن يكون مفيدًا للغاية وتوفير الوقت لتحديد وظائفك الخاصة لرسم أشكال أكثر تعقيدًا. في هذا البرنامج النصي ، كان سيستغرق الأمر ضعف عدد خطوط التعليمات البرمجية كما فعلت الآن.
سوف ننظر إلى خاصية FillStyle في عمق أكبر في هذا البرنامج التعليمي. أنا هنا أستخدمه لتغيير لون التعبئة من الأسود الافتراضي إلى الأبيض والعودة مرة أخرى.
في المثال كله ، أبرز شيء هو استخدام وظيفة المستديرة وإعدادات خاصية FillStyle. الوظائف المخصصة مفيدة للغاية لتغليف رسم الرسومات المعقدة. باستخدام وظيفة مخصصة في هذا المثال يحفظ حوالي نصف الكود.
في الأمثلة التالية ، سوف نستكشف الاستخدام المتعمق لسمات FillStyle. فيما يلي استخدامه لتغيير لون التعبئة ، من الأسود الافتراضي ، إلى الأبيض ، ثم العودة إلى الأسود.
عرض المثال
دالة draw () {var ctx = document.getElementById ('canvas'). getContext ('2d') ؛ RoundedRect (CTX ، 12،12،150،150،15) ؛ RoundedRect (CTX ، 19،19،150،150،9) ؛ RoundedRect (CTX ، 53،53،49،33،10) ؛ RoundedRect (CTX ، 53،119،49،16،6) ؛ RoundedRect (CTX ، 135،53،49،33،10) ؛ RoundedRect (CTX ، 135،119،25،49،10) ؛ ctx.beginpath () ؛ CTX.ARC (37،37،13 ، MATH.PI/7 ، -MATH.PI/7 ، true) ؛ CTX.Lineto (31،37) ؛ ctx.fill () ؛ لـ (i = 0 ؛ i <8 ؛ i ++) {ctx.fillRect (51+i*16،35،4،4) ؛ } لـ (i = 0 ؛ i <6 ؛ i ++) {ctx.fillRect (115،51+i*16،4،4) ؛ } لـ (i = 0 ؛ i <8 ؛ i ++) {ctx.fillRect (51+i*16،99،4،4) ؛ } ctx.beginpath () ؛ CTX.Moveto (83،116) ؛ CTX.Lineto (83،102) ؛ CTX.Beziercurveto (83،94،89،88،97،88) ؛ CTX.Beziercurveto (105،88،111،94،111،102) ؛ CTX.LINETOTO (111،116) ؛ CTX.LINETETO (106.333،111.333) ؛ CTX.Lineteto (101.666،116) ؛ CTX.LINETOTO (97،111.333) ؛ CTX.LINETOTO (92.333،116) ؛ CTX.LINETETO (87.666،111.333) ؛ CTX.LINETOTO (83،116) ؛ ctx.fill () ؛ ctx.fillstyle = أبيض ؛ ctx.beginpath () ؛ CTX.Moveto (91،96) ؛ CTX.Beziercurveto (88،96،87،99،87،101) ؛ CTX.Beziercurveto (87،103،88،106،91،106) ؛ CTX.Beziercurveto (94،106،95،103،95،101) ؛ CTX.Beziercurveto (95،99،94،96،91،96) ؛ CTX.Moveto (103،96) ؛ CTX.Beziercurveto (100،96،99،99،99،101) ؛ CTX.Beziercurveto (99،103،100،106،103،106) ؛ CTX.Beziercurveto (106،106،107،103،107،101) ؛ CTX.Beziercurveto (107،99،106،96،103،96) ؛ ctx.fill () ؛ ctx.fillstyle = أسود ؛ ctx.beginpath () ؛ CTX.ARC (101،102،2،0 ، MATH.PI*2 ، true) ؛ ctx.fill () ؛ ctx.beginpath () ؛ CTX.ARC (89،102،2،0 ، Math.PI*2 ، True) ؛ ctx.fill () ؛ ctx.fill () ؛ CTX.ARC (89،102،2،0 ، Math.PI*2 ، True) ؛ ctx.fill () ؛ ctx.fill () ؛ } function oundedderect (ctx ، x ، y ، العرض ، الارتفاع ، نصف القطر) {ctx.beginpath () ؛ ctx.moveto (x ، y+radius) ؛ ctx.lineto (x ، y+height-radius) ؛ ctx.quadraticCurveto (x ، y+الارتفاع ، x+نصف قطرها ، y+الارتفاع) ؛ ctx.lineto (x+width-radius ، y+height) ؛ ctx.quadraticCurveto (x+عرض ، y+الارتفاع ، x+عرض ، y+radius) ؛ ctx.lineto (x+width ، y+radius) ؛ ctx.quadraticCurveto (x+width ، y ، x+width-radius ، y) ؛ CTX.Lineto (X+RADIUS ، Y) ؛ ctx.quadraticCurveto (x ، y ، x ، y+radius) ؛ CTX.Stroke () ؛}