How to create a shadow drop effect around a wpf button like the google button

后端 未结 2 789
独厮守ぢ
独厮守ぢ 2021-02-13 20:26

I am trying to create a google button in wpf. I have found the following link that specifies the google\'s button css style

Google button css style

Right now I h

2条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-13 20:46

    In the past, I implemented material elevation like this:

    public static class UI
    {
        private static readonly DropShadowEffect[] sShadows = new[]
        {
            new DropShadowEffect()
            {
                BlurRadius = 5,
                ShadowDepth = 1
            },
            new DropShadowEffect()
            {
                BlurRadius = 8,
                ShadowDepth = 1.5
            },
            new DropShadowEffect()
            {
                BlurRadius = 14,
                ShadowDepth = 4.5
            },
            new DropShadowEffect()
            {
                BlurRadius = 25,
                ShadowDepth = 8
            },
            new DropShadowEffect()
            {
                BlurRadius = 35,
                ShadowDepth = 13
            }
        };
    
        public static readonly DependencyProperty ElevationProperty = DependencyProperty.RegisterAttached("Elevation", typeof(double), typeof(UI), new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsRender, null, OnElevationChanged));
    
        public static double GetElevation(this UIElement element) => element.GetValue(ElevationProperty) as double? ?? default;
    
        public static void SetElevation(this UIElement element, double elevation) => element.SetValue(ElevationProperty, elevation);
    
        private static object OnElevationChanged(DependencyObject dependencyObject, object value)
        {
            if (dependencyObject is UIElement element && value is double elevation)
            {
                if (elevation == 0)
                {
                    element.Effect = null;
                }
                else
                {
                    var effect = CreateElevation(elevation, element.Effect);
    
                    if (effect != null)
                        element.Effect = effect;
                }
            }
    
            return value;
        }
    
        private static void MixShadows(DropShadowEffect target, DropShadowEffect other, double balance)
        {
            target.BlurRadius = target.BlurRadius * (1 - balance) + other.BlurRadius * balance;
            target.ShadowDepth = target.ShadowDepth * (1 - balance) + other.ShadowDepth * balance;
        }
    
        private static Effect CreateElevation(double elevation, Effect source)
        {
            if (elevation < 0 || elevation > 12)
                throw new ArgumentOutOfRangeException("Elevation must be between 0 and 12.", nameof(elevation));
    
            elevation = Math.Max(0, elevation / 12 * shadows.Length - 1);
    
            var shadows = sShadows;
            var prevIndex = (int)Math.Floor(elevation);
            var index = (int)elevation;
            var nextIndex = (int)Math.Ceiling(elevation);
            var approx = elevation - index;
            var shadow = shadows[index];
            var modify = false;
    
            if (approx != 0)
                MixShadows(shadow, approx < 0 ? shadows[prevIndex] : shadows[nextIndex], Math.Abs(approx));
    
            if (source is DropShadowEffect sourceShadow)
            {
                sourceShadow.BlurRadius = shadow.BlurRadius;
                sourceShadow.ShadowDepth = shadow.ShadowDepth;
                shadow = sourceShadow;
                modify = true;
            }
    
            shadow.Direction = 270;
            shadow.Color = Color.FromArgb(0xAA, 0, 0, 0);
            shadow.Opacity = .42;
            shadow.RenderingBias = RenderingBias.Performance;
    
            return modify ? null : shadow;
        }
    }
    

    Then,

    
    

    Any value between 2 and 12 can be set as the elevation of any UIElement.

提交回复
热议问题