图片的轮播展示效果如果使用2D实现,需要将3D中存在的近大远小效果使用图片的缩放呈现,因此需要存储和计算图片的位置同时还要计算存储图片的缩放信息。将所有图片的位置连线看作是一个椭圆,就可以根据图片的个数获得所有图片在椭圆上的位置,从0-1均匀分布,如4个图片位置为0、0.25、0.5、0.75,5个图片位置为0、0.2、0.4、0.6、0.8。根据这个位置可以分别计算图片在2D平面上的实际位置(投影的位置)和图片的缩放比例,然后根据这些信息生成图片并实现在鼠标拖动过程中图片的改变,使用DOTWEEN可以方便实现动画效果。

将RotationDiagram2D挂载到空物体上,之后生成的图片都是这个物体的子物体,这个脚本是轮播图的管理脚本。RotationDiagramItem是挂载在图片上的脚本,在生成图片时也会添加这个脚本,实现了图片的运动等各种效果。

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI; public class RotationDiagram2D : MonoBehaviour
{
public Vector2 ItemSize; //图片的大小
public Sprite[] ItemSprites; //图片精灵集合
public float ScaleMax; //图片的最大scale
public float ScaleMin; //图片的最小scale
public float Offset; //图片的偏移量(相邻图片的间隔) private List<RotationDiagramItem> _items; //存储所有图片RotationDiagramItem组件的集合
private List<ItemPosData> _posData; //存储所有图片ItemPosData的集合 /// <summary>
/// 调用相应的方法进行初始化
/// </summary>
private void Start()
{
_items = new List<RotationDiagramItem>();
_posData = new List<ItemPosData>();
CreateItem();
CalculateData();
SetItemData();
} /// <summary>
/// 生成临时的空物体,在空物体上添加各种组件并返回
/// </summary>
/// <returns></returns>
private GameObject CreateTemplate()
{
GameObject item = new GameObject("Template");
item.AddComponent<RectTransform>().sizeDelta = ItemSize;
item.AddComponent<Image>();
item.AddComponent<RotationDiagramItem>();
return item;
} /// <summary>
/// 生成所有物体,根据图片精灵个数生成对应个数的物体,并设置好图片精灵,将RotationDiagramItem组件添加到集合中,将组件的Change方法注册到Action中
/// </summary>
private void CreateItem()
{
GameObject template = CreateTemplate();
RotationDiagramItem itemTemp = null; foreach(Sprite sprite in ItemSprites)
{
itemTemp = Instantiate(template).GetComponent<RotationDiagramItem>();
itemTemp.SetParent(transform);
itemTemp.SetSprite(sprite);
itemTemp.AddMoveListener(Change);
_items.Add(itemTemp); } Destroy(template);
} /// <summary>
/// 根据鼠标拖拽的方向得到相应的信号,并调用Change方法
/// </summary>
/// <param name="offsetX"></param> 鼠标拖拽的方向
private void Change(float offsetX)
{
int symbol = offsetX >= 0 ? 1 : -1;
Change(symbol);
} /// <summary>
/// 根据信号改变所有图片的id并更改物体的位置缩放等信息
/// </summary>
/// <param name="symbol"></param>
private void Change(int symbol)
{
foreach (RotationDiagramItem item in _items)
{
item.ChangeId(symbol, _items.Count);
} for (int i = 0; i < _posData.Count; i++)
{
_items[i].SetPosData(_posData[_items[i].PosId]);
}
} /// <summary>
/// 计算图片的位置缩放等信息
/// </summary>
private void CalculateData()
{
List<ItemData> itemDatas = new List<ItemData>(); float length = (ItemSize.x + Offset) * _items.Count;
float radioOffset = 1 / (float)_items.Count; float radio = 0;
for(int i = 0;i < _items.Count;i++)
{
ItemData itemData = new ItemData();
itemData.PosId = i;
itemDatas.Add(itemData); _items[i].PosId = i; ItemPosData data = new ItemPosData();
data.x = GetX(radio, length);
data.scaleTimes = GetScaleTimes(radio, ScaleMax, ScaleMin); radio += radioOffset;
_posData.Add(data);
} itemDatas = itemDatas.OrderBy(u => _posData[u.PosId].scaleTimes).ToList(); for (int i = 0; i < itemDatas.Count; i++)
{
_posData[itemDatas[i].PosId].order = i;
}
} /// <summary>
/// 设置图片的位置缩放等信息
/// </summary>
private void SetItemData()
{
for (int i = 0; i < _posData.Count; i++)
{
_items[i].SetPosData(_posData[i]);
}
} /// <summary>
/// 计算图片对应的横坐标
/// </summary>
/// <param name="radio"></param> 代表图片在椭圆形圆圈上位置的数值,这个值在0-1之间
/// <param name="length"></param> 整个图片展示墙的长度
/// <returns></returns>
private float GetX(float radio,float length)
{
if(radio > 1 || radio < 0)
{
Debug.LogError("当前比例必须是0-1的值");
return 0;
}
if(radio >= 0 && radio < 0.25f)
{
return length * radio;
}
else if(radio >= 0.25f && radio < 0.75f)
{
return length * (0.5f - radio);
}
else
{
return length * (radio - 1);
}
} /// <summary>
/// 计算图片的缩放倍数
/// </summary>
/// <param name="radio"></param> 图片在椭圆上的位置
/// <param name="max"></param> 图片的最大缩放比例
/// <param name="min"></param> 图片的最小缩放比例
/// <returns></returns>
private float GetScaleTimes(float radio,float max,float min)
{
if (radio > 1 || radio < 0)
{
Debug.LogError("当前比例必须是0-1的值");
return 0;
} if (radio < 0.5f)
return Mathf.Lerp(max, min, radio);
else
return Mathf.Lerp(min, max, radio - 0.5f);
} } /// <summary>
/// 记录图片的位置、缩放和层级信息的类
/// </summary>
public class ItemPosData
{
public float x;
public float scaleTimes;
public int order;
} /// <summary>
/// 记录图片次序和层级信息的结构体
/// </summary>
public struct ItemData
{
public int PosId;
public int OrderId;
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using DG.Tweening; public class RotationDiagramItem : MonoBehaviour, IDragHandler,IEndDragHandler
{
public int PosId;
private float _offsetX;
public Action<float> _moveAction;
public float _aniTime = 1; private Image _image;
private Image Image
{
get
{
if (_image == null)
_image = GetComponent<Image>(); return _image;
}
} private RectTransform _rect;
private RectTransform Rect
{
get
{
if (_rect == null)
_rect = GetComponent<RectTransform>(); return _rect;
}
} /// <summary>
/// 设置父物体
/// </summary>
/// <param name="parent"></param> 父物体
public void SetParent(Transform parent)
{
transform.SetParent(parent);
} /// <summary>
/// 设置图片
/// </summary>
/// <param name="sprite"></param> 图片精灵
public void SetSprite(Sprite sprite)
{
Image.sprite = sprite;
} /// <summary>
/// 设置位置和大小
/// </summary>
/// <param name="data"></param> 保存图片位置和大小信息的对象
public void SetPosData(ItemPosData data)
{
Rect.DOAnchorPos(Vector2.right * data.x, _aniTime);
//Rect.anchoredPosition3D = Vector2.right * data.x;
Rect.DOScale(Vector3.one * data.scaleTimes, _aniTime);
//Rect.localScale = Vector3.one * data.scaleTimes;
StartCoroutine(Wait(data));
} /// <summary>
/// 等待后设置图片层级
/// </summary>
/// <param name="data"></param> 保存图片信息的对象
/// <returns></returns>
private IEnumerator Wait(ItemPosData data)
{
yield return new WaitForSeconds(_aniTime * 0.5f);
transform.SetSiblingIndex(data.order);
} /// <summary>
/// IDragHandler接口的实现方法
/// </summary>
/// <param name="eventData"></param>
public void OnDrag(PointerEventData eventData)
{
_offsetX += eventData.delta.x;
} /// <summary>
/// IEndDragHandler接口的实现方法
/// </summary>
/// <param name="eventData"></param>
public void OnEndDrag(PointerEventData eventData)
{
_moveAction(_offsetX);
_offsetX = 0;
} /// <summary>
/// 添加监听器,监听鼠标的拖动
/// </summary>
/// <param name="onMove"></param>
public void AddMoveListener(Action<float> onMove)
{
_moveAction = onMove;
} /// <summary>
/// 根据信号改变图片的id
/// </summary>
/// <param name="symbol"></param> 代表图片拖动方向的信号值
/// <param name="totalItemNum"></param> 图片的总数
public void ChangeId(int symbol,int totalItemNum)
{
int id = PosId;
id += symbol;
if(id < 0)
{
id += totalItemNum;
}
PosId = id % totalItemNum;
}
}

图片轮播展示效果-2D实现的更多相关文章

