Skip to content

Instantly share code, notes, and snippets.

@andrew-raphael-lukasik
Last active November 8, 2023 15:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrew-raphael-lukasik/e7476208779f70e66fbedf5eb10aa2f8 to your computer and use it in GitHub Desktop.
Save andrew-raphael-lukasik/e7476208779f70e66fbedf5eb10aa2f8 to your computer and use it in GitHub Desktop.
basic color picker for UI Toolkit

Color picker / UI Toolkit

GIF 08 11 2023 01-37-22

// src*: https://gist.github.com/andrew-raphael-lukasik/e7476208779f70e66fbedf5eb10aa2f8
using UnityEngine;
using UnityEngine.UIElements;
[UnityEngine.Scripting.Preserve]
public class ColorPickerElement : VisualElement
{
public new class UxmlFactory : UxmlFactory<ColorPickerElement,UxmlTraits> {}
public new class UxmlTraits : VisualElement.UxmlTraits
{
UxmlFloatAttributeDescription hueAttr = new UxmlFloatAttributeDescription{ name="hue" , defaultValue=0.5f };
UxmlFloatAttributeDescription brightnessAttr = new UxmlFloatAttributeDescription{ name="brightness" , defaultValue=1f };
public override void Init ( VisualElement ve , IUxmlAttributes attributes , CreationContext context )
{
base.Init( ve , attributes , context );
var instance = (ColorPickerElement) ve;
instance.hue = hueAttr.GetValueFromBag(attributes,context);
instance.brightness = brightnessAttr.GetValueFromBag(attributes,context);
}
}
public float hue { get; set; }
public float brightness { get; set; }
public Color color => Color.HSVToRGB(1-hue%1,1,brightness);
public Gradient circleGradient { get; set; } = new Gradient{
mode = GradientMode.Blend ,
colorKeys = new GradientColorKey[]{
new GradientColorKey( Color.HSVToRGB(0,1,1) , 0 ) ,
new GradientColorKey( Color.HSVToRGB(1*1f/6f,1,1) , 1*1f/6f ) ,
new GradientColorKey( Color.HSVToRGB(2*1f/6f,1,1) , 2*1f/6f ) ,
new GradientColorKey( Color.HSVToRGB(3*1f/6f,1,1) , 3*1f/6f ) ,
new GradientColorKey( Color.HSVToRGB(4*1f/6f,1,1) , 4*1f/6f ) ,
new GradientColorKey( Color.HSVToRGB(5*1f/6f,1,1) , 5*1f/6f ) ,
new GradientColorKey( Color.HSVToRGB(1,1,1) , 1 ) ,
}
};
public ColorPickerElement ()
{
generateVisualContent += OnGenerateVisualContent;
this.RegisterCallback<ClickEvent>( OnMouseClicked );
}
void OnMouseClicked ( ClickEvent evt )
{
Vector2 dir = (Vector2)evt.localPosition - contentRect.center;
hue = 0.25f + ( Mathf.Atan2(-dir.y,dir.x) / Mathf.PI ) * -0.5f;
Rect rect = contentRect;
float swh = Mathf.Min( rect.width , rect.height );// smaller dimension
brightness = dir.magnitude / (swh*0.4f);
this.MarkDirtyRepaint();
}
void OnGenerateVisualContent ( MeshGenerationContext mgc )
{
Rect rect = contentRect;
float swh = Mathf.Min( rect.width , rect.height );// smaller dimension
if( swh<0.01f ) return;// skip rendering when collapsed
var paint = mgc.painter2D;
float circleRadius = swh*0.4f;
float gradientWidth = swh*0.05f;
// selected color circle
paint.BeginPath();
{
paint.Arc( rect.center , circleRadius-gradientWidth/2 , 0 , 360 );
paint.fillColor = color;
paint.Fill();
}
paint.ClosePath();
// color ring
paint.BeginPath();
{
paint.Arc( rect.center , circleRadius , 270-0.001f , -90 , ArcDirection.CounterClockwise );
paint.lineWidth = gradientWidth + 0.2f;
paint.strokeColor = Color.black;
paint.Stroke();// border
paint.lineWidth = gradientWidth;
paint.strokeGradient = circleGradient;
paint.Stroke();// hues
}
paint.ClosePath();
// hue position marker
paint.BeginPath();
{
float hueAngle = -Mathf.PI/2 + hue * Mathf.PI*2;
paint.Arc( rect.center + Vector2.Scale(new Vector2(circleRadius,circleRadius),new Vector2(Mathf.Cos(hueAngle),Mathf.Sin(hueAngle))) , swh*0.03f , 0 , 360 );
paint.lineWidth = 0.4f;
paint.strokeColor = Color.white;
paint.Stroke();
}
paint.ClosePath();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment