在现代应用程序开发中,精美的视觉效果往往能提升用户体验。作为.NET平台上强大的跨平台2D图形绘图引擎,SkiaSharp提供了丰富的API来创建各种视觉效果。本文将聚焦于SkiaSharp中线条风格设计的艺术表现,通过详细的代码案例,帮助开发者掌握线宽、线帽和线段连接等关键技术,打造独具特色的视觉体验。
关键词:SkiaSharp教程、C#绘图、线条风格设计、.NET图形开发、跨平台UI、Xamarin绘图、MAUI绘图
SkiaSharp是Google's Skia图形库的.NET绑定,支持多平台(Windows、macOS、iOS、Android等)图形渲染。在开始线条艺术设计前,先了解几个核心概念:
C#// SkiaSharp核心组件
// SKCanvas: 画布,提供绘图表面
// SKPaint: 画笔,定义如何绘制(颜色、线宽、线帽等)
// SKPath: 路径,定义要绘制的几何形状
线宽决定线条的粗细,单位为像素。
C#// 创建不同线宽的画笔
SKPaint thinPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Blue,
StrokeWidth = 2, // 细线
IsAntialias = true // 抗锯齿,使线条更平滑
};
SKPaint mediumPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Red,
StrokeWidth = 8, // 中等线宽
IsAntialias = true
};
SKPaint thickPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Green,
StrokeWidth = 16, // 粗线
IsAntialias = true
};
线帽定义线条两端的形状,有三种基本类型:
C#// 线帽类型
SKPaint buttCapPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.DarkBlue,
StrokeWidth = 12,
StrokeCap = SKStrokeCap.Butt, // 平头线帽,线条在端点处切平
IsAntialias = true
};
SKPaint roundCapPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.DarkRed,
StrokeWidth = 12,
StrokeCap = SKStrokeCap.Round, // 圆头线帽,线条两端为半圆形
IsAntialias = true
};
SKPaint squareCapPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.DarkGreen,
StrokeWidth = 12,
StrokeCap = SKStrokeCap.Square, // 方头线帽,线条两端为矩形延伸
IsAntialias = true
};
线段连接定义线段交汇处的形状:
C#// 线段连接类型
SKPaint miterJoinPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Purple,
StrokeWidth = 12,
StrokeJoin = SKStrokeJoin.Miter, // 尖角连接
IsAntialias = true
};
SKPaint roundJoinPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Orange,
StrokeWidth = 12,
StrokeJoin = SKStrokeJoin.Round, // 圆角连接
IsAntialias = true
};
SKPaint bevelJoinPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Brown,
StrokeWidth = 12,
StrokeJoin = SKStrokeJoin.Bevel, // 斜角连接
IsAntialias = true
};
创建一个简单但富有艺术感的线条组合,展示不同线帽和线宽的视觉效果:
C#using SkiaSharp;
using SkiaSharp.Views.Desktop;
namespace AppLineStyle
{
public partial class Form1 : Form
{
private SKControl skiaControl;
public Form1()
{
InitializeComponent();
SetupSkiaControl();
}
private void SetupSkiaControl()
{
// 创建SkiaSharp控件
skiaControl = new SKControl();
skiaControl.Dock = DockStyle.Fill;
skiaControl.PaintSurface += SkiaControl_PaintSurface;
// 添加到窗体
this.Controls.Add(skiaControl);
// 设置窗体属性
this.Text = "SkiaSharp 艺术线条演示";
this.Size = new System.Drawing.Size(800, 600);
this.StartPosition = FormStartPosition.CenterScreen;
}
private void SkiaControl_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
// 调用你的绘图方法
DrawArtisticLines(e.Surface.Canvas);
}
public void DrawArtisticLines(SKCanvas canvas)
{
// 清除背景
canvas.Clear(SKColors.White);
// 创建几种不同风格的画笔
SKPaint[] paints = new SKPaint[3];
// 细长线条,圆形线帽
paints[0] = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.DodgerBlue,
StrokeWidth = 10,
StrokeCap = SKStrokeCap.Round,
IsAntialias = true
};
// 中等线条,方形线帽
paints[1] = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Crimson,
StrokeWidth = 15,
StrokeCap = SKStrokeCap.Square,
IsAntialias = true
};
// 粗线条,平头线帽
paints[2] = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.ForestGreen,
StrokeWidth = 20,
StrokeCap = SKStrokeCap.Butt,
IsAntialias = true
};
// 绘制波浪线图案
int height = canvas.DeviceClipBounds.Height;
int width = canvas.DeviceClipBounds.Width;
float centerY = height / 2f;
for (int i = 0; i < paints.Length; i++)
{
using (SKPath path = new SKPath())
{
path.MoveTo(0, centerY + i * 80 - 80);
// 创建一个波浪形状
for (int x = 0; x < width; x += 60)
{
path.CubicTo(
x + 15, centerY + i * 80 - 120,
x + 45, centerY + i * 80 - 40,
x + 60, centerY + i * 80 - 80);
}
canvas.DrawPath(path, paints[i]);
}
}
// 添加说明文字
using (SKPaint textPaint = new SKPaint
{
Color = SKColors.Black,
TextSize = 24,
IsAntialias = true,
Typeface= SKTypeface.FromFamilyName("Microsoft YaHei"),
})
{
canvas.DrawText("圆形线帽", 20, centerY - 80 + 40, textPaint);
canvas.DrawText("方形线帽", 20, centerY + 40, textPaint);
canvas.DrawText("平头线帽", 20, centerY + 80 + 40, textPaint);
}
// 记得释放画笔资源
foreach (var paint in paints)
{
paint?.Dispose();
}
}
}
}

创建一个模拟绘图应用的画笔选择面板,展示各种线条样式:
C#using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SkiaSharp;
using SkiaSharp.Views.Desktop;
namespace AppLineStyle
{
public partial class Form2 : Form
{
private SKControl skiaControl;
public Form2()
{
InitializeComponent();
// 创建SkiaSharp控件
skiaControl = new SKControl();
skiaControl.Dock = DockStyle.Fill;
skiaControl.PaintSurface += SkiaControl_PaintSurface;
// 添加到窗体
this.Controls.Add(skiaControl);
}
private void SkiaControl_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
// 调用你的绘图方法
DrawBrushSelectionPanel(e.Surface.Canvas);
}
public void DrawBrushSelectionPanel(SKCanvas canvas)
{
// 你的完整绘制代码
canvas.Clear(new SKColor(240, 240, 240));
float panelWidth = canvas.DeviceClipBounds.Width * 0.9f;
float panelHeight = canvas.DeviceClipBounds.Height * 0.8f;
float startX = (canvas.DeviceClipBounds.Width - panelWidth) / 2;
float startY = (canvas.DeviceClipBounds.Height - panelHeight) / 2;
// 绘制面板背景
SKPaint panelPaint = new SKPaint
{
Color = SKColors.White,
IsAntialias = true
};
SKRect panelRect = new SKRect(startX, startY, startX + panelWidth, startY + panelHeight);
canvas.DrawRoundRect(panelRect, 20, 20, panelPaint);
// 添加阴影
SKPaint shadowPaint = new SKPaint
{
Color = new SKColor(0, 0, 0, 50),
IsAntialias = true,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 10)
};
canvas.DrawRoundRect(new SKRect(startX + 5, startY + 5, startX + panelWidth + 5, startY + panelHeight + 5), 20, 20, shadowPaint);
// 绘制标题
SKPaint titlePaint = new SKPaint
{
Color = SKColors.DarkSlateGray,
TextSize = 40,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei"),
};
canvas.DrawText("画笔样式选择器", startX + panelWidth / 2, startY + 60, titlePaint);
// 画笔样式数组
SKStrokeCap[] caps = new SKStrokeCap[] { SKStrokeCap.Butt, SKStrokeCap.Round, SKStrokeCap.Square };
string[] capNames = new string[] { "平头", "圆头", "方头" };
SKColor[] colors = new SKColor[] { SKColors.CornflowerBlue, SKColors.Tomato, SKColors.MediumSeaGreen };
float[] lineWidths = new float[] { 4, 8, 16, 24 };
string[] widthNames = new string[] { "极细", "细", "中", "粗" };
// 绘制线帽示例
float capStartY = startY + 120;
float lineLength = 200;
SKPaint labelPaint = new SKPaint
{
Color = SKColors.DarkSlateGray,
TextSize = 24,
IsAntialias = true,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei"),
};
canvas.DrawText("线帽样式:", startX + 30, capStartY - 20, labelPaint);
for (int i = 0; i < caps.Length; i++)
{
float y = capStartY + i * 60;
SKPaint linePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = colors[i],
StrokeWidth = 16,
StrokeCap = caps[i],
IsAntialias = true
};
canvas.DrawLine(startX + 50, y, startX + 50 + lineLength, y, linePaint);
canvas.DrawText(capNames[i], startX + 50 + lineLength + 30, y + 10, labelPaint);
}
// 绘制线宽示例
float widthStartY = capStartY + caps.Length * 60 + 40;
canvas.DrawText("线宽选择:", startX + 30, widthStartY - 20, labelPaint);
for (int i = 0; i < lineWidths.Length; i++)
{
float y = widthStartY + i * 60;
SKPaint linePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.SlateGray,
StrokeWidth = lineWidths[i],
StrokeCap = SKStrokeCap.Round,
IsAntialias = true
};
canvas.DrawLine(startX + 50, y, startX + 50 + lineLength, y, linePaint);
canvas.DrawText(widthNames[i] + $" ({lineWidths[i]}px)", startX + 50 + lineLength + 30, y + 10, labelPaint);
}
}
}
}

