القماش في HTML5 لا يوفر مباشرة طريقة لرسم علامات القطع. فيما يلي ملخص للعديد من طرق الرسم. الأساليب المختلفة لها مزايا وعيوبها الخاصة ، ويتم اختيارها وفقًا للوضع. معلمات كل طريقة هي نفسها:
السياق هو كائن بيئة الرسم ثنائي الأبعاد ،
X هو الإحداثي الأفقي لمركز القطع الناقص.
y هو الإحداثي العمودي لمركز القطع الناقص.
A هو طول محور النصف الأفقي للقطع الناقص.
B هو طول المحور نصف العمودي للقطع الناقص.
طريقة معادلة المعلمةتستخدم هذه الطريقة المعادلات البارامترية للقطع الناقص لرسم القطع الناقص
.
// المعلمات x و y من الوظيفة هي مركز القطع الناقص ؛ A و B هما المحور نصف الأفقي للقطع الناقص ، على التوالي
// لا يمكن أن يكون طول المحور نصف العمودي 0 في نفس الوقت
// عيب هذه الطريقة هو أنه عندما يكون linwidth أوسع ويلات القطع الناقص الاغراء
// نهاية المحور الرئيسي للقطع الناقص الداخلية حادة ، ليست سلسة ، ولديها كفاءة منخفضة
وظيفة paramellipse (السياق ، x ، y ، a ، b)
{
// ماكس هو أكبر قيم المحور الرئيسي A و B.
// أقوم بزيادة 1/كحد أقصى لكل دورة ، مما يشير إلى الزيادة في الدرجة
// سيجعل هذا المسار (ARC) مرسومًا في كل حلقة قريبة من 1 بكسل
var step = (a> b)؟ 1 / a: 1 / b ؛
context.beginPath () ؛
context.moveto (x + a ، y) ؛ // ارسم من نقطة النهاية اليسرى للقطع الناقص
لـ (var i = 0 ؛ i <2 * math.pi ؛ i += الخطوة)
{
// معادلة المعلمة هي x = a * cos (i) ، y = b * sin (i) ،
// المعلمة هي I ، تشير إلى الدرجة (راديان)
context.lineto (x + a * math.cos (i) ، y + b * math.sin (i)) ؛
}
context.closepath () ؛
سياق. ضربة () ؛
} ؛
طريقة ضغط موحدةتستخدم هذه الطريقة مبدأ الضغط الموحد في الرياضيات لضغط الدائرة بشكل موحد في القطع الناقص ، والتي يمكن من الناحية النظرية الحصول على القطع الناقص القياسية. سيكون للرمز التالي مشاكل مع عرض خط غير متناسق. الحل هو رؤية تعليقات Simonleung في الطابق الخامس.
.
// الطريقة هي رسم الدائرة باستخدام طريقة القوس والجمع بين المقياس ل
// التحجيم في اتجاه المحور الأفقي أو العمودي (حتى الضغط)
// تصبح حافة القطع الناقص المرسومة في هذه الطريقة أكثر سمكًا لأن الحافة أقرب إلى نهاية المحور الرئيسي ، وعرض خط نهاية المحور الرئيسي أمر طبيعي
// كلما اقتربت الحافة من المحور الثانوي ، يكون التمرد والأرق القطع الناقص ، وحتى الانقطاع سبب. هذا هو نتيجة الحجم.
// هذا العيب هو في بعض الأحيان ميزة ، مثل عند التعبير عن التأثير ثلاثي الأبعاد للحلقة (هالة الكوكب)
// للحالة التي تكون فيها المعلمات A أو B 0 ، هذه الطريقة غير قابلة للتطبيق
وظيفة evencompellipse (السياق ، x ، y ، a ، b)
{
context.save () ؛
// حدد واحد أكبر من A و B كمعلمة نصف قطرها لطريقة القوس
var r = (a> b)؟ ج: ب ؛
var ratiox = a / r ؛ // نسبة قياس المحور الأفقي
var ratioy = b / r ؛ // نسبة قياس محور الأبعاد
context.scale (نسبة ، ratioy) ؛ // التحجيم (حتى الضغط)
context.beginPath () ؛
// ارسم عكس اتجاه عقارب الساعة من الطرف الأيسر من القطع الناقص
context.moveto ((x + a) / ratiox ، y / ratioy) ؛
conext.arc (x / ratiox ، y / ratioy ، r ، 0 ، 2 * math.pi) ؛
context.closepath () ؛
سياق. ضربة () ؛
context.restore () ؛
} ؛
طريقة منحنى Bezier المكعبة واحدةيعد رسم منحنى Bezier المكعب للقطع الناقص تقريبًا عند الرسم فعليًا ، ومن الناحية النظرية ، إنه أيضًا تقريب. ومع ذلك ، نظرًا لكفاءتها العالية ، غالبًا ما يتم استخدامها لرسم القطع في رسومات ناقلات الكمبيوتر ، لكنني لست واضحًا جدًا بشأن النظرية المحددة. يكمن التقريب في اختيار مواضع نقطتي التحكم. تم الحصول على موضع نقطة التحكم لهذه الطريقة بنفسي والدقة على ما يرام.
.
// ستنتج هذه الطريقة أيضًا عندما يكون عرض الخط أوسع ويلات القطع الناقص.
// نهاية المحور الطويل حاد وليست سلسة
وظيفة bezierellipse1 (السياق ، x ، y ، a ، b)
{
// المفتاح هو إعداد نقطتين تحكم في Beziercurveto
//0.5 و 0.6 هما معاملان رئيسيان (تم الحصول عليهما للتجربة في هذه الوظيفة)
var ox = 0.5 * a ،
oy = 0.6 * b ؛
context.save () ؛
context.translate (x ، y) ؛
context.beginPath () ؛
// ارسم عكس اتجاه عقارب الساعة من الطرف السفلي من المحور الطولي الناقص
context.moveto (0 ، b) ؛
context.beziercurveto (ox ، b ، a ، oy ، a ، 0) ؛
context.beziercurveto (a ، -oy ، ox ، -b ، 0 ، -b) ؛
context.beziercurveto (-ox ، -b ، -a ، -oy ، -a ، 0) ؛
context.beziercurveto (-a ، oy ، -ox ، b ، 0 ، b) ؛
context.closepath () ؛
سياق. ضربة () ؛
context.restore () ؛
} ؛
طريقة منحنى Bezier المكعبة اثنينيتم تغيير هذه الطريقة من الرد إلى منشور في Stackoverflow ، بدقة عالية وأيضًا طريقة شائعة الاستخدام لرسم القطع.
.
// ستنتج هذه الطريقة أيضًا عندما يكون عرض الخط أوسع ويلات القطع الناقصات.
// ، نهاية المحور الطويل حاد وليس ناعمًا
// هذه الطريقة أكثر دقة من طريقة Bessel السابقة ، ولكن لديها طريقة أقل كفاءة قليلاً
وظيفة Bezierellipse2 (CTX ، X ، Y ، A ، B)
{
var k = .5522848 ،
OX = A * K ، // إزاحة نقطة التحكم الأفقي
oy = b * k ؛ // إزاحة نقطة التحكم العمودي
ctx.beginpath () ؛
// ارسم أربعة منحنيات بيزييه مكعبة في اتجاه عقارب الساعة من نقطة النهاية اليسرى من القطع الناقص
ctx.moveto (x - a ، y) ؛
ctx.beziercurveto (x - a ، y - oy ، x - ox ، y - b ، x ، y - b) ؛
ctx.beziercurveto (x + ox ، y - b ، x + a ، y - oy ، x + a ، y) ؛
ctx.beziercurveto (x + a ، y + oy ، x + ox ، y + b ، x ، y + b) ؛
ctx.beziercurveto (x - ox ، y + b ، x - a ، y + oy ، x - a ، y) ؛
ctx.closepath () ؛
ctx.stroke () ؛
} ؛
طريقة صريفيمكن أن ترسم هذه الطريقة القطرات استنادًا إلى خصائص القماش التي تتمكن من تشغيل وحدات البكسل واستخدام الخوارزميات الأساسية في الرسومات. على سبيل المثال ، خوارزمية القطع الناقص في نقطة الوسط ، إلخ.
أحد الأمثلة على ذلك هو منشور مدونة من قبل Doudou ، صديق حديقة ، فئة تحسين Canvas HTML5 (I) - رسومات النقطية (1) خوارزمية نقطة الوسط والدائرة. هذه الطريقة بدائية نسبيًا ومرنة وفعالة ودقيقة ، ولكنها أكثر تعقيدًا لتحقيق وظيفة مفيدة لرسم القطع. على سبيل المثال ، عندما يتغير عرض الخط ، تصبح الخوارزمية أكثر تعقيدًا. على الرغم من أنها خوارزمية لرسم الدوائر ، إلا أن الخوارزمية لرسم الحوادث تشبهها ، بحيث يمكنك الرجوع إليها أدناه.
العرض التوضيحي
فيما يلي العديد من مظاهرات رسم وظائف القطع الناقص بالإضافة إلى طريقة النقطية. رمز العرض هو كما يلي:
<div id = "canvaswrap" style = "الخلفية: #ffff ؛ العرض: 600px ؛ الارتفاع: 600px ؛ الحدود: 1px سوداء صلبة ؛"> </div>
<script type = "text/javaScript"> // <! [CDATA [
var canvas ،
سياق؛
var div = document.getElementById ("canvaswrap") ؛
div.innerhtml = "" ؛
canvas = document.createElement ("canvas") ؛
canvas.style.width = "600px"
canvas.style.height = "600px"
canvas.width = 600 ؛
canvas.Height = 600 ؛
context = canvas.getContext ("2d") ؛
div.appendchild (قماش) ؛
وظيفة execdraw ()
{
// حل مشكلة عرض الخط أقل من أو يساوي 1 في الكروم
context.linewidth = 1.1 ؛
context.strokestyle = "Black"
paramellipse (السياق ، 130 ، 80 ، 50 ، 50) ؛ //دائرة
paramellipse (السياق ، 130 ، 80 ، 100 ، 20) ؛ // القطع الناقص
Evencompellipse (سياق ، 130 ، 200 ، 50 ، 50) ؛ //دائرة
Evencompellipse (السياق ، 130 ، 200 ، 100 ، 20) ؛ // Ellipe
Bezierellipse1 (السياق ، 470 ، 80 ، 50 ، 50) ؛ //دائرة
Bezierellipse1 (السياق ، 470 ، 80 ، 100 ، 20) ؛ // Ellipe
Bezierellipse2 (السياق ، 470 ، 200 ، 50 ، 50) ؛ //دائرة
Bezierellipse2 (السياق ، 470 ، 200 ، 100 ، 20) ؛ // Ellipe
// اكتشاف التشابه (درجة التداخل)
paramellipse (السياق ، 300 ، 450 ، 250 ، 50) ؛
context.strokestyle = "Yellow" ؛
Bezierellipse1 (السياق ، 300 ، 450 ، 250 ، 50) ؛
context.strokestyle = "Blue" ؛
Bezierellipse2 (السياق ، 300 ، 450 ، 250 ، 50) ؛
} ؛
وظيفة clearcavnas ()
{
context.clearRect (0 ، 0 ، 600 ، 600) ؛
} ؛
//]]> </script>
<p>
<button onClick = "execdraw () ؛" اكتب = "زر"> تنفيذ </button>
<button onClick = "ClearCanvas () ؛" اكتب = "زر"> تنظيف </button>
</p>
لاحظ أنه لتشغيل الرمز بنجاح ، يلزم المتصفح الذي يدعم اللوحة التي تدعم HTML5.
كانت هذه هي المرة الأولى التي كتبت فيها مدونة ، ولم يكن من السهل القيام بذلك طوال اليوم! لا يعرض قالب البشرة الداكنة في حديقة المدونة الرمز المدرج جيدًا. لقد أخذت آلام كبيرة للحصول على تنسيق الكود!