194 lines
7.7 KiB
C#
194 lines
7.7 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace EasyChart
|
|
{
|
|
internal sealed class ChartBackgroundModule : IChartModule
|
|
{
|
|
private ChartElement _owner;
|
|
private VisualElement _layer;
|
|
|
|
public void Bind(ChartElement owner, ChartKernel kernel)
|
|
{
|
|
_owner = owner;
|
|
if (_owner == null) return;
|
|
_layer = _owner.BackgroundLayerInternal;
|
|
if (_layer == null) return;
|
|
|
|
_layer.generateVisualContent += OnGenerateVisualContent;
|
|
}
|
|
|
|
public void Unbind()
|
|
{
|
|
if (_layer != null)
|
|
{
|
|
_layer.generateVisualContent -= OnGenerateVisualContent;
|
|
}
|
|
_layer = null;
|
|
_owner = null;
|
|
}
|
|
|
|
private void OnGenerateVisualContent(MeshGenerationContext ctx)
|
|
{
|
|
if (_owner == null) return;
|
|
|
|
var profile = _owner.Profile;
|
|
if (profile == null) return;
|
|
if (profile.background == null) return;
|
|
|
|
var bg = profile.background;
|
|
if (!bg.show) return;
|
|
|
|
if (_layer == null) return;
|
|
float width = _layer.contentRect.width;
|
|
float height = _layer.contentRect.height;
|
|
if (width <= 0 || height <= 0) return;
|
|
|
|
var painter = ctx.painter2D;
|
|
|
|
var fill = bg.textureFill;
|
|
var tex = fill != null ? fill.texture : null;
|
|
if (tex == null)
|
|
{
|
|
painter.fillColor = fill != null ? fill.color : Color.clear;
|
|
painter.BeginPath();
|
|
painter.MoveTo(new Vector2(0, 0));
|
|
painter.LineTo(new Vector2(width, 0));
|
|
painter.LineTo(new Vector2(width, height));
|
|
painter.LineTo(new Vector2(0, height));
|
|
painter.ClosePath();
|
|
painter.Fill();
|
|
return;
|
|
}
|
|
|
|
if (Application.isPlaying)
|
|
{
|
|
bool hasPro = ProPackage.IsInstalled;
|
|
var desiredWrap = (hasPro && fill != null && fill.animationType == TextureFillAnimationType.TextureScale)
|
|
? TextureWrapMode.Clamp
|
|
: TextureWrapMode.Repeat;
|
|
|
|
if (tex.wrapMode != desiredWrap)
|
|
tex.wrapMode = desiredWrap;
|
|
}
|
|
|
|
var mesh = ctx.Allocate(4, 6, tex);
|
|
Color tint = fill != null ? fill.color : Color.white;
|
|
|
|
Vector2 tiling = fill != null ? fill.tiling : Vector2.one;
|
|
Vector2 offset = fill != null ? fill.offset : Vector2.zero;
|
|
|
|
if (fill != null && ProPackage.IsInstalled && fill.animationType != TextureFillAnimationType.None)
|
|
{
|
|
float t = Time.realtimeSinceStartup;
|
|
if (fill.animationType == TextureFillAnimationType.TextureUvMove)
|
|
{
|
|
offset -= fill.uvMoveSpeed * t;
|
|
}
|
|
else if (fill.animationType == TextureFillAnimationType.TextureScale)
|
|
{
|
|
var baseTiling = tiling;
|
|
|
|
float u = t * fill.scaleSpeed;
|
|
float c01;
|
|
|
|
Vector2 factor;
|
|
switch (fill.scaleType)
|
|
{
|
|
case TextureFillScaleType.ZoomIn:
|
|
{
|
|
float p = Mathf.Repeat(u, 1f);
|
|
var s = Vector2.Lerp(fill.scaleFrom, fill.scaleTo, p);
|
|
s.x = Mathf.Max(0.0001f, s.x);
|
|
s.y = Mathf.Max(0.0001f, s.y);
|
|
factor = new Vector2(1f / s.x, 1f / s.y);
|
|
c01 = p;
|
|
break;
|
|
}
|
|
case TextureFillScaleType.ZoomOut:
|
|
{
|
|
float p = Mathf.Repeat(u, 1f);
|
|
var s = Vector2.Lerp(fill.scaleTo, fill.scaleFrom, p);
|
|
s.x = Mathf.Max(0.0001f, s.x);
|
|
s.y = Mathf.Max(0.0001f, s.y);
|
|
factor = new Vector2(1f / s.x, 1f / s.y);
|
|
c01 = p;
|
|
break;
|
|
}
|
|
case TextureFillScaleType.PingPong:
|
|
{
|
|
float p = Mathf.PingPong(u, 1f);
|
|
var s = Vector2.Lerp(fill.scaleFrom, fill.scaleTo, p);
|
|
s.x = Mathf.Max(0.0001f, s.x);
|
|
s.y = Mathf.Max(0.0001f, s.y);
|
|
factor = new Vector2(1f / s.x, 1f / s.y);
|
|
c01 = p;
|
|
break;
|
|
}
|
|
case TextureFillScaleType.Sin:
|
|
default:
|
|
{
|
|
float s = Mathf.Sin(u);
|
|
float p = (s + 1f) * 0.5f;
|
|
var sc = Vector2.Lerp(fill.scaleFrom, fill.scaleTo, p);
|
|
sc.x = Mathf.Max(0.0001f, sc.x);
|
|
sc.y = Mathf.Max(0.0001f, sc.y);
|
|
factor = new Vector2(1f / sc.x, 1f / sc.y);
|
|
c01 = p;
|
|
break;
|
|
}
|
|
}
|
|
|
|
factor.x = Mathf.Max(0.0001f, factor.x);
|
|
factor.y = Mathf.Max(0.0001f, factor.y);
|
|
tiling = new Vector2(baseTiling.x * factor.x, baseTiling.y * factor.y);
|
|
offset += (baseTiling - tiling) * 0.5f;
|
|
|
|
if (fill.colorFadeGradient != null)
|
|
tint *= fill.colorFadeGradient.Evaluate(c01);
|
|
}
|
|
else if (fill.animationType == TextureFillAnimationType.TextureFade)
|
|
{
|
|
float u = t * fill.colorFadeSpeed;
|
|
float c01;
|
|
switch (fill.colorFadeWrap)
|
|
{
|
|
case TextureFillColorOverLifeWrap.Loop:
|
|
c01 = Mathf.Repeat(u, 1f);
|
|
break;
|
|
case TextureFillColorOverLifeWrap.Clamp:
|
|
c01 = Mathf.Clamp01(u);
|
|
break;
|
|
case TextureFillColorOverLifeWrap.PingPong:
|
|
default:
|
|
c01 = Mathf.PingPong(u, 1f);
|
|
break;
|
|
}
|
|
|
|
if (fill.colorFadeGradient != null)
|
|
tint = fill.colorFadeGradient.Evaluate(c01);
|
|
else
|
|
tint = Color.Lerp(fill.colorFadeStart, fill.colorFadeEnd, c01);
|
|
}
|
|
}
|
|
|
|
float u0 = 0f * tiling.x + offset.x;
|
|
float u1 = 1f * tiling.x + offset.x;
|
|
float v0 = 1f * tiling.y + offset.y;
|
|
float v1 = 0f * tiling.y + offset.y;
|
|
|
|
mesh.SetNextVertex(new Vertex { position = new Vector3(0, 0, Vertex.nearZ), tint = tint, uv = new Vector2(u0, v0) });
|
|
mesh.SetNextVertex(new Vertex { position = new Vector3(width, 0, Vertex.nearZ), tint = tint, uv = new Vector2(u1, v0) });
|
|
mesh.SetNextVertex(new Vertex { position = new Vector3(width, height, Vertex.nearZ), tint = tint, uv = new Vector2(u1, v1) });
|
|
mesh.SetNextVertex(new Vertex { position = new Vector3(0, height, Vertex.nearZ), tint = tint, uv = new Vector2(u0, v1) });
|
|
|
|
mesh.SetNextIndex(0);
|
|
mesh.SetNextIndex(1);
|
|
mesh.SetNextIndex(2);
|
|
mesh.SetNextIndex(2);
|
|
mesh.SetNextIndex(3);
|
|
mesh.SetNextIndex(0);
|
|
}
|
|
}
|
|
}
|