none
Lacklustre LinearGradient Swatch RRS feed

  • Question

  • I am attempting to create an optically useful colour swatch. It should contain all the primary colours and blends of these in full saturation. 

    I tried defining various LinearGradient  brushes to do this, but I wasn't very happy with the result. Then I decided to create one mathematically by iterating HSL with constant Saturation and Luminosity components and returning RGB. This result lacks a proper blend too. I tried with up to 100,000 points... Same result. (The mathematical approach has the advantage that a slider can be calibrated to return RGB Html values from a hash table.)

    I suspect that what I want to do is perfectly possible, but perhaps I am missing something obvious?

    Here is a test example which utilises both methods.

    To switch between the examples: Make line 63 look like the commented line 68 and then uncomment 73.

    Function HSL2RGB([double]$h,[double]$sl,[double]$l)
    {
        [double]$v,$r,$g,$b,$m,$sv,$fract,$vsf,$mid1,$mid2;$r=$l;$g=$l;$b=$l
        if ($l-le0.5){$v=$l*(1.0+$sl)}else{$v=($l+$sl-$l*$sl)}    
        if ($v-gt0)
        {
              $m = $l + $l - $v
              $sv = ($v - $m ) / $v
              $h = $h * 6.0
              [int]$sextant = $h
              $fract = $h - $sextant
              $vsf = $v * $sv * $fract
              $mid1 = $m + $vsf
              $mid2 = $v - $vsf
              switch ($sextant)
              {   
                  0 {$r=$v;$g=$mid1;$b=$m;break}
                  1 {$r=$mid2;$g=$v;$b=$m;break}
                  2 {$r=$m;$g=$v;$b=$mid1;break}
                  3 {$r=$m;$g=$mid2;$b=$v;break}
                  4 {$r=$mid1;$g=$m;$b=$v;break}
                  5 {$r=$v;$g=$m;$b=$mid2;break}
              }
        }
    
        $rgb = [System.Drawing.Color]::FromArgb([byte]255,$([Convert]::ToByte("{0:f0}" -f $($r * 255))),$([Convert]::ToByte("{0:f0}" -f $($b * 255))),$([Convert]::ToByte("{0:f0}" -f $($g * 255))))
        return $rgb
    }
    
    Add-Type -AssemblyName PresentationFramework, PresentationCore, WindowsBase, System.Drawing
    
    $GS = [System.Windows.Media.GradientStopCollection]::New()
    for([double]$i = 0; $i -lt 1; $i+=0.01)
    {
        $c = HSL2RGB $i 0.5 0.5
        [void]$GS.add($([System.Windows.Media.GradientStop]::new($([Windows.Media.Color]::FromArgb($c.A,$c.R,$c.B,$c.G)),$i)))
    }
    $Fill = [System.Windows.Media.LinearGradientBrush]::new($GS, $(new-object Windows.Point @([double] 0, [double] 0)), $(new-object Windows.Point @([double] 0, [double] 1)))
    
    [xml]$xaml = @"
    <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="Test" Height="300" Width="100" SizeToContent="WidthAndHeight" WindowStyle="ThreeDBorderWindow" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" Background="WhiteSmoke">
        <Window.Resources>
            <LinearGradientBrush x:Key="Brush" StartPoint="0,0" EndPoint="0,1">
                <LinearGradientBrush.GradientStops>
                    <GradientStop Color="Black" Offset="0" />
                    <GradientStop Color="Red" Offset="0.1" />
                    <GradientStop Color="Yellow" Offset="0.25" />
                    <GradientStop Color="Lime" Offset="0.4" />
                    <GradientStop Color="Aqua" Offset="0.55" />
                    <GradientStop Color="Blue" Offset="0.7" />
                    <GradientStop Color="Fuchsia" Offset="0.9" />
                    <GradientStop Color="White" Offset="0.98" />
                    <GradientStop Color="White" Offset="1" />
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Window.Resources>
        <Grid Background="White">
            <Border x:Name="Border"  Background="{StaticResource Brush}" Width="30" Height="255" />
        </Grid>
    </Window>
    "@
    
    # <Border x:Name="Border" Width="30" Height="255" />
    
    $Form = [Windows.Markup.XamlReader]::Load([Xml.XmlNodeReader]::new($xaml))
    $xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]")  |% {New-Variable  -Name $_.Name -Value $Form.FindName($_.Name) -Force}
    #$border.BackGround = $Fill
    [void]$Form.ShowDialog()

    Many thanks for any help. Edit: If you think I should be posting this in a language agnostic forum, please point me.



    • Edited by Anthony Guyon Thursday, February 21, 2019 2:37 PM Added redirection comment to another forum.
    Thursday, February 21, 2019 2:16 PM

Answers

  • You need to ask these questions in  Web development forum.  Also the script you are using is not supported in this forum.

    \_(ツ)_/

    • Marked as answer by Anthony Guyon Thursday, February 21, 2019 2:46 PM
    Thursday, February 21, 2019 2:45 PM