Color picker / UI Toolkit
Last active
November 8, 2023 15:36
-
-
Save andrew-raphael-lukasik/e7476208779f70e66fbedf5eb10aa2f8 to your computer and use it in GitHub Desktop.
basic color picker for UI Toolkit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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