  1. UIScrollView,UIPageControl,UIImageView 实现图片轮播的效果

    上一篇博客介绍了如何将XCode创立的项目提交到Git版本控制,这次就直接做一个图片轮播的展示demo,刚好可以把UIScrollView.UIPageControl.UIImageView这三个控件 ...

  2. JQuery图片轮播滚动效果(网页效果--每日一更)

    今天,带来的是一个图片的轮播滚动效果! 先来看一下效果展示:亲,请点击这里 原理很简单,设置一个定时器,使图片列表在每隔一段时间后滚动一次.而循环效果,就是在每一滚动的时候,将第一张图片放到最后一张的 ...

  3. Js 图片轮播渐隐效果

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. 【原创smarty仿淘宝商品图片轮播+放大镜效果】

    1.去掉图片集字段,字符串的多余字符 $goods_pic_display=$row[DISPLAY];$goods_pic_display1=str_replace('"', '', $g ...

  5. H5+CSS3做图片轮播滚动效果

    HTML代码部分: <div id="wrap"> <ul id="list"> <li>10</li> < ...

  6. jQuery个性化图片轮播效果

    jQuery个性化图片轮播效果 购物产品展示:图片轮播器<效果如下所示> 思路说明: 每隔一段时间,实现图片的自动切换及选项卡选中效果,鼠标划入图片动画停止,划出或离开动画开始 两个区域: ...

  7. 使用js制作一般网站首页图片轮播效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. UIScrollView实现图片轮播器及其无限循环效果

    图片轮播器: 一.实现效果 实现图片的自动轮播            二.实现代码 storyboard中布局 代码: 1 #import "YYViewController.h" ...

  9. html中使用JS实现图片轮播效果

    1.首先是效果图,要在网页中实现下图的轮播效果,有四张图片,每张图片有自己的标题,然后还有右下角的小方框,鼠标悬浮在小方框上,会切换到对应的图片中去. 2.先是HTML中的内容,最外层是轮播图整个的容 ...

随机推荐

  1. Win Docker 安装C盘清理方法之一

    背景 由于Docker默认安装到C盘,C盘空间越发的小了,虽然(win10)C盘满了并不会很大影响,但是强迫症患者是不能忍得 解决办法 查询https://stackoverflow.com/ques ...

  2. Ubuntu无法ssh远程连接问题 (转)

    [系统]Ubuntu 12.04 server [问题描述]新安装的Ubuntu系统无法直接通过ssh远程连接. [解决办法] 新安装的Ubuntu系统并未安装ssh-server服务,需要自行安装, ...

  3. vue中添加文字或图片水印

    首先引用warterMark.js,内容如下 'use strict' var watermark = (className,str,type) => { let dom = document. ...

  4. Task1:知识图谱介绍(1天)

    一.知识图谱简介 "知识图谱本质上是语义网络(Semantic Network)的知识库".但这有点抽象,所以换个角度,从实际应用的角度出发其实可以简单地把知识图谱理解成多关系图( ...

  5. 使用javafx开发一款桌面个性化软件

    本来笔者只是打算开发一个显示在桌面的cpu和内存监控工具,没想到迭代了几次版本之后变成了桌面个性化工具了. 目前实现功能: cpu和内存的实时监控 开机自动启动 自定义logo 自定义主题颜色 鼠标拖 ...

  6. CentOS7上安装jdk,mysql

    最近笔者的云服务器由于中毒,重装系统了... 所以就记录下所有服务的搭建过程吧 1.安装jdk 在oracle上下载linux系统的jdk,笔者这里使用的是1.8 https://www.oracle ...

  7. 天梯赛练习 L3-016 二叉搜索树的结构 (30分)

    题目分析: 用数型结构先建树,一边输入一边建立,根节点的下标为1,所以左孩子为root*2,右孩子为root*2+1,输入的时候可用cin输入字符串也可用scanf不会超时,判断是否在同一层可以判断两 ...

  8. 记一次使用logmnr查找操作人流程

    经常遇到开发的需求,帮我查一下是谁修改了表里面的记录,是谁对表进行了DDL操作,此类问题可以使用logmnr解决 1.根据操作时间定位归档日志 SELECT name FROM V$ARCHIVED_ ...

  9. 绝对定位上下左右都为0 margin为auto为什么能居中

    老规矩,先来一段废话,我大学刚入门的时候觉得CSS很简单,记一记就会了,不就是盒模型嘛,现在想来觉得自己那时候真的很自以为是哈哈.但是随着工作沉淀,我明白了任何技术都有着它的深度和广度,正是因为不少人 ...

  10. STL_string容器

    一.string概念 string是STL的字符串类型,通常用来表示字符串.而在使用string之前,字符串通常是用char*表示的.string与char*都可以用来表示字符串,那么二者有什么区别. ...