Skip to content

Commit

Permalink
feat: render curve handle
Browse files Browse the repository at this point in the history
  • Loading branch information
witalosk committed Jan 29, 2025
1 parent db2da90 commit c77b78c
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 19 deletions.
14 changes: 7 additions & 7 deletions Assets/Scenes/ExampleUIToolkit.unity
Original file line number Diff line number Diff line change
Expand Up @@ -502,8 +502,8 @@ MonoBehaviour:
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 0.15
value: 0.6
time: 0.14864197
value: 0.6042264
inSlope: -0.014109591
outSlope: -0.014109591
tangentMode: 0
Expand All @@ -529,14 +529,14 @@ MonoBehaviour:
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 0.6
time: 0.5994507
value: 0.8
inSlope: 1.0853208
outSlope: 1.0853208
inSlope: 0.29443783
outSlope: 0.29443783
tangentMode: 0
weightedMode: 0
inWeight: 0.3082114
outWeight: 0.086051084
inWeight: 0.765727
outWeight: 0.090113364
- serializedVersion: 3
time: 1
value: 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,10 @@ private void UpdateControlPoints()
_timeField.SetValueWithoutNotify(_curve.keys[index].time);
_valueField.SetValueWithoutNotify(_curve.keys[index].value);
},
newPos =>
(newPos, lt, rt) =>
{
newPos = ScreenToGraphCoordinate(newPos);
_curve.MoveKey(index, new Keyframe(newPos.x, newPos.y));
_curve.MoveKey(index, new Keyframe(newPos.x, newPos.y, lt, rt));
UpdateCurvePreview();
UpdateControlPoints();
_timeField.SetValueWithoutNotify(_curve.keys[index].time);
Expand All @@ -273,7 +273,12 @@ private void UpdateControlPoints()
var controlPoint = _controlPoints[i];
_curvePreviewElement.Add(controlPoint);
var position = GraphToScreenCoordinate(new Vector2(key.time, key.value));
controlPoint.SetPosition(position.x * _curvePreviewElement.resolvedStyle.width, (1f - position.y) * _curvePreviewElement.resolvedStyle.height);
controlPoint.SetPosition(
position.x * _curvePreviewElement.resolvedStyle.width,
(1f - position.y) * _curvePreviewElement.resolvedStyle.height,
key.inTangent,
key.outTangent
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ namespace RosettaUI.UIToolkit
public class AnimationCurveEditorControlPoint : VisualElement
{
private Action _onPointSelected;
private Action<Vector2> _onPointMoved;
private Action<Vector2, float, float> _onPointMoved;
private Vector2 _elementPositionOnDown;
private Vector2 _mouseDownPosition;
private float _leftTan;
private float _rightTan;

private AnimationCurveEditorControlPointHandle _leftHandle;
private AnimationCurveEditorControlPointHandle _rightHandle;

private const float ControlPointSize = 10f;

public AnimationCurveEditorControlPoint(Action onPointSelected, Action<Vector2> onPointMoved)
public AnimationCurveEditorControlPoint(Action onPointSelected, Action<Vector2, float, float> onPointMoved)
{
_onPointSelected = onPointSelected;
_onPointMoved = onPointMoved;
Expand All @@ -26,12 +31,23 @@ public AnimationCurveEditorControlPoint(Action onPointSelected, Action<Vector2>
AddToClassList("rosettaui-animation-curve-editor__control-point");
style.width = ControlPointSize;
style.height = ControlPointSize;

// Handles
_leftHandle = new AnimationCurveEditorControlPointHandle(0f);
Add(_leftHandle);
_rightHandle = new AnimationCurveEditorControlPointHandle(180f);
Add(_rightHandle);
}

public void SetPosition(float x, float y)
public void SetPosition(float x, float y, float leftTan, float rightTan)
{
style.left = x - ControlPointSize * 0.5f;
style.top = y - ControlPointSize * 0.5f;
_leftHandle.SetAngle(Mathf.Atan(leftTan) * Mathf.Rad2Deg);
_rightHandle.SetAngle(180f + Mathf.Atan(rightTan) * Mathf.Rad2Deg);
_leftTan = leftTan;
_rightTan = rightTan;
Debug.Log($"SetPosition: {x}, {y}, {leftTan}, {rightTan}");
}

private void OnMouseDown(MouseDownEvent evt)
Expand All @@ -49,16 +65,24 @@ private void OnMouseDown(MouseDownEvent evt)

private void OnMouseMove(MouseMoveEvent evt)
{
style.left = _elementPositionOnDown.x + (evt.mousePosition.x - _mouseDownPosition.x);
style.top = _elementPositionOnDown.y + (evt.mousePosition.y - _mouseDownPosition.y);
_onPointMoved?.Invoke(Vector2.up + new Vector2(style.left.value.value, -style.top.value.value) / parent.layout.size);
SetMousePosition(evt.mousePosition);
}

private void OnMouseLeave(MouseLeaveEvent evt)
{
style.left = _elementPositionOnDown.x + (evt.mousePosition.x - _mouseDownPosition.x);
style.top = _elementPositionOnDown.y + (evt.mousePosition.y - _mouseDownPosition.y);
_onPointMoved?.Invoke(Vector2.up + new Vector2(style.left.value.value, -style.top.value.value) / parent.layout.size);
SetMousePosition(evt.mousePosition);
}

private void SetMousePosition(Vector2 mousePosition)
{
style.left = _elementPositionOnDown.x + (mousePosition.x - _mouseDownPosition.x);
style.top = _elementPositionOnDown.y + (mousePosition.y - _mouseDownPosition.y);
_onPointMoved?.Invoke(
Vector2.up + new Vector2(style.left.value.value,
-style.top.value.value) / parent.layout.size,
_leftTan,
_rightTan
);
}

private void OnMouseUp(MouseUpEvent evt)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using UnityEngine;
using UnityEngine.UIElements;

namespace RosettaUI.UIToolkit
{
public class AnimationCurveEditorControlPointHandle : VisualElement
{
private VisualElement _lineElement;
private VisualElement _handleElement;

public AnimationCurveEditorControlPointHandle(float angle)
{
AddToClassList("rosettaui-animation-curve-editor__control-point-handle");
InitUI();
SetAngle(angle);
}

private void InitUI()
{
_lineElement = new VisualElement();
_lineElement.AddToClassList("rosettaui-animation-curve-editor__control-point-handle__line");
_lineElement.style.position = Position.Absolute;
_lineElement.style.left = 5;
_lineElement.style.top = 4;
_lineElement.style.backgroundColor = new StyleColor(Color.white);
_lineElement.style.borderTopWidth = 0.5f;
_lineElement.style.borderBottomWidth = 0.5f;
_lineElement.style.borderLeftWidth = 0.5f;
_lineElement.style.borderRightWidth = 0.5f;
_lineElement.style.borderTopColor = new StyleColor(Color.black);
_lineElement.style.borderBottomColor = new StyleColor(Color.black);
_lineElement.style.borderLeftColor = new StyleColor(Color.black);
_lineElement.style.borderRightColor = new StyleColor(Color.black);
_lineElement.style.transformOrigin = new StyleTransformOrigin(new TransformOrigin(0, Length.Percent(50)));
_lineElement.style.opacity = 0.5f;
_lineElement.style.width = 50;
_lineElement.style.height = 2;
// _lineElement.style.zIndex = 1;
Add(_lineElement);

float handleSize = 8;
_handleElement = new VisualElement();
_handleElement.AddToClassList("rosettaui-animation-curve-editor__control-point-handle__handle");
_handleElement.style.position = Position.Absolute;
_handleElement.style.right = -handleSize * 0.5f;
_handleElement.style.top = -handleSize * 0.5f;
_handleElement.style.width = handleSize;
_handleElement.style.height = handleSize;
_handleElement.style.borderTopLeftRadius = handleSize * 0.5f;
_handleElement.style.borderTopRightRadius = handleSize * 0.5f;
_handleElement.style.borderBottomLeftRadius = handleSize * 0.5f;
_handleElement.style.borderBottomRightRadius = handleSize * 0.5f;
_handleElement.style.backgroundColor = new StyleColor(Color.gray);
_lineElement.Add(_handleElement);

}

public void SetAngle(float angle)
{
_lineElement.style.rotate = new StyleRotate(new Rotate(Angle.Degrees(-angle)));
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c77b78c

Please sign in to comment.