创建带有渐变色的艺术线条,展示更高级的线条效果:
C#using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SkiaSharp;
using SkiaSharp.Views.Desktop;
namespace AppLineStyle
{
public partial class Form3 : Form
{
private SKControl skiaControl;
public Form3()
{
InitializeComponent();
// 创建SkiaSharp控件
skiaControl = new SKControl();
skiaControl.Dock = DockStyle.Fill;
skiaControl.PaintSurface += SkiaControl_PaintSurface;
// 添加到窗体
this.Controls.Add(skiaControl);
}
private void SkiaControl_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
// 调用你的绘图方法
DrawGradientArtLines(e.Surface.Canvas);
}
public void DrawGradientArtLines(SKCanvas canvas)
{
// 设置深色背景
canvas.Clear(new SKColor(30, 30, 40));
int width = canvas.DeviceClipBounds.Width;
int height = canvas.DeviceClipBounds.Height;
// 创建渐变画笔
SKPaint gradientPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
StrokeWidth = 8,
StrokeCap = SKStrokeCap.Round,
IsAntialias = true
};
// 创建径向渐变的颜色数组
SKColor[] gradientColors = new SKColor[]
{
new SKColor(255, 50, 50), // 红色
new SKColor(255, 150, 0), // 橙色
new SKColor(255, 255, 0), // 黄色
new SKColor(0, 255, 0), // 绿色
new SKColor(0, 150, 255), // 青色
new SKColor(75, 0, 255), // 蓝色
new SKColor(255, 0, 255) // 紫色
};
// 路径点数量
int pathPoints = 12;
float radius = Math.Min(width, height) * 0.4f;
float centerX = width / 2f;
float centerY = height / 2f;
// 创建一个环形路径
SKPath circlePath = new SKPath();
for (int i = 0; i <= 360; i += 1)
{
float angle = i * (float)Math.PI / 180;
float x = centerX + radius * (float)Math.Cos(angle);
float y = centerY + radius * (float)Math.Sin(angle);
if (i == 0)
circlePath.MoveTo(x, y);
else
circlePath.LineTo(x, y);
}
// 创建渐变效果
SKPathEffect dashEffect = SKPathEffect.CreateDash(
new float[] { 15, 10 }, // 线段长度和间隔
0 // 偏移
);
// 创建一个路径测量对象来测量路径长度
SKPathMeasure pathMeasure = new SKPathMeasure(circlePath);
float pathLength = pathMeasure.Length;
// 创建多个路径,每个路径具有不同的线宽和偏移
for (int i = 0; i < 8; i++)
{
// 使用径向渐变
gradientPaint.Shader = SKShader.CreateSweepGradient(
new SKPoint(centerX, centerY),
gradientColors,
null);
// 设置线条样式
gradientPaint.StrokeWidth = 20 - i * 2;
gradientPaint.PathEffect = SKPathEffect.CreateDash(
new float[] { 15, 5 + i * 1.5f },
i * 5 // 偏移,创造交错效果
);
// 缩放路径
SKPath scaledPath = new SKPath(circlePath);
SKMatrix scaleMatrix = SKMatrix.CreateScale(
0.8f + i * 0.05f,
0.8f + i * 0.05f,
centerX,
centerY);
scaledPath.Transform(scaleMatrix);
// 绘制路径
canvas.DrawPath(scaledPath, gradientPaint);
}
// 添加说明文字
SKPaint textPaint = new SKPaint
{
Color = SKColors.White,
TextSize = 30,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei"),
};
canvas.DrawText("渐变线条艺术", centerX, height - 50, textPaint);
}
}
}

