AngleSharp by Florian Rappl

<PackageReference Include="AngleSharp" Version="0.8.1" />

.NET API 1,172,480 bytes

 CssPerspectiveOriginProperty

More information available at: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective-origin
using AngleSharp.Css; using AngleSharp.Css.Values; using AngleSharp.Extensions; using System; namespace AngleSharp.Dom.Css { internal sealed class CssPerspectiveOriginProperty : CssProperty, ICssPerspectiveOriginProperty, ICssProperty { internal static readonly Point Default = Point.Center; internal static readonly IValueConverter<Point> Converter = Converters.LengthOrPercentConverter.To((Length m) => new Point(m, m)).Or(Keywords.Left, new Point(Length.Zero, Length.Half)).Or(Keywords.Center, new Point(Length.Half, Length.Half)) .Or(Keywords.Right, new Point(Length.Full, Length.Half)) .Or(Keywords.Top, new Point(Length.Half, Length.Zero)) .Or(Keywords.Bottom, new Point(Length.Half, Length.Full)) .Or(Converters.WithAny(Converters.LengthOrPercentConverter.Or(Keywords.Left, Length.Zero).Or(Keywords.Right, Length.Full).Or(Keywords.Center, Length.Half) .Option(Length.Half), Converters.LengthOrPercentConverter.Or(Keywords.Top, Length.Zero).Or(Keywords.Bottom, Length.Full).Or(Keywords.Center, Length.Half) .Option(Length.Half)).To((Tuple<Length, Length> m) => new Point(m.Item1, m.Item2))); private Point _pt; public Length X => _pt.X; public Length Y => _pt.Y; internal CssPerspectiveOriginProperty(CssStyleDeclaration rule) : base(PropertyNames.PerspectiveOrigin, rule, PropertyFlags.Animatable) { Reset(); } public void SetPosition(Point pt) { _pt = pt; } internal override void Reset() { _pt = Default; } protected override bool IsValid(ICssValue value) { return Converter.TryConvert(value, SetPosition); } } }