zoukankan      html  css  js  c++  java
  • [UWP]分享一个基于HSV色轮的调色板应用

    1. 前言

    上一篇文章介绍了HSV色轮,这次分享一个基于HSV色轮的调色板应用,应用地址:ColorfulBox - Microsoft Store

    2. 功能

    ColorfulBox是Adobe 色轮的简单模仿,只实现了最基本的功能,UI也没那么好看,也没用MVVM框架。

    2.1 HSV色轮

    这个应用最好玩的地方在于分布于HSV色轮上的各个点(ColorPoint)以及可以通过拖动它们改变颜色。ColorPoint的基本结构如下(不是完整代码):

    public class ColorPoint : DependencyObject, INotifyPropertyChanged
    {
    
        public event EventHandler<PropertyEventArgs> ColorChanged;
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnColorChanged(Color oldValue, Color newValue)
        {
            ColorChanged?.Invoke(this, new PropertyEventArgs(nameof(Color), oldValue, newValue));
        }
    
    
        private Color _color;
    
        /// <summary>
        /// 获取或设置 Color 的值
        /// </summary>
        public Color Color
        {
            get { return _color; }
            set
            {
                if (_color == value)
                    return;
    
                var oldValue = _color;
                _color = value;
                OnPropertyChanged("Color");
                ColorChanged?.Invoke(this, new PropertyEventArgs(nameof(Color), oldValue, _color));
            }
        }
    }
    
    

    由于Color是一个struct,UWP没办法监视struct的值改变事件,所以才使用ColorPoint来包装Color及其它功能。

    色轮本身是一个ListView,这样比直接继承Control少写很多代码,尤其是SelectedItem相关的代码还挺无趣的。虽然色轮从外表看不出是个ListView,改改ControlTemplate,再配合GetContainerForItemOverride()PrepareContainerForItemOverride(DependencyObject element, object item)两个函数,可以让ListView完全改头换面。熟悉XAML的开发者应该都不会对这两个ItemsControl中的关键函数感到陌生。

    <Style TargetType="local:HsvWheelColorPalette">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:HsvWheelColorPalette">
                    <Grid Background="{TemplateBinding Background}">
                        <Image Source="ms-appx:///Assets/Wheel.png" />
                        <ItemsPresenter />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemContainerStyle"
                Value="{StaticResource HsvWheelColorPointVisualStyle}" />
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <Grid />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new ColorPointVisual();
    }
    
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);
        if (element is ColorPointVisual visual)
        {
            visual.ManipulationStarted -= OnColorPointVisualDragStarted;
            visual.ManipulationStarted += OnColorPointVisualDragStarted;
    
            visual.ManipulationDelta -= OnColorPointVisualDragDelta;
            visual.ManipulationDelta += OnColorPointVisualDragDelta;
        }
    
        var colorPoint = item as ColorPoint;
        colorPoint.ColorChanged -= OnColorChanged;
        colorPoint.ColorChanged += OnColorChanged;
    }
    
    

    在UWP中拖动的代码变得很简洁,这次直接在PrepareContainerForItemOverride(DependencyObject element, object item)为ColorPointVisual订阅拖动的事件。至于ColorPointVisual的布局,只需要转换Color为HsvColor,再计算距离中心点的角度(Hue)和距离(Saturation)就可以得出,为了不和ListView的代码耦合,尽量使用Binding:

    <TransformGroup>
        <TranslateTransform X="{Binding TranslateX, Source={StaticResource SaturationAndRadiusToTransformXBridge}}" />
        <RotateTransform Angle="{Binding Color, Converter={StaticResource ColorToAngleConverter}}" />
    </TransformGroup>
    
    

    2.2 后续功能

    Hsv色轮是整个应用中最有趣的部分,之后只需要按部就班添加各种色彩规则(目前只有Analogous,即类比)和输出的颜色模型。由于开源这个应用的目的是作为一个用于学习的应用,不想添加太多功能让这个项目的代码变得复杂。

    2.3 已知的问题

    Hsv色轮中各个ColorPoint拖动并不是太平滑,这是因为Hsv颜色只能表示360 * 100 = 36000 种颜色,而Hsv色轮上有πr^2 个像素点,它们之间做不到完全匹配。虽然已经想到解决方案,不过暂时没太大兴致解决。

    3. 结语

    前面提到ColorfulBox是一个用于学习的应用,不会有太多复杂的技术,暂时连MVVM都不会有。将来添加功能也会很谨慎(主要看心情),希望代码不会膨胀得太夸张吧。

    题外话,UWP一直缺少一个ColorPicker控件,而微软将在Fall Update (1709)中提供新的控件ColorPicker,同样基于HSV色轮。等了这么久终于等到了。

    4. 参考

    色论 _ 色彩配置 - Adobe Color CC
    操作事件

    5. 源码

    Colorful-Box

  • 相关阅读:
    晕晕的一天
    23. 合并K个排序链表
    25. K 个一组翻转链表
    328. 奇偶链表
    86. 分隔链表
    290. 单词规律
    202. 快乐数
    242. 有效的字母异位词
    16.最接近的三数之和
    (转) java 简单工厂模式(实现一个计算器)
  • 原文地址:https://www.cnblogs.com/dino623/p/ColorfulBox.html
Copyright © 2011-2022 走看看