展示各种线段连接方式的视觉效果差异:
C#using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SkiaSharp;
using SkiaSharp.Views.Desktop;
namespace AppLineStyle
{
public partial class Form3 : Form
{
private SKControl skiaControl;
public Form3()
{
InitializeComponent();
// 创建SkiaSharp控件
skiaControl = new SKControl();
skiaControl.Dock = DockStyle.Fill;
skiaControl.PaintSurface += SkiaControl_PaintSurface;
// 添加到窗体
this.Controls.Add(skiaControl);
}
private void SkiaControl_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
// 调用你的绘图方法
DrawLineJoinStyles(e.Surface.Canvas);
}
public void DrawLineJoinStyles(SKCanvas canvas)
{
// 设置背景
canvas.Clear(SKColors.White);
int width = canvas.DeviceClipBounds.Width;
int height = canvas.DeviceClipBounds.Height;
// 创建标题文本
SKPaint titlePaint = new SKPaint
{
Color = SKColors.Black,
TextSize = 30,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface= SKTypeface.FromFamilyName("Microsoft YaHei")
};
canvas.DrawText("线段连接风格对比", width / 2, 60, titlePaint);
// 创建子标题
SKPaint subtitlePaint = new SKPaint
{
Color = SKColors.DarkGray,
TextSize = 20,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei")
};
canvas.DrawText("同一形状,不同连接方式的视觉效果", width / 2, 100, subtitlePaint);
// 定义线段连接类型和名称
SKStrokeJoin[] joins = new SKStrokeJoin[]
{
SKStrokeJoin.Miter,
SKStrokeJoin.Round,
SKStrokeJoin.Bevel
};
string[] joinNames = new string[]
{
"尖角(Miter)",
"圆角(Round)",
"斜角(Bevel)"
};
SKColor[] colors = new SKColor[]
{
SKColors.RoyalBlue,
SKColors.Crimson,
SKColors.ForestGreen
};
// 绘制示例形状
float startY = 150;
float shapesPerRow = 3;
float shapeWidth = width / shapesPerRow;
float shapeHeight = 150;
// 绘制锯齿形状和星形
for (int row = 0; row < 2; row++)
{
for (int i = 0; i < joins.Length; i++)
{
float startX = i * shapeWidth;
// 创建画笔
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = colors[i],
StrokeWidth = 20,
StrokeJoin = joins[i],
IsAntialias = true
};
// 绘制路径
SKPath path = new SKPath();
if (row == 0) // 锯齿形状
{
float zigzagWidth = shapeWidth * 0.7f;
float zigzagHeight = shapeHeight * 0.7f;
float zigzagX = startX + (shapeWidth - zigzagWidth) / 2;
float zigzagY = startY + (shapeHeight - zigzagHeight) / 2;
// 创建锯齿路径
path.MoveTo(zigzagX, zigzagY);
for (int j = 0; j < 5; j++)
{
path.LineTo(zigzagX + zigzagWidth * j / 4, zigzagY + (j % 2 == 0 ? zigzagHeight : 0));
}
}
else // 星形
{
float starRadius = Math.Min(shapeWidth, shapeHeight) * 0.35f;
float centerX = startX + shapeWidth / 2;
float centerY = startY + shapeHeight * 1.5f;
// 创建五角星
for (int j = 0; j <= 10; j++)
{
float angle = (float)(Math.PI / 2 + j * Math.PI * 2 / 10);
float radius = j % 2 == 0 ? starRadius : starRadius * 0.5f;
float x = centerX + radius * (float)Math.Cos(angle);
float y = centerY - radius * (float)Math.Sin(angle);
if (j == 0)
path.MoveTo(x, y);
else
path.LineTo(x, y);
}
path.Close();
}
// 绘制形状
canvas.DrawPath(path, paint);
// 添加标签
SKPaint labelPaint = new SKPaint
{
Color = SKColors.Black,
TextSize = 18,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei")
};
float labelY = row == 0 ?
startY + shapeHeight + 25 :
startY + shapeHeight * 2 + 25;
canvas.DrawText(joinNames[i], startX + shapeWidth / 2, labelY, labelPaint);
}
}
}
}
}

