2025-02-21 17:26:17 +08:00
|
|
|
|
using QFramework;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.Events;
|
|
|
|
|
|
using UnityEngine.EventSystems;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
using UnityEngine.Rendering;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
|
|
|
|
|
|
[RequireComponent(typeof(Camera))]
|
|
|
|
|
|
public class ScreenShotPainter : MonoBehaviour
|
|
|
|
|
|
{
|
|
|
|
|
|
public class LineSegment
|
|
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
public RenderTexture Texture { get; set; }
|
2025-02-21 17:26:17 +08:00
|
|
|
|
public Color Color { get; set; }
|
|
|
|
|
|
public float Width { get; set; }
|
|
|
|
|
|
public bool IsEraser { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public LineSegment(Color color, float width, bool isEraser)
|
|
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
Texture = RenderTexture.GetTemporary(Screen.width, Screen.height, 24);
|
2025-02-21 17:26:17 +08:00
|
|
|
|
Color = color;
|
|
|
|
|
|
Width = width;
|
|
|
|
|
|
IsEraser = isEraser;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static ScreenShotPainter instance;
|
|
|
|
|
|
|
|
|
|
|
|
#region private numbers
|
|
|
|
|
|
|
|
|
|
|
|
//[SerializeField]
|
|
|
|
|
|
private string _captureSavePath;
|
|
|
|
|
|
|
|
|
|
|
|
//private Canvas _paintCanvas;
|
|
|
|
|
|
|
|
|
|
|
|
//[SerializeField]
|
|
|
|
|
|
private Texture _defaultBrushRawImage;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 涂鸦的RenderTexture图片
|
|
|
|
|
|
/// </summary>
|
2025-02-24 17:03:44 +08:00
|
|
|
|
private RenderTexture _currentRenderTexture;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 涂鸦的RenderTexture图片
|
|
|
|
|
|
/// </summary>
|
2025-02-24 17:03:44 +08:00
|
|
|
|
//private RenderTexture _historyRenderTexture;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 截图灰化背景图
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
//[SerializeField]
|
|
|
|
|
|
private RawImage _bgRawImage;
|
|
|
|
|
|
|
|
|
|
|
|
//绘图shader&material
|
|
|
|
|
|
//[SerializeField]
|
|
|
|
|
|
private Shader _paintBrushShader;
|
|
|
|
|
|
private Material _paintBrushMat;
|
|
|
|
|
|
|
|
|
|
|
|
//清理renderTexture的shader&material
|
|
|
|
|
|
//[SerializeField]
|
|
|
|
|
|
private Shader _clearBrushShader;
|
|
|
|
|
|
private Material _clearBrushMat;
|
|
|
|
|
|
//[SerializeField]
|
|
|
|
|
|
private Shader _eraserBrushShader;
|
|
|
|
|
|
private Material _eraserBrushMat;
|
|
|
|
|
|
//笔刷的默认颜色
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private Color _defaultColor = Color.black;
|
|
|
|
|
|
|
|
|
|
|
|
//涂鸦的画布
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private RawImage _paintCanvasImg;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 笔刷的大小
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private float _brushSize = 300f;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 橡皮擦的大小
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private float _eraserSize = 300f;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 笔刷间隔
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private float _brushLerpSize;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 默认上一次点的位置
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Vector2 _lastPoint;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 截图框选左下角点坐标
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Vector2 _leftDownConnerPoint;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 截图框选右上角点坐标
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Vector2 _rightUpConnerPoint;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 截图框选左上角点坐标
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Vector2 _leftUpConnerPoint;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 截图框选右下角点坐标
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Vector2 _rightDownConnerPoint;
|
|
|
|
|
|
|
|
|
|
|
|
//屏幕的宽高
|
|
|
|
|
|
private int _screenWidth;
|
|
|
|
|
|
private int _screenHeight;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 框选截图区域
|
|
|
|
|
|
//框选截图起始点
|
|
|
|
|
|
private Vector2 _startPoint;
|
|
|
|
|
|
private Vector2 _endPoint;
|
|
|
|
|
|
//框的颜色
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private Color _rectColor = Color.red;
|
|
|
|
|
|
|
|
|
|
|
|
private bool _haveCirmformRectStarPoint;
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 组件开关
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private bool _enabled;
|
|
|
|
|
|
|
|
|
|
|
|
private bool _eraserFlag;
|
|
|
|
|
|
private CaptureType _defaultCaptureType;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 是否已经选了区域
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private bool _haveRegion;
|
|
|
|
|
|
|
|
|
|
|
|
private bool _drawRegionRect;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 截图标记位
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private bool _captureFlag;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 是否要截取UI
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private bool _captureWithUI;
|
|
|
|
|
|
|
|
|
|
|
|
private Material _lineMaterial;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 一些外部注册事件
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 画完区域后要做的事情(其实就是处理UI面板,给外部调用)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private FinishedRegionEvent _finishedRegionEvent = new FinishedRegionEvent();
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 取消选择区域后要做的事情(其实就是处理UI面板,给外部调用)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private CannelRegionEvent _cannelRegionEvent = new CannelRegionEvent();
|
|
|
|
|
|
|
|
|
|
|
|
private FinishedCaptureEvent _finishedCapture = new FinishedCaptureEvent();
|
|
|
|
|
|
|
|
|
|
|
|
private EscapeCaptureEvent _escapeCaptureEvent = new EscapeCaptureEvent();
|
|
|
|
|
|
|
|
|
|
|
|
private EnterCaptureModeEvent _enterCaptureModeEvent = new EnterCaptureModeEvent();
|
|
|
|
|
|
|
|
|
|
|
|
private EraserModeUpdateEvent _eraserModeUpdateEvent = new EraserModeUpdateEvent();
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region public properties
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public FinishedRegionEvent FinishedRegionEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _finishedRegionEvent; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public CannelRegionEvent CannelRegionEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _cannelRegionEvent; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public FinishedCaptureEvent FinishedCapture
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _finishedCapture; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public EscapeCaptureEvent EscapeCaptureEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _escapeCaptureEvent; }
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Stack<LineSegment> _lineStack = new Stack<LineSegment>();
|
|
|
|
|
|
private LineSegment _currentLine;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public enum Status
|
|
|
|
|
|
{
|
|
|
|
|
|
Pen,
|
|
|
|
|
|
Eraser,
|
|
|
|
|
|
Line,
|
2025-02-24 11:11:14 +08:00
|
|
|
|
Rect,
|
|
|
|
|
|
Circle,
|
2025-02-21 17:26:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
public EnterCaptureModeEvent EnterCaptureModeEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _enterCaptureModeEvent; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public EraserModeUpdateEvent EraserModeUpdateEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _eraserModeUpdateEvent; }
|
|
|
|
|
|
}
|
|
|
|
|
|
#region life circle
|
|
|
|
|
|
|
|
|
|
|
|
bool isInited = false;
|
|
|
|
|
|
|
|
|
|
|
|
Status status = Status.Pen;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private CommandBuffer _commandBuffer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private float _lastPaintTime;
|
|
|
|
|
|
private float _paintInterval = 0.02f; // 每0.02秒绘制一次
|
|
|
|
|
|
|
2025-02-24 17:37:06 +08:00
|
|
|
|
Image circleImg;
|
|
|
|
|
|
Image rectImg;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
void Awake()
|
|
|
|
|
|
{
|
|
|
|
|
|
instance = this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-24 17:37:06 +08:00
|
|
|
|
public void Init(RawImage drawImg, RawImage bgRawImg, Image circleImg, Image rectImg)
|
2025-02-21 17:26:17 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (isInited == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
isInited = true;
|
2025-02-24 17:37:06 +08:00
|
|
|
|
this.circleImg = circleImg;
|
|
|
|
|
|
this.rectImg = rectImg;
|
|
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
_commandBuffer = new CommandBuffer();
|
|
|
|
|
|
_commandBuffer.name = "PaintCommandBuffer";
|
|
|
|
|
|
|
2025-02-21 17:26:17 +08:00
|
|
|
|
|
|
|
|
|
|
_bgRawImage = bgRawImg;
|
|
|
|
|
|
_paintCanvasImg = drawImg;
|
|
|
|
|
|
|
|
|
|
|
|
_captureWithUI = true;
|
|
|
|
|
|
_captureSavePath = Application.dataPath;
|
|
|
|
|
|
_defaultCaptureType = CaptureType.FreeRegion;
|
|
|
|
|
|
|
|
|
|
|
|
//_paintCanvasImg = GameObject.FindObjectOfType<Canvas>().transform.Find("paintCanvasImg").GetComponent<RawImage>();
|
|
|
|
|
|
_screenWidth = Screen.width;
|
|
|
|
|
|
_screenHeight = Screen.height;
|
|
|
|
|
|
_paintBrushShader = Resources.Load<Shader>("Shaders/PaintBrush");
|
|
|
|
|
|
_paintBrushMat = new Material(_paintBrushShader);
|
|
|
|
|
|
_clearBrushShader = Resources.Load<Shader>("Shaders/ClearBrush");
|
|
|
|
|
|
_clearBrushMat = new Material(_clearBrushShader);
|
|
|
|
|
|
_eraserBrushShader = Resources.Load<Shader>("Shaders/EraserBrush");
|
|
|
|
|
|
_eraserBrushMat = new Material(_eraserBrushShader);
|
|
|
|
|
|
|
|
|
|
|
|
_defaultBrushRawImage = Resources.Load<Texture>("brush-1");
|
|
|
|
|
|
|
|
|
|
|
|
//初始化刷子
|
|
|
|
|
|
_paintBrushMat.SetTexture("_BrushTex", _defaultBrushRawImage);
|
|
|
|
|
|
_paintBrushMat.SetColor("_Color", _defaultColor);
|
|
|
|
|
|
_brushSize = PaintingParams.BrushDefaultSize;
|
|
|
|
|
|
_brushLerpSize = (_defaultBrushRawImage.width + _defaultBrushRawImage.height) / 2.0f / _brushSize;
|
|
|
|
|
|
_paintBrushMat.SetFloat("_Size", _brushSize);
|
|
|
|
|
|
_paintBrushMat.SetFloat("_SizeY", _brushSize * (float)_screenHeight / (float)_screenWidth);
|
|
|
|
|
|
|
|
|
|
|
|
_eraserSize = PaintingParams.EraserDefaultSize;
|
|
|
|
|
|
_eraserBrushMat.SetTexture("_BrushTex", _defaultBrushRawImage);
|
|
|
|
|
|
_eraserBrushMat.SetColor("_Color", new Color(0f, 0f, 0f, 0f));
|
|
|
|
|
|
_eraserBrushMat.SetFloat("_Size", _eraserSize);
|
|
|
|
|
|
_eraserBrushMat.SetFloat("_SizeY", _eraserSize * (float)_screenHeight / (float)_screenWidth);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
_currentRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
|
|
|
|
|
|
_paintCanvasImg.texture = _currentRenderTexture;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
|
|
|
|
|
|
// 激活渲染纹理,确保它可以被写入
|
2025-02-24 17:03:44 +08:00
|
|
|
|
RenderTexture.active = _currentRenderTexture;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
GL.Clear(true, true, Color.clear);
|
|
|
|
|
|
|
|
|
|
|
|
//给画布添加事件
|
|
|
|
|
|
var paintEventTrigger = _paintCanvasImg.GetOrAddComponent<EventTrigger>();
|
|
|
|
|
|
|
|
|
|
|
|
paintEventTrigger.triggers = new List<EventTrigger.Entry>();
|
|
|
|
|
|
|
|
|
|
|
|
EventTrigger.Entry dragEntry = new EventTrigger.Entry();
|
|
|
|
|
|
dragEntry.eventID = EventTriggerType.Drag;
|
|
|
|
|
|
dragEntry.callback.AddListener(PaintDragging);
|
|
|
|
|
|
|
|
|
|
|
|
EventTrigger.Entry endDragEntry = new EventTrigger.Entry();
|
|
|
|
|
|
endDragEntry.eventID = EventTriggerType.EndDrag;
|
|
|
|
|
|
endDragEntry.callback.AddListener(OnPaintEndDrag);
|
|
|
|
|
|
paintEventTrigger.triggers.Add(dragEntry);
|
|
|
|
|
|
paintEventTrigger.triggers.Add(endDragEntry);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EventTrigger.Entry beginDrawEntry = new EventTrigger.Entry();
|
|
|
|
|
|
beginDrawEntry.eventID = EventTriggerType.BeginDrag;
|
|
|
|
|
|
beginDrawEntry.callback.AddListener(OnPaintBeginDrag);
|
|
|
|
|
|
//paintEventTrigger.triggers.Add(dragEntry);
|
|
|
|
|
|
paintEventTrigger.triggers.Add(beginDrawEntry);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 Graphics.Blit 清除渲染纹理
|
2025-02-24 17:03:44 +08:00
|
|
|
|
Graphics.Blit(null, _currentRenderTexture, _clearBrushMat);
|
2025-02-21 17:26:17 +08:00
|
|
|
|
|
|
|
|
|
|
// 恢复默认的渲染纹理
|
|
|
|
|
|
RenderTexture.active = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Update()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_enabled)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (_defaultCaptureType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case CaptureType.FullScreen:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CaptureType.FreeRegion:
|
|
|
|
|
|
//已经选了区域,可以开始涂鸦了
|
|
|
|
|
|
if (_haveRegion)
|
|
|
|
|
|
{
|
|
|
|
|
|
//如果按下右键,表示重新选择区域,清除掉之前的记录
|
|
|
|
|
|
if (Input.GetMouseButtonUp(1))
|
|
|
|
|
|
{
|
|
|
|
|
|
_defaultCaptureType = CaptureType.FreeRegion;
|
|
|
|
|
|
_haveRegion = false;
|
|
|
|
|
|
_haveCirmformRectStarPoint = false;
|
|
|
|
|
|
_startPoint = Vector2.zero;
|
|
|
|
|
|
_endPoint = Vector2.zero;
|
|
|
|
|
|
_drawRegionRect = false;
|
|
|
|
|
|
_leftUpConnerPoint = Vector2.zero;
|
|
|
|
|
|
_leftDownConnerPoint = Vector2.zero;
|
|
|
|
|
|
_rightUpConnerPoint = Vector2.zero;
|
|
|
|
|
|
_rightDownConnerPoint = Vector2.zero;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
_currentRenderTexture.Release();
|
2025-02-21 17:26:17 +08:00
|
|
|
|
_bgRawImage.material.SetVector("_Rect", new Vector4(0, 0, 0, 0));
|
|
|
|
|
|
_eraserFlag = false;
|
|
|
|
|
|
//Graphics.Blit(_blitRenderTexture, _blitRenderTexture, _clearBrushMat); //清除一下
|
|
|
|
|
|
CannelRegionEvent.Invoke();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
//涂鸦的侦听逻辑
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
//未选择区域,要先选区域
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
//switch (_defaultCaptureType)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// case CaptureType.FullScreen:
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// case CaptureType.FreeRegion:
|
|
|
|
|
|
// //如果没有点下选择起点
|
|
|
|
|
|
if (!_haveCirmformRectStarPoint)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Input.GetMouseButtonDown(0))
|
|
|
|
|
|
{
|
|
|
|
|
|
//超出屏幕外
|
|
|
|
|
|
if (Input.mousePosition.x < 0 || Input.mousePosition.x > Screen.width ||
|
|
|
|
|
|
Input.mousePosition.y < 0 || Input.mousePosition.y > Screen.height)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
_startPoint = Input.mousePosition;
|
|
|
|
|
|
_haveCirmformRectStarPoint = true;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//如果选下了起点,刷新鼠标位置
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_drawRegionRect = true;
|
|
|
|
|
|
if (Input.GetMouseButton(0))
|
|
|
|
|
|
{
|
|
|
|
|
|
_endPoint = Input.mousePosition;
|
|
|
|
|
|
//限制坐标在屏幕内
|
|
|
|
|
|
_endPoint.x = Mathf.Clamp(_endPoint.x, 0f, Screen.width);
|
|
|
|
|
|
_endPoint.y = Mathf.Clamp(_endPoint.y, 0f, Screen.height);
|
|
|
|
|
|
//设置灰化区域
|
|
|
|
|
|
Vector4 rect = new Vector4(Mathf.Min(_startPoint.x, _endPoint.x) / Screen.width,
|
|
|
|
|
|
Mathf.Min(_startPoint.y, _endPoint.y) / Screen.height,
|
|
|
|
|
|
Mathf.Max(_startPoint.x, _endPoint.x) / Screen.width,
|
|
|
|
|
|
Mathf.Max(_startPoint.y, _endPoint.y) / Screen.height);
|
|
|
|
|
|
_bgRawImage.material.SetVector("_Rect", rect);
|
|
|
|
|
|
}
|
|
|
|
|
|
//鼠标抬起,截图框选区域确定
|
|
|
|
|
|
if (Input.GetMouseButtonUp(0))
|
|
|
|
|
|
{
|
|
|
|
|
|
_endPoint = Input.mousePosition;
|
|
|
|
|
|
//限制坐标在屏幕内
|
|
|
|
|
|
_endPoint.x = Mathf.Clamp(_endPoint.x, 0f, Screen.width);
|
|
|
|
|
|
_endPoint.y = Mathf.Clamp(_endPoint.y, 0f, Screen.height);
|
|
|
|
|
|
|
|
|
|
|
|
_haveRegion = true;
|
|
|
|
|
|
_leftUpConnerPoint = GetCaptureViewLeftUpConnerPoint();
|
|
|
|
|
|
_rightUpConnerPoint = GetCaptureViewRightUpConnerPoint();
|
|
|
|
|
|
_rightDownConnerPoint = GetCaptureViewRightDownConnerPoint();
|
|
|
|
|
|
_leftDownConnerPoint = GetCaptureViewLeftDownConnerPoint();
|
|
|
|
|
|
FinishedRegionEvent.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// default:
|
|
|
|
|
|
// throw new ArgumentOutOfRangeException();
|
|
|
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
|
|
////侦听截图事件
|
|
|
|
|
|
//if (Input.GetKeyUp(KeyCode.Space))
|
|
|
|
|
|
//{
|
|
|
|
|
|
// _CaptureFlag = true;
|
|
|
|
|
|
//}
|
|
|
|
|
|
//全屏截图
|
|
|
|
|
|
if (Input.GetKeyUp(KeyCode.F) && _defaultCaptureType == CaptureType.FreeRegion && !_haveRegion)
|
|
|
|
|
|
{
|
|
|
|
|
|
_defaultCaptureType = CaptureType.FullScreen;
|
|
|
|
|
|
_leftDownConnerPoint = Vector2.zero;
|
|
|
|
|
|
_leftUpConnerPoint = new Vector2(0, _screenHeight);
|
|
|
|
|
|
_rightUpConnerPoint = new Vector2(_screenWidth, _screenHeight);
|
|
|
|
|
|
_rightDownConnerPoint = new Vector2(_screenWidth, 0);
|
|
|
|
|
|
_drawRegionRect = true;
|
|
|
|
|
|
_haveCirmformRectStarPoint = true;
|
|
|
|
|
|
_haveRegion = true;
|
|
|
|
|
|
|
|
|
|
|
|
_bgRawImage.gameObject.SetActive(false);
|
|
|
|
|
|
_bgRawImage.material.SetVector("_Rect", new Vector4(0, 0, 1, 1));
|
|
|
|
|
|
//涂鸦选项UI初始化
|
|
|
|
|
|
FinishedRegionEvent.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_eraserModeUpdateEvent.Invoke(_eraserFlag);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//退出截图
|
|
|
|
|
|
if (Input.GetKeyUp(KeyCode.Escape))
|
|
|
|
|
|
{
|
|
|
|
|
|
ResetData();
|
|
|
|
|
|
_enabled = false;
|
|
|
|
|
|
|
|
|
|
|
|
_escapeCaptureEvent.Invoke();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnPostRender()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!enabled)
|
|
|
|
|
|
return;
|
|
|
|
|
|
if (_drawRegionRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
//如果材质球不存在
|
|
|
|
|
|
if (!_lineMaterial)
|
|
|
|
|
|
{
|
|
|
|
|
|
//实例一个材质球
|
|
|
|
|
|
Shader shader = Shader.Find("Hidden/Internal-Colored");
|
|
|
|
|
|
_lineMaterial = new Material(shader);
|
|
|
|
|
|
_lineMaterial.hideFlags = HideFlags.HideAndDontSave;
|
|
|
|
|
|
//设置参数
|
|
|
|
|
|
_lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
|
|
|
|
|
_lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
|
|
|
|
|
//设置参数
|
|
|
|
|
|
_lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
|
|
|
|
|
|
//设置参数
|
|
|
|
|
|
_lineMaterial.SetInt("_ZWrite", 0);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GL.PushMatrix();//保存摄像机变换矩阵,把投影视图矩阵和模型视图矩阵压入堆栈保
|
|
|
|
|
|
|
|
|
|
|
|
GL.LoadPixelMatrix();//设置用屏幕坐标绘图
|
|
|
|
|
|
|
|
|
|
|
|
_lineMaterial.SetPass(0);
|
|
|
|
|
|
GL.Begin(GL.LINES);
|
|
|
|
|
|
GL.Color(_rectColor);
|
|
|
|
|
|
|
|
|
|
|
|
switch (_defaultCaptureType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case CaptureType.FullScreen:
|
|
|
|
|
|
GL.Vertex3(_leftUpConnerPoint.x, _leftUpConnerPoint.y, 0);
|
|
|
|
|
|
GL.Vertex3(_rightUpConnerPoint.x, _rightUpConnerPoint.y, 0);
|
|
|
|
|
|
|
|
|
|
|
|
GL.Vertex3(_rightUpConnerPoint.x, _rightUpConnerPoint.y, 0);
|
|
|
|
|
|
GL.Vertex3(_rightDownConnerPoint.x, _rightDownConnerPoint.y, 0);
|
|
|
|
|
|
|
|
|
|
|
|
GL.Vertex3(_rightDownConnerPoint.x, _rightDownConnerPoint.y, 0);
|
|
|
|
|
|
GL.Vertex3(_leftDownConnerPoint.x, _leftDownConnerPoint.y, 0);
|
|
|
|
|
|
|
|
|
|
|
|
GL.Vertex3(_leftDownConnerPoint.x, _leftDownConnerPoint.y, 0);
|
|
|
|
|
|
GL.Vertex3(_leftUpConnerPoint.x, _leftUpConnerPoint.y, 0);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CaptureType.FreeRegion:
|
|
|
|
|
|
GL.Vertex3(_startPoint.x, _startPoint.y, 0);
|
|
|
|
|
|
GL.Vertex3(_endPoint.x, _startPoint.y, 0);
|
|
|
|
|
|
|
|
|
|
|
|
GL.Vertex3(_endPoint.x, _startPoint.y, 0);
|
|
|
|
|
|
GL.Vertex3(_endPoint.x, _endPoint.y, 0);
|
|
|
|
|
|
|
|
|
|
|
|
GL.Vertex3(_endPoint.x, _endPoint.y, 0);
|
|
|
|
|
|
GL.Vertex3(_startPoint.x, _endPoint.y, 0);
|
|
|
|
|
|
|
|
|
|
|
|
GL.Vertex3(_startPoint.x, _endPoint.y, 0);
|
|
|
|
|
|
GL.Vertex3(_startPoint.x, _startPoint.y, 0);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
throw new ArgumentOutOfRangeException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GL.End();
|
|
|
|
|
|
GL.PopMatrix();//恢复摄像机投影矩阵
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//截图
|
|
|
|
|
|
if (_captureFlag && !_captureWithUI && _haveRegion)
|
|
|
|
|
|
{
|
|
|
|
|
|
_drawRegionRect = false;
|
|
|
|
|
|
float width = _rightUpConnerPoint.x - _leftDownConnerPoint.x;
|
|
|
|
|
|
float height = _rightUpConnerPoint.y - _leftDownConnerPoint.y;
|
|
|
|
|
|
Rect rect = new Rect(_leftDownConnerPoint.x, Screen.height - _leftUpConnerPoint.y, width, height);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Texture2D tex1 = new Texture2D((int)width, (int)height, TextureFormat.RGB24, false);
|
|
|
|
|
|
//Read the pixels in the Rect starting at 0,0 and ending at the screen's width and height
|
|
|
|
|
|
tex1.ReadPixels(rect, 0, 0, false);
|
|
|
|
|
|
tex1.Apply();
|
|
|
|
|
|
//Check that the display field has been assigned in the Inspector
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
byte[] tex1bytes = tex1.EncodeToPNG();
|
|
|
|
|
|
|
|
|
|
|
|
string tex1path = _captureSavePath + "/RenderTextureActive.png";
|
|
|
|
|
|
System.IO.File.WriteAllBytes(tex1path, tex1bytes);
|
|
|
|
|
|
Debug.Log(string.Format("截屏了一张照片: {0}", tex1path));
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
//Texture2D CombineTex = new Texture2D(_renderTex.width, _renderTex.height, TextureFormat.ARGB32, false);
|
|
|
|
|
|
RenderTexture prev = RenderTexture.active;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
RenderTexture.active = _currentRenderTexture;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
Texture2D BliTexture2D = new Texture2D((int)width, (int)height, TextureFormat.ARGB32, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BliTexture2D.ReadPixels(rect, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
byte[] bytes = BliTexture2D.EncodeToPNG();
|
|
|
|
|
|
|
|
|
|
|
|
string path = _captureSavePath + "/BlitTexture.png";
|
|
|
|
|
|
|
|
|
|
|
|
string filename = path;
|
|
|
|
|
|
System.IO.File.WriteAllBytes(filename, bytes);
|
|
|
|
|
|
Debug.Log(string.Format("截屏了一张照片: {0}", filename));
|
|
|
|
|
|
#endif
|
|
|
|
|
|
RenderTexture.active = null;
|
|
|
|
|
|
|
|
|
|
|
|
Texture2D combineTexture2D = MergeImage(tex1, BliTexture2D);
|
|
|
|
|
|
byte[] combineTexture2DbBytes = combineTexture2D.EncodeToPNG();
|
|
|
|
|
|
string str = DateTime.Now.ToString("hh_mm_ss");
|
|
|
|
|
|
string fileName = DateTime.Now.ToString("yyyy_MM_dd") + "_" + str + ".png";
|
|
|
|
|
|
string path2 = _captureSavePath + "/" + fileName;
|
|
|
|
|
|
|
|
|
|
|
|
System.IO.File.WriteAllBytes(path2, combineTexture2DbBytes);
|
|
|
|
|
|
Debug.Log(string.Format("截屏了一张照片: {0}", path2));
|
|
|
|
|
|
|
|
|
|
|
|
_captureFlag = false;
|
|
|
|
|
|
//重置数据
|
|
|
|
|
|
ResetData();
|
|
|
|
|
|
_finishedCapture.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
//UI也截取
|
|
|
|
|
|
if (_captureFlag && _captureWithUI && _haveRegion)
|
|
|
|
|
|
{
|
|
|
|
|
|
StartCoroutine(StartCapture());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region private function
|
|
|
|
|
|
|
|
|
|
|
|
#region 涂鸦相关方法
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-03-14 14:18:59 +08:00
|
|
|
|
|
|
|
|
|
|
public void SetStatus(Status status)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.status = status;
|
|
|
|
|
|
ChangeToEraser(this.status == Status.Eraser);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-21 17:26:17 +08:00
|
|
|
|
private void OnPaintBeginDrag(BaseEventData arg0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_enabled && _haveRegion)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (status)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Status.Pen:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case Status.Line:
|
|
|
|
|
|
|
|
|
|
|
|
if (Input.GetMouseButton(0))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_currentLine == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
|
|
|
|
|
|
}
|
|
|
|
|
|
LerpPaint(Input.mousePosition, _eraserFlag);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-24 11:11:14 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case Status.Circle:
|
2025-02-24 17:03:44 +08:00
|
|
|
|
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
|
|
|
|
|
|
_lastPoint = Input.mousePosition;
|
2025-02-24 17:37:06 +08:00
|
|
|
|
circleImg.gameObject.SetActive(true);
|
|
|
|
|
|
// TODO: 这样会使UI位置有偏差 后续修改
|
|
|
|
|
|
circleImg.transform.position = Input.mousePosition;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case Status.Rect:
|
2025-02-24 17:37:06 +08:00
|
|
|
|
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
|
|
|
|
|
|
_lastPoint = Input.mousePosition;
|
|
|
|
|
|
//rectImg.gameObject.SetActive(true);
|
|
|
|
|
|
// TODO: 这样会使UI位置有偏差 后续修改
|
|
|
|
|
|
//rectImg.transform.position = Input.mousePosition;
|
|
|
|
|
|
isRect = true;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private void PaintDragging(BaseEventData data)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_enabled && _haveRegion)
|
|
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
if (Input.GetMouseButton(0) && Time.time - _lastPaintTime > _paintInterval)
|
2025-02-21 17:26:17 +08:00
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
_lastPaintTime = Time.time;
|
|
|
|
|
|
// 绘制逻辑
|
|
|
|
|
|
if (Input.GetMouseButton(0))
|
2025-02-24 11:11:14 +08:00
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
switch (status)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Status.Pen:
|
|
|
|
|
|
case Status.Eraser:
|
|
|
|
|
|
if (_currentLine == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
|
|
|
|
|
|
}
|
|
|
|
|
|
LerpPaint(Input.mousePosition, _eraserFlag);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case Status.Rect:
|
2025-02-24 17:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case Status.Circle:
|
|
|
|
|
|
var dis = Vector2.Distance(_lastPoint, Input.mousePosition) * 2;
|
|
|
|
|
|
circleImg.rectTransform.sizeDelta = new Vector2(dis, dis);
|
2025-02-24 17:03:44 +08:00
|
|
|
|
break;
|
2025-02-24 17:37:06 +08:00
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
}
|
2025-02-24 11:11:14 +08:00
|
|
|
|
}
|
2025-02-21 17:26:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private void OnPaintEndDrag(BaseEventData data)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_enabled && _haveRegion)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (status)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Status.Pen:
|
|
|
|
|
|
case Status.Eraser:
|
|
|
|
|
|
if (Input.GetMouseButtonUp(0))
|
2025-02-24 11:11:14 +08:00
|
|
|
|
{
|
|
|
|
|
|
FinishedRaw();
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
|
2025-02-24 11:11:14 +08:00
|
|
|
|
case Status.Line:
|
|
|
|
|
|
if (_currentLine != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
LerpPaint(Input.mousePosition, false);
|
|
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
FinishedRaw();
|
2025-02-24 11:11:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
case Status.Rect:
|
2025-02-24 17:37:06 +08:00
|
|
|
|
isRect = false;
|
|
|
|
|
|
RectFactory();
|
2025-02-24 11:11:14 +08:00
|
|
|
|
break;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
|
2025-02-24 11:11:14 +08:00
|
|
|
|
case Status.Circle:
|
2025-02-24 17:03:44 +08:00
|
|
|
|
if (_currentLine != null)
|
2025-02-24 11:11:14 +08:00
|
|
|
|
{
|
|
|
|
|
|
float radius = Vector2.Distance(_lastPoint, Input.mousePosition);
|
|
|
|
|
|
var points = GenerateCirclePoints(_lastPoint, radius);
|
|
|
|
|
|
_lastPoint = default;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
|
2025-02-24 11:11:14 +08:00
|
|
|
|
foreach (var item in points)
|
|
|
|
|
|
{
|
|
|
|
|
|
LerpPaint(item, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
LerpPaint(points[0], false);
|
|
|
|
|
|
FinishedRaw();
|
2025-02-24 17:03:44 +08:00
|
|
|
|
|
2025-02-24 17:37:06 +08:00
|
|
|
|
circleImg.gameObject.SetActive(false);
|
2025-02-24 11:11:14 +08:00
|
|
|
|
}
|
2025-02-21 17:26:17 +08:00
|
|
|
|
break;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
|
2025-02-21 17:26:17 +08:00
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-14 14:18:59 +08:00
|
|
|
|
public void FinishedRaw()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_currentLine != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 保存当前纹理到 LineSegment
|
|
|
|
|
|
RenderTexture.active = _currentLine.Texture;
|
|
|
|
|
|
Graphics.Blit(_currentRenderTexture, _currentLine.Texture);
|
|
|
|
|
|
RenderTexture.active = null;
|
|
|
|
|
|
|
|
|
|
|
|
_lineStack.Push(_currentLine);
|
|
|
|
|
|
_currentLine = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_lastPoint = Vector2.zero;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
bool isRect = false;
|
|
|
|
|
|
private void OnGUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isRect)
|
|
|
|
|
|
{
|
|
|
|
|
|
var points = GenerateRectanglePoints(_lastPoint, Input.mousePosition);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float minX = float.MaxValue;
|
|
|
|
|
|
float minY = float.MaxValue;
|
|
|
|
|
|
float maxX = float.MinValue;
|
|
|
|
|
|
float maxY = float.MinValue;
|
|
|
|
|
|
|
|
|
|
|
|
// 找出最小和最大的 x、y 坐标
|
|
|
|
|
|
foreach (Vector2 point in points)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (point.x < minX)
|
|
|
|
|
|
{
|
|
|
|
|
|
minX = point.x;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (point.x > maxX)
|
|
|
|
|
|
{
|
|
|
|
|
|
maxX = point.x;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (point.y < minY)
|
|
|
|
|
|
{
|
|
|
|
|
|
minY = point.y;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (point.y > maxY)
|
|
|
|
|
|
{
|
|
|
|
|
|
maxY = point.y;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float x = minX;
|
|
|
|
|
|
float y = maxY;
|
|
|
|
|
|
float width = maxX - minX;
|
|
|
|
|
|
float height = maxY - minY;
|
|
|
|
|
|
|
|
|
|
|
|
Rect rect = new Rect(x, y, width, height);
|
|
|
|
|
|
|
|
|
|
|
|
GUI.backgroundColor = Color.blue;
|
|
|
|
|
|
GUI.color = Color.yellow;
|
|
|
|
|
|
GUI.Box(rect, "我帮你绘制了个 Rect Box");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-24 11:11:14 +08:00
|
|
|
|
List<Vector2> GenerateCirclePoints(Vector2 center, float r, int numPoints = 36)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<Vector2> points = new List<Vector2>();
|
|
|
|
|
|
for (int i = 0; i < numPoints; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 计算每个点的角度
|
|
|
|
|
|
float angle = 2 * Mathf.PI * i / numPoints;
|
|
|
|
|
|
// 根据三角函数计算点的坐标
|
|
|
|
|
|
float x = center.x + r * Mathf.Cos(angle);
|
|
|
|
|
|
float y = center.y + r * Mathf.Sin(angle);
|
|
|
|
|
|
points.Add(new Vector2(x, y));
|
|
|
|
|
|
}
|
|
|
|
|
|
return points;
|
|
|
|
|
|
}
|
2025-02-24 17:03:44 +08:00
|
|
|
|
|
|
|
|
|
|
public void RectFactory()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_lastPoint != default)
|
|
|
|
|
|
{
|
|
|
|
|
|
var points = GenerateRectanglePoints(_lastPoint, Input.mousePosition);
|
|
|
|
|
|
|
|
|
|
|
|
LerpPaint(points[0], false);
|
|
|
|
|
|
LerpPaint(points[1], false);
|
|
|
|
|
|
LerpPaint(points[2], false);
|
|
|
|
|
|
LerpPaint(points[3], false);
|
|
|
|
|
|
LerpPaint(points[0], false);
|
|
|
|
|
|
FinishedRaw();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Vector2[] GenerateRectanglePoints(Vector2 start, Vector2 thirdPoint)
|
2025-02-24 11:11:14 +08:00
|
|
|
|
{
|
|
|
|
|
|
Vector2[] points = new Vector2[4];
|
|
|
|
|
|
points[0] = start;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
// 原本的 end 点(这里用 thirdPoint 替代)作为数组的第三个元素
|
|
|
|
|
|
points[2] = thirdPoint;
|
2025-02-24 11:11:14 +08:00
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
if (start.x < thirdPoint.x)
|
2025-02-24 11:11:14 +08:00
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
if (start.y < thirdPoint.y)
|
2025-02-24 11:11:14 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 从左下方到右上方
|
2025-02-24 17:03:44 +08:00
|
|
|
|
points[1] = new Vector2(thirdPoint.x, start.y);
|
|
|
|
|
|
points[3] = new Vector2(start.x, thirdPoint.y);
|
2025-02-24 11:11:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 从左上方到右下方
|
2025-02-24 17:03:44 +08:00
|
|
|
|
points[1] = new Vector2(thirdPoint.x, start.y);
|
|
|
|
|
|
points[3] = new Vector2(start.x, thirdPoint.y);
|
2025-02-24 11:11:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
if (start.y < thirdPoint.y)
|
2025-02-24 11:11:14 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 从右下方到左上方
|
2025-02-24 17:03:44 +08:00
|
|
|
|
points[1] = new Vector2(start.x, thirdPoint.y);
|
|
|
|
|
|
points[3] = new Vector2(thirdPoint.x, start.y);
|
2025-02-24 11:11:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 从右上方到左下方
|
2025-02-24 17:03:44 +08:00
|
|
|
|
points[1] = new Vector2(start.x, thirdPoint.y);
|
|
|
|
|
|
points[3] = new Vector2(thirdPoint.x, start.y);
|
2025-02-24 11:11:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return points;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-03-14 14:18:59 +08:00
|
|
|
|
public void Clear()
|
2025-02-24 11:11:14 +08:00
|
|
|
|
{
|
2025-03-14 14:18:59 +08:00
|
|
|
|
// 重新分配 RenderTexture
|
|
|
|
|
|
_currentRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
|
2025-02-24 17:03:44 +08:00
|
|
|
|
|
2025-03-14 14:18:59 +08:00
|
|
|
|
// 更新画布的纹理
|
|
|
|
|
|
_paintCanvasImg.texture = _currentRenderTexture;
|
2025-02-24 11:11:14 +08:00
|
|
|
|
|
2025-03-14 14:18:59 +08:00
|
|
|
|
// 清空线条栈
|
|
|
|
|
|
_lineStack.Clear();
|
2025-02-24 17:03:44 +08:00
|
|
|
|
}
|
2025-02-24 11:11:14 +08:00
|
|
|
|
|
2025-02-21 17:26:17 +08:00
|
|
|
|
public void Undo()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_lineStack.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 移除最后一条线
|
|
|
|
|
|
var line = _lineStack.Pop();
|
|
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
// 如果栈中还有剩余的线条,切换到上一个线条的纹理
|
|
|
|
|
|
if (_lineStack.Count > 0)
|
2025-02-21 17:26:17 +08:00
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
var previousLine = _lineStack.Peek();
|
2025-03-14 14:18:59 +08:00
|
|
|
|
//RenderTexture.active = _currentRenderTexture;
|
|
|
|
|
|
//Graphics.Blit(previousLine.Texture, _currentRenderTexture);
|
|
|
|
|
|
//RenderTexture.active = null;
|
|
|
|
|
|
_currentRenderTexture = previousLine.Texture;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
_paintCanvasImg.texture = previousLine.Texture;
|
2025-03-14 14:18:59 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Clear();
|
2025-02-21 17:26:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-02-24 17:03:44 +08:00
|
|
|
|
|
2025-02-21 17:26:17 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 绘画进行插值
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="point"></param>
|
2025-02-24 17:03:44 +08:00
|
|
|
|
Vector2[] vector2s = new Vector2[10000];
|
2025-02-21 17:26:17 +08:00
|
|
|
|
private void LerpPaint(Vector2 point, bool isEraser)
|
|
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
Paint(isEraser, point);
|
2025-02-21 17:26:17 +08:00
|
|
|
|
|
|
|
|
|
|
if (_lastPoint == Vector2.zero)
|
|
|
|
|
|
{
|
|
|
|
|
|
_lastPoint = point;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float dis = Vector2.Distance(point, _lastPoint);
|
|
|
|
|
|
if (dis > _brushLerpSize)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector2 dir = (point - _lastPoint).normalized;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
int num = (int)(dis / (_brushLerpSize));
|
2025-02-21 17:26:17 +08:00
|
|
|
|
for (int i = 0; i < num; i++)
|
|
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
vector2s[i] = _lastPoint + dir * (i + 1) * _brushLerpSize;
|
|
|
|
|
|
Paint(isEraser, vector2s[i]);
|
2025-02-21 17:26:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
_lastPoint = point;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 画点方法
|
2025-02-24 17:03:44 +08:00
|
|
|
|
private void Paint(bool isEraser, Vector2 point)
|
2025-02-21 17:26:17 +08:00
|
|
|
|
{
|
2025-02-24 17:03:44 +08:00
|
|
|
|
Material material = null;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
if (point.x < _leftDownConnerPoint.x || point.x > _rightUpConnerPoint.x || point.y < _leftDownConnerPoint.y || point.y > _rightUpConnerPoint.y)
|
|
|
|
|
|
return;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
Vector2 uv = new Vector2(point.x / (float)_screenWidth, point.y / (float)_screenHeight);
|
2025-02-21 17:26:17 +08:00
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
if (isEraser)
|
2025-02-21 17:26:17 +08:00
|
|
|
|
{
|
|
|
|
|
|
_eraserBrushMat.SetVector("_UV", uv);
|
2025-02-24 17:03:44 +08:00
|
|
|
|
material = _eraserBrushMat;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_paintBrushMat.SetVector("_UV", uv);
|
2025-02-24 17:03:44 +08:00
|
|
|
|
material = _paintBrushMat;
|
2025-02-21 17:26:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-24 17:03:44 +08:00
|
|
|
|
_commandBuffer.Blit(_currentRenderTexture, _currentRenderTexture, material);
|
|
|
|
|
|
|
|
|
|
|
|
Graphics.ExecuteCommandBuffer(_commandBuffer);
|
|
|
|
|
|
_commandBuffer.Clear();
|
|
|
|
|
|
}
|
2025-02-21 17:26:17 +08:00
|
|
|
|
public Vector2 GetCaptureViewLeftDownConnerPoint()
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector2 vec = new Vector2(Mathf.Min(_startPoint.x, _endPoint.x), Mathf.Min(_startPoint.y, _endPoint.y));
|
|
|
|
|
|
return vec;
|
|
|
|
|
|
}
|
|
|
|
|
|
public Vector2 GetCaptureViewRightUpConnerPoint()
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector2 vec = new Vector2(Mathf.Max(_startPoint.x, _endPoint.x), Mathf.Max(_startPoint.y, _endPoint.y));
|
|
|
|
|
|
return vec;
|
|
|
|
|
|
}
|
|
|
|
|
|
public Vector2 GetCaptureViewLeftUpConnerPoint()
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector2 vec = new Vector2(Mathf.Min(_startPoint.x, _endPoint.x), Mathf.Max(_startPoint.y, _endPoint.y));
|
|
|
|
|
|
return vec;
|
|
|
|
|
|
}
|
|
|
|
|
|
public Vector2 GetCaptureViewRightDownConnerPoint()
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector2 vec = new Vector2(Mathf.Max(_startPoint.x, _endPoint.x), Mathf.Min(_startPoint.y, _endPoint.y));
|
|
|
|
|
|
return vec;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 合成图片
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Texture2D MergeImage(Texture2D tex1, Texture2D tex2)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < tex1.width; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int j = 0; j < tex1.height; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Color color1 = tex1.GetPixel(i, j);
|
|
|
|
|
|
Color color2 = tex2.GetPixel(i, j);
|
|
|
|
|
|
Color newColor = color2.a * color2 + (1.0f - color2.a) * color1;
|
|
|
|
|
|
newColor.a = 1f;
|
|
|
|
|
|
tex1.SetPixel(i, j, newColor);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return tex1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
IEnumerator StartCapture()
|
|
|
|
|
|
{
|
|
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
|
|
float width = _rightUpConnerPoint.x - _leftDownConnerPoint.x;
|
|
|
|
|
|
float height = _rightUpConnerPoint.y - _leftDownConnerPoint.y;
|
|
|
|
|
|
Debug.Log(_leftDownConnerPoint.x.ToString("0.00"));
|
|
|
|
|
|
Debug.Log(_leftDownConnerPoint.y.ToString("0.00"));
|
|
|
|
|
|
Debug.Log("width:" + width);
|
|
|
|
|
|
Debug.Log("width:" + height);
|
|
|
|
|
|
Rect rect = new Rect(_leftDownConnerPoint.x, _leftDownConnerPoint.y, width, height); //坑爹啊 如果是开携程在WaitForEndOfFrame时候截图,那么他的坐标系换了。。rect起始点要设置在左下角
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Texture2D tex1 = new Texture2D((int)width, (int)height, TextureFormat.RGB24, false);
|
|
|
|
|
|
//Read the pixels in the Rect starting at 0,0 and ending at the screen's width and height
|
|
|
|
|
|
tex1.ReadPixels(rect, 0, 0, false);
|
|
|
|
|
|
tex1.Apply();
|
|
|
|
|
|
//Check that the display field has been assigned in the Inspector
|
|
|
|
|
|
byte[] tex1bytes = tex1.EncodeToPNG();
|
|
|
|
|
|
|
|
|
|
|
|
string str = DateTime.Now.ToString("hh_mm_ss");
|
|
|
|
|
|
string fileName = DateTime.Now.ToString("yyyy_MM_dd") + "_" + str + ".png";
|
|
|
|
|
|
string tex1path = _captureSavePath + "/" + fileName;
|
|
|
|
|
|
System.IO.File.WriteAllBytes(tex1path, tex1bytes);
|
|
|
|
|
|
Debug.Log(string.Format("截屏了一张照片(有UI): {0}", tex1path));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_captureFlag = false;
|
|
|
|
|
|
ResetData();
|
|
|
|
|
|
//推出截屏
|
|
|
|
|
|
EscapeCaptureEvent.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 截图完成后重置数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void ResetData()
|
|
|
|
|
|
{
|
|
|
|
|
|
_defaultCaptureType = CaptureType.FreeRegion;
|
|
|
|
|
|
_drawRegionRect = false;
|
|
|
|
|
|
_haveRegion = false;
|
|
|
|
|
|
_haveCirmformRectStarPoint = false;
|
2025-02-24 17:03:44 +08:00
|
|
|
|
_currentRenderTexture.Release();
|
2025-02-21 17:26:17 +08:00
|
|
|
|
_startPoint = Vector2.zero;
|
|
|
|
|
|
_endPoint = Vector2.zero;
|
|
|
|
|
|
_leftUpConnerPoint = Vector2.zero;
|
|
|
|
|
|
_leftDownConnerPoint = Vector2.zero;
|
|
|
|
|
|
_rightDownConnerPoint = Vector2.zero;
|
|
|
|
|
|
_rightUpConnerPoint = Vector2.zero;
|
|
|
|
|
|
_lastPoint = Vector2.zero;
|
|
|
|
|
|
_bgRawImage.material.SetVector("_Rect", new Vector4(0, 0, 1, 1));
|
|
|
|
|
|
_bgRawImage.gameObject.SetActive(false);
|
|
|
|
|
|
_paintCanvasImg.gameObject.SetActive(false);
|
|
|
|
|
|
_eraserFlag = false;
|
|
|
|
|
|
_enabled = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region public function
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 进入截图模式
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void SwitchOn(bool isFullScreen)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isFullScreen)
|
|
|
|
|
|
{
|
|
|
|
|
|
_defaultCaptureType = CaptureType.FullScreen;
|
|
|
|
|
|
_bgRawImage.gameObject.SetActive(false);
|
|
|
|
|
|
_bgRawImage.material.SetVector("_Rect", new Vector4(0, 0, 1, 1));
|
|
|
|
|
|
|
|
|
|
|
|
_leftDownConnerPoint = Vector2.zero;
|
|
|
|
|
|
_leftUpConnerPoint = new Vector2(0, _screenHeight);
|
|
|
|
|
|
_rightUpConnerPoint = new Vector2(_screenWidth, _screenHeight);
|
|
|
|
|
|
_rightDownConnerPoint = new Vector2(_screenWidth, 0);
|
|
|
|
|
|
_drawRegionRect = true;
|
|
|
|
|
|
_haveCirmformRectStarPoint = true;
|
|
|
|
|
|
_haveRegion = true;
|
|
|
|
|
|
_lastPoint = Vector2.zero;
|
|
|
|
|
|
//涂鸦选项UI初始化
|
|
|
|
|
|
FinishedRegionEvent.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
_defaultCaptureType = CaptureType.FreeRegion;
|
|
|
|
|
|
_bgRawImage.gameObject.SetActive(true);
|
|
|
|
|
|
_bgRawImage.material.SetVector("_Rect", new Vector4(0, 0, 0, 0));
|
|
|
|
|
|
}
|
|
|
|
|
|
_paintCanvasImg.gameObject.SetActive(true);
|
|
|
|
|
|
_enterCaptureModeEvent.Invoke();
|
|
|
|
|
|
_enabled = true;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
public void SaveCapture()
|
|
|
|
|
|
{
|
|
|
|
|
|
_captureFlag = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetPaintColor(Color color)
|
|
|
|
|
|
{
|
|
|
|
|
|
_paintBrushMat.SetColor("_Color", color);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetPaintingSize(float size)
|
|
|
|
|
|
{
|
|
|
|
|
|
_paintBrushMat.SetFloat("_Size", size);
|
|
|
|
|
|
_brushLerpSize = (_defaultBrushRawImage.width + _defaultBrushRawImage.height) / 2.0f / size;
|
|
|
|
|
|
_eraserBrushMat.SetFloat("_Size", size);
|
|
|
|
|
|
_brushLerpSize = (_defaultBrushRawImage.width + _defaultBrushRawImage.height) / 2.0f / size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetPaintingSize(float sizeX, float sizeY)
|
|
|
|
|
|
{
|
|
|
|
|
|
_paintBrushMat.SetFloat("_Size", sizeX);
|
|
|
|
|
|
_paintBrushMat.SetFloat("_SizeY", sizeY);
|
|
|
|
|
|
if (sizeX > sizeY)
|
|
|
|
|
|
_brushLerpSize = (_defaultBrushRawImage.width + _defaultBrushRawImage.height) / 2.0f / sizeX;
|
|
|
|
|
|
if (sizeX <= sizeY)
|
|
|
|
|
|
_brushLerpSize = (_defaultBrushRawImage.width + _defaultBrushRawImage.height) / 2.0f / sizeY;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
public void SetEraserSize(float sizeX, float sizeY)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
if (sizeX > sizeY)
|
|
|
|
|
|
_brushLerpSize = (_defaultBrushRawImage.width + _defaultBrushRawImage.height) / 2.0f / sizeX;
|
|
|
|
|
|
if (sizeX <= sizeY)
|
|
|
|
|
|
_brushLerpSize = (_defaultBrushRawImage.width + _defaultBrushRawImage.height) / 2.0f / sizeY;
|
|
|
|
|
|
_eraserBrushMat.SetFloat("_Size", sizeX);
|
|
|
|
|
|
_eraserBrushMat.SetFloat("_SizeY", sizeY);
|
|
|
|
|
|
//_brushLerpSize = (_defaultBrushRawImage.width + _defaultBrushRawImage.height) / 2.0f / size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ChangeToEraser(bool toEraser)
|
|
|
|
|
|
{
|
|
|
|
|
|
_eraserFlag = toEraser;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class FinishedRegionEvent : UnityEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class CannelRegionEvent : UnityEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class FinishedCaptureEvent : UnityEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
public class EscapeCaptureEvent : UnityEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class EnterCaptureModeEvent : UnityEvent
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class EraserModeUpdateEvent : UnityEvent<bool>
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public enum CaptureType
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自动全屏截屏
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
FullScreen,
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自由框选截屏
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
FreeRegion
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 笔刷橡皮擦计算参数 ,计算公式,比如笔刷的是【缩放倍数=BrushSizeMaxValue +(1-slider.value)*BrushSizeFactor】,橡皮擦类似
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static class PaintingParams
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 缩小因子,越大说明可调节范围越大
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static float BrushSizeFactor = 300f;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 笔刷图片最大缩小倍数(画布大小的笔刷图案要缩小多少倍数显示,缩小的越小,笔刷显示效果越大)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static float BrushSizeMaxValue = 50;
|
|
|
|
|
|
|
|
|
|
|
|
public static float EraserSizeFactor = 50;
|
|
|
|
|
|
|
|
|
|
|
|
public static float EraserSizeMaxValue = 50;
|
|
|
|
|
|
|
|
|
|
|
|
public static float BrushDefaultSize = 300;
|
|
|
|
|
|
public static float EraserDefaultSize = 100;
|
|
|
|
|
|
}
|