private ICanvasImage CreateLuminanceToAlpha() { var contrastAdjustedTiger = new LinearTransferEffect { Source = bitmapTiger, RedOffset = -3, GreenOffset = -3, BlueOffset = -3, }; var tigerAlpha = new LuminanceToAlphaEffect { Source = contrastAdjustedTiger }; var tigerAlphaWithWhiteRgb = new LinearTransferEffect { Source = tigerAlpha, RedOffset = 1, GreenOffset = 1, BlueOffset = 1, RedSlope = 0, GreenSlope = 0, BlueSlope = 0, }; var recombinedRgbAndAlpha = new ArithmeticCompositeEffect { Source1 = tigerAlphaWithWhiteRgb, Source2 = bitmapTiger, }; var movedTiger = new Transform2DEffect { Source = recombinedRgbAndAlpha }; const float turbulenceSize = 128; var backgroundImage = new CropEffect { Source = new TileEffect { Source = new TurbulenceEffect { Octaves = 8, Size = new Vector2(turbulenceSize), Tileable = true }, SourceRectangle = new Rect(0, 0, turbulenceSize, turbulenceSize) }, SourceRectangle = new Rect((bitmapTiger.Size.ToVector2() * -0.5f).ToPoint(), (bitmapTiger.Size.ToVector2() * 1.5f).ToPoint()) }; var tigerOnBackground = new BlendEffect { Foreground = movedTiger, Background = backgroundImage }; // Animation moves the alpha bitmap around, and alters color transfer settings to change how solid it is. animationFunction = elapsedTime => { contrastAdjustedTiger.RedSlope = contrastAdjustedTiger.GreenSlope = contrastAdjustedTiger.BlueSlope = ((float)Math.Sin(elapsedTime * 0.9) + 2) * 3; var dx = (float)Math.Cos(elapsedTime) * 50; var dy = (float)Math.Sin(elapsedTime) * 50; movedTiger.TransformMatrix = Matrix3x2.CreateTranslation(dx, dy); }; return(tigerOnBackground); }
public static SoftwareBitmap GetCropedSoftwareBitmap(this InkCanvas canvas, IEnumerable <InkStroke> strokes = null, float newWidth = 0, float newHeight = 0, bool keepRelativeSize = false) { strokes = strokes ?? canvas.InkPresenter.StrokeContainer.GetStrokes(); var bounds = strokes.GetBoundingBoxForInkStrokes(); if (keepRelativeSize) { // copy strokes, resize them, but keep the stroke size the same, tranlsate to as close to 0, 0 as possible var newStrokes = new List <InkStroke>(); var scaleX = (float)(newWidth / bounds.Width); var scaleY = (float)(newHeight / bounds.Height); var translateX = 1 - (float)bounds.X * scaleX; var translateY = 1 - (float)bounds.Y * scaleY; foreach (var stroke in strokes) { var newStroke = stroke.Clone(); newStroke.PointTransform = Matrix3x2.CreateScale(scaleX, scaleY) * Matrix3x2.CreateTranslation(translateX, translateY); newStroke.DrawingAttributes = GetDefaultInkDrawingAttributes(); newStrokes.Add(newStroke); } strokes = newStrokes; bounds = strokes.GetBoundingBoxForInkStrokes(); } bounds.X = Math.Max(bounds.X, 0); bounds.Y = Math.Max(bounds.Y, 0); var bitmap = canvas.GetSoftwareBitmap(strokes); if (newWidth > 0 && newHeight > 0) { return(bitmap.CropAndResize(bounds, newWidth, newHeight)); } return(bitmap.Crop(bounds)); }
void DrawStuff(CanvasDrawingSession ds) { int horizontalLimit = (int)m_canvasControl.ActualWidth; int verticalLimit = (int)m_canvasControl.ActualHeight; DrawnContentType drawnContentType = (DrawnContentType)m_drawnContentTypeCombo.SelectedValue; ds.Clear(NextRandomColor()); Vector2 point; float radiusX; float radiusY; Random random = new Random(); m_canvasSwapChainPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed; switch (drawnContentType) { case DrawnContentType.Clear_Only: break; case DrawnContentType.Bitmap: if (m_bitmap_tiger != null) { ds.DrawImage(m_bitmap_tiger, NextRandomPoint(horizontalLimit, verticalLimit).ToVector2()); } else { DrawNoBitmapErrorMessage(ds, horizontalLimit / 2, verticalLimit / 2); } break; case DrawnContentType.Rectangle_Filled: Point bound0 = NextRandomPoint(horizontalLimit, verticalLimit); Point bound1 = NextRandomPoint(horizontalLimit, verticalLimit); m_linearGradientBrush.StartPoint = bound0.ToVector2(); m_linearGradientBrush.EndPoint = bound1.ToVector2(); ds.FillRectangle( new Rect(bound0, bound1), m_linearGradientBrush); break; case DrawnContentType.Ellipse_Fill: NextRandomEllipse(horizontalLimit, verticalLimit, out point, out radiusX, out radiusY); ds.FillEllipse( point, radiusX, radiusY, NextRandomColor()); break; case DrawnContentType.Circle_Fill: ds.FillCircle( NextRandomPoint(horizontalLimit, verticalLimit).ToVector2(), 100, NextRandomColor()); break; case DrawnContentType.Text: var p = NextRandomPoint(horizontalLimit, verticalLimit); var x = (float)p.X; var y = (float)p.Y; var color = NextRandomColor(); ds.DrawLine(new Vector2(x, 0), new Vector2(x, verticalLimit), color); ds.DrawLine(new Vector2(0, y), new Vector2(horizontalLimit, y), color); ds.DrawText( "Centered", p.ToVector2(), color, new CanvasTextFormat() { FontSize = 18, VerticalAlignment = CanvasVerticalAlignment.Center, HorizontalAlignment = CanvasHorizontalAlignment.Center }); var r = NextRandomRect(horizontalLimit, verticalLimit); ds.DrawRectangle(r, color); ds.DrawText( m_quiteLongText, r, NextRandomColor(), new CanvasTextFormat() { FontFamily = "Comic Sans MS", FontSize = 18, HorizontalAlignment = CanvasHorizontalAlignment.Justified, Options = CanvasDrawTextOptions.Clip }); break; case DrawnContentType.ImageBrush: if (m_bitmap_tiger != null) { m_imageBrush.Image = m_bitmap_tiger; m_imageBrush.ExtendX = (CanvasEdgeBehavior)(m_random.Next(3)); m_imageBrush.ExtendY = (CanvasEdgeBehavior)(m_random.Next(3)); ds.FillRectangle(new Rect(0, 0, horizontalLimit, verticalLimit), m_imageBrush); } else { DrawNoBitmapErrorMessage(ds, horizontalLimit / 2, verticalLimit / 2); } break; case DrawnContentType.OffscreenTarget: m_imageBrush.Image = m_offscreenTarget; m_imageBrush.ExtendX = (CanvasEdgeBehavior)(m_random.Next(3)); m_imageBrush.ExtendY = (CanvasEdgeBehavior)(m_random.Next(3)); ds.FillRectangle(new Rect(0, 0, horizontalLimit, verticalLimit), m_imageBrush); break; case DrawnContentType.Gradients: Vector2 center = NextRandomPoint(horizontalLimit, verticalLimit).ToVector2(); m_radialGradientBrush.Center = center; float radius = m_random.Next(horizontalLimit / 2); m_radialGradientBrush.OriginOffset = new Vector2(radius, radius); m_radialGradientBrush.RadiusX = radius; m_radialGradientBrush.RadiusY = radius; ds.FillCircle(center, radius, m_radialGradientBrush); Vector2 line0 = NextRandomPoint(horizontalLimit, verticalLimit).ToVector2(); Vector2 line1 = NextRandomPoint(horizontalLimit, verticalLimit).ToVector2(); m_linearGradientBrush.StartPoint = line0; m_linearGradientBrush.EndPoint = line1; float thickness = m_random.Next(horizontalLimit / 2); ds.DrawLine(line0, line1, m_linearGradientBrush, thickness); break; case DrawnContentType.AlternateBitmapLoading: if (m_bitmap_colorGrids != null) { Matrix3x2 scale = Matrix3x2.CreateScale(20); ds.Transform = scale; ds.DrawImage(m_bitmap_colorGrids[0]); ds.Transform = scale * Matrix3x2.CreateTranslation(200, 0); ds.DrawImage(m_bitmap_colorGrids[1]); ds.Transform = scale * Matrix3x2.CreateTranslation(0, 200); ds.DrawImage(m_bitmap_colorGrids[2]); } else { DrawNoBitmapErrorMessage(ds, horizontalLimit / 2, verticalLimit / 2); } break; case DrawnContentType.SwapChainPanel: m_canvasSwapChainPanel.Visibility = Windows.UI.Xaml.Visibility.Visible; float swapChainWidth = horizontalLimit * ((float)random.NextDouble() / 2 + 0.5f); float swapChainHeight = verticalLimit * ((float)random.NextDouble() / 2 + 0.5f); if (m_swapChain == null) { m_swapChain = new CanvasSwapChain(ds, swapChainWidth, swapChainHeight); m_canvasSwapChainPanel.SwapChain = m_swapChain; } else { m_swapChain.ResizeBuffers(swapChainWidth, swapChainHeight); } using (CanvasDrawingSession panelDS = m_swapChain.CreateDrawingSession(NextRandomColor())) { panelDS.DrawCircle(swapChainWidth / 2.0f, swapChainHeight / 2.0f, 100.0f, NextRandomColor(), 20.0f); } m_swapChain.Present(); break; case DrawnContentType.Test_Scene0_Default: GeometryTestScene0.DrawGeometryTestScene(ds, TestSceneRenderingType.Default); break; case DrawnContentType.Test_Scene0_Wireframe: GeometryTestScene0.DrawGeometryTestScene(ds, TestSceneRenderingType.Wireframe); break; case DrawnContentType.Test_Scene1_Default: GeometryTestScene1.DrawGeometryTestScene(ds, TestSceneRenderingType.Default); break; case DrawnContentType.Test_Scene1_Randomized: GeometryTestScene1.DrawGeometryTestScene(ds, TestSceneRenderingType.Randomized); break; case DrawnContentType.Test_Scene1_Wireframe: GeometryTestScene1.DrawGeometryTestScene(ds, TestSceneRenderingType.Wireframe); break; default: System.Diagnostics.Debug.Assert(false); // Unexpected break; } }
public void Matrix3x2CreateRotationCenterTest() { float radians = MathHelper.ToRadians(30.0f); Vector2 center = new Vector2(23, 42); Matrix3x2 rotateAroundZero = Matrix3x2.CreateRotation(radians, Vector2.Zero); Matrix3x2 rotateAroundZeroExpected = Matrix3x2.CreateRotation(radians); Assert.True(MathHelper.Equal(rotateAroundZero, rotateAroundZeroExpected)); Matrix3x2 rotateAroundCenter = Matrix3x2.CreateRotation(radians, center); Matrix3x2 rotateAroundCenterExpected = Matrix3x2.CreateTranslation(-center) * Matrix3x2.CreateRotation(radians) * Matrix3x2.CreateTranslation(center); Assert.True(MathHelper.Equal(rotateAroundCenter, rotateAroundCenterExpected)); }
public void Matrix3x2CreateSkewCenterTest() { float skewX = 1, skewY = 2; Vector2 center = new Vector2(23, 42); Matrix3x2 skewAroundZero = Matrix3x2.CreateSkew(skewX, skewY, Vector2.Zero); Matrix3x2 skewAroundZeroExpected = Matrix3x2.CreateSkew(skewX, skewY); Assert.True(MathHelper.Equal(skewAroundZero, skewAroundZeroExpected)); Matrix3x2 skewAroundCenter = Matrix3x2.CreateSkew(skewX, skewY, center); Matrix3x2 skewAroundCenterExpected = Matrix3x2.CreateTranslation(-center) * Matrix3x2.CreateSkew(skewX, skewY) * Matrix3x2.CreateTranslation(center); Assert.True(MathHelper.Equal(skewAroundCenter, skewAroundCenterExpected)); }
private void canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args) { if (!finishedLoadingResources) { return; } float targetWidth = (float)sender.Size.Width; float targetHeight = (float)sender.Size.Height; float gridWidthInDips = gridWidth * cellSize; float gridHeightInDips = gridHeight * cellSize; // Some layout stuff float nextPieceGridSizeInDips = 5 * cellSize; Rect nextPieceArea = new Rect(gridWidthInDips + 100, 150, nextPieceGridSizeInDips, nextPieceGridSizeInDips); Rect gridBackground = new Rect(0, 0, gridWidthInDips, gridHeightInDips); Rect statisticsArea = new Rect(-275, 0, 175, 500); Rect linesClearedArea = new Rect(0, -120, 250, 50); args.DrawingSession.Antialiasing = CanvasAntialiasing.Aliased; args.DrawingSession.TextAntialiasing = CanvasTextAntialiasing.Aliased; args.DrawingSession.Transform = Matrix3x2.Identity; var cameraTransforms = GetCameraTransforms(args, targetWidth, targetHeight, gridWidthInDips, gridHeightInDips); // Patterned background backgroundBitmapBrush.Transform = Matrix3x2.CreateTranslation(backgroundScrollX, backgroundScrollY) * cameraTransforms.Final; args.DrawingSession.FillRectangle(0, 0, targetWidth, targetHeight, backgroundBitmapBrush); EnsurePrebakedDrawing(gridWidthInDips, gridHeightInDips, gridBackground, nextPieceArea, statisticsArea, linesClearedArea); // Draw prebaked content args.DrawingSession.Transform = cameraTransforms.Prebaked; args.DrawingSession.DrawImage(prebakedDrawing); Color black = Colors.Black; black.A = 128; args.DrawingSession.FillGeometry(prebakedGeometryInverseRegion, black); args.DrawingSession.Transform = cameraTransforms.Final; DrawNextPieceUI(args, nextPieceArea); DrawStatisticsUI(args, gridWidthInDips, statisticsArea); DrawLinesClearedUI(args, linesClearedArea); DrawScoreUI(args, gridWidthInDips); // Draw the grid for (int cellY = 0; cellY < gridHeight; ++cellY) { for (int cellX = 0; cellX < gridWidth; ++cellX) { int cell = grid.GetCell(cellX, cellY); if (cell == -1) { // No color. } else { DrawBlock(args.DrawingSession, cellX, cellY, cell); } } } var currentPiece = grid.GetCurrentPieceCoordinates(); // Draw the current piece for (int i = 0; i < 4; ++i) { DrawBlock(args.DrawingSession, currentPiece.Location[i].X, currentPiece.Location[i].Y, grid.GetCurrentPieceType()); } if (gameOver) { args.DrawingSession.Transform = Matrix3x2.Identity; Color semitransparentBlack = Colors.Black; semitransparentBlack.A = 128; args.DrawingSession.FillRectangle(0, 0, targetWidth, targetHeight, semitransparentBlack); CanvasTextFormat sadText = new CanvasTextFormat(); sadText.FontFamily = "Times New Roman"; sadText.FontSize = 300; args.DrawingSession.DrawText("GAME\n OVER", 0, 0, Colors.White, sadText); } if (rowClearingAnimation.IsAnimating()) { var rowsBeingCleared = grid.GetRowsBeingCleared(); Color white = Colors.White; white.A = 180; foreach (var row in rowsBeingCleared) { args.DrawingSession.FillRectangle(0, row * cellSize, gridWidthInDips, cellSize, white); } } if (showDebuggingAids) { // Draw the current and target camera locations args.DrawingSession.FillCircle(cameraX, cameraY, 7, Colors.Magenta); args.DrawingSession.FillCircle(cameraTargetX, cameraTargetY, 7, Colors.LightPink); // Draw a debugging guide over the whole thing args.DrawingSession.Transform = Matrix3x2.Identity; args.DrawingSession.DrawLine(targetWidth / 2, 0, targetWidth / 2, targetHeight, Colors.Red); args.DrawingSession.DrawLine(0, targetHeight / 2, targetWidth, targetHeight / 2, Colors.Red); } }
public static async Task ExportSvgAsync( ExportStyle style, InstalledFont selectedFont, FontVariant selectedVariant, Character selectedChar, CanvasTypography typography) { try { string name = $"{selectedFont.Name} - {selectedVariant.PreferredName} - {selectedChar.UnicodeString}.svg"; if (await PickFileAsync(name, "SVG", new[] { ".svg" }) is StorageFile file) { CachedFileManager.DeferUpdates(file); var device = Utils.CanvasDevice; var textColor = style == ExportStyle.Black ? Colors.Black : Colors.White; /* SVG Exports render at fixed size - but a) they're vectors, and b) they're * inside an auto-scaling viewport. So rendersize is *largely* pointless */ float canvasH = 1024f, canvasW = 1024f, fontSize = 1024f; using (CanvasTextLayout layout = new CanvasTextLayout(device, $"{selectedChar.Char}", new CanvasTextFormat { FontSize = fontSize, FontFamily = selectedVariant.Source, FontStretch = selectedVariant.FontFace.Stretch, FontWeight = selectedVariant.FontFace.Weight, FontStyle = selectedVariant.FontFace.Style, HorizontalAlignment = CanvasHorizontalAlignment.Center }, canvasW, canvasH)) { layout.SetTypography(0, 1, typography); using (CanvasGeometry temp = CanvasGeometry.CreateText(layout)) { var b = temp.ComputeBounds(); double scale = Math.Min(1, Math.Min(canvasW / b.Width, canvasH / b.Height)); Matrix3x2 transform = Matrix3x2.CreateTranslation(new Vector2((float)-b.Left, (float)-b.Top)) * Matrix3x2.CreateScale(new Vector2((float)scale)); using (CanvasGeometry geom = temp.Transform(transform)) { /* * Unfortunately this only constructs a monochrome path, if we want color * Win2D does not yet expose the neccessary API's to get the individual glyph * layers that make up a colour glyph. * * We'll need to handle this in C++/CX if we want to do this at some point. */ SVGPathReciever rc = new SVGPathReciever(); geom.SendPathTo(rc); Rect bounds = geom.ComputeBounds(); using (CanvasSvgDocument document = Utils.GenerateSvgDocument(device, bounds.Width, bounds.Height, rc)) { ((CanvasSvgNamedElement)document.Root.FirstChild).SetColorAttribute("fill", textColor); await Utils.WriteSvgAsync(document, file); } } } } await CachedFileManager.CompleteUpdatesAsync(file); } } catch (Exception ex) { await SimpleIoc.Default.GetInstance <IDialogService>() .ShowMessageBox(ex.Message, Localization.Get("SaveImageError")); } }
internal static void DrawIcon(Tile.Feature f, float scale, CanvasDrawingSession session, CanvasSvgDocument icon, Color black, Color darkGray) { float iconSize = 0.001f; Queue <uint> q = new Queue <uint>(f.Geometries); float cx = 0; float cy = 0; if (f.Type == Tile.GeomType.Point) { var cmd = DecodeCommand(q.Dequeue()); cx += DecodeParameter(q.Dequeue()) * scale; cy += DecodeParameter(q.Dequeue()) * scale; var m = session.Transform; session.Transform = Matrix3x2.CreateScale(0.25f, new Vector2(cx, cy)) * Matrix3x2.CreateTranslation(-2, -2); session.DrawSvg(icon, new Windows.Foundation.Size(iconSize, iconSize), cx - iconSize / 2f, cy - iconSize / 2f); session.Transform = m; //session.DrawCircle(cx, cy, 0.1f, Colors.Red); } }
/// <summary> /// Creates a translation matrix from the given vector. /// </summary> /// <param name="position">The translation position.</param> /// <returns>A translation matrix.</returns> public static Matrix3x2 CreateTranslation(PointF position) => Matrix3x2.CreateTranslation(position);
/// <summary> /// Performs translation on top matrix /// </summary> public void TranslateLocal(float transX, float transY) { m_top = Matrix3x2.CreateTranslation(transX, transY) * m_top; }
/// <summary> /// Performs translation on top matrix /// </summary> public void TranslateLocal(Vector2 transVector) { m_top = Matrix3x2.CreateTranslation(transVector) * m_top; }
protected override void UpdateGeometries() { var geo = CanvasGeometry.CreateRectangle(Context.Creator, new Rect(X2 - 2, Y2 - 2, 4, 4)); AddGeometry(new GeometryConfig { Geometry = geo, FillColor = Pen.Color }); using (var pathBuilder = new CanvasPathBuilder(Context.Creator)) { pathBuilder.BeginFigure(X1, Y1); pathBuilder.AddLine(X2, Y2); pathBuilder.AddLine(X3, Y3); pathBuilder.EndFigure(CanvasFigureLoop.Open); geo = CanvasGeometry.CreatePath(pathBuilder); AddGeometry(new GeometryConfig { Geometry = geo, Style = GeometryStyle.Stroke, StrokeColor = Pen.Color, StrokeWidth = Pen.Width }); } #region glyph if (IsGlyphVisible) { var r = (float)Math.Abs(Math.Atan((Y3 - Y2) / (X3 - X2))); var s = (float)Radians123; var gw = (float)Math.Cos(r) * Pen.GlyphSize; var gh = (float)Math.Sin(r) * Pen.GlyphSize; switch (P3Quadrant) { case 1: r = -r; gh = -gh; break; case 2: gh = -gh; r -= (float)Math.PI; break; case 3: r = (float)Math.PI - r; break; case 4: break; } switch (P3Quadrant) { case 2: case 3: gw = -gw; if (!isP1Upper) { s = -s; } break; case 1: case 4: if (isP1Upper) { s = -s; } break; } using (var pathBuilder = new CanvasPathBuilder(Context.Creator)) { pathBuilder.BeginFigure(gw + X2, gh + Y2); pathBuilder.AddArc(new Vector2(X2, Y2), Pen.GlyphSize, Pen.GlyphSize, r, s); pathBuilder.EndFigure(CanvasFigureLoop.Open); geo = CanvasGeometry.CreatePath(pathBuilder); AddGeometry(new GeometryConfig { Geometry = geo, Style = GeometryStyle.Stroke, StrokeColor = Pen.Color, StrokeWidth = Pen.Width }); } } #endregion #region Text var radians = -(float)Math.Atan((Y2 - Y3) / (X3 - X2)); var textLayout = CreateTextLayout(Angle.Round3().ToString() + "°", Context.Creator); var bounds = textLayout.LayoutBounds; var size = new Size(bounds.Width + 10, bounds.Height); var centerX = X2 + (X3 - X2 - size.Width) / 2; var centerY = Y2 + (Y3 - Y2 - size.Height) / 2; var ySegment = size.Height / 2 + Pen.Width / 2 + 5; var offsetX = Math.Sin(radians) * ySegment; var offsetY = Math.Cos(radians) * ySegment; offsetX = Math.Abs(offsetX); offsetX = radians < 0 ? offsetX : -offsetX; var left = centerX - offsetX; var top = centerY - offsetY; var rotation = Matrix3x2.CreateRotation(radians, new Vector2((float)(left + size.Width / 2), (float)(top + size.Height / 2))); geo = CanvasGeometry .CreateRectangle(Context.Creator, new Rect(left, top, size.Width, size.Height)) .Transform(rotation); AddGeometry(new GeometryConfig { Geometry = geo, FillColor = Pen.TextBackground }); geo = CanvasGeometry .CreateText(textLayout) .Transform(Matrix3x2.CreateTranslation((float)left + 5, (float)top)) .Transform(rotation); AddGeometry(new GeometryConfig { Geometry = geo, IsHitTestUnit = false, FillColor = Pen.TextColor }); #endregion }
void Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args) { var ds = args.DrawingSession; foreach (var ball in bouncingBalls) { switch (CurrentMode) { case LayerMode.LayerFade: // Fade the layer opacity in and out. // Note how this produces different results from LayerMode.PerPrimitiveFade! using (ds.CreateLayer(ball.FadeAlpha)) { ball.Draw(ds); } break; case LayerMode.PerPrimitiveFade: // Not using layers at all: fade in and out by individually modifying the alpha // of each primitive that makes up the ball shape. The result is quite different // from LayerMode.LayerFade, which fades out the entire contents of the layer // as a single operation. When primitives are faded individually, making the // main filled circle partially translucent allows the black drop shadow circle // to show through from below it, so the balls become darker as they fade out. // Also note how the inner portion of the white X becomes visible during fades, // which it is not when using LayerMode.LayerFade. ball.Draw(ds, ball.FadeAlpha); break; case LayerMode.OpacityBrush: // Use a brush to modify opacity of the layer contents. gradientBrush.Center = ball.Position; gradientBrush.RadiusX = gradientBrush.RadiusY = ball.Radius * ball.FadeAlpha * 3; using (ds.CreateLayer(gradientBrush)) { ball.Draw(ds); } break; case LayerMode.ClipGeometry: // Clip the layer using a geometry region. var clipTransform = Matrix3x2.CreateRotation(ball.FadeAge * 2) * Matrix3x2.CreateScale(ball.Radius * ball.FadeAlpha * 4) * Matrix3x2.CreateTranslation(ball.Position); using (ds.CreateLayer(1, clipGeometry, clipTransform)) { ball.Draw(ds); } break; } } if (CurrentMode == LayerMode.PerPrimitiveFade) { ds.DrawText("Not using layers!\n\n" + "Note how the drop shadow circles and inside of\n" + "the white X's show through as the shapes fade out", sender.Size.ToVector2() / 2, Colors.White, textFormat); } }
private void doDraw(CanvasDrawingSession ds) { ds.FillRectangle(new Rect(0.0, 0.0, ActualWidth, ActualHeight), Color.FromArgb(255, 255, 240, 224)); // Note loop and dancer speed // ... // For interactive leadin, show countdown // ... // Scale coordinate system to dancer's size var range = Math.Min(ActualWidth, ActualHeight); ds.Transform = Matrix3x2.CreateTranslation(new Vector2((float)ActualWidth / 2, (float)ActualHeight / 2)); var s = range / 13; // Flip and rotate ds.Transform = Matrix.CreateScale(s, -s) * ds.Transform; ds.Transform = Matrix.CreateRotation(Math.PI / 2) * ds.Transform; // Draw grid if on if (showGrid) { GeometryMaker.makeOne(geometry).drawGrid(s, ds); } // Always show bigon center mark if (geometry == GeometryType.BIGON) { ds.DrawLine(0, -0.5f, 0, 0.5f, Colors.Black, 1 / (float)s); ds.DrawLine(-0.5f, 0, 0.5f, 0, Colors.Black, 1 / (float)s); } // Draw paths if requested foreach (Dancer d in dancers) { if (!d.hidden && (showPaths || d.showPath)) { d.drawPath(ds); } } // Draw handholds foreach (Dancer d in dancers) { var loc = d.location; if (d.rightHandVisibility) { if (d.rightdancer == null) // hexagon center { } else if (d.rightdancer.CompareTo(d) < 0) { var loc2 = d.rightdancer.location; ds.DrawLine(loc, loc2, Colors.Orange, 0.05f); ds.FillCircle((loc + loc2) / 2, 0.125f, Colors.Orange); } } if (d.leftHandVisibility) { if (d.leftdancer == null) // hexagon center { } else if (d.leftdancer.CompareTo(d) < 0) { var loc2 = d.leftdancer.location; ds.DrawLine(loc, loc2, Colors.Orange, 0.05f); ds.FillCircle((loc + loc2) / 2, 0.125f, Colors.Orange); } } } // Draw dancers foreach (Dancer d in dancers) { if (!d.hidden) { var txsave = ds.Transform; ds.Transform = d.tx * ds.Transform; d.draw(ds); ds.Transform = txsave; } } }
public static void Apply() { //XYWH int X = (int)App.Setting.CropX; int Y = (int)App.Setting.CropY; int W = (int)App.Setting.CropW; int H = (int)App.Setting.CropH; Matrix3x2 Matrix = Matrix3x2.CreateTranslation(-App.Model.Width / 2, -App.Model.Height / 2) * Matrix3x2.CreateRotation(App.Setting.CropAngle) * Matrix3x2.CreateTranslation(App.Model.Width / 2, App.Model.Height / 2) * Matrix3x2.CreateTranslation(-X, -Y); //跟随宽高 App.Model.X += (App.Model.Width - W) / 2 * App.Model.XS; App.Model.Y += (App.Model.Height - H) / 2 * App.Model.YS; App.Model.CanvasWidth = W * App.Model.XS; App.Model.CanvasHeight = H * App.Model.YS; App.Model.Width = W; App.Model.Height = H; foreach (Layer L in App.Model.Layers) { CanvasRenderTarget crt = new CanvasRenderTarget(App.Model.VirtualControl, W, H); using (CanvasDrawingSession ds = crt.CreateDrawingSession()) { ds.DrawImage(new Transform2DEffect { Source = L.CanvasRenderTarget, TransformMatrix = Matrix }); } L.CanvasRenderTarget = crt; L.SetWriteableBitmap(App.Model.VirtualControl); if (App.Model.isLowView) { L.LowView(); } else { L.SquareView(); } } //初始化 App.Initialize(App.Model.VirtualControl, W, H); App.Model.MaskAnimatedTarget = new CanvasRenderTarget(App.Model.AnimatedControl, W, H); //Undo:撤销 App.Model.Undos.Clear();//清空 App.Model.UndoIndex = 0; App.Model.isUndo = false; App.Model.isRedo = false; }
/** * Draws SVG to fit into a image of the specified dimensions * @deprecated * */ public CanvasRenderTarget Draw(int width, int height, Color lineColor, Color fillColor) { CanvasDevice device = CanvasDevice.GetSharedDevice(); CanvasRenderTarget crt = new CanvasRenderTarget(device, width, height, 96); ////BitmapImage bmp = new BitmapImage(); ////SoftwareBitmap sb = new SoftwareBitmap(BitmapPixelFormat.Rgba8, width, height); //WriteableBitmap wbmp = new WriteableBitmap(width, height); //crt.GetPixelBytes(wbmp.PixelBuffer); Rect rect = _cg.ComputeBounds(); Matrix3x2 m = new Matrix3x2(); float sx = (float)(width / rect.Width); float sy = (float)(height / rect.Height); if (sx < sy) { m = Matrix3x2.CreateScale(sx, sx); } else { m = Matrix3x2.CreateScale(sy, sy); } _cg.Transform(m); rect = _cg.ComputeBounds(); m = new Matrix3x2(); float transx = 0; float transy = 0; if (rect.X < 0) { transx = (float)rect.X * -1.0f; } if (rect.Y < 0) { transy = (float)rect.Y * -1.0f; } m = Matrix3x2.CreateTranslation(transx, transy); _cg.Transform(m); rect = _cg.ComputeBounds(); //Debug.WriteLine(rect.ToString()); using (CanvasDrawingSession ds = crt.CreateDrawingSession()) { ds.Clear(Colors.Transparent); ds.DrawGeometry(_cg, Colors.Red, 1f); Color c = Color.FromArgb(128, 0, 255, 255); ds.FillGeometry(_cg, c); ds.DrawRectangle(0, 0, width - 1, height - 1, Colors.Green); } return(crt); }//*/
void EnsurePrebakedDrawing( float gridWidthInDips, float gridHeightInDips, Rect gridBackground, Rect nextPieceArea, Rect statisticsArea, Rect linesClearedArea) { if (prebakedDrawingValid) { return; } // This pre-baked image will be drawn at the camera transform. using (var ds = prebakedDrawing.CreateDrawingSession()) { ds.Antialiasing = CanvasAntialiasing.Aliased; ds.TextAntialiasing = CanvasTextAntialiasing.Aliased; ds.Clear(Colors.Transparent); ds.DrawRectangle(0, 0, (float)prebakedDrawing.Size.Width, (float)prebakedDrawing.Size.Height, Colors.Black, 15); float margin = 30; ds.DrawRectangle(margin, margin, (float)prebakedDrawing.Size.Width - margin - margin, (float)prebakedDrawing.Size.Height - margin - margin, Colors.Black, 2); margin = 25; ds.DrawRectangle(margin, margin, (float)prebakedDrawing.Size.Width - margin - margin, (float)prebakedDrawing.Size.Height - margin - margin, Colors.Black, 2); // Fixed camera float cameraX = gridWidthInDips / 2; float cameraY = gridHeightInDips / 2; var translate = Matrix3x2.CreateTranslation( ((float)prebakedDrawing.Size.Width / 2) - cameraX, ((float)prebakedDrawing.Size.Height / 2) - cameraY); ds.Transform = translate; FillDarkBackground(ds, gridBackground); FillDarkBackground(ds, nextPieceArea); DrawStyledText(ds, "Next", (float)nextPieceArea.X, (float)nextPieceArea.Y); FillDarkBackground(ds, statisticsArea); DrawStyledText(ds, "Statistics", (float)statisticsArea.X, (float)statisticsArea.Y); int y = (int)statisticsArea.Y; PieceType[] types = new PieceType[] { PieceType.T, PieceType.R, PieceType.Z, PieceType.O, PieceType.S, PieceType.L, PieceType.I }; foreach (var type in types) { var coords = grid.GetPieceCoordinates((int)type); for (int i = 0; i < 4; ++i) { DrawBlock(ds, coords.Location[i].X, coords.Location[i].Y, (int)type, (int)statisticsArea.X, y); } y += 65; } FillDarkBackground(ds, linesClearedArea); var targetRectangle = CanvasGeometry.CreateRectangle(ds, 0, 0, (float)prebakedDrawing.Size.Width, (float)prebakedDrawing.Size.Height); var hugeRectangle = CanvasGeometry.CreateRectangle(ds, -10000, -10000, 20000, 20000); prebakedGeometryInverseRegion = hugeRectangle.CombineWith(targetRectangle, Matrix3x2.Identity, CanvasGeometryCombine.Exclude); } prebakedDrawingValid = true; }
private void canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args) { var ds = args.DrawingSession; Rect rect = new Rect(0, 0, sender.ActualWidth, sender.ActualHeight); if (ThumbnailGenerator.IsDrawingThumbnail) { rect.Width = sender.ActualWidth / 2; } if (!ThumbnailGenerator.IsDrawingThumbnail) { ds.DrawText("Win2D DrawText", rect, drawingColor, new CanvasTextFormat() { FontSize = 14, HorizontalAlignment = CanvasHorizontalAlignment.Center, VerticalAlignment = CanvasVerticalAlignment.Top }); DrawAlignedText(ds, rect, CanvasHorizontalAlignment.Left, CanvasVerticalAlignment.Top); DrawAlignedText(ds, rect, CanvasHorizontalAlignment.Right, CanvasVerticalAlignment.Top); DrawAlignedText(ds, rect, CanvasHorizontalAlignment.Left, CanvasVerticalAlignment.Bottom); DrawAlignedText(ds, rect, CanvasHorizontalAlignment.Right, CanvasVerticalAlignment.Bottom); } var screenCenter = new Size(sender.ActualWidth, sender.ActualHeight).ToVector2() / 2; Matrix3x2 directionTransform = GetDirectionTransform(CurrentDirection); var arrowBounds = arrow.ComputeStrokeBounds(4); var arrowCenter = new Size(arrowBounds.Width, arrowBounds.Height).ToVector2() / 2; float scaleAmount = (float)Math.Max(5.0, (rect.Width / arrowBounds.Width) / 4); var scaleAndPositionTransform = Matrix3x2.CreateScale(scaleAmount, scaleAmount, arrowCenter) * Matrix3x2.CreateTranslation(screenCenter - arrowCenter); ds.Transform = directionTransform * scaleAndPositionTransform; ds.DrawGeometry(MakeDirectionIcon(ds), drawingColor, 4, new CanvasStrokeStyle() { TransformBehavior = CanvasStrokeTransformBehavior.Fixed }); }
public static async Task ExportPngAsync( ExportStyle style, InstalledFont selectedFont, FontVariant selectedVariant, Character selectedChar, CanvasTypography typography) { try { string name = $"{selectedFont.Name} - {selectedVariant.PreferredName} - {selectedChar.UnicodeString}.png"; if (await PickFileAsync(name, "Png Image", new[] { ".png" }) is StorageFile file) { CachedFileManager.DeferUpdates(file); var device = Utils.CanvasDevice; var localDpi = 96; //Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi; var canvasH = (float)App.AppSettings.PngSize; var canvasW = (float)App.AppSettings.PngSize; var renderTarget = new CanvasRenderTarget(device, canvasW, canvasH, localDpi); using (var ds = renderTarget.CreateDrawingSession()) { ds.Clear(Colors.Transparent); var d = App.AppSettings.PngSize; var r = App.AppSettings.PngSize / 2; var textColor = style == ExportStyle.Black ? Colors.Black : Colors.White; var fontSize = (float)d; using (CanvasTextLayout layout = new CanvasTextLayout(device, $"{selectedChar.Char}", new CanvasTextFormat { FontSize = fontSize, FontFamily = selectedVariant.Source, FontStretch = selectedVariant.FontFace.Stretch, FontWeight = selectedVariant.FontFace.Weight, FontStyle = selectedVariant.FontFace.Style, HorizontalAlignment = CanvasHorizontalAlignment.Center, Options = style == ExportStyle.ColorGlyph ? CanvasDrawTextOptions.EnableColorFont : CanvasDrawTextOptions.Default }, canvasW, canvasH)) { if (style == ExportStyle.ColorGlyph) { layout.Options = CanvasDrawTextOptions.EnableColorFont; } layout.SetTypography(0, 1, typography); var db = layout.DrawBounds; double scale = Math.Min(1, Math.Min(canvasW / db.Width, canvasH / db.Height)); var x = -db.Left + ((canvasW - (db.Width * scale)) / 2d); var y = -db.Top + ((canvasH - (db.Height * scale)) / 2d); ds.Transform = Matrix3x2.CreateTranslation(new Vector2((float)x, (float)y)) * Matrix3x2.CreateScale(new Vector2((float)scale)); ds.DrawTextLayout(layout, new Vector2(0), textColor); } } using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite)) { fileStream.Size = 0; await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Png, 1f); } await CachedFileManager.CompleteUpdatesAsync(file); } } catch (Exception ex) { await SimpleIoc.Default.GetInstance <IDialogService>() .ShowMessageBox(ex.Message, Localization.Get("SaveImageError")); } }
private Matrix3x2 GetDirectionTransform(CanvasTextDirection direction) { var arrowBounds = arrow.ComputeStrokeBounds(4); var arrowCenter = new Size(arrowBounds.Width, arrowBounds.Height).ToVector2() / 2; Matrix3x2 directionTransform = Matrix3x2.Identity; switch (direction) { case CanvasTextDirection.LeftToRightThenTopToBottom: directionTransform = Matrix3x2.Identity; break; case CanvasTextDirection.RightToLeftThenTopToBottom: directionTransform = Matrix3x2.CreateScale(-1, 1); break; case CanvasTextDirection.LeftToRightThenBottomToTop: directionTransform = Matrix3x2.CreateScale(1, -1); break; case CanvasTextDirection.RightToLeftThenBottomToTop: directionTransform = Matrix3x2.CreateScale(-1, -1); break; case CanvasTextDirection.TopToBottomThenLeftToRight: directionTransform = Matrix3x2.CreateRotation((float)Math.PI / 2) * Matrix3x2.CreateScale(-1, 1); break; case CanvasTextDirection.BottomToTopThenLeftToRight: directionTransform = Matrix3x2.CreateRotation((float)-Math.PI / 2); break; case CanvasTextDirection.TopToBottomThenRightToLeft: directionTransform = Matrix3x2.CreateRotation((float)Math.PI / 2); break; case CanvasTextDirection.BottomToTopThenRightToLeft: directionTransform = Matrix3x2.CreateRotation((float)-Math.PI / 2) * Matrix3x2.CreateScale(-1, 1); break; } directionTransform = Matrix3x2.CreateTranslation(-arrowCenter) * directionTransform * Matrix3x2.CreateTranslation(arrowCenter); return(directionTransform); }
public override void Draw(GameTime gameTime) { base.Draw(gameTime); using (var ds = this.GraphicsDevice.CreateDrawingSession()) { if (gameTime.TotalGameTime.Seconds >= 2) { ds.Clear(Colors.AliceBlue); } if (gameTime.TotalGameTime.Seconds >= 4) { ds.Clear(Colors.AntiqueWhite); } if (gameTime.TotalGameTime.Seconds >= 6) { ds.Clear(Colors.Aqua); } if (gameTime.TotalGameTime.Seconds >= 8) { ds.Clear(Colors.Aquamarine); } if (gameTime.TotalGameTime.Seconds >= 10) { ds.Clear(Colors.CornflowerBlue); } ds.DrawText("Hello GameFramework", new Vector2(0, 0), Colors.Black); ds.DrawText($"GameTime.ElapsedGameTime = {gameTime.ElapsedGameTime.TotalMilliseconds}", new Vector2(0, 40), Colors.Black); ds.DrawText($"GameTime.TotalGameTime = {gameTime.TotalGameTime}", new Vector2(0, 60), Colors.Black); ds.DrawText($"GameTime.UpdateCount = {gameTime.UpdateCount}", new Vector2(0, 80), Colors.Black); ds.DrawText($"GameTime.IsRunningSlowly = {gameTime.IsRunningSlowly}", new Vector2(0, 100), Colors.Black); float frameRate = 1 / (float)gameTime.ElapsedGameTime.TotalSeconds; ds.DrawText($"FrameRate = {frameRate}", new Vector2(0, 120), Colors.Black); ds.DrawText("LogicalDPI = " + this.GraphicsDevice.LogicalDpi, new Vector2(0, 160), Colors.Black); ds.DrawText("Size = " + this.GraphicsDevice.Size.ToString(), new Vector2(0, 180), Colors.Black); var matrix3X2 = Matrix3x2.CreateTranslation(100, 100); ds.Draw(this.maxBitmap, matrix3X2, Vector4.One); KeyboardState keyBoardState = this.keyboard.GetState(); if (keyBoardState.PressedKeys.Count > 0) { ds.DrawText("KeyboardState: " + keyBoardState.PressedKeys.Count + " keys pressed", new Vector2(10, 300), Colors.Black); var keyList = keyBoardState.PressedKeys.ToList(); for (int i = 0; i < keyList.Count; i++) { ds.DrawText("KeyboardState: " + keyList[i].ToString() + " pressed", new Vector2(10, 315 + (i * 15)), Colors.Black); } } // this.spriteBatch.Begin(); // this.spriteBatch.Draw(); } }
public void Translate(float dx, float dy) { ds.Transform *= Matrix3x2.CreateTranslation(dx, dy); }
public void Matrix3x2CreateScaleCenterTest3() { Vector2 scale = new Vector2(3, 4); Vector2 center = new Vector2(23, 42); Matrix3x2 scaleAroundZero = Matrix3x2.CreateScale(scale.X, scale.Y, Vector2.Zero); Matrix3x2 scaleAroundZeroExpected = Matrix3x2.CreateScale(scale.X, scale.Y); Assert.True(MathHelper.Equal(scaleAroundZero, scaleAroundZeroExpected)); Matrix3x2 scaleAroundCenter = Matrix3x2.CreateScale(scale.X, scale.Y, center); Matrix3x2 scaleAroundCenterExpected = Matrix3x2.CreateTranslation(-center) * Matrix3x2.CreateScale(scale.X, scale.Y) * Matrix3x2.CreateTranslation(center); Assert.True(MathHelper.Equal(scaleAroundCenter, scaleAroundCenterExpected)); }
private static void SendResponse(IAsyncResult state) { try { HttpListenerContext ctx = listener.EndGetContext(state); if (ctx.Request.Url.AbsolutePath.Equals("/")) { LibPCars2.SharedMemory.TelemetryData telemetry = GameConnectHandler.Telemetry; if (telemetry == null) { ctx.Response.StatusCode = 500; ctx.Response.OutputStream.Close(); } else { DataTransfer.OverlayExport jsonOutput = new DataTransfer.OverlayExport(telemetry); ctx.Response.ContentEncoding = Encoding.UTF8; ctx.Response.ContentType = "application/json"; StreamWriter s = new StreamWriter(ctx.Response.OutputStream, new UTF8Encoding(false)); JsonSerializer jsonCodec = new JsonSerializer(); jsonCodec.Serialize(s, jsonOutput); s.Close(); } } else if (ctx.Request.Url.AbsolutePath.Equals("/carPosition")) { LibPCars2.SharedMemory.TelemetryData telemetry = GameConnectHandler.Telemetry; if (telemetry != null && telemetry.ViewedParticipantIndex != -1) { LibPCars2.SharedMemory.ParticipantInfo p = telemetry.Participants[telemetry.ViewedParticipantIndex]; LibPCars2.SharedMemory.ParticipantInfoEx pEx = telemetry.ParticipantsEx[telemetry.ViewedParticipantIndex]; lastPosition = new Vector2(p.WorldPosition.X, p.WorldPosition.Z); lastOrientation = new Vector3(pEx.Orientation.X, pEx.Orientation.Y, pEx.Orientation.Z); } Vector2 position = Vector2.Transform(lastPosition, worldTransform); Matrix4x4 rotation = GenerateRotation(lastOrientation.X, lastOrientation.Y, lastOrientation.Z); Vector3 forwardX = Vector3.Normalize(Vector3.Transform(Vector3.UnitX, rotation)); Vector3 forwardZ = Vector3.Normalize(Vector3.Transform(Vector3.UnitZ, rotation)); float rCos = (forwardX.X + forwardZ.Z) / 2; float rSin = (forwardX.Z - forwardZ.X) / 2; Matrix3x2 totalTransform = new Matrix3x2(-rCos, rSin, -rSin, -rCos, 0, 0) * Matrix3x2.CreateTranslation(position); ctx.Response.ContentEncoding = Encoding.UTF8; ctx.Response.ContentType = "application/json"; StreamWriter s = new StreamWriter(ctx.Response.OutputStream, new UTF8Encoding(false)); JsonSerializer jsonCodec = new JsonSerializer(); jsonCodec.Serialize(s, new { position, transformMatrix = totalTransform, }); s.Close(); } else if (ctx.Request.Url.AbsolutePath.Equals("/map")) { ctx.Response.ContentEncoding = Encoding.UTF8; ctx.Response.ContentType = "text/html"; using (FileStream workFile = new FileStream("Resources/mapOverlay.html", FileMode.Open, FileAccess.Read)) { workFile.CopyTo(ctx.Response.OutputStream); } ctx.Response.OutputStream.Close(); } else if (ctx.Request.Url.AbsolutePath.Equals("/update")) { ctx.Response.StatusCode = 200; string name = ctx.Request.QueryString["driver"]; if (!string.IsNullOrWhiteSpace(name)) { ReturnData.DriverName = name; } else { ctx.Response.StatusCode = 400; } ctx.Response.OutputStream.Close(); } else { ctx.Response.StatusCode = 404; ctx.Response.OutputStream.Close(); } listener.BeginGetContext(SendResponse, null); } catch (ObjectDisposedException) { listener = null; } }
protected override void DrawChart(CanvasDrawingSession canvas) { if (chartData == null) { return; } int transitionAlpha = 255; if (canvas != null) { //canvas.save(); } if (transitionMode == TRANSITION_MODE_CHILD) { transitionAlpha = (int)(transitionParams.progress * transitionParams.progress * 255); } if (isEmpty) { if (emptyDataAlpha != 0) { emptyDataAlpha -= 0.12f; if (emptyDataAlpha < 0) { emptyDataAlpha = 0; } Invalidate(); } } else { if (emptyDataAlpha != 1f) { emptyDataAlpha += 0.12f; if (emptyDataAlpha > 1f) { emptyDataAlpha = 1f; } Invalidate(); } } transitionAlpha = (int)(transitionAlpha * emptyDataAlpha); float sc = 0.4f + emptyDataAlpha * 0.6f; if (canvas != null) { canvas.Transform = Matrix3x2.CreateScale( new Vector2(sc, sc), new Vector2(chartArea.centerX(), chartArea.centerY()) ); } int radius = (int)((chartArea.Width > chartArea.Height ? chartArea.Height : chartArea.Width) * 0.45f); rectF = CreateRect( chartArea.centerX() - radius, chartArea.centerY() + 16 - radius, chartArea.centerX() + radius, chartArea.centerY() + 16 + radius ); float a = 0f; float rText; int n = lines.Count; float localSum = 0f; for (int i = 0; i < n; i++) { float v = lines[i].drawingPart * lines[i].alpha; localSum += v; } if (localSum == 0) { if (canvas != null) { //canvas.restore(); } return; } for (int i = 0; i < n; i++) { if (lines[i].alpha <= 0 && !lines[i].enabled) { continue; } lines[i].paint.A = (byte)transitionAlpha; float currentPercent = lines[i].drawingPart / localSum * lines[i].alpha; darawingValuesPercentage[i] = currentPercent; if (currentPercent == 0) { continue; } if (canvas != null) { //canvas.save(); } float textAngle = -90 + a + currentPercent / 2f * 360f; if (lines[i].selectionA > 0f) { float ai = INTERPOLATOR.getInterpolation(lines[i].selectionA); if (canvas != null) { canvas.Transform = Matrix3x2.CreateTranslation( MathF.Cos(MathFEx.ToRadians(textAngle)) * 8 * ai, MathF.Sin(MathFEx.ToRadians(textAngle)) * 8 * ai ); } } //lines[i].paint.setStyle(Paint.Style.FILL_AND_STROKE); lines[i].paint.StrokeWidth = 1; //lines[i].paint.setAntiAlias(!USE_LINES); if (canvas != null && transitionMode != TRANSITION_MODE_CHILD) { //canvas.drawArc( // rectF, // a, // (currentPercent) * 360f, // true, // lines[i].paint); var b = a + currentPercent * 360f; var builder = new CanvasPathBuilder(canvas); var center = new Vector2((float)rectF.X + (float)rectF.Width / 2, (float)rectF.Y + (float)rectF.Height / 2); builder.BeginFigure(center); builder.AddLine( new Vector2( (float)(center.X + Math.Sin(a * Math.PI / 180) * (float)rectF.Width / 2), (float)(center.Y - Math.Cos(a * Math.PI / 180) * (float)rectF.Height / 2))); builder.AddArc( new Vector2( (float)(center.X + Math.Sin(b * Math.PI / 180) * (float)rectF.Width / 2), (float)(center.Y - Math.Cos(b * Math.PI / 180) * (float)rectF.Height / 2)), (float)rectF.Width / 2, (float)rectF.Height / 2, 0, CanvasSweepDirection.Clockwise, (b - a) >= 180.0 ? CanvasArcSize.Large : CanvasArcSize.Small); builder.EndFigure(CanvasFigureLoop.Closed); canvas.FillGeometry(CanvasGeometry.CreatePath(builder), lines[i].paint.Color); //lines[i].paint.setStyle(Paint.Style.STROKE); //canvas.restore(); canvas.Transform = Matrix3x2.Identity; } lines[i].paint.A = 255; a += currentPercent * 360f; } a = 0f; if (canvas != null) { var textFormat = new CanvasTextFormat(); var textLayout = new CanvasTextLayout(canvas, "100%", textFormat, float.PositiveInfinity, float.PositiveInfinity); for (int i = 0; i < n; i++) { if (lines[i].alpha <= 0 && !lines[i].enabled) { continue; } float currentPercent = lines[i].drawingPart * lines[i].alpha / localSum; //canvas.save(); float textAngle = -90 + a + currentPercent / 2f * 360f; if (lines[i].selectionA > 0f) { float ai = INTERPOLATOR.getInterpolation(lines[i].selectionA); canvas.Transform = Matrix3x2.CreateTranslation( MathF.Cos(MathFEx.ToRadians(textAngle)) * 8 * ai, MathF.Sin(MathFEx.ToRadians(textAngle)) * 8 * ai ); } int percent = (int)(100f * currentPercent); if (currentPercent >= 0.02f && percent > 0 && percent <= 100) { rText = (float)(rectF.Width * 0.42f * Math.Sqrt(1f - currentPercent)); //textPaint.setTextSize(MIN_TEXT_SIZE + currentPercent * MAX_TEXT_SIZE); //textPaint.setAlpha((int)(transitionAlpha * lines[i].alpha)); //canvas.drawText( // lookupTable[percent], // (float)(rectF.centerX() + rText * Math.Cos(MathEx.ToRadians(textAngle))), // (float)(rectF.centerY() + rText * Math.Sin(MathEx.ToRadians(textAngle))) - ((textPaint.descent() + textPaint.ascent()) / 2), // textPaint); var regions = textLayout.GetCharacterRegions(0, lookupTable[percent].Length); canvas.DrawText( lookupTable[percent], rectF.centerX() + rText * MathF.Cos(MathFEx.ToRadians(textAngle)) - (float)regions[0].LayoutBounds.Width / 2, rectF.centerY() + rText * MathF.Sin(MathFEx.ToRadians(textAngle)) - (float)regions[0].LayoutBounds.Height / 2 /*- ((textPaint.descent() + textPaint.ascent()) / 2)*/, Color.FromArgb((byte)(transitionAlpha * lines[i].alpha), 255, 255, 255) ); } //canvas.restore(); canvas.Transform = Matrix3x2.Identity; lines[i].paint.A = 255; a += currentPercent * 360f; } //canvas.restore(); canvas.Transform = Matrix3x2.Identity; } }
/** * Animation related methods **/ /* * methods to do with manipulating animations **/ private async Task RunAnimation(Animation animation, bool revert) { animationsRunningCount++; List <InkStroke> strokesToAnimate = new List <InkStroke>(); ClearSelection(); foreach (var s in animation.inkStrokesId) { // check if stroke still exists var stroke = inkCanvas.InkPresenter.StrokeContainer.GetStrokeById(s); if (stroke != null && inkCanvas.InkPresenter.StrokeContainer.GetStrokes().Contains(stroke)) { strokesToAnimate.Add(stroke); } } if (strokesToAnimate.Count == 0) { // we can delete this current animation entry animations.GetAnimations().Remove(animation); polyCanvas.Children.Remove(animation.GetPolyline()); polyCanvas.Children.Remove(animation.nameText); return; } var delta = animation.startPoint; var pline = animation.GetPolyline(); pline.Opacity = 1; animation.isActive = true; animation.nameText.Opacity = 1; Rect currentPosition; lock (moveSelectedLock) { currentPosition = FindCurrentPositionForAnimation(strokesToAnimate); } foreach (InkStroke stroke in strokesToAnimate) { stroke.PointTransform = Matrix3x2.CreateTranslation((float)(animation.startPoint.X - (currentPosition.X + currentPosition.Width / 2) + stroke.PointTransform.Translation.X), (float)(animation.startPoint.Y - (currentPosition.Y + currentPosition.Height / 2) + stroke.PointTransform.Translation.Y)); } var i = -1; //Stopwatch stopwatch = Stopwatch.StartNew(); foreach (Point pt in animation.GetPolyline().Points) { foreach (InkStroke stroke in strokesToAnimate) { stroke.PointTransform = Matrix3x2.CreateTranslation((float)(pt.X - delta.X + stroke.PointTransform.Translation.X), (float)(pt.Y - delta.Y + stroke.PointTransform.Translation.Y)); } delta = pt; await Task.Delay(TimeSpan.FromSeconds(0.001)); i++; } //stopwatch.Stop(); //Debug.WriteLine("ms " + stopwatch.ElapsedMilliseconds); if (revert) { lock (moveSelectedLock) { currentPosition = FindCurrentPositionForAnimation(strokesToAnimate); } foreach (InkStroke stroke in strokesToAnimate) { stroke.PointTransform = Matrix3x2.CreateTranslation((float)(animation.startPoint.X - (currentPosition.X + currentPosition.Width / 2) + stroke.PointTransform.Translation.X), (float)(animation.startPoint.Y - (currentPosition.Y + currentPosition.Height / 2) + stroke.PointTransform.Translation.Y)); } } pline.Opacity = togglePath.IsChecked == true ? 0.5 : 0; animation.nameText.Opacity = togglePath.IsChecked == true ? 0.5 : 0; animation.isActive = false; foreach (var stroke in inkCanvas.InkPresenter.StrokeContainer.GetStrokes()) { stroke.Selected = false; } animationsRunningCount--; }
public static async Task <ExportResult> ExportPngAsync( ExportStyle style, InstalledFont selectedFont, CharacterRenderingOptions options, Character selectedChar, AppSettings settings) { try { using var typography = options.CreateCanvasTypography(); string name = GetFileName(selectedFont, options.Variant, selectedChar, "png"); if (await PickFileAsync(name, "PNG Image", new[] { ".png" }) is StorageFile file) { CachedFileManager.DeferUpdates(file); if (options.Analysis.GlyphFormats.Contains(GlyphImageFormat.Png)) { IBuffer buffer = GetGlyphBuffer(options.Variant.FontFace, selectedChar.UnicodeIndex, GlyphImageFormat.Png); await FileIO.WriteBufferAsync(file, buffer); } else { var device = Utils.CanvasDevice; var localDpi = 96; //Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi; var canvasH = (float)settings.PngSize; var canvasW = (float)settings.PngSize; using var renderTarget = new CanvasRenderTarget(device, canvasW, canvasH, localDpi); using (var ds = renderTarget.CreateDrawingSession()) { ds.Clear(Colors.Transparent); var d = settings.PngSize; var r = settings.PngSize / 2; var textColor = style == ExportStyle.Black ? Colors.Black : Colors.White; var fontSize = (float)d; using CanvasTextLayout layout = new CanvasTextLayout(device, $"{selectedChar.Char}", new CanvasTextFormat { FontSize = fontSize, FontFamily = options.Variant.Source, FontStretch = options.Variant.FontFace.Stretch, FontWeight = options.Variant.FontFace.Weight, FontStyle = options.Variant.FontFace.Style, HorizontalAlignment = CanvasHorizontalAlignment.Center, Options = style == ExportStyle.ColorGlyph ? CanvasDrawTextOptions.EnableColorFont : CanvasDrawTextOptions.Default }, canvasW, canvasH); if (style == ExportStyle.ColorGlyph) { layout.Options = CanvasDrawTextOptions.EnableColorFont; } layout.SetTypography(0, 1, typography); var db = layout.DrawBounds; double scale = Math.Min(1, Math.Min(canvasW / db.Width, canvasH / db.Height)); var x = -db.Left + ((canvasW - (db.Width * scale)) / 2d); var y = -db.Top + ((canvasH - (db.Height * scale)) / 2d); ds.Transform = Matrix3x2.CreateTranslation(new Vector2((float)x, (float)y)) * Matrix3x2.CreateScale(new Vector2((float)scale)); ds.DrawTextLayout(layout, new Vector2(0), textColor); } using var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite); fileStream.Size = 0; await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Png, 1f); } await CachedFileManager.CompleteUpdatesAsync(file); return(new ExportResult(true, file)); } } catch (Exception ex) { await Ioc.Default.GetService <IDialogService>() .ShowMessageAsync(ex.Message, Localization.Get("SaveImageError")); } return(new ExportResult(false, null)); }
public static void Render(bool isNumber = false) { App.Model.SecondCanvasImage = new Transform2DEffect { Source = App.Model.SecondTopRenderTarget, TransformMatrix = Matrix3x2.CreateTranslation(-App.Model.Width / 2, -App.Model.Height / 2) * Matrix3x2.CreateRotation(App.Setting.CropAngle) * Matrix3x2.CreateTranslation(App.Model.Width / 2, App.Model.Height / 2) }; App.Model.isReRender = true; //重新渲染 App.Model.Refresh++; //画布刷新 }
internal static Matrix3x2 GetMatrix(double x, double y) { return(Matrix3x2.CreateTranslation((float)x, (float)y)); }
public void Translate(PointF value) { world = Matrix3x2.CreateTranslation(value.X, value.Y) * world; }