这里模拟一个交互式线条设计工具的界面,展示如何组合使用各种线条属性:
C#using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SkiaSharp;
using SkiaSharp.Views.Desktop;
namespace AppLineStyle
{
public partial class Form3 : Form
{
private SKControl skiaControl;
private int[] selectedOptions = new int[] { 2, 1, 1 }; // 10px, 圆头, 圆角
public Form3()
{
InitializeComponent();
// 创建SkiaSharp控件
skiaControl = new SKControl();
skiaControl.Dock = DockStyle.Fill;
skiaControl.PaintSurface += SkiaControl_PaintSurface;
skiaControl.MouseDown += SkiaControl_MouseDown;
// 添加到窗体
this.Controls.Add(skiaControl);
}
private void SkiaControl_MouseDown(object sender, MouseEventArgs e)
{
int width = skiaControl.Width;
// 工具栏区域的参数
float toolbarLeft = 20;
float toolbarTop = 70;
float optionHeight = 30;
float spacing = 10;
float optionStartX = toolbarLeft + 100;
float optionWidth = 70;
string[][] options = new string[][]
{
new string[] { "2px", "5px", "10px", "15px", "20px" },
new string[] { "平头", "圆头", "方头" },
new string[] { "尖角", "圆角", "斜角" }
};
// 循环每行判断
for (int i = 0; i < options.Length; i++)
{
float rowY = toolbarTop + 20 + i * (optionHeight + spacing);
for (int j = 0; j < options[i].Length; j++)
{
float optionX = optionStartX + j * (optionWidth + spacing);
RectangleF rect = new RectangleF(optionX, rowY, optionWidth, optionHeight);
if (rect.Contains(e.X, e.Y))
{
selectedOptions[i] = j;
skiaControl.Invalidate(); // 触发重绘
return;
}
}
}
}
private void SkiaControl_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
// 调用你的绘图方法
DrawInteractiveLineDesigner(e.Surface.Canvas);
}
public void DrawInteractiveLineDesigner(SKCanvas canvas)
{
// 设置背景
canvas.Clear(new SKColor(245, 245, 250));
int width = canvas.DeviceClipBounds.Width;
int height = canvas.DeviceClipBounds.Height;
// 标题
SKPaint titlePaint = new SKPaint
{
Color = SKColors.DarkSlateBlue,
TextSize = 32,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright)
};
canvas.DrawText("交互式线条设计工具", width / 2, 50, titlePaint);
// 绘制工具栏背景
SKRect toolbarRect = new SKRect(20, 70, width - 20, 200);
SKPaint toolbarPaint = new SKPaint
{
Color = SKColors.White,
IsAntialias = true
};
canvas.DrawRoundRect(toolbarRect, 10, 10, toolbarPaint);
// 绘制阴影
SKPaint shadowPaint = new SKPaint
{
Color = new SKColor(0, 0, 0, 30),
IsAntialias = true,
MaskFilter = SKMaskFilter.CreateBlur(SKBlurStyle.Normal, 5)
};
canvas.DrawRoundRect(new SKRect(toolbarRect.Left + 3, toolbarRect.Top + 3,
toolbarRect.Right + 3, toolbarRect.Bottom + 3),
10, 10, shadowPaint);
// 定义要显示的线条属性
string[] propNames = new string[] { "线宽", "线帽", "连接" };
string[][] options = new string[][]
{
new string[] { "2px", "5px", "10px", "15px", "20px" },
new string[] { "平头", "圆头", "方头" },
new string[] { "尖角", "圆角", "斜角" }
};
// 绘制工具栏选项
SKPaint labelPaint = new SKPaint
{
Color = SKColors.DarkSlateBlue,
TextSize = 18,
IsAntialias = true,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei"),
};
SKPaint optionPaint = new SKPaint
{
Color = SKColors.White,
IsAntialias = true
};
SKPaint selectedOptionPaint = new SKPaint
{
Color = new SKColor(230, 240, 255),
IsAntialias = true
};
SKPaint optionTextPaint = new SKPaint
{
Color = SKColors.DarkSlateBlue,
TextSize = 16,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei"),
};
float startY = toolbarRect.Top + 20;
float optionHeight = 30;
float spacing = 10;
for (int i = 0; i < propNames.Length; i++)
{
float rowY = startY + i * (optionHeight + spacing);
// 绘制属性名称
canvas.DrawText(propNames[i] + ":", toolbarRect.Left + 20, rowY + optionHeight / 2 + 5, labelPaint);
// 绘制选项
float optionStartX = toolbarRect.Left + 100;
float optionWidth = 70;
for (int j = 0; j < options[i].Length; j++)
{
float optionX = optionStartX + j * (optionWidth + spacing);
SKRect optionRect = new SKRect(optionX, rowY, optionX + optionWidth, rowY + optionHeight);
// 绘制选项背景(选中的和未选中的不同)
canvas.DrawRoundRect(optionRect, 5, 5, j == selectedOptions[i] ? selectedOptionPaint : optionPaint);
// 绘制边框
SKPaint borderPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = j == selectedOptions[i] ? SKColors.RoyalBlue : SKColors.LightGray,
StrokeWidth = j == selectedOptions[i] ? 2 : 1,
IsAntialias = true
};
canvas.DrawRoundRect(optionRect, 5, 5, borderPaint);
// 绘制选项文本
canvas.DrawText(options[i][j], optionX + optionWidth / 2, rowY + optionHeight / 2 + 5, optionTextPaint);
}
}
// 绘制预览区域
SKRect previewRect = new SKRect(20, 220, width - 20, height - 20);
canvas.DrawRoundRect(previewRect, 10, 10, toolbarPaint);
canvas.DrawRoundRect(new SKRect(previewRect.Left + 3, previewRect.Top + 3,
previewRect.Right + 3, previewRect.Bottom + 3),
10, 10, shadowPaint);
// 绘制预览区域标题
SKPaint previewTitlePaint = new SKPaint
{
Color = SKColors.DarkSlateBlue,
TextSize = 24,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei"),
};
canvas.DrawText("预览效果", width / 2, previewRect.Top + 30, previewTitlePaint);
// 根据选择的选项创建画笔
float[] strokeWidths = new float[] { 2, 5, 10, 15, 20 };
SKStrokeCap[] strokeCaps = new SKStrokeCap[] { SKStrokeCap.Butt, SKStrokeCap.Round, SKStrokeCap.Square };
SKStrokeJoin[] strokeJoins = new SKStrokeJoin[] { SKStrokeJoin.Miter, SKStrokeJoin.Round, SKStrokeJoin.Bevel };
SKPaint customPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.MediumSlateBlue,
StrokeWidth = strokeWidths[selectedOptions[0]],
StrokeCap = strokeCaps[selectedOptions[1]],
StrokeJoin = strokeJoins[selectedOptions[2]],
IsAntialias = true
};
// 在预览区域绘制一些示例形状
float centerX = previewRect.MidX;
float centerY = previewRect.MidY + 50;
float size = 150;
// 绘制一个星形
SKPath starPath = new SKPath();
for (int i = 0; i <= 10; i++)
{
float angle = (float)(Math.PI / 2 + i * Math.PI * 2 / 10);
float radius = i % 2 == 0 ? size : size * 0.4f;
float x = centerX + radius * (float)Math.Cos(angle);
float y = centerY - radius * (float)Math.Sin(angle);
if (i == 0)
starPath.MoveTo(x, y);
else
starPath.LineTo(x, y);
}
//starPath.Close();
canvas.DrawPath(starPath, customPaint);
// 添加一些说明文字
SKPaint descPaint = new SKPaint
{
Color = SKColors.DarkSlateBlue,
TextSize = 18,
IsAntialias = true,
TextAlign = SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("Microsoft YaHei"),
};
// 格式化当前设置信息
string settingsText = $"当前设置: 线宽={strokeWidths[selectedOptions[0]]}px, " +
$"线帽={options[1][selectedOptions[1]]}, " +
$"连接={options[2][selectedOptions[2]]}";
canvas.DrawText(settingsText, centerX, previewRect.Bottom - 30, descPaint);
}
}
}

以上案例可以广泛应用于:
在实际应用中,为确保流畅体验,请注意:
IsAntialias:抗锯齿虽能提升视觉效果,但会增加计算负担ClipRect 限制绘制范围,避免不必要的计算C#// 性能优化示例:限制绘制区域
public void OptimizedDrawing(SKCanvas canvas)
{
// 保存当前状态
canvas.Save();
// 限制绘制区域
canvas.ClipRect(new SKRect(0, 0, 500, 500));
// 执行绘制
DrawComplexGraphics(canvas);
// 恢复状态
canvas.Restore();
}
SkiaSharp提供了丰富而强大的线条样式API,通过合理组合线宽、线帽和线段连接等属性,我们可以创建出各种精美的视觉效果。本文通过5个详细案例,展示了如何在实际项目中灵活运用这些功能,打造独特的视觉体验。无论是开发数据可视化应用、创意绘图工具,还是游戏界面,掌握这些技术都将极大提升产品的视觉表现力。
希望这些实例能为您的开发工作提供灵感!如有任何问题,欢迎在评论区留言。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!