150 lines
4.7 KiB
C#
150 lines
4.7 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace ImageCropperNamespace
|
|
{
|
|
[RequireComponent( typeof( CanvasRenderer ) )]
|
|
public class CircleGraphic : MaskableGraphic
|
|
{
|
|
public enum Mode { FillInside = 0, FillOutside = 1, Edge = 2 };
|
|
|
|
[SerializeField]
|
|
private Sprite renderSprite;
|
|
|
|
[SerializeField]
|
|
private int detail = 64;
|
|
|
|
[SerializeField]
|
|
private Mode mode;
|
|
|
|
[SerializeField]
|
|
private float edgeThickness = 1;
|
|
|
|
private Vector2 uv;
|
|
private Color32 color32;
|
|
|
|
private float width, height;
|
|
private float deltaWidth, deltaHeight;
|
|
private float deltaRadians;
|
|
|
|
public override Texture mainTexture { get { return renderSprite != null ? renderSprite.texture : s_WhiteTexture; } }
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
|
|
if( renderSprite != null )
|
|
{
|
|
Vector4 packedUv = UnityEngine.Sprites.DataUtility.GetOuterUV( renderSprite );
|
|
uv = new Vector2( packedUv.x + packedUv.z, packedUv.y + packedUv.w ) * 0.5f; // uv center point
|
|
}
|
|
}
|
|
|
|
protected override void OnPopulateMesh( VertexHelper vh )
|
|
{
|
|
Rect r = GetPixelAdjustedRect();
|
|
|
|
color32 = color;
|
|
width = r.width * 0.5f;
|
|
height = r.height * 0.5f;
|
|
|
|
vh.Clear();
|
|
|
|
Vector2 pivot = rectTransform.pivot;
|
|
deltaWidth = r.width * ( 0.5f - pivot.x );
|
|
deltaHeight = r.height * ( 0.5f - pivot.y );
|
|
|
|
if( mode == Mode.FillInside )
|
|
{
|
|
deltaRadians = 360f / detail * Mathf.Deg2Rad;
|
|
FillInside( vh );
|
|
}
|
|
else if( mode == Mode.FillOutside )
|
|
{
|
|
int quarterDetail = ( detail + 3 ) / 4;
|
|
deltaRadians = 360f / ( quarterDetail * 4 ) * Mathf.Deg2Rad;
|
|
|
|
vh.AddVert( new Vector3( width + deltaWidth, height + deltaHeight, 0f ), color32, uv );
|
|
vh.AddVert( new Vector3( -width + deltaWidth, height + deltaHeight, 0f ), color32, uv );
|
|
vh.AddVert( new Vector3( -width + deltaWidth, -height + deltaHeight, 0f ), color32, uv );
|
|
vh.AddVert( new Vector3( width + deltaWidth, -height + deltaHeight, 0f ), color32, uv );
|
|
|
|
int triangleIndex = 4;
|
|
FillOutside( vh, new Vector3( width + deltaWidth, deltaHeight, 0f ), 0, quarterDetail, ref triangleIndex );
|
|
FillOutside( vh, new Vector3( deltaWidth, height + deltaHeight, 0f ), 1, quarterDetail, ref triangleIndex );
|
|
FillOutside( vh, new Vector3( -width + deltaWidth, deltaHeight, 0f ), 2, quarterDetail, ref triangleIndex );
|
|
FillOutside( vh, new Vector3( deltaWidth, -height + deltaHeight, 0f ), 3, quarterDetail, ref triangleIndex );
|
|
}
|
|
else
|
|
{
|
|
deltaRadians = 360f / detail * Mathf.Deg2Rad;
|
|
GenerateEdges( vh );
|
|
}
|
|
}
|
|
|
|
public override void Cull( Rect clipRect, bool validRect )
|
|
{
|
|
canvasRenderer.cull = false;
|
|
}
|
|
|
|
private void FillInside( VertexHelper vh )
|
|
{
|
|
vh.AddVert( new Vector3( deltaWidth, deltaHeight, 0f ), color32, uv );
|
|
vh.AddVert( new Vector3( width + deltaWidth, deltaHeight, 0f ), color32, uv );
|
|
|
|
int triangleIndex = 2;
|
|
for( int i = 1; i < detail; i++, triangleIndex++ )
|
|
{
|
|
float radians = i * deltaRadians;
|
|
|
|
vh.AddVert( new Vector3( Mathf.Cos( radians ) * width + deltaWidth, Mathf.Sin( radians ) * height + deltaHeight, 0f ), color32, uv );
|
|
vh.AddTriangle( triangleIndex, triangleIndex - 1, 0 );
|
|
}
|
|
|
|
vh.AddTriangle( 1, triangleIndex - 1, 0 );
|
|
}
|
|
|
|
private void FillOutside( VertexHelper vh, Vector3 initialPoint, int quarterIndex, int detail, ref int triangleIndex )
|
|
{
|
|
int startIndex = quarterIndex * detail;
|
|
int endIndex = ( quarterIndex + 1 ) * detail;
|
|
|
|
vh.AddVert( initialPoint, color32, uv );
|
|
triangleIndex++;
|
|
|
|
for( int i = startIndex + 1; i <= endIndex; i++, triangleIndex++ )
|
|
{
|
|
float radians = i * deltaRadians;
|
|
|
|
vh.AddVert( new Vector3( Mathf.Cos( radians ) * width + deltaWidth, Mathf.Sin( radians ) * height + deltaHeight, 0f ), color32, uv );
|
|
vh.AddTriangle( quarterIndex, triangleIndex - 1, triangleIndex );
|
|
}
|
|
}
|
|
|
|
private void GenerateEdges( VertexHelper vh )
|
|
{
|
|
float innerWidth = width - edgeThickness;
|
|
float innerHeight = height - edgeThickness;
|
|
|
|
vh.AddVert( new Vector3( width + deltaWidth, deltaHeight, 0f ), color32, uv );
|
|
vh.AddVert( new Vector3( innerWidth + deltaWidth, deltaHeight, 0f ), color32, uv );
|
|
|
|
int triangleIndex = 2;
|
|
for( int i = 1; i < detail; i++, triangleIndex += 2 )
|
|
{
|
|
float radians = i * deltaRadians;
|
|
float cos = Mathf.Cos( radians );
|
|
float sin = Mathf.Sin( radians );
|
|
|
|
vh.AddVert( new Vector3( cos * width + deltaWidth, sin * height + deltaHeight, 0f ), color32, uv );
|
|
vh.AddVert( new Vector3( cos * innerWidth + deltaWidth, sin * innerHeight + deltaHeight, 0f ), color32, uv );
|
|
|
|
vh.AddTriangle( triangleIndex, triangleIndex - 2, triangleIndex - 1 );
|
|
vh.AddTriangle( triangleIndex, triangleIndex - 1, triangleIndex + 1 );
|
|
}
|
|
|
|
vh.AddTriangle( 0, triangleIndex - 2, triangleIndex - 1 );
|
|
vh.AddTriangle( 0, triangleIndex - 1, 1 );
|
|
}
|
|
}
|
|
} |