赞
踩
##简单说一下逻辑吧,脚本一共就两个,一个拖拽脚本,一个处理图像的脚本
#场景里的UI层级如下图
#唯一挂载的脚本里面的东西是这些,如下图。(ps:我懒就全用拖拽的方式了)
#处理逻辑的脚本,代码比较简单,对着项目运行一下,简单看看就全懂了,里面也有部分注释
能拿到Sprite自然能对Sprite做你想做的事情
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class Cutting : MonoBehaviour
{
public Sprite selectPhoto; public Transform Obj; public Button clickBtn; public Button okBtn; public Material guideMat; private float cutRangeWidth; private float cutRangeHeight; private float ratio = 0; private string curState = "CutFreeButton"; public Image tempImage; public Image showImg; private DragScript ltDrag; private DragScript rtDrag; private DragScript lbDrag; private DragScript rbDrag; private DragScript cenDrag; public Toggle cutFreeTog; public Toggle cut23Tog; public Toggle cut11Tog; public Toggle cut34Tog; public Toggle cut43Tog; RectTransform rbRect; RectTransform lbRect; RectTransform rtRect; RectTransform ltRect; RectTransform cen; private void Start() { clickBtn.onClick.AddListener(ShowCut); okBtn.onClick.AddListener(SetCut); ltDrag = Obj.Find("CutEditorLT").gameObject.AddComponent<DragScript>(); rtDrag = Obj.Find("CutEditorRT").gameObject.AddComponent<DragScript>(); lbDrag = Obj.Find("CutEditorLB").gameObject.AddComponent<DragScript>(); rbDrag = Obj.Find("CutEditorRB").gameObject.AddComponent<DragScript>(); cenDrag = Obj.Find("CutEditorCen").gameObject.AddComponent<DragScript>(); ltDrag.Draging += DragLT; rtDrag.Draging += DragRT; lbDrag.Draging += DragLB; rbDrag.Draging += DragRB; cenDrag.Draging += DragCen; cutFreeTog.onValueChanged.AddListener(CutFree); cut23Tog.onValueChanged.AddListener(Cut23); cut11Tog.onValueChanged.AddListener(Cut11); cut34Tog.onValueChanged.AddListener(Cut34); cut43Tog.onValueChanged.AddListener(Cut43); rbRect = Obj.Find("CutEditorRB").GetComponent<RectTransform>(); lbRect = Obj.Find("CutEditorLB").GetComponent<RectTransform>(); rtRect = Obj.Find("CutEditorRT").GetComponent<RectTransform>(); ltRect = Obj.Find("CutEditorLT").GetComponent<RectTransform>(); cen = Obj.Find("CutEditorCen").GetComponent<RectTransform>(); } /// <summary> /// 裁剪(进入裁剪界面,初始化数据,其实也没啥可初始化的) /// </summary> private void ShowCut() { cutRangeWidth = tempImage.preferredWidth; cutRangeHeight = tempImage.preferredHeight; Obj.Find("GuideMask").GetComponent<RectTransform>().sizeDelta = new Vector2(cutRangeWidth, cutRangeHeight); Obj.Find("CutEditorLT").GetComponent<Image>().color = Color.red; Obj.Find("CutEditorRT").GetComponent<Image>().color = Color.red; Obj.Find("CutEditorLB").GetComponent<Image>().color = Color.red; Obj.Find("CutEditorRB").GetComponent<Image>().color = Color.red; CutFree(false); } private void CutFree(bool isSelect) { ChangeButtonState("CutFreeButton"); float width = cutRangeWidth; float height = cutRangeHeight; UpdateCen(width, height, Vector2.zero); ltRect.anchoredPosition = new Vector2(-width / 2, height / 2); rtRect.anchoredPosition = new Vector2(width / 2, height / 2); lbRect.anchoredPosition = new Vector2(-width / 2, -height / 2); rbRect.anchoredPosition = new Vector2(width / 2, -height / 2); } private void Cut23(bool isSelect) { ChangeButtonState("Cut23Button"); SetCutRate(2 / 3f); } private void Cut11(bool isSelect) { ChangeButtonState("Cut11Button"); SetCutRate(1 / 1f); } private void Cut34(bool isSelect) { ChangeButtonState("Cut34Button"); SetCutRate(3 / 4f); } private void Cut43(bool isSelect) { ChangeButtonState("Cut43Button"); SetCutRate(4 / 3f); } //设置比例 private void SetCutRate(float rate) { float width; float height; if (cutRangeWidth / cutRangeHeight > rate) { height = cutRangeHeight; width = cutRangeHeight * rate; } else { width = cutRangeWidth; height = cutRangeWidth / rate; } ltRect.anchoredPosition = new Vector2(-width / 2, height / 2); rtRect.anchoredPosition = new Vector2(width / 2, height / 2); lbRect.anchoredPosition = new Vector2(-width / 2, -height / 2); rbRect.anchoredPosition = new Vector2(width / 2, -height / 2); UpdateCen(width, height, Vector2.zero); } //处理Toggle按钮时间,设定比例,只能按照规定比例更改大小 private void ChangeButtonState(string objName) { if (curState == objName) return; if (!string.IsNullOrEmpty(curState)) curState = objName; switch (curState) { case "CutFreeButton": ratio = 0; break; case "Cut23Button": ratio = 2 / 3f; break; case "Cut11Button": ratio = 1 / 1f; break; case "Cut34Button": ratio = 3 / 4f; break; case "Cut43Button": ratio = 4 / 3f; break; } } #region 拖动角标事件 private void DragRB(PointerEventData data) { if (Input.touchCount > 1) return; //Vector2 delta = Input.GetTouch(0).deltaPosition; Vector2 delta = data.delta; if (ratio != 0) { if (Mathf.Abs(delta.x) > Mathf.Abs(delta.y)) { delta.y = delta.x / ratio * -1; } else { delta.x = delta.y * ratio * -1; } } Vector2 oriPos = rbRect.anchoredPosition; rbRect.transform.position += (Vector3)delta; Vector2 endPos = rbRect.anchoredPosition; bool state = ratio == 0 ? true : false; if (endPos.x > cutRangeWidth / 2) { if (ratio == 0) endPos.x = cutRangeWidth / 2; else endPos = oriPos; } else if (endPos.x < ltRect.anchoredPosition.x + 150) { if (ratio == 0) endPos.x = ltRect.anchoredPosition.x + 150; else endPos = oriPos; } if (endPos.y > ltRect.anchoredPosition.y - 100) { if (ratio == 0) endPos.y = ltRect.anchoredPosition.y - 100; else endPos = oriPos; } else if (endPos.y < -cutRangeHeight / 2) { if (ratio == 0) endPos.y = -cutRangeHeight / 2; else endPos = oriPos; } rbRect.anchoredPosition = endPos; lbRect.anchoredPosition = new Vector2(lbRect.anchoredPosition.x, endPos.y); rtRect.anchoredPosition = new Vector3(endPos.x, rtRect.anchoredPosition.y); Vector2 pos = Vector2.Lerp(lbRect.anchoredPosition, rtRect.anchoredPosition, 0.5f); float width = rtRect.anchoredPosition.x - lbRect.anchoredPosition.x; float height = rtRect.anchoredPosition.y - lbRect.anchoredPosition.y; UpdateCen(width, height, pos); } private void DragLB(PointerEventData data) { //禁止双手操作 if (Input.touchCount > 1) return; //Vector2 delta = Input.GetTouch(0).deltaPosition; Vector2 delta = data.delta; if (ratio != 0) { if (Mathf.Abs(delta.x) > Mathf.Abs(delta.y)) { delta.y = delta.x / ratio; } else { delta.x = delta.y * ratio; } } Vector2 oriPos = lbRect.anchoredPosition; lbRect.transform.position += (Vector3)delta; Vector2 endPos = lbRect.anchoredPosition; if (endPos.x < -cutRangeWidth / 2) { if (ratio == 0) endPos.x = -cutRangeWidth / 2; else endPos = oriPos; } else if (endPos.x > rtRect.anchoredPosition.x - 150) { if (ratio == 0) endPos.x = rtRect.anchoredPosition.x - 150; else endPos = oriPos; } if (endPos.y > rtRect.anchoredPosition.y - 100) { if (ratio == 0) endPos.y = rtRect.anchoredPosition.y - 100; else endPos = oriPos; } else if (endPos.y < -cutRangeHeight / 2) { if (ratio == 0) endPos.y = -cutRangeHeight / 2; else endPos = oriPos; } lbRect.anchoredPosition = endPos; ltRect.anchoredPosition = new Vector3(endPos.x, rtRect.anchoredPosition.y); rbRect.anchoredPosition = new Vector2(rtRect.anchoredPosition.x, endPos.y); Vector2 pos = Vector2.Lerp(ltRect.anchoredPosition, rbRect.anchoredPosition, 0.5f); float width = rbRect.anchoredPosition.x - ltRect.anchoredPosition.x; float height = ltRect.anchoredPosition.y - rbRect.anchoredPosition.y; UpdateCen(width, height, pos); } private void DragRT(PointerEventData data) { if (Input.touchCount > 1) return; //Vector2 delta = Input.GetTouch(0).deltaPosition; Vector2 delta = data.delta; if (ratio != 0) { if (Mathf.Abs(delta.x) > Mathf.Abs(delta.y)) { delta.y = delta.x / ratio; } else { delta.x = delta.y * ratio; } } Vector2 oriPos = rtRect.anchoredPosition; rtRect.transform.position += (Vector3)delta; Vector2 endPos = rtRect.anchoredPosition; if (endPos.x > cutRangeWidth / 2) { if (ratio == 0) endPos.x = cutRangeWidth / 2; else endPos = oriPos; } else if (endPos.x < lbRect.anchoredPosition.x + 150) { if (ratio == 0) endPos.x = lbRect.anchoredPosition.x + 150; else endPos = oriPos; } if (endPos.y < lbRect.anchoredPosition.y + 100) { if (ratio == 0) endPos.y = lbRect.anchoredPosition.y + 100; else endPos = oriPos; } else if (endPos.y > cutRangeHeight / 2) { if (ratio == 0) endPos.y = cutRangeHeight / 2; else endPos = oriPos; } rtRect.anchoredPosition = endPos; rbRect.anchoredPosition = new Vector3(endPos.x, lbRect.anchoredPosition.y); ltRect.anchoredPosition = new Vector2(lbRect.anchoredPosition.x, endPos.y); Vector2 pos = Vector2.Lerp(ltRect.anchoredPosition, rbRect.anchoredPosition, 0.5f); float width = rbRect.anchoredPosition.x - ltRect.anchoredPosition.x; float height = ltRect.anchoredPosition.y - rbRect.anchoredPosition.y; UpdateCen(width, height, pos); } private void DragLT(PointerEventData data) { if (Input.touchCount > 1) return; //Vector2 delta = Input.GetTouch(0).deltaPosition; //Vector2 delta = Input.mouseScrollDelta; //Debug.Log(data.delta); Vector2 delta = data.delta; if (ratio != 0) { if (Mathf.Abs(delta.x) > Mathf.Abs(delta.y)) { delta.y = delta.x / ratio * -1; } else { delta.x = delta.y * ratio * -1; } } Vector2 oriPos = ltRect.anchoredPosition; ltRect.transform.position += (Vector3)delta; Vector2 endPos = ltRect.anchoredPosition; if (endPos.x < -cutRangeWidth / 2) { if (ratio == 0) endPos.x = -cutRangeWidth / 2; else endPos = oriPos; } else if (endPos.x > rbRect.anchoredPosition.x - 150) { if (ratio == 0) endPos.x = rbRect.anchoredPosition.x - 150; else endPos = oriPos; } if (endPos.y < rbRect.anchoredPosition.y + 100) { if (ratio == 0) endPos.y = rbRect.anchoredPosition.y + 100; else endPos = oriPos; } else if (endPos.y > cutRangeHeight / 2) { if (ratio == 0) endPos.y = cutRangeHeight / 2; else endPos = oriPos; } ltRect.anchoredPosition = endPos; lbRect.anchoredPosition = new Vector2(endPos.x, rbRect.anchoredPosition.y); rtRect.anchoredPosition = new Vector3(rbRect.anchoredPosition.x, endPos.y); Vector2 pos = Vector2.Lerp(ltRect.anchoredPosition, rbRect.anchoredPosition, 0.5f); float width = rtRect.anchoredPosition.x - lbRect.anchoredPosition.x; float height = rtRect.anchoredPosition.y - lbRect.anchoredPosition.y; UpdateCen(width, height, pos); } private void DragCen(PointerEventData data) { Transform cen = Obj.Find("CutEditorCen").transform; RectTransform cenRect = Obj.Find("CutEditorCen").transform.GetComponent<RectTransform>(); //Debug.Log(cen.position); float x = cen.position.x + data.delta.x; float y = cen.position.y + data.delta.y; //做限定 防止中心框拖出图片框 float cenX = Mathf.Clamp(x, tempImage.transform.position.x - cutRangeWidth * 0.5f + cenRect.rect.width * 0.5f, tempImage.transform.position.x + cutRangeWidth * 0.5f - cenRect.rect.width * 0.5f); float cenY = Mathf.Clamp(y, tempImage.transform.position.y - cutRangeHeight * 0.5f + cenRect.rect.height * 0.5f, tempImage.transform.position.y + cutRangeHeight * 0.5f - cenRect.rect.height * 0.5f); cen.position = new Vector2(cenX, cenY); Vector2 cenPos = cen.gameObject.GetComponent<RectTransform>().anchoredPosition; float width = rtRect.anchoredPosition.x - lbRect.anchoredPosition.x; float height = rtRect.anchoredPosition.y - lbRect.anchoredPosition.y; if (cenPos.x < (-cutRangeWidth + width) / 2) cenPos.x = (-cutRangeWidth + width) / 2; else if (cenPos.x > (cutRangeWidth - width) / 2) cenPos.x = (cutRangeWidth - width) / 2; if (cenPos.y < (-cutRangeHeight + height) / 2) cenPos.y = (-cutRangeHeight + height) / 2; else if (cenPos.y > (cutRangeHeight - height) / 2) cenPos.y = (cutRangeHeight - height) / 2; ltRect.anchoredPosition = new Vector2(cenPos.x - width / 2, cenPos.y + height / 2); rtRect.anchoredPosition = new Vector2(cenPos.x + width / 2, cenPos.y + height / 2); lbRect.anchoredPosition = new Vector2(cenPos.x - width / 2, cenPos.y - height / 2); rbRect.anchoredPosition = new Vector2(cenPos.x + width / 2, cenPos.y - height / 2); UpdateGuide(width, height, cenPos); } #endregion //更新中心点坐标 private void UpdateCen(float width, float height, Vector2 pos) { var cen = Obj.Find("CutEditorCen").GetComponent<RectTransform>(); cen.sizeDelta = new Vector2(width, height); cen.anchoredPosition = pos; UpdateGuide(width, height, cen.anchoredPosition); } //更新遮罩信息 private void UpdateGuide(float width, float height, Vector2 rectPos) { guideMat.SetFloat("_Width", width); guideMat.SetFloat("_Height", height); guideMat.SetVector("_Center", new Vector4(rectPos.x, rectPos.y , 0, 0)); } /// <summary> /// 确认裁剪 /// </summary> private void SetCut() { float rate = 1; if (selectPhoto.texture.width / selectPhoto.texture.height >= 1f) { rate = selectPhoto.texture.height / cutRangeHeight; } else { rate = selectPhoto.texture.width / cutRangeWidth; } RectTransform lt = Obj.Find("CutEditorLT").GetComponent<RectTransform>(); RectTransform rb = Obj.Find("CutEditorRB").GetComponent<RectTransform>(); RectTransform cen =Obj.Find("CutEditorCen").GetComponent<RectTransform>(); float width = (rb.anchoredPosition.x - lt.anchoredPosition.x) * rate; float height = (lt.anchoredPosition.y - rb.anchoredPosition.y) * rate; Vector2 cenPos = new Vector2(cen.anchoredPosition.x * rate + selectPhoto.texture.width / 2, cen.anchoredPosition.y * rate + selectPhoto.texture.height / 2); //InitProject.Instance.StartDoCoroutine(ProjectBehaviour.Instence.CutSprite(selectPhoto, Mathf.CeilToInt(width), Mathf.CeilToInt(height), cenPos, (result) => //{ // ScreenAdaptation(result); //})); CutSprite(selectPhoto, Mathf.CeilToInt(width), Mathf.CeilToInt(height), cenPos, UpdataImage); } public void CutSprite(Sprite oriSprite, int width, int height, Vector2 center, Action<Sprite> finishedCB = null) { Texture2D newTexture = new Texture2D(Mathf.CeilToInt(width), Mathf.CeilToInt(height)); //遍历写入像素的过程 int start_X = (int)(center.x - width / 2); start_X = start_X > 0 ? start_X : 1; int start_Y = (int)(center.y - height / 2); start_Y = start_Y > 0 ? start_Y : 1; int end_X = (int)(center.x + width / 2); end_X = end_X < oriSprite.rect.width ? end_X : (int)oriSprite.rect.width; int end_Y = (int)(center.y + height / 2); end_Y = end_Y < oriSprite.rect.height ? end_Y : (int)oriSprite.rect.height; for (int y = start_Y - 1; y < end_Y; y++) { for (int x = start_X - 1; x < end_X; x++) { Color color = oriSprite.texture.GetPixel(x, y); newTexture.SetPixel(x - start_X + 1, y - start_Y + 1, color); } } newTexture.anisoLevel = 2; newTexture.Apply(); Sprite result = Sprite.Create(newTexture, new Rect(0, 0, newTexture.width, newTexture.height), new Vector2(0.5f, 0.5f)); finishedCB?.Invoke(result); } public void UpdataImage(Sprite sprite) { showImg.sprite = sprite; showImg.SetNativeSize(); }
}
#拖动脚本,需要挂载到四个角标和中心图片上的
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class DragScript : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler { public Action<PointerEventData> BeginDrag; public Action<PointerEventData> EndDrag; public Action<PointerEventData> Draging; public void OnBeginDrag(PointerEventData eventData) { BeginDrag?.Invoke(eventData); } public void OnDrag(PointerEventData eventData) { Draging?.Invoke(eventData); } public void OnEndDrag(PointerEventData eventData) { EndDrag?.Invoke(eventData); } }
工程地址,用的自取
链接:https://pan.baidu.com/s/1d4sKndjHJvmnWoT5nOZ8pA
提取码:tshm
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。