05-10-12, 11:23 AM
كاتب الموضوع : silverlight
بسم الله الرحمن الرحيم
بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته
مقدمـــــة:
كما يعلم القارئ أن جميع المبرمجين يحرصون علي أن تظهر البرامج التي يصنعونها بشكل جذاب بل ويحاولون إضفاء لمسات جمالية بطرق مختلفة حتي يجذبون المستخدم لبرامجهم لذلك ستجد الجميع يهتمون بمثل هذه الأمور حيث أنها تمثل سوقا تجاريا لابأس به وبشكل عام هذا ما سنحاول أن نوضح بعضا منه في هذا الموضوع
وكما سبق وكتبت في الجزء الأول أننا هنا لا نناقش كيف نرسم أو كيف نستخدم أوامر الرسم المختلفة بل سوف نناقش كيف نستفيد ونطور في أوامر +GDI الموجودة في الدوت نت بحيث نستفيد منها بشكل أفضل لذلك أفترض أن قارئ هذا المقال لديه المام جيد بأوامر +GDI وكيفية استخدامها
الفكرة الثانية:
الفكرة التي سوف نتحدث عنها اليوم هي كيف نرسم Ribbon أو كيف نرسم Glow
المثال الأول :
كيف يمكن أن نستفيد من الأوامر الخاصة برسم الأقواس بالإضافة الي رسم المسارات أو ما يعرف باسم GraphicsPath .......... الكود التالي يوضح كيف نرسم قوس من دائرة في داخل مستطيل
كود :
Public Class Form1
Private DarkColor As Color = Color.DarkOrange
Private LightColor As Color = Color.Orange
Private rect As New Rectangle(10, 10, 150, 150)
Private angle As Integer
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
' الغرض من رسم هذا المستطيل لكي يعمل كخلفية فقط لتوضيح كيف سيكون شكل القوس الذي نرسمه
e.Graphics.FillRectangle(Brushes.Black, Rect)
angle = 180
Using Path As Drawing2D.GraphicsPath = New Drawing2D.GraphicsPath()
Path.AddArc(Rect, angle, 180)
Using p As Pen = New Pen(DarkColor)
Using lgb As New LinearGradientBrush(Path.GetBounds(), Color.FromArgb(84, LightColor), Color.FromArgb(128, LightColor), LinearGradientMode.Vertical)
e.Graphics.FillPath(lgb, Path)
End Using
e.Graphics.DrawPath(p, Path)
End Using
End Using
End Sub
End Class
حاول عزيزي القارئ أن تقوم بتغيير قيمة هذا المتغير لكي يساوي 180 أو 90 أو 270 ولاحظ الفارق في كل مرة ستجرب فيها الكود ستكتشف أن إتجاه القوس المرسوم داخل المستطيل يتغير تبعا للزاوية التي نحددها ........
المثال الثاني:
الأن لنرسم نفس القوس ولكن هذه المرة سوف نقوم بعمل Blend للألوان المستخدمة في رسم القوس وسنكرر الرسم فقط من أجل المقارنة بين مارسمناه في المثال الأول والمثال الثاني
كود :
Public Class Form1
Private DarkColor As Color = Color.DarkOrange
Private LightColor As Color = Color.Orange
Private rect As New Rectangle(10, 10, 150, 150)
Private angle As Integer
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Dim m_blend As New Blend
m_blend.Factors = New Single() {0.0F, 0.4F, 0.8F, 1.0F}
m_blend.Positions = New Single() {0.0F, 0.3F, 0.4F, 1.0F}
' الغرض من رسم هذا المستطيل هو أن يعمل كخلفية فقط لتوضيح كيف سيكون شكل القوس الذي نرسمه
e.Graphics.FillRectangle(Brushes.Black, Rect)
angle = 180
Using Path As Drawing2D.GraphicsPath = New Drawing2D.GraphicsPath()
Path.AddArc(rect, angle, 180)
Using p As Pen = New Pen(DarkColor)
Using lgb As New LinearGradientBrush(Path.GetBounds(), Color.FromArgb(84, LightColor), Color.FromArgb(128, LightColor), LinearGradientMode.Vertical)
lgb.Blend = m_blend
e.Graphics.FillPath(lgb, Path)
End Using
e.Graphics.DrawPath(p, Path)
End Using
End Using
' الغرض من رسم هذا المستطيل هو أن يعمل كخلفية فقط لتوضيح كيف سيكون شكل القوس الذي نرسمه
Dim rect1 As Rectangle = New Rectangle(Rect.X + Rect.Width + 5, Rect.Y, Rect.Width, Rect.Height)
e.Graphics.FillRectangle(Brushes.Black, rect1)
' يتم إعادة رسم هذا الجزء من أجل المقارنة فقط لا غير
Using Path As Drawing2D.GraphicsPath = New Drawing2D.GraphicsPath()
Path.AddArc(rect1, angle, 180)
Using p As Pen = New Pen(DarkColor)
Using lgb As New LinearGradientBrush(Path.GetBounds(), Color.FromArgb(84, LightColor), Color.FromArgb(128, LightColor), LinearGradientMode.Vertical)
e.Graphics.FillPath(lgb, Path)
End Using
e.Graphics.DrawPath(p, Path)
End Using
End Using
End Sub
End Class
حالو تغيير قيم Positions و Factors الخاصة بالكلاس Blend لتكتشف بنفسك اهمية هذا الكلاس في عملية التحكم في تدرج الأولوان
المثال الثالث:
سنعيد رسم المثال الثاني كما هو ولكن بدلا من أن نستخدم مستطيلا كخلفية للأقواس المرسومة سنرسم Ellipse .... جرب المثال ولاحظ الفارق
كود :
Public Class Form1
Private DarkColor As Color = Color.DarkOrange
Private LightColor As Color = Color.Orange
Private rect As New Rectangle(10, 10, 150, 150)
Private angle As Integer
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Dim m_blend As New Blend
m_blend.Factors = New Single() {0.0F, 0.4F, 0.8F, 1.0F}
m_blend.Positions = New Single() {0.0F, 0.3F, 0.4F, 1.0F}
' هنا تم رسم شكل بيضاوي بدلا من المستطيل الموجود في المثال السابق
e.Graphics.FillEllipse(Brushes.Black, rect)
angle = 180
Using Path As Drawing2D.GraphicsPath = New Drawing2D.GraphicsPath()
Path.AddArc(rect, angle, 180)
Using p As Pen = New Pen(DarkColor)
Using lgb As New LinearGradientBrush(Path.GetBounds(), Color.FromArgb(84, LightColor), Color.FromArgb(128, LightColor), LinearGradientMode.Vertical)
lgb.Blend = m_blend
e.Graphics.FillPath(lgb, Path)
End Using
e.Graphics.DrawPath(p, Path)
End Using
End Using
' يتم إعادة رسم هذا الجزء من أجل المقارنة فقط لا غير
Dim rect1 As Rectangle = New Rectangle(rect.X + rect.Width + 5, rect.Y, rect.Width, rect.Height)
' هنا تم رسم شكل بيضاوي بدلا من المستطيل الموجود في المثال السابق
e.Graphics.FillEllipse(Brushes.Black, rect1)
Using Path As Drawing2D.GraphicsPath = New Drawing2D.GraphicsPath()
Path.AddArc(rect1, angle, 180)
Using p As Pen = New Pen(DarkColor)
Using lgb As New LinearGradientBrush(Path.GetBounds(), Color.FromArgb(84, LightColor), Color.FromArgb(128, LightColor), LinearGradientMode.Vertical)
e.Graphics.FillPath(lgb, Path)
End Using
e.Graphics.DrawPath(p, Path)
End Using
End Using
End Sub
End Class
حاول أيضا عزيزي القارئ ان تقوم بتغيير الألوان المستخدمة في الرسم لكي تلاحظ الفوارق المختلفة في الأمثلة السابقة
المثال الرابع:
قد يتساءل البعض كيف نتحكم في ارتفاع القوس وهنا سنحاول ان نرسم نفس الكود أعلاه ولكن بأسلوب مختلف قليلا
كود :
Public Class Form1
Private DarkColor As Color = Color.Black
Private LightColor As Color = Color.Orange
Private rect As New Rectangle(10, 10, 150, 150)
Private startAngle As Integer
Private sweepAngle As Integer = 100
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
Using path = New GraphicsPath
startAngle = ((180 - sweepAngle) / 2)
path.AddArc(rect, CSng(startAngle), CSng(sweepAngle))
Dim pt As Point = Point.Round(path.PathData.Points(0))
Using lgb = New LinearGradientBrush(New Point(Rect.Left, Rect.Bottom), New Point(Rect.Left, (pt.Y - 1)), DarkColor, Color.FromArgb(50, DarkColor))
e.Graphics.FillPath(lgb, path)
End Using
End Using
End Sub
End Class
أيضا أرجو أن تلاحظ كيف تم تحديد أول نقطة موجودة بالمسار GraphicsPath عن طريق تعريف متغير عبارة عن Point وكيف تم ربطها مع PathData وهو عبارة عن ReadOnly Property خاصة بالمسار وهي عبارة عن Array تحدد النقط الكلية الخاصة بشكل المسار GraphicsPath حيث باستخدامها يمكن استرجاع أول وأخر نقطة بالمسار فقط لاغير أما باق النقاط التي تمثل شكل المسار فهناك استحالة تامة لاسترجاع باق القيم الخاصة بها
المثال الخامس:
سنعيد رسم الفكرة الموجودة بالمثال السابق مع إضافة مستطيل أخر الي المسار وأرجو ان تلاحظ هنا ما سيحدث
كود :
Public Class Form1
Private DarkColor As Color = Color.Black
Private LightColor As Color = Color.Orange
Private rect As New Rectangle(10, 10, 150, 150)
Private startAngle As Integer
Private sweepAngle As Integer = 130
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
Using path = New GraphicsPath
startAngle = ((180 - sweepAngle) / 2)
path.AddArc(rect, CSng(startAngle), CSng(sweepAngle))
Dim pt As Point = Point.Round(path.PathData.Points(0))
Dim r As Rectangle = rect
r.Inflate(-1, -1)
path.AddArc(r, CSng(startAngle), CSng(sweepAngle))
Using lgb = New LinearGradientBrush(New Point(rect.Left, rect.Bottom), New Point(rect.Left, (pt.Y - 1)), DarkColor, Color.FromArgb(50, DarkColor))
e.Graphics.FillPath(lgb, path)
End Using
End Using
End Sub
End Class
أرجو أن تحاول عزيزي القارئ أن تجرب جميع الأمثلة أعلاه لكي يتضح لك مدي أهمية كلا من الأقواس Arcs و المسار GraphicsPath في طرق أو عمليات الرسم +GDI المختلفة
باق الأمثلة والأفكار سيتم عرضها بالمشاركات التالية
تقبلوا تحياتي
أخوكم عمر