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); } }
/// <summary> /// Creates a rotation matrix using the given rotation in degrees. /// </summary> /// <param name="degrees">The amount of rotation, in degrees.</param> /// <returns>A rotation matrix.</returns> public static Matrix3x2 CreateRotationDegrees(float degrees) => Matrix3x2.CreateRotation(GeometryUtilities.DegreeToRadian(degrees));
/// <summary> /// Creates a rotation matrix using the given rotation in degrees and a center point. /// </summary> /// <param name="degrees">The amount of rotation, in degrees.</param> /// <param name="centerPoint">The center point.</param> /// <returns>A rotation matrix.</returns> public static Matrix3x2 CreateRotationDegrees(float degrees, PointF centerPoint) => Matrix3x2.CreateRotation(GeometryUtilities.DegreeToRadian(degrees), centerPoint);
public void Matrix3x2CreateRotationCenterTest() { double radians = MathHelper.ToRadians(30.0); 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)); }
/// <summary> /// Appends a rotation matrix using the given rotation in radians at the given origin. /// </summary> /// <param name="radians">The amount of rotation, in radians.</param> /// <param name="origin">The rotation origin point.</param> /// <returns>The <see cref="AffineTransformBuilder"/>.</returns> public AffineTransformBuilder AppendRotationRadians(float radians, Vector2 origin) => this.AppendMatrix(Matrix3x2.CreateRotation(radians, origin));
private void OnLoaded(object sender, RoutedEventArgs e) { //SampleHelper deviceHelper = new SampleHelper(); DeviceLostHelper lostHelper = new DeviceLostHelper(); _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor; _generator = _compositor.CreateCompositionGenerator(); _width = 300f; _height = 300f; // Create the combined geometry var ellipse1 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.45f * _width, 0.225f * _height); var ellipse2 = CanvasGeometry.CreateEllipse(_generator.Device, _width / 2, _height / 2, 0.225f * _width, 0.45f * _height); _combinedGeometry = ellipse1.CombineWith(ellipse2, Matrix3x2.Identity, CanvasGeometryCombine.Union); // Create custom shaped visual using CompositionMaskBrush _visual1 = _compositor.CreateSpriteVisual(); _visual1.Size = new Vector2(_width, _height); _visual1.Offset = new Vector3(((CompositionGrid1.ActualWidth - _width) / 2).ToSingle(), ((CompositionGrid1.ActualHeight - _height) / 2).ToSingle(), 0); var visualChild = _compositor.CreateSpriteVisual(); visualChild.Size = new Vector2(_width * 0.75f, _height * 0.75f); visualChild.Offset = new Vector3(_width * 0.125f, _height * 0.125f, 0); _visual1.Children.InsertAtTop(visualChild); // Create the CompositionMask var compositionMask = _generator.CreateMaskSurface(_visual1.Size.ToSize(), _combinedGeometry); // Create SurfaceBrush from CompositionMask var mask = _compositor.CreateSurfaceBrush(compositionMask.Surface); var source = _compositor.CreateColorBrush(Color.FromArgb(255, 0, 173, 239)); // Create mask brush var maskBrush = _compositor.CreateMaskBrush(); maskBrush.Mask = mask; maskBrush.Source = source; _visual1.Brush = maskBrush; ElementCompositionPreview.SetElementChildVisual(CompositionGrid1, _visual1); // Create custom shaped visual using CompositionMaskBrush _visual2 = _compositor.CreateSpriteVisual(); _visual2.Size = new Vector2(_width, _height); _visual2.Offset = new Vector3(((CompositionGrid2.ActualWidth - _width) / 2).ToSingle(), ((CompositionGrid2.ActualHeight - _height) / 2).ToSingle(), 0); // Create the CompositionMask filled with color var compositionMask2 = _generator.CreateGeometrySurface(_visual2.Size.ToSize(), _combinedGeometry, Color.FromArgb(192, 192, 0, 0)); // Create SurfaceBrush from CompositionMask var surfaceBrush = _compositor.CreateSurfaceBrush(compositionMask2.Surface); _visual2.Brush = surfaceBrush; ElementCompositionPreview.SetElementChildVisual(CompositionGrid2, _visual2); // Initialize the visuals for the Animated Canvas // Create the container to host the visuals var container = _compositor.CreateContainerVisual(); container.Size = new Vector2(CompositionGrid3.ActualWidth.ToSingle(), CompositionGrid3.ActualHeight.ToSingle()); // Background Visual _bgVisual = _compositor.CreateSpriteVisual(); _bgVisual.Size = new Vector2(_width, _height); _bgVisual.Offset = new Vector3(((CompositionGrid3.ActualWidth - _width) / 2).ToSingle(), ((CompositionGrid3.ActualHeight - _height) / 2).ToSingle(), 0); var radians = ((45f * Math.PI) / 180).ToSingle(); var bgGeometry = _combinedGeometry.Transform(Matrix3x2.CreateRotation(radians, new Vector2(_width / 2, _height / 2))); var bgMask = _generator.CreateGeometrySurface(_bgVisual.Size.ToSize(), bgGeometry, Color.FromArgb(255, 0, 173, 239)); var bgBrush = _compositor.CreateSurfaceBrush(bgMask.Surface); _bgVisual.Brush = bgBrush; container.Children.InsertAtBottom(_bgVisual); // Animated Visual _animatedVisual = _compositor.CreateSpriteVisual(); _animatedVisual.Size = new Vector2(_width, _height); _animatedVisual.Offset = new Vector3(((CompositionGrid3.ActualWidth - _width) / 2).ToSingle(), ((CompositionGrid3.ActualHeight - _height) / 2).ToSingle(), 0); // Create the Excluded geometry _outerGeometry = CanvasGeometry.CreateRectangle(_generator.Device, 0, 0, _width, _height); var excludedGeometry = _outerGeometry.CombineWith(_combinedGeometry, Matrix3x2.Identity, CanvasGeometryCombine.Exclude); // Create the CompositionMask _animatedMaskSurface = _generator.CreateGeometrySurface(_animatedVisual.Size.ToSize(), excludedGeometry, Color.FromArgb(192, 192, 0, 0)); var animBrush = _compositor.CreateSurfaceBrush(_animatedMaskSurface.Surface); _animatedVisual.Brush = animBrush; container.Children.InsertAtTop(_animatedVisual); ElementCompositionPreview.SetElementChildVisual(CompositionGrid3, container); }
public void DrawGlyphRun(Vector2 point, CanvasFontFace fontFace, float fontSize, CanvasGlyph[] glyphs, bool isSideways, uint bidiLevel, object brush, CanvasTextMeasuringMode measuringMode, string localeName, string textString, int[] clusterMapIndices, uint characterIndex, CanvasGlyphOrientation glyphOrientation) { Matrix3x2 OTrans = ds.Transform; int i = 0; if (characterIndex == 0) { ds.Transform = Matrix3x2.CreateTranslation(new Vector2(-0.5f * PTextW, -R)) * Matrix3x2.CreateRotation(Offset, Origin); ds.DrawGlyphRun(Origin, fontFace, fontSize, new CanvasGlyph[] { glyphs[0] }, isSideways, bidiLevel, Brush); MovingRad = 0; i++; } while (i < glyphs.Length) { float TextW = TextWidths[i + characterIndex]; float Rad = TextW / R; float OffsetRad = 0.5f * (PTextW + TextW) / R + MovingRad; MovingRad += Rad; // Stop drawing texts if ring is already crowded if (6.2831f < (OffsetRad + Rad)) { break; } ds.Transform = Matrix3x2.CreateTranslation(new Vector2(-0.5f * TextW, -R)) * Matrix3x2.CreateRotation(OffsetRad + Offset, Origin); ds.DrawGlyphRun(Origin, fontFace, fontSize, new CanvasGlyph[] { glyphs[i] }, isSideways, bidiLevel, Brush); i++; } ds.Transform = OTrans; }
/// <summary> /// Performs a rotation on top matrix. /// </summary> /// <param name="radians">The angle in radians.</param> /// <param name="centerPoint">The center point of the rotation.</param> public void RotateYawPitchRollLocal(float radians, Vector2 centerPoint) { m_top = Matrix3x2.CreateRotation(radians, centerPoint) * m_top; }
/// <summary> /// Creates a rotation matrix using the given rotation in degrees. /// </summary> /// <param name="degrees">The amount of rotation, in degrees.</param> /// <returns>A rotation matrix.</returns> public static Matrix3x2 CreateRotationDegrees(float degrees) => Matrix3x2.CreateRotation(MathFExtensions.DegreeToRadian(degrees));
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 }
/// <summary> /// Performs a rotation on top matrix. /// </summary> /// <param name="radians">The angle in radians.</param> public void RotateYawPitchRollLocal(float radians) { m_top = Matrix3x2.CreateRotation(radians) * m_top; }
public void DrawCommon(CanvasDrawingSession g) { //save tansform var save = g.Transform; g.FillRectangle(new Rect(X2 - 2, Y2 - 2, 4, 4), Pen.Color); using (var pathBuilder = new CanvasPathBuilder(g)) { pathBuilder.BeginFigure(X1, Y1); pathBuilder.AddLine(X2, Y2); pathBuilder.AddLine(X3, Y3); pathBuilder.EndFigure(CanvasFigureLoop.Open); g.DrawGeometry(CanvasGeometry.CreatePath(pathBuilder), Pen.Color, 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(g)) { pathBuilder.BeginFigure(gw + X2, gh + Y2); pathBuilder.AddArc(new Vector2(X2, Y2), Pen.GlyphSize, Pen.GlyphSize, r, s); pathBuilder.EndFigure(CanvasFigureLoop.Open); g.DrawGeometry(CanvasGeometry.CreatePath(pathBuilder), Pen.Color, Pen.Width); } } #endregion //TODO 调整文字显示位置,得到更好的视图 var radians = -(float)Math.Atan((Y2 - Y3) / (X3 - X2)); var textLayout = CreateTextLayout(Angle.Round3().ToString() + "°", g); 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; centerX = left + size.Width / 2; centerY = top + size.Height / 2; g.Transform = Matrix3x2.CreateRotation(radians, new Vector2((float)centerX, (float)centerY)); var rect = new Rect(left, top, size.Width, size.Height); g.FillRectangle(rect, Pen.TextBackground); g.DrawTextLayout(textLayout, (float)left + 5, (float)top, Pen.TextColor); //recover transform g.Transform = save; }
private Vector2 ConvertToVisualizationCoordinates(Vector2 vector) { return(Vector2.Transform(this.newDirectionUnitVector, Matrix3x2.CreateRotation((float)(-90 * (Math.PI / 180))))); }
private void SetNewDirectionUnitVector() { this.newDirectionUnitVector = Vector2.Transform(this.carDirectionUnitVector, Matrix3x2.CreateRotation((float)(this.steeringAngle * (Math.PI / 180)))); }
protected override void UpdateGeometries() { var geo = CanvasGeometry.CreateRectangle(Context.Creator, new Rect(X1 - 2, Y1 - 2, 4, 4)); AddGeometry(new GeometryConfig { Geometry = geo, FillColor = Pen.Color }); var radians = -(float)Radians; using (var pathBuilder = new CanvasPathBuilder(Context.Creator)) { pathBuilder.BeginFigure(X1, Y1); pathBuilder.AddLine(X2, Y2); pathBuilder.EndFigure(CanvasFigureLoop.Open); geo = CanvasGeometry.CreatePath(pathBuilder); AddGeometry(new GeometryConfig { Geometry = geo, Style = GeometryStyle.Stroke, StrokeColor = Pen.Color, StrokeWidth = Pen.Width }); } if (IsGlyphVisible) { geo = CanvasGeometry.CreateRectangle(Context.Creator, new Rect(X1, Y1 - Pen.GlyphSize / 2, Pen.Width, Pen.GlyphSize)) .Transform(Matrix3x2.CreateRotation(radians, new Vector2(X1, Y1))); AddGeometry(new GeometryConfig { Geometry = geo, FillColor = Pen.Color }); geo = CanvasGeometry.CreateRectangle(Context.Creator, new Rect(X2, Y2 - Pen.GlyphSize / 2, Pen.Width, Pen.GlyphSize)) .Transform(Matrix3x2.CreateRotation(radians, new Vector2(X2, Y2))); AddGeometry(new GeometryConfig { Geometry = geo, FillColor = Pen.Color, }); } #region Text var textLayout = CreateTextLayout(Distance.Round3().ToString(), Context.Creator); var bounds = textLayout.LayoutBounds; var size = new Size(bounds.Width + 10, bounds.Height); var centerX = X1 + (X2 - X1 - size.Width) / 2; var centerY = Y1 + (Y2 - Y1 - 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 }
/// <summary> /// Creates a rotation matrix using the given rotation in degrees and a center point. /// </summary> /// <param name="degrees">The amount of rotation, in degrees.</param> /// <param name="centerPoint">The center point.</param> /// <returns>A rotation matrix.</returns> public static Matrix3x2 CreateRotationDegrees(float degrees, PointF centerPoint) => Matrix3x2.CreateRotation(MathFExtensions.DegreeToRadian(degrees), centerPoint);
void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args) { var ds = args.DrawingSession; var centerPoint = (arcPoints[0] + arcPoints[1]) / 2; // Draw the end point markers. if (!ThumbnailGenerator.IsDrawingThumbnail) { for (int i = 0; i < 2; i++) { ds.DrawCircle(arcPoints[i], hitTestRadius, (i == activeDrag) ? Colors.White : Colors.Gray); } } switch (CurrentOverload) { case AddArcOverload.AroundEllipse: // Compute positions. var ellipseRadius = (arcPoints[1] - arcPoints[0]) / 2; ellipseRadius.X = Math.Abs(ellipseRadius.X); ellipseRadius.Y = Math.Abs(ellipseRadius.Y); float startAngle = Utils.DegreesToRadians(ArcStartAngle); float sweepAngle = Utils.DegreesToRadians(ArcSweepAngle); var startPoint = centerPoint + Vector2.Transform(Vector2.UnitX, Matrix3x2.CreateRotation(startAngle)) * ellipseRadius; // Draw the bounding rectangle. if (!ThumbnailGenerator.IsDrawingThumbnail) { ds.DrawRectangle(new Rect(arcPoints[0].ToPoint(), arcPoints[1].ToPoint()), Color.FromArgb(255, 64, 64, 64)); } // Draw the arc. using (var builder = new CanvasPathBuilder(sender)) { builder.BeginFigure(startPoint); builder.AddArc(centerPoint, ellipseRadius.X, ellipseRadius.Y, startAngle, sweepAngle); builder.EndFigure(CanvasFigureLoop.Open); using (var geometry = CanvasGeometry.CreatePath(builder)) { ds.DrawGeometry(geometry, Colors.Yellow, strokeWidth, strokeStyle); } } break; case AddArcOverload.PointToPoint: // Display a warning if this is an invalid arc configuration. bool isRadiusTooSmall = IsArcRadiusTooSmall(); if (isRadiusTooSmall) { ds.DrawText("Radius is less than the\ndistance between the\nstart and end points", centerPoint, Colors.Red, textFormat); } // Draw the arc. using (var builder = new CanvasPathBuilder(sender)) { builder.BeginFigure(arcPoints[0]); builder.AddArc(arcPoints[1], ArcRadiusX, ArcRadiusY, Utils.DegreesToRadians(ArcRotation), ArcSweepDirection, ArcSize); builder.EndFigure(CanvasFigureLoop.Open); using (var geometry = CanvasGeometry.CreatePath(builder)) { ds.DrawGeometry(geometry, isRadiusTooSmall ? Colors.Red : Colors.Yellow, strokeWidth, strokeStyle); } } break; } }
public void Rotate(float angle) { ds.Transform *= Matrix3x2.CreateRotation(angle); }
public void RotateLocal(float degrees) { TransformLocal(Matrix3x2.CreateRotation(MathHelper.DegreesToRadians(degrees))); }
/// <summary> /// Creates a rotation matrix for the given point and angle. /// </summary> /// <param name="origin">The origin point to rotate around</param> /// <param name="degrees">Rotation in degrees</param> /// <returns>The rotation <see cref="Matrix3x2"/></returns> public static Matrix3x2 CreateRotation(Point origin, float degrees) { float radians = ImageMaths.DegreesToRadians(degrees); return(Matrix3x2.CreateRotation(radians, new Vector2(origin.X, origin.Y))); }
protected void CanvasAnimatedControl_Draw(Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args) { // First, ensure we have exclusive access to the list of sprites. we don't want this changing while we are trying // to draw it. If another thread has access to it, we will skip drawing this frame. if (Monitor.TryEnter(Sprite.Sprites)) { try { // Establish the scale. Normally we draw at 1.0 scale. However, if the drawing surface is SMALLER than our coordinate space, we // need to scale down. Likewise, if we are in fullscreen mode, we'll need to scale up. if (sender.Size.Width < Dimensions.Width || sender.Size.Height < Dimensions.Height || fullscreen) { scale = (float)Math.Min(sender.Size.Width / Dimensions.Width, sender.Size.Height / Dimensions.Height); } else { scale = 1.0f; } // Draw the 'scale' transform into the scene args.DrawingSession.Transform = Matrix3x2.CreateScale(scale, new Vector2((float)(sender.Size.Width / 2), (float)(sender.Size.Height / 2))); // Upper-left corner of the destination drawing space var origin = new Point() { X = (sender.Size.Width - Dimensions.Width) / 2, Y = (sender.Size.Height - Dimensions.Height) / 2 }; // Rectangle describing the destination drawing space var destrect = new Rect(origin, Dimensions); // Creating a layer around the destination drawing space is how we clip drawing to only the // expected drawing space using (args.DrawingSession.CreateLayer(1.0f, destrect)) { // Draw the background if (background != null && bitmaps.ContainsKey(background)) { args.DrawingSession.DrawImage(bitmaps[background], destrect); } // The sprites are all positioned relative to the 'center', so we need to know where that is // on the screen right now var center = new Point(sender.Size.Width / 2, sender.Size.Height / 2); // Draw each sprite foreach (var sprite in Sprite.Sprites.OrderBy(x => x.Layer)) { // Only draw the sprite if we have a costume loaded for it if (sprite.Costume != null && sprite.Visible && bitmaps.ContainsKey(sprite.Costume)) { // Fetch the correct drawing resource for this sprite var bitmap = bitmaps[sprite.Costume]; // Figure out how big of space the sprite will occupy in the scene. This is where we // apply sprite scaling. Also, this value is used for collisions. sprite.CostumeSize = new Size(bitmap.Size.Width * sprite.Scale, bitmap.Size.Height * sprite.Scale); // The 'drawme' is the canvas image we will ultimately draw. Along the way we will optionally // apply effects to it. ICanvasImage drawme = bitmap; // Opacity effect if we are not fully opaque if (sprite.Opacity < 1.0) { drawme = new OpacityEffect() { Source = drawme, Opacity = (float)sprite.Opacity }; } // Rotation effect if we are rotated. if (sprite.RotationAngle != 0.0) { drawme = new Transform2DEffect() { Source = drawme, TransformMatrix = Matrix3x2.CreateRotation((float)sprite.RotationAngle, new Vector2((float)bitmap.Size.Width / 2, (float)bitmap.Size.Height / 2)) }; } // Flip horizontal, if so indicated if (sprite.FlipHorizontal) { drawme = new Transform2DEffect() { Source = drawme, TransformMatrix = Matrix3x2.CreateScale(-1.0f, 1.0f, new Vector2((float)bitmap.Size.Width / 2, (float)bitmap.Size.Height / 2)) }; } // Where in the scene to draw the sprite var draw_at = new Point(center.X + sprite.Position.X - sprite.CostumeSize.Width / 2, center.Y - sprite.Position.Y - sprite.CostumeSize.Height / 2); // Draw the sprite! args.DrawingSession.DrawImage(drawme, new Rect(draw_at, sprite.CostumeSize), new Rect(new Point(0, 0), bitmap.Size)); // Render the 'saying' if (sprite.Saying?.Length > 0) { var drawingSession = args.DrawingSession; var format = new CanvasTextFormat { FontSize = 30.0f, WordWrapping = CanvasWordWrapping.NoWrap }; var textLayout = new CanvasTextLayout(drawingSession, sprite.Saying, format, 0.0f, 0.0f); float xcenter = (float)(center.X + sprite.Position.X); float ytop = (float)(center.Y - sprite.Position.Y + bitmap.Size.Height / 2 + 10.0); var theRectYouAreLookingFor = new Rect(xcenter - textLayout.LayoutBounds.Width / 2 - 5, ytop, textLayout.LayoutBounds.Width + 10, textLayout.LayoutBounds.Height); drawingSession.FillRectangle(theRectYouAreLookingFor, Colors.White); drawingSession.DrawTextLayout(textLayout, xcenter - (float)textLayout.LayoutBounds.Width / 2, ytop, Colors.Black); } } } } } catch (Exception ex) { // This is not a great thing to do with exceptions... } finally { Monitor.Exit(Sprite.Sprites); } } }
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++; //画布刷新 }
/// <summary> /// Creates a path rotated by the specified radians around its center. /// </summary> /// <param name="path">The path to rotate.</param> /// <param name="radians">The radians to rotate the path.</param> /// <returns>A <see cref="IPath"/> with a rotate transform applied.</returns> public static IPath Rotate(this IPath path, float radians) { return(path.Transform(Matrix3x2.CreateRotation(radians, RectangleF.Center(path.Bounds)))); }
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; }
void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args) { var elapsedTime = (float)args.Timing.TotalTime.TotalSeconds; // Center in the control. var position = (sender.Size.ToVector2() - tigerSize) / 2; position.Y -= tigerSize.Y * 0.75f; // Is the sketch effect enabled? ICanvasImage sourceImage; if (SketchEnabled) { sourceImage = sketchEffect; } else { sourceImage = bitmapTiger; } // Which dissolve mode are we currently displaying? ICanvasImage dissolveMask; switch (CurrentDissolve) { case DissolveType.Ripples: // Use the custom rippleEffect as our dissolve mask, and animate its offset. dissolveMask = rippleEffect; rippleEffect.Properties["offset"] = -elapsedTime * 6; break; case DissolveType.Turbulence: // Use a turbulence image as the dissolve mask. dissolveMask = turbulence; break; case DissolveType.LinearGradient: // Use a linear gradient as the dissolve mask, and slowly rotate it. dissolveMask = linearGradient; linearGradient.TransformMatrix = Matrix3x2.CreateRotation(elapsedTime / 3, tigerSize / 2); break; case DissolveType.RadialGradient: // Use a radial gradient as the dissolve mask. dissolveMask = radialGradient; break; case DissolveType.NoDissolve: // Dissolve is turned off, so just draw the source image directly. args.DrawingSession.DrawImage(sourceImage, position); return; default: throw new NotSupportedException(); } // Animate the dissolve amount. dissolveEffect.Properties["dissolveAmount"] = (float)Math.Sin(elapsedTime * 2.4) / 2 + 0.5f; // Draw the custom effect. dissolveEffect.Source1 = sourceImage; dissolveEffect.Source2 = dissolveMask; args.DrawingSession.DrawImage(dissolveEffect, position); if (!ThumbnailGenerator.IsDrawingThumbnail) { // Display the current dissolve mask. args.DrawingSession.DrawText("Dissolve mask:", position.X, position.Y + tigerSize.Y * 1.5f - 32, Colors.Gray); args.DrawingSession.DrawImage(dissolveMask, position.X, position.Y + tigerSize.Y * 1.5f, bitmapTiger.Bounds); // Display the current dissolve amount. string dissolvePercentage = string.Format("{0:0}%", (float)dissolveEffect.Properties["dissolveAmount"] * 100); args.DrawingSession.DrawText(dissolvePercentage, position + tigerSize * new Vector2(1.2f, 0.4f), Colors.Gray); } }
protected SharpDX.Direct2D1.Image Output(DeviceContext rDc) { D2DBitmap ntdx = null; try { ntdx = D2DBitmap.FromWicBitmap(rDc, _Pelete); } catch (Exception e) { MessageBox.Show(e.ToString()); } Image result1; var blEf = new SharpDX.Direct2D1.Effect(rDc, Effect.Opacity); blEf.SetInput(0, ntdx, new RawBool()); blEf.SetValue(0, Opacity); result1 = blEf.Output; blEf.Dispose(); if (size_changed) { var tfEf = new SharpDX.Direct2D1.Effects.AffineTransform2D(rDc); tfEf.SetInput(0, result1, new RawBool()); result1.Dispose(); var x_rate = _Size.Width / (double)_Pelete.Size.Width; var y_rate = _Size.Height / (double)_Pelete.Size.Height; tfEf.TransformMatrix = new RawMatrix3x2((float)x_rate, 0f, 0f, (float)y_rate, 0f, 0f); result1 = tfEf.Output; tfEf.Dispose(); } if (Orientation != 1.0f) { var tfEf1 = new SharpDX.Direct2D1.Effects.AffineTransform2D(rDc); tfEf1.SetInput(0, result1, new RawBool()); result1.Dispose(); var mr32 = Matrix3x2.CreateRotation((float)Orientation, new Vector2(RotationPoint.X, RotationPoint.Y)); tfEf1.TransformMatrix = new RawMatrix3x2(mr32.M11, mr32.M12, mr32.M21, mr32.M22, mr32.M31, mr32.M32); result1 = tfEf1.Output; tfEf1.Dispose(); } if (this.Saturation != 1f) { var stEf = new SharpDX.Direct2D1.Effects.Saturation(rDc); stEf.SetInput(0, result1, new RawBool()); result1.Dispose(); stEf.Value = Saturation; result1 = stEf.Output; stEf.Dispose(); } if (this.Brightness != 0.5f) { var btEf = new SharpDX.Direct2D1.Effects.Brightness(rDc); btEf.SetInput(0, result1, new RawBool()); result1.Dispose(); btEf.BlackPoint = new RawVector2(1.0f - Brightness, Brightness); // btEf.WhitePoint =; result1 = btEf.Output; btEf.Dispose(); } ntdx.Dispose(); return(result1); }
/// <summary> /// Creates a rotation matrix using the given rotation in radians and a center point. /// </summary> /// <param name="radians">The amount of rotation, in radians.</param> /// <param name="centerPoint">The center point.</param> /// <returns>A rotation matrix.</returns> public static Matrix3x2 CreateRotation(float radians, PointF centerPoint) => Matrix3x2.CreateRotation(radians, centerPoint);
public static PhpArray imagettftext(Context ctx, PhpResource im, double size, double angle, int x, int y, long color, string font_file, string text) { var img = PhpGdImageResource.ValidImage(im); if (img == null) { return(null); } if (string.IsNullOrEmpty(font_file)) { PhpException.Throw(PhpError.Warning, Resources.filename_cannot_be_empty); return(null); } var font_stream = PhpStream.Open(ctx, font_file, "rb"); if (font_stream == null) { PhpException.Throw(PhpError.Warning, Resources.invalid_font_filename, font_file); return(null); } // Font preparation FontFamily family; try { family = new FontCollection().Install(font_stream.RawStream); // TODO: perf: global font collection cache if (ReferenceEquals(family, null)) { throw new InvalidOperationException(); } } catch { PhpException.Throw(PhpError.Warning, Resources.invalid_font_filename, font_file); return(null); } finally { font_stream.Dispose(); } FontStyle style; if (family.IsStyleAvailible(FontStyle.Regular)) { style = FontStyle.Regular; } else if (family.IsStyleAvailible(FontStyle.Bold)) { style = FontStyle.Bold; } else if (family.IsStyleAvailible(FontStyle.Italic)) { style = FontStyle.Italic; } else if (family.IsStyleAvailible(FontStyle.BoldItalic)) { style = FontStyle.BoldItalic; } else { return(null); } var font = new Font(family, (float)size, style); var textsize = TextMeasurer.Measure(text, new RendererOptions(font)); // text transformation: var matrix = (angle == 0.0) ? Matrix3x2.Identity : Matrix3x2.CreateRotation((float)(angle * -2.0 * Math.PI / 360.0f)); matrix.Translation = new Vector2(x, y); var path = new SixLabors.Shapes.PathBuilder(matrix).AddLine(0, 0, textsize.Width, 0).Build(); // draw the text: // TODO: col < 0 => turn off antialiasing img.Image.DrawText(text, font, FromRGBA(Math.Abs(color)), path); // calculate drawen text boundaries: var pts = new Vector2[] { new Vector2(0, textsize.Height), // lower left new Vector2(textsize.Width, textsize.Height), // lower right new Vector2(textsize.Width, 0), // upper right new Vector2(0, 0), // upper left }; for (int i = 0; i < pts.Length; i++) { pts[i] = Vector2.Transform(pts[i], matrix); } return(new PhpArray(8) { pts[0].X, pts[0].Y, pts[1].X, pts[1].Y, pts[2].X, pts[2].Y, pts[3].X, pts[3].Y, }); }
/// <inheritdoc/> protected override void BeginGlyph(RectangleF rect) { SegmentInfo point = this.path.PointAlongPath(rect.Left); PointF targetPoint = point.Point + new PointF(0, rect.Top - this.yOffset); // due to how matrix combining works you have to combine thins in the revers order of operation // this one rotates the glype then moves it. Matrix3x2 matrix = Matrix3x2.CreateTranslation(targetPoint - rect.Location) * Matrix3x2.CreateRotation(point.Angle - Pi, point.Point); this.builder.SetTransform(matrix); }
static Matrix3x2 rotationMatrix(Vector2 vps, float angle) { return(Matrix3x2.CreateRotation(angle, vps * 0.5f)); }