- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我从未在编程中使用过 SkiaSharp 或处理过 SVG 和旋转点。我对矩阵的工作原理感到困惑;研究时看起来很复杂。我知道我可以将我的 pivotX/Y 点移动到中心,这样我就可以说我想将图像旋转 180 度,所有像素都是 1:1。
注意:我没有创建任何这些 SVG,它们是由公司内部的某个人制作的。
我正在使用 Xamarin 社区工具包来获取自定义弹出窗口。我绘制的 SVG 总是颠倒绘制的。所以我想将它旋转 180 度,但我不确定如何将 pivotX/Y 设置在 StarPath
或 Canvas center
的中心。
这个问题的全部要点让我可以学习如何在 SkiaSharp 中操作 Matrix 并能够通过指定 degrees
width/2
来创建旋转我的路径的方法高度/2
Xamarin 代码
<?xml version="1.0" encoding="utf-8" ?>
<xct:Popup xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="uCue_Game.View.LostLifePopUp"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:sksh="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
Size="400, 400"
Color="Transparent">
<StackLayout BackgroundColor="Black"
Opacity="1">
<sksh:SKCanvasView x:Name="canvasView"
PaintSurface="canvasView_PaintSurface"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HeightRequest="300"
Opacity="1"/>
<Label Text="Wrong Answer"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
FontSize="15"
TextColor="White"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
Opacity="1"/>
</StackLayout>
</xct:Popup>
C#代码
public partial class LostLifePopUp : Popup
{
SKPath StarPath = SKPath.ParseSvgPathData("M492" +
" 348 c16 -18 47 -67 69 -110 38 -76 40 -78 77 -78 55 -1 156 -24 186 -43 42" +
" -28 34 -61 -27 -120 -29 -29 -70 -63 -90 -77 -24 -16 -35 -30 -31 -40 18 -48" +
" 44 -170 44 -211 0 -44 -3 -49 -25 -55 -31 -8 -144 27 -209 64 l-47 27 -97 -47" +
" c-102 -50 -157 -65 -181 -49 -20 13 -16 97 9 195 l20 79 -58 61 c-69 73 -102" +
" 118 -102 141 0 22 66 50 177 75 l90 21 22 53 c12 29 35 74 51 100 38 59 76 63" +
" 122 14z");
SKPath StarFill = SKPath.ParseSvgPathData("M487" +
" 363 c21 -24 58 -71 83 -105 32 -46 51 -64 74 -69 65 -14 201 -56 213 -65 28" +
" -23 2 -34 -85 -35 -109 -1 -229 -31 -336 -85 -136 -69 -223 -82 -298 -43 -32" +
" 17 -98 73 -98 84 0 4 10 18 23 32 12 14 32 37 44 51 12 15 35 29 50 33 15 4" +
" 49 15 75 26 38 16 51 29 76 76 50 94 89 142 116 142 15 0 38 -16 63 -42z");
SKPath StarShine = SKPath.ParseSvgPathData(
"M0 1215 m0 -1215 m1260 0 m1260 0 m0 1215 m0 1215 m-1260 0 m-1260 0 m0" +
" -1215z m1395 838 c35 -35 95 -164 95 -204 0 -55 -64 -92" +
" -117 -69 -56 25 -68 54 -68 166 0 105 10 134 45 134 9 0 30 -12 45 -27z");
SKPaint StrokeRed = new SKPaint
{
Style = SKPaintStyle.StrokeAndFill,
Color = SKColors.Red,
StrokeWidth = 5,
StrokeCap = SKStrokeCap.Round,
StrokeJoin = SKStrokeJoin.Round
};
SKPaint FillYellow = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.Yellow,
StrokeWidth = 5,
StrokeCap = SKStrokeCap.Round,
StrokeJoin = SKStrokeJoin.Round
};
SKPaint GoldShine = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Green,
StrokeWidth = 40,
StrokeCap = SKStrokeCap.Round,
StrokeJoin = SKStrokeJoin.Round
};
public LostLifePopUp()
{
InitializeComponent();
}
private void canvasView_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
SKRect bounds;
StarPath.GetBounds(out bounds);
var surface = e.Surface;
var surfaceWidth = e.RawInfo.Width;
var surfaceHeight = e.RawInfo.Height;
var canvas = surface.Canvas;
canvas.Flush();
canvas.Clear();
var rot = SKMatrix.CreateRotationDegrees(37, surfaceWidth / 2 - 50, surfaceHeight / 2);
canvas.SetMatrix(rot);
canvas.Translate(surfaceWidth / 2, surfaceHeight / 2);
canvas.Scale(0.9f * Math.Min(surfaceWidth / bounds.Width,
surfaceHeight / bounds.Height));
canvas.Translate(-bounds.MidX, -bounds.MidY);
canvas.DrawPath(StarShine, GoldShine);
canvas.DrawPath(StarPath, StrokeRed);
canvas.DrawPath(StarFill, FillYellow);
}
}
当前更新的代码 - 我的时间不多了,所以我现在不能再玩这个 SkiaSharp
了。我将开发这个游戏的第二个版本,这是一个更复杂的版本,所以我会在开始时尽快回到这个。我真的不满意 SKMatrix.PostConcat
使方法 过时
并且无法从任何地方访问。当有人失去等级时,我的明星有 2 个状态,我不得不采取非常错误的方法来实现它,但它是稍后修复的东西。此外,如果 Canvas 大小发生变化,整个绘图都会变得糟糕,其他地方都一样。
private void canvasView_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
SKRect bounds;
StarPath.GetBounds(out bounds);
var surface = e.Surface;
var surfaceWidth = e.RawInfo.Width;
var surfaceHeight = e.RawInfo.Height;
var canvas = surface.Canvas;
var result = SKMatrix.CreateIdentity();
var translate = SKMatrix.CreateTranslation(-surfaceWidth / 2, -surfaceHeight / 2);
var rotate = SKMatrix.CreateRotationDegrees(180);
var translate2 = SKMatrix.CreateTranslation(surfaceWidth * 2, surfaceHeight);
SKMatrix.PostConcat(ref result, translate);
SKMatrix.PostConcat(ref result, rotate);
SKMatrix.PostConcat(ref result, translate2);
StarPath.Transform(result);
StarFill.Transform(result);
canvas.Scale(0.8f * Math.Min(surfaceWidth / bounds.Width, surfaceHeight / bounds.Height));
canvas.DrawPath(StarPath, WhiteOutline);
canvas.DrawPath(StarPath, Yellow);
canvas.DrawPath(StarFill, Shine);
if (DrawMain == true)
{
canvas.Scale(0.7f * Math.Min(surfaceWidth / bounds.Width, surfaceHeight / bounds.Height));
translate2 = SKMatrix.CreateTranslation(surfaceWidth * 2.5f, surfaceHeight * 2);
SKMatrix.PostConcat(ref result, translate2);
StarShine.Transform(result);
canvas.DrawPath(StarShine, White);
}
if (DrawSecond == true)
{
canvas.DrawPath(StarPath, WhiteOutline);
}
}
这是目前的样子。我看不到闪耀,填充实际上也没有填满整个星星……右图是它应该看起来的样子。
最佳答案
============更新答案======
在我看来,您可以更改 StarPath 以在中心绘制星星。
我在 300 X 300 canvasview 上制作这个
SKPath StarPath = SKPath.ParseSvgPathData("m 492" +
" 805.6 c 16 -18 47 -67 69 -110 c 38 -76 40 -78 77 -78 c 55 -1 156 -24 186 -43" +
" c 42 -28 34 -61 -27 -120 c -29 -29 -70 -63 -90 -77 c -24 -16 -35 -30 -31 -40" +
" c 18 -48 44 -170 44 -211 c 0 -44 -3 -49 -25 -55 c -31 -8 -144 27 -209 64" +
" l -47 27 l -97 -47 c -102 -50 -157 -65 -181 -49 c -20 13 -16 97 9 195 l 20 79" +
" l -58 61 c -69 73 -102 118 -102 141 c 0 22 66 50 177 75 l 90 21 l 22 53 c 12 29" +
" 35 74 51 100 c 38 59 76 63 122 14 z");
它在中心绘制星星。我使用具有@3x 比例因子的高分辨率的iphone13 模拟器。
============原始答案
感谢@ThisQRequiresASpecialist 的评论。我发现变换的顺序非常重要。如果旋转 Canvas ,坐标系也会旋转。也就是说如果你旋转90度,x轴变成y轴,y轴变成x轴,给后面的平移带来麻烦。所以先平移再旋转可能会更好。
在您的情况下,要旋转 180 度并平移到中心,只需尝试以下代码:
void canvasView_PaintSurface(System.Object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e)
{
SKImageInfo info = e.Info;
SKRect bounds;
var surface = e.Surface;
var surfaceWidth = info.Width;
var surfaceHeight = info.Height;
StarPath.GetTightBounds(out bounds);
canvas.Translate(surfaceWidth/2 - bounds.MidX, (surfaceHeight / 2 - bounds.MidY)); // Translate to the center
canvas.RotateDegrees(180, bounds.MidX, bounds.MidY); // rotate 180
...
=======在这里更新=======
@ThisQRequiresASpecialist 的评论也展示了一种使用 Matrix 的新方法。我还制作了一个演示,它运行良好。
var result = SKMatrix.CreateIdentity();
var rotate = SKMatrix.CreateRotationDegrees(180, bounds.MidX, bounds.MidY);
var translate = SKMatrix.CreateTranslation(surfaceWidth / 2 - bounds.MidX, -(surfaceHeight / 2 - bounds.MidY));
SKMatrix.PostConcat(ref result, translate);
SKMatrix.PostConcat(ref result, rotate);
StarPath.Transform(result);
canvas.DrawPath(StarPath, StrokeRed);
更多信息可以引用The Rotate Transform
希望我的回答能帮到你。
关于c# - SkiaSharp 在 Canvas 中心设置新的旋转点并围绕该点旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74347823/
我可以使用两种方法添加一个 child ,一种是 Canvas.AddVisualChild(Visual); Canvas.AddLogicalChild(Visual); 我在视觉对象的 Draw
在过去的几周里,我一直在尝试各种方法,试图找到将 BDD 用于依赖于 HTML5 Canvas 元素以及用户与之交互的 Web 应用程序的最佳方法。 我一直在使用 Jasmine 和 Cucumber
我正在尝试完成撤消/重做。我正在使用loadFromJSON(...)从我存储在数组中的 Canvas 状态重新构建 Canvas 。基本上,我的想法是破坏现有的 Canvas 并重新构建 Canva
我正在尝试在 Canvas 上设置简单的放大/缩小功能。我正在使用 KineticJS 处理触摸事件并在 Canvas 中绘图,但无法实现缩放。 KinteicJS 有一个类似的例子,但它们总是在中心
我正在使用 processing.js 在 javascript 中开发一个画笔应用程序 它正在使用 Canvas 对象。我想在 Canvas 的背景中保留一个图像。在前景中画一些东西。在保存时,我只
您好,我想为 discord.js Bot 安装 Canvas 。 当我尝试使用以下命令安装 Canvas 时npm install canvas我收到以下错误: pi@server:~/Bots/D
我正在尝试使用 Canvas 和动力学的组合来构建填充图案,但在尝试获得连续线时遇到了问题。 此 jsfiddle显示了到目前为止我所拥有的,但是因为我的重复模式是正方形,角会影响线条,我尝试使用 l
我正在开发一个 webassembly 程序。 我可以使用 emscripten_set_canvas_size 设置 Canvas 大小(我一直读到我需要切换到新的 API,因为这个 API 会贬值
您好,我已经为第一个 Canvas 中的第一个图像创建了一个圆形表单,但我没有成功使用第一个 Canvas 的 dataURL 并将其添加到第二个 Canvas 中。 这是我的 fiddle :htt
问题在于不同浏览器之间的不一致。 使用Dart Chrome,JS Chrome,JS Opera运行 双击可以进入和退出全屏 m_oCanvas.width =(window.screen.widt
我正在使用Flutter框架和Dart开发图像编辑器,因此无法将矩阵滤镜应用于 Canvas 。 我正在尝试使用“Paint”类和“canvas.drawPaint(paint)”函数将矩阵过滤器应用
如果在已经具有非整数比例因子的 Canvas 上绘制图像,我会遇到 Canvas 上下文drawImage()方法的问题。似乎这样的图像以一种奇怪的方式被剪切(有时图像的最右边的部分被剪切,有时是最底
Canvas 的“宽度”属性值有限制吗? 在下面的示例中,我在 ScrolledWindow 中创建一个 Canvas。 # Packages package require BWidget # Ma
我正在尝试制作类似于 this article 底部的效果的文本效果 我建议的方法是: 制作两个 Canvas ,一个是可见的,另一个是不可见的我用它作为缓冲区。 在缓冲区 Canvas 上绘制一些文
例如var new = canvas.toDataURL("image/png"); 我希望这个新变量中存在的 base64 显示到存在的第二个 Canvas 元素中。但是它不使用 drawimage
有人有使用这两个 Node.js 库中的一个或两个的经验吗?很想知道每个人的成功或困难。 最佳答案 LearnBoost是社区中最多产的 Node 模块开发人员之一,因此我选择使用 node-canv
如何知道 Canvas 运行的是“WebGL”还是普通 Canvas ? 通过检查源代码,我发现这两种情况都是 Canvas 。 最佳答案 这真的取决于你想如何去发现。 例如你可以这样调用 `getC
在 Canvas 上绘图非常好。甚至橡皮擦也能正常工作。问题是,当 Canvas 保存为图像时,它绘制的是黑线而不是橡皮擦。 为了更好地理解,我添加了屏幕截图和代码。 1。在删除绘图时 - 一个。源代
我正在尝试为 Canvas 附加鼠标悬停和鼠标移出事件: 默认 Canvas 是函数drawcircle的 Canvas 。 如果用户越过 Canvas ,应将其更改为drawEllipse的 Can
我正在使用 Three.js 构建一个简单的 2D 游戏。我只使用世界的 X 和 Y 位置来移动对象,将它们的 z 位置保留为零。我使用禁用旋转的 TrackballControls,以允许使用右键单
我是一名优秀的程序员,十分优秀!