Synchronize the Net40
This commit is contained in:
1 parent
a8284c2564
commit
4d4fb36d1b
68 files changed
+1246
-272
No files matched your search
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace HandyControl.Tools.Converter
|
||||
{
|
||||
public class BorderCircularConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values.Length == 2 && values[0] is double width && values[1] is double height)
|
||||
{
|
||||
if (width < double.Epsilon || height < double.Epsilon)
|
||||
{
|
||||
return new CornerRadius();
|
||||
}
|
||||
|
||||
var min = Math.Min(width, height);
|
||||
return new CornerRadius(min / 2);
|
||||
}
|
||||
|
||||
return DependencyProperty.UnsetValue;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//referenced from https://stackoverflow.com/a/5650367/9639378
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace HandyControl.Tools.Converter
|
||||
{
|
||||
public class BorderClipConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values.Length == 3 && values[0] is double width && values[1] is double height && values[2] is CornerRadius radius)
|
||||
{
|
||||
if (width < double.Epsilon || height < double.Epsilon)
|
||||
{
|
||||
return Geometry.Empty;
|
||||
}
|
||||
|
||||
var clip = new RectangleGeometry(new Rect(0, 0, width, height), radius.TopLeft, radius.TopLeft);
|
||||
clip.Freeze();
|
||||
|
||||
return clip;
|
||||
}
|
||||
|
||||
return DependencyProperty.UnsetValue;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using HandyControl.Expression.Drawing;
|
||||
|
||||
namespace HandyControl.Tools.Extension
|
||||
{
|
||||
public static class GeometryExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取路径总长度
|
||||
/// </summary>
|
||||
/// <param name="geometry"></param>
|
||||
/// <returns></returns>
|
||||
public static double GetTotalLength(this Geometry geometry)
|
||||
{
|
||||
if (geometry == null) return 0;
|
||||
|
||||
var pathGeometry = PathGeometry.CreateFromGeometry(geometry);
|
||||
pathGeometry.GetPointAtFractionLength(1e-4, out var point, out _);
|
||||
var length = (pathGeometry.Figures[0].StartPoint - point).Length * 1e+4;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取路径总长度
|
||||
/// </summary>
|
||||
/// <param name="geometry"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="strokeThickness"></param>
|
||||
/// <returns></returns>
|
||||
public static double GetTotalLength(this Geometry geometry, Size size, double strokeThickness = 1)
|
||||
{
|
||||
if (geometry == null) return 0;
|
||||
|
||||
if (MathHelper.IsVerySmall(size.Width) || MathHelper.IsVerySmall(size.Height)) return 0;
|
||||
|
||||
var length = GetTotalLength(geometry);
|
||||
var sw = geometry.Bounds.Width / size.Width;
|
||||
var sh = geometry.Bounds.Height / size.Height;
|
||||
var min = Math.Min(sw, sh);
|
||||
|
||||
if (MathHelper.IsVerySmall(min) || MathHelper.IsVerySmall(strokeThickness)) return 0;
|
||||
|
||||
length /= min;
|
||||
return length / strokeThickness;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using HandyControl.Controls;
|
||||
|
||||
namespace HandyControl.Tools
|
||||
{
|
||||
public class GithubGravatarGenerator : IGravatarGenerator
|
||||
{
|
||||
private const int RenderDataMaxLength = 15;
|
||||
|
||||
public object GetGravatar(string id)
|
||||
{
|
||||
var hashcode = GetHashCode(id);
|
||||
var renderData = GetRenderData(hashcode);
|
||||
var renderBrush = GetRenderBrush(hashcode);
|
||||
var geometryGroup = new GeometryGroup();
|
||||
|
||||
void AddRec(int i, int j, bool hidden = false)
|
||||
{
|
||||
var rec = new RectangleGeometry(new Rect(new Point(i, j), hidden ? new Size() : new Size(1, 1)));
|
||||
geometryGroup.Children.Add(rec);
|
||||
}
|
||||
|
||||
var index = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int j = 0; j < 5; j++, index++)
|
||||
{
|
||||
AddRec(i, j, renderData[index] == 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 5; j++, index++)
|
||||
{
|
||||
AddRec(2, j, renderData[index] == 0);
|
||||
}
|
||||
|
||||
index -= 10;
|
||||
for (int i = 3; i < 5; i++)
|
||||
{
|
||||
for (int j = 0; j < 5; j++, index++)
|
||||
{
|
||||
AddRec(i, j, renderData[index] == 0);
|
||||
}
|
||||
index -= 10;
|
||||
}
|
||||
|
||||
var path = new Path
|
||||
{
|
||||
Data = geometryGroup,
|
||||
Fill = renderBrush,
|
||||
VerticalAlignment = VerticalAlignment.Top
|
||||
};
|
||||
|
||||
RenderOptions.SetEdgeMode(path, EdgeMode.Aliased);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private string GetHashCode(string id)
|
||||
{
|
||||
var md5 = MD5.Create();
|
||||
var bytes = Encoding.ASCII.GetBytes(id);
|
||||
var hash = md5.ComputeHash(bytes);
|
||||
var stringBuilder = new StringBuilder();
|
||||
foreach (var item in hash)
|
||||
{
|
||||
stringBuilder.Append(item.ToString("X2"));
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
private int[] GetRenderData(string hashcode)
|
||||
{
|
||||
var arr = new int[RenderDataMaxLength];
|
||||
for (int i = 0; i < RenderDataMaxLength; i++)
|
||||
{
|
||||
var c = hashcode[i];
|
||||
var v = (int)c;
|
||||
arr[i] = v % 2;
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
private Brush GetRenderBrush(string hashcode)
|
||||
{
|
||||
var v = (double)int.Parse(hashcode.Substring(hashcode.Length - 7), NumberStyles.HexNumber);
|
||||
var scale = v / 0xfffffff;
|
||||
var color = Hsl2Rgb(scale);
|
||||
return new SolidColorBrush(color);
|
||||
}
|
||||
|
||||
//adapted from https://github.com/stewartlord/identicon.js/blob/4fad7cafec1b7a4d896015e084e861625ef5d64f/identicon.js#L110
|
||||
private Color Hsl2Rgb(double h, double s = 0.7, double b = 0.5)
|
||||
{
|
||||
h *= 6;
|
||||
var arr = new[]
|
||||
{
|
||||
b += s *= b < .5 ? b : 1 - b,
|
||||
b - h % 1 * s * 2,
|
||||
b -= s *= 2,
|
||||
b,
|
||||
b + h % 1 * s,
|
||||
b + s
|
||||
};
|
||||
|
||||
var hValue = (int)Math.Floor(h);
|
||||
|
||||
return Color.FromRgb((byte)(arr[hValue % 6] * 255), (byte)(arr[(hValue | 16) % 6] * 255),
|
||||
(byte)(arr[(hValue | 8) % 6] * 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user