1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320 |
- using System;
- using UnityEngine;
- using FairyGUI.Utils;
- namespace FairyGUI
- {
- /// <summary>
- ///
- /// </summary>
- public class ScrollPane : EventDispatcher
- {
- /// <summary>
- /// 当前被拖拽的滚动面板。同一时间只能有一个在进行此操作。
- /// </summary>
- public static ScrollPane draggingPane { get; private set; }
- ScrollType _scrollType;
- float _scrollStep;
- float _decelerationRate;
- Margin _scrollBarMargin;
- bool _bouncebackEffect;
- bool _touchEffect;
- bool _scrollBarDisplayAuto;
- bool _vScrollNone;
- bool _hScrollNone;
- bool _needRefresh;
- int _refreshBarAxis;
- bool _displayOnLeft;
- bool _snapToItem;
- internal bool _displayInDemand;
- bool _mouseWheelEnabled;
- bool _softnessOnTopOrLeftSide;
- bool _pageMode;
- Vector2 _pageSize;
- bool _inertiaDisabled;
- bool _maskDisabled;
- bool _floating;
- bool _dontClipMargin;
- float _xPos;
- float _yPos;
- Vector2 _viewSize;
- Vector2 _contentSize;
- Vector2 _overlapSize;
- Vector2 _containerPos;
- Vector2 _beginTouchPos;
- Vector2 _lastTouchPos;
- Vector2 _lastTouchGlobalPos;
- Vector2 _velocity;
- float _velocityScale;
- float _lastMoveTime;
- bool _dragged;
- bool _isHoldAreaDone;
- int _aniFlag;
- internal int _loop;
- int _headerLockedSize;
- int _footerLockedSize;
- bool _hover;
- int _tweening;
- Vector2 _tweenStart;
- Vector2 _tweenChange;
- Vector2 _tweenTime;
- Vector2 _tweenDuration;
- Action _refreshDelegate;
- TimerCallback _tweenUpdateDelegate;
- GTweenCallback1 _hideScrollBarDelegate;
- GComponent _owner;
- Container _maskContainer;
- Container _container;
- GScrollBar _hzScrollBar;
- GScrollBar _vtScrollBar;
- GComponent _header;
- GComponent _footer;
- Controller _pageController;
- EventListener _onScroll;
- EventListener _onScrollEnd;
- EventListener _onPullDownRelease;
- EventListener _onPullUpRelease;
- static int _gestureFlag;
- public static float TWEEN_TIME_GO = 0.3f; //调用SetPos(ani)时使用的缓动时间
- public static float TWEEN_TIME_DEFAULT = 0.3f; //惯性滚动的最小缓动时间
- public static float PULL_RATIO = 0.5f; //下拉过顶或者上拉过底时允许超过的距离占显示区域的比例
- public ScrollPane(GComponent owner)
- {
- _onScroll = new EventListener(this, "onScroll");
- _onScrollEnd = new EventListener(this, "onScrollEnd");
- _scrollStep = UIConfig.defaultScrollStep;
- _softnessOnTopOrLeftSide = UIConfig.allowSoftnessOnTopOrLeftSide;
- _decelerationRate = UIConfig.defaultScrollDecelerationRate;
- _touchEffect = UIConfig.defaultScrollTouchEffect;
- _bouncebackEffect = UIConfig.defaultScrollBounceEffect;
- _mouseWheelEnabled = true;
- _pageSize = Vector2.one;
- _refreshDelegate = Refresh;
- _tweenUpdateDelegate = TweenUpdate;
- _hideScrollBarDelegate = __barTweenComplete;
- _owner = owner;
- _maskContainer = new Container();
- _owner.rootContainer.AddChild(_maskContainer);
- _container = _owner.container;
- _container.SetXY(0, 0);
- _maskContainer.AddChild(_container);
- _owner.rootContainer.onMouseWheel.Add(__mouseWheel);
- _owner.rootContainer.onTouchBegin.Add(__touchBegin);
- _owner.rootContainer.onTouchMove.Add(__touchMove);
- _owner.rootContainer.onTouchEnd.Add(__touchEnd);
- }
- public void Setup(ByteBuffer buffer)
- {
- _scrollType = (ScrollType)buffer.ReadByte();
- ScrollBarDisplayType scrollBarDisplay = (ScrollBarDisplayType)buffer.ReadByte();
- int flags = buffer.ReadInt();
- if (buffer.ReadBool())
- {
- _scrollBarMargin.top = buffer.ReadInt();
- _scrollBarMargin.bottom = buffer.ReadInt();
- _scrollBarMargin.left = buffer.ReadInt();
- _scrollBarMargin.right = buffer.ReadInt();
- }
- string vtScrollBarRes = buffer.ReadS();
- string hzScrollBarRes = buffer.ReadS();
- string headerRes = buffer.ReadS();
- string footerRes = buffer.ReadS();
- _displayOnLeft = (flags & 1) != 0;
- _snapToItem = (flags & 2) != 0;
- _displayInDemand = (flags & 4) != 0;
- _pageMode = (flags & 8) != 0;
- if ((flags & 16) != 0)
- _touchEffect = true;
- else if ((flags & 32) != 0)
- _touchEffect = false;
- if ((flags & 64) != 0)
- _bouncebackEffect = true;
- else if ((flags & 128) != 0)
- _bouncebackEffect = false;
- _inertiaDisabled = (flags & 256) != 0;
- _maskDisabled = (flags & 512) != 0;
- _floating = (flags & 1024) != 0;
- _dontClipMargin = (flags & 2048) != 0;
- if (scrollBarDisplay == ScrollBarDisplayType.Default)
- {
- if (Application.isMobilePlatform)
- scrollBarDisplay = ScrollBarDisplayType.Auto;
- else
- scrollBarDisplay = UIConfig.defaultScrollBarDisplay;
- }
- if (scrollBarDisplay != ScrollBarDisplayType.Hidden)
- {
- if (_scrollType == ScrollType.Both || _scrollType == ScrollType.Vertical)
- {
- string res = vtScrollBarRes != null ? vtScrollBarRes : UIConfig.verticalScrollBar;
- if (!string.IsNullOrEmpty(res))
- {
- _vtScrollBar = UIPackage.CreateObjectFromURL(res) as GScrollBar;
- if (_vtScrollBar == null)
- Debug.LogWarning("FairyGUI: cannot create scrollbar from " + res);
- else
- {
- _vtScrollBar.SetScrollPane(this, true);
- _owner.rootContainer.AddChild(_vtScrollBar.displayObject);
- }
- }
- }
- if (_scrollType == ScrollType.Both || _scrollType == ScrollType.Horizontal)
- {
- string res = hzScrollBarRes != null ? hzScrollBarRes : UIConfig.horizontalScrollBar;
- if (!string.IsNullOrEmpty(res))
- {
- _hzScrollBar = UIPackage.CreateObjectFromURL(res) as GScrollBar;
- if (_hzScrollBar == null)
- Debug.LogWarning("FairyGUI: cannot create scrollbar from " + res);
- else
- {
- _hzScrollBar.SetScrollPane(this, false);
- _owner.rootContainer.AddChild(_hzScrollBar.displayObject);
- }
- }
- }
- _scrollBarDisplayAuto = scrollBarDisplay == ScrollBarDisplayType.Auto;
- if (_scrollBarDisplayAuto)
- {
- if (_vtScrollBar != null)
- _vtScrollBar.displayObject.visible = false;
- if (_hzScrollBar != null)
- _hzScrollBar.displayObject.visible = false;
- _owner.rootContainer.onRollOver.Add(__rollOver);
- _owner.rootContainer.onRollOut.Add(__rollOut);
- }
- }
- else
- _mouseWheelEnabled = false;
- if (Application.isPlaying)
- {
- if (headerRes != null)
- {
- _header = (GComponent)UIPackage.CreateObjectFromURL(headerRes);
- if (_header == null)
- Debug.LogWarning("FairyGUI: cannot create scrollPane header from " + headerRes);
- }
- if (footerRes != null)
- {
- _footer = (GComponent)UIPackage.CreateObjectFromURL(footerRes);
- if (_footer == null)
- Debug.LogWarning("FairyGUI: cannot create scrollPane footer from " + footerRes);
- }
- if (_header != null || _footer != null)
- _refreshBarAxis = (_scrollType == ScrollType.Both || _scrollType == ScrollType.Vertical) ? 1 : 0;
- }
- SetSize(owner.width, owner.height);
- }
- /// <summary>
- ///
- /// </summary>
- public void Dispose()
- {
- RemoveEventListeners();
- if (_tweening != 0)
- Timers.inst.Remove(_tweenUpdateDelegate);
- if (draggingPane == this)
- draggingPane = null;
- _pageController = null;
- if (_hzScrollBar != null)
- _hzScrollBar.Dispose();
- if (_vtScrollBar != null)
- _vtScrollBar.Dispose();
- if (_header != null)
- _header.Dispose();
- if (_footer != null)
- _footer.Dispose();
- }
- /// <summary>
- /// Dispatched when scrolling.
- /// 在滚动时派发该事件。
- /// </summary>
- public EventListener onScroll
- {
- get { return _onScroll ?? (_onScroll = new EventListener(this, "onScroll")); }
- }
- /// <summary>
- /// 在滚动结束时派发该事件。
- /// </summary>
- public EventListener onScrollEnd
- {
- get { return _onScrollEnd ?? (_onScrollEnd = new EventListener(this, "onScrollEnd")); }
- }
- /// <summary>
- /// 向下拉过上边缘后释放则派发该事件。
- /// </summary>
- public EventListener onPullDownRelease
- {
- get { return _onPullDownRelease ?? (_onPullDownRelease = new EventListener(this, "onPullDownRelease")); }
- }
- /// <summary>
- /// 向上拉过下边缘后释放则派发该事件。
- /// </summary>
- public EventListener onPullUpRelease
- {
- get { return _onPullUpRelease ?? (_onPullUpRelease = new EventListener(this, "onPullUpRelease")); }
- }
- /// <summary>
- ///
- /// </summary>
- public GComponent owner
- {
- get { return _owner; }
- }
- /// <summary>
- ///
- /// </summary>
- public GScrollBar hzScrollBar
- {
- get { return _hzScrollBar; }
- }
- /// <summary>
- ///
- /// </summary>
- public GScrollBar vtScrollBar
- {
- get { return _vtScrollBar; }
- }
- /// <summary>
- ///
- /// </summary>
- public GComponent header
- {
- get { return _header; }
- }
- /// <summary>
- ///
- /// </summary>
- public GComponent footer
- {
- get { return _footer; }
- }
- /// <summary>
- /// 滚动到达边缘时是否允许回弹效果。
- /// </summary>
- public bool bouncebackEffect
- {
- get { return _bouncebackEffect; }
- set { _bouncebackEffect = value; }
- }
- /// <summary>
- /// 是否允许拖拽内容区域进行滚动。
- /// </summary>
- public bool touchEffect
- {
- get { return _touchEffect; }
- set { _touchEffect = value; }
- }
- /// <summary>
- /// 是否允许惯性滚动。
- /// </summary>
- public bool inertiaDisabled
- {
- get { return _inertiaDisabled; }
- set { _inertiaDisabled = value; }
- }
- /// <summary>
- /// 是否允许在左/上边缘显示虚化效果。
- /// </summary>
- public bool softnessOnTopOrLeftSide
- {
- get { return _softnessOnTopOrLeftSide; }
- set { _softnessOnTopOrLeftSide = value; }
- }
- /// <summary>
- /// 当调用ScrollPane.scrollUp/Down/Left/Right时,或者点击滚动条的上下箭头时,滑动的距离。
- /// </summary>
- public float scrollStep
- {
- get { return _scrollStep; }
- set
- {
- _scrollStep = value;
- if (_scrollStep == 0)
- _scrollStep = UIConfig.defaultScrollStep;
- }
- }
- /// <summary>
- /// 滚动位置是否保持贴近在某个元件的边缘。
- /// </summary>
- public bool snapToItem
- {
- get { return _snapToItem; }
- set { _snapToItem = value; }
- }
- /// <summary>
- /// 是否页面滚动模式。
- /// </summary>
- public bool pageMode
- {
- get { return _pageMode; }
- set { _pageMode = value; }
- }
- /// <summary>
- ///
- /// </summary>
- public Controller pageController
- {
- get { return _pageController; }
- set { _pageController = value; }
- }
- /// <summary>
- /// 是否允许使用鼠标滚轮进行滚动。
- /// </summary>
- public bool mouseWheelEnabled
- {
- get { return _mouseWheelEnabled; }
- set { _mouseWheelEnabled = value; }
- }
- /// <summary>
- /// 当处于惯性滚动时减速的速率。默认值是UIConfig.defaultScrollDecelerationRate。
- /// 越接近1,减速越慢,意味着滑动的时间和距离更长。
- /// </summary>
- public float decelerationRate
- {
- get { return _decelerationRate; }
- set { _decelerationRate = value; }
- }
- /// <summary>
- /// </summary>
- public bool isDragged
- {
- get { return _dragged; }
- }
- /// <summary>
- /// 当前X轴滚动位置百分比,0~1(包含)。
- /// </summary>
- public float percX
- {
- get { return _overlapSize.x == 0 ? 0 : _xPos / _overlapSize.x; }
- set { SetPercX(value, false); }
- }
- /// <summary>
- /// 设置当前X轴滚动位置百分比,0~1(包含)。
- /// </summary>
- /// <param name="value"></param>
- /// <param name="ani">是否使用缓动到达目标。</param>
- public void SetPercX(float value, bool ani)
- {
- _owner.EnsureBoundsCorrect();
- SetPosX(_overlapSize.x * Mathf.Clamp01(value), ani);
- }
- /// <summary>
- /// 当前Y轴滚动位置百分比,0~1(包含)。
- /// </summary>
- public float percY
- {
- get { return _overlapSize.y == 0 ? 0 : _yPos / _overlapSize.y; }
- set { SetPercY(value, false); }
- }
- /// <summary>
- /// 设置当前Y轴滚动位置百分比,0~1(包含)。
- /// </summary>
- /// <param name="value"></param>
- /// <param name="ani">是否使用缓动到达目标。</param>
- public void SetPercY(float value, bool ani)
- {
- _owner.EnsureBoundsCorrect();
- SetPosY(_overlapSize.y * Mathf.Clamp01(value), ani);
- }
- /// <summary>
- /// 当前X轴滚动位置,值范围是viewWidth与contentWidth之差。
- /// </summary>
- public float posX
- {
- get { return _xPos; }
- set { SetPosX(value, false); }
- }
- /// <summary>
- /// 设置当前X轴滚动位置。
- /// </summary>
- /// <param name="value"></param>
- /// <param name="ani">是否使用缓动到达目标。</param>
- public void SetPosX(float value, bool ani)
- {
- _owner.EnsureBoundsCorrect();
- if (_loop == 1)
- LoopCheckingNewPos(ref value, 0);
- value = Mathf.Clamp(value, 0, _overlapSize.x);
- if (value != _xPos)
- {
- _xPos = value;
- PosChanged(ani);
- }
- }
- /// <summary>
- /// 当前Y轴滚动位置,值范围是viewHeight与contentHeight之差。
- /// </summary>
- public float posY
- {
- get { return _yPos; }
- set { SetPosY(value, false); }
- }
- /// <summary>
- /// 设置当前Y轴滚动位置。
- /// </summary>
- /// <param name="value"></param>
- /// <param name="ani">是否使用缓动到达目标。</param>
- public void SetPosY(float value, bool ani)
- {
- _owner.EnsureBoundsCorrect();
- if (_loop == 2)
- LoopCheckingNewPos(ref value, 1);
- value = Mathf.Clamp(value, 0, _overlapSize.y);
- if (value != _yPos)
- {
- _yPos = value;
- PosChanged(ani);
- }
- }
- /// <summary>
- /// 返回当前滚动位置是否在最下边。
- /// </summary>
- public bool isBottomMost
- {
- get { return _yPos == _overlapSize.y || _overlapSize.y == 0; }
- }
- /// <summary>
- /// 返回当前滚动位置是否在最右边。
- /// </summary>
- public bool isRightMost
- {
- get { return _xPos == _overlapSize.x || _overlapSize.x == 0; }
- }
- /// <summary>
- /// 如果处于分页模式,返回当前在X轴的页码。
- /// </summary>
- public int currentPageX
- {
- get
- {
- if (!_pageMode)
- return 0;
- int page = Mathf.FloorToInt(_xPos / _pageSize.x);
- if (_xPos - page * _pageSize.x > _pageSize.x * 0.5f)
- page++;
- return page;
- }
- set
- {
- if (!_pageMode)
- return;
- _owner.EnsureBoundsCorrect();
- if (_overlapSize.x > 0)
- this.SetPosX(value * _pageSize.x, false);
- }
- }
- /// <summary>
- /// 如果处于分页模式,可设置X轴的页码。
- /// </summary>
- /// <param name="value"></param>
- /// <param name="ani">是否使用缓动到达目标。</param>
- public void SetCurrentPageX(int value, bool ani)
- {
- if (!_pageMode)
- return;
- _owner.EnsureBoundsCorrect();
- if (_overlapSize.x > 0)
- this.SetPosX(value * _pageSize.x, ani);
- }
- /// <summary>
- /// 如果处于分页模式,返回当前在Y轴的页码。
- /// </summary>
- public int currentPageY
- {
- get
- {
- if (!_pageMode)
- return 0;
- int page = Mathf.FloorToInt(_yPos / _pageSize.y);
- if (_yPos - page * _pageSize.y > _pageSize.y * 0.5f)
- page++;
- return page;
- }
- set
- {
- if (!_pageMode)
- return;
- _owner.EnsureBoundsCorrect();
- if (_overlapSize.y > 0)
- this.SetPosY(value * _pageSize.y, false);
- }
- }
- /// <summary>
- /// 如果处于分页模式,可设置Y轴的页码。
- /// </summary>
- /// <param name="value"></param>
- /// <param name="ani">是否使用缓动到达目标。</param>
- public void SetCurrentPageY(int value, bool ani)
- {
- if (!_pageMode)
- return;
- _owner.EnsureBoundsCorrect();
- if (_overlapSize.y > 0)
- this.SetPosY(value * _pageSize.y, ani);
- }
- /// <summary>
- /// 这个值与PosX不同在于,他反映的是实时位置,而PosX在有缓动过程的情况下只是终值。
- /// </summary>
- public float scrollingPosX
- {
- get
- {
- return Mathf.Clamp(-_container.x, 0, _overlapSize.x);
- }
- }
- /// <summary>
- /// 这个值与PosY不同在于,他反映的是实时位置,而PosY在有缓动过程的情况下只是终值。
- /// </summary>
- public float scrollingPosY
- {
- get
- {
- return Mathf.Clamp(-_container.y, 0, _overlapSize.y);
- }
- }
- /// <summary>
- /// 显示内容宽度。
- /// </summary>
- public float contentWidth
- {
- get
- {
- return _contentSize.x;
- }
- }
- /// <summary>
- /// 显示内容高度。
- /// </summary>
- public float contentHeight
- {
- get
- {
- return _contentSize.y;
- }
- }
- /// <summary>
- /// 显示区域宽度。
- /// </summary>
- public float viewWidth
- {
- get { return _viewSize.x; }
- set
- {
- value = value + _owner.margin.left + _owner.margin.right;
- if (_vtScrollBar != null && !_floating)
- value += _vtScrollBar.width;
- _owner.width = value;
- }
- }
- /// <summary>
- /// 显示区域高度。
- /// </summary>
- public float viewHeight
- {
- get { return _viewSize.y; }
- set
- {
- value = value + _owner.margin.top + _owner.margin.bottom;
- if (_hzScrollBar != null && !_floating)
- value += _hzScrollBar.height;
- _owner.height = value;
- }
- }
- /// <summary>
- ///
- /// </summary>
- public void ScrollTop()
- {
- ScrollTop(false);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="ani"></param>
- public void ScrollTop(bool ani)
- {
- this.SetPercY(0, ani);
- }
- /// <summary>
- ///
- /// </summary>
- public void ScrollBottom()
- {
- ScrollBottom(false);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="ani"></param>
- public void ScrollBottom(bool ani)
- {
- this.SetPercY(1, ani);
- }
- /// <summary>
- ///
- /// </summary>
- public void ScrollUp()
- {
- ScrollUp(1, false);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="ratio"></param>
- /// <param name="ani"></param>
- public void ScrollUp(float ratio, bool ani)
- {
- if (_pageMode)
- SetPosY(_yPos - _pageSize.y * ratio, ani);
- else
- SetPosY(_yPos - _scrollStep * ratio, ani);
- }
- /// <summary>
- ///
- /// </summary>
- public void ScrollDown()
- {
- ScrollDown(1, false);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="ratio"></param>
- /// <param name="ani"></param>
- public void ScrollDown(float ratio, bool ani)
- {
- if (_pageMode)
- SetPosY(_yPos + _pageSize.y * ratio, ani);
- else
- SetPosY(_yPos + _scrollStep * ratio, ani);
- }
- /// <summary>
- ///
- /// </summary>
- public void ScrollLeft()
- {
- ScrollLeft(1, false);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="speed"></param>
- /// <param name="ani"></param>
- public void ScrollLeft(float ratio, bool ani)
- {
- if (_pageMode)
- SetPosX(_xPos - _pageSize.x * ratio, ani);
- else
- SetPosX(_xPos - _scrollStep * ratio, ani);
- }
- /// <summary>
- ///
- /// </summary>
- public void ScrollRight()
- {
- ScrollRight(1, false);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="ratio"></param>
- /// <param name="ani"></param>
- public void ScrollRight(float ratio, bool ani)
- {
- if (_pageMode)
- SetPosX(_xPos + _pageSize.x * ratio, ani);
- else
- SetPosX(_xPos + _scrollStep * ratio, ani);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="obj">obj can be any object on stage, not limited to the direct child of this container.</param>
- public void ScrollToView(GObject obj)
- {
- ScrollToView(obj, false);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="obj">obj can be any object on stage, not limited to the direct child of this container.</param>
- /// <param name="ani">If moving to target position with animation</param>
- public void ScrollToView(GObject obj, bool ani)
- {
- ScrollToView(obj, ani, false);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="obj">obj can be any object on stage, not limited to the direct child of this container.</param>
- /// <param name="ani">If moving to target position with animation</param>
- /// <param name="setFirst">If true, scroll to make the target on the top/left; If false, scroll to make the target any position in view.</param>
- public void ScrollToView(GObject obj, bool ani, bool setFirst)
- {
- _owner.EnsureBoundsCorrect();
- if (_needRefresh)
- Refresh();
- Rect rect = new Rect(obj.x, obj.y, obj.width, obj.height);
- if (obj.parent != _owner)
- rect = obj.parent.TransformRect(rect, _owner);
- ScrollToView(rect, ani, setFirst);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="rect">Rect in local coordinates</param>
- /// <param name="ani">If moving to target position with animation</param>
- /// <param name="setFirst">If true, scroll to make the target on the top/left; If false, scroll to make the target any position in view.</param>
- public void ScrollToView(Rect rect, bool ani, bool setFirst)
- {
- _owner.EnsureBoundsCorrect();
- if (_needRefresh)
- Refresh();
- if (_overlapSize.y > 0)
- {
- float bottom = _yPos + _viewSize.y;
- if (setFirst || rect.y <= _yPos || rect.height >= _viewSize.y)
- {
- if (rect.yMax >= bottom) //if an item size is large than viewSize, dont scroll
- return;
- if (_pageMode)
- this.SetPosY(Mathf.Floor(rect.y / _pageSize.y) * _pageSize.y, ani);
- else
- SetPosY(rect.y, ani);
- }
- else if (rect.yMax > bottom)
- {
- if (_pageMode)
- this.SetPosY(Mathf.Floor(rect.y / _pageSize.y) * _pageSize.y, ani);
- else if (rect.height <= _viewSize.y / 2)
- SetPosY(rect.y + rect.height * 2 - _viewSize.y, ani);
- else
- SetPosY(rect.y + Mathf.Min(rect.height - _viewSize.y, 0), ani);
- }
- }
- if (_overlapSize.x > 0)
- {
- float right = _xPos + _viewSize.x;
- if (setFirst || rect.x <= _xPos || rect.width >= _viewSize.x)
- {
- if (rect.xMax >= right) //if an item size is large than viewSize, dont scroll
- return;
- if (_pageMode)
- this.SetPosX(Mathf.Floor(rect.x / _pageSize.x) * _pageSize.x, ani);
- SetPosX(rect.x, ani);
- }
- else if (rect.xMax > right)
- {
- if (_pageMode)
- this.SetPosX(Mathf.Floor(rect.x / _pageSize.x) * _pageSize.x, ani);
- else if (rect.width <= _viewSize.x / 2)
- SetPosX(rect.x + rect.width * 2 - _viewSize.x, ani);
- else
- SetPosX(rect.x + Mathf.Min(rect.width - _viewSize.x, 0), ani);
- }
- }
- if (!ani && _needRefresh)
- Refresh();
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="obj">obj must be the direct child of this container</param>
- /// <returns></returns>
- public bool IsChildInView(GObject obj)
- {
- if (_overlapSize.y > 0)
- {
- float dist = obj.y + _container.y;
- if (dist <= -obj.height || dist >= _viewSize.y)
- return false;
- }
- if (_overlapSize.x > 0)
- {
- float dist = obj.x + _container.x;
- if (dist <= -obj.width || dist >= _viewSize.x)
- return false;
- }
- return true;
- }
- /// <summary>
- /// 当滚动面板处于拖拽滚动状态或即将进入拖拽状态时,可以调用此方法停止或禁止本次拖拽。
- /// </summary>
- public void CancelDragging()
- {
- Stage.inst.RemoveTouchMonitor(_owner.rootContainer);
- if (draggingPane == this)
- draggingPane = null;
- _gestureFlag = 0;
- _dragged = false;
- }
- /// <summary>
- /// 设置Header固定显示。如果size为0,则取消固定显示。
- /// </summary>
- /// <param name="size">Header显示的大小</param>
- public void LockHeader(int size)
- {
- if (_headerLockedSize == size)
- return;
- _headerLockedSize = size;
- if (!isDispatching("onPullDownRelease") && _container.xy[_refreshBarAxis] >= 0)
- {
- _tweenStart = _container.xy;
- _tweenChange = Vector2.zero;
- _tweenChange[_refreshBarAxis] = _headerLockedSize - _tweenStart[_refreshBarAxis];
- _tweenDuration = new Vector2(TWEEN_TIME_DEFAULT, TWEEN_TIME_DEFAULT);
- StartTween(2);
- }
- }
- /// <summary>
- /// 设置Footer固定显示。如果size为0,则取消固定显示。
- /// </summary>
- /// <param name="size"></param>
- public void LockFooter(int size)
- {
- if (_footerLockedSize == size)
- return;
- _footerLockedSize = size;
- if (!isDispatching("onPullUpRelease") && _container.xy[_refreshBarAxis] <= -_overlapSize[_refreshBarAxis])
- {
- _tweenStart = _container.xy;
- _tweenChange = Vector2.zero;
- float max = _overlapSize[_refreshBarAxis];
- if (max == 0)
- max = Mathf.Max(_contentSize[_refreshBarAxis] + _footerLockedSize - _viewSize[_refreshBarAxis], 0);
- else
- max += _footerLockedSize;
- _tweenChange[_refreshBarAxis] = -max - _tweenStart[_refreshBarAxis];
- _tweenDuration = new Vector2(TWEEN_TIME_DEFAULT, TWEEN_TIME_DEFAULT);
- StartTween(2);
- }
- }
- internal void OnOwnerSizeChanged()
- {
- SetSize(_owner.width, _owner.height);
- PosChanged(false);
- }
- internal void HandleControllerChanged(Controller c)
- {
- if (_pageController == c)
- {
- if (_scrollType == ScrollType.Horizontal)
- this.SetCurrentPageX(c.selectedIndex, true);
- else
- this.SetCurrentPageY(c.selectedIndex, true);
- }
- }
- void UpdatePageController()
- {
- if (_pageController != null && !_pageController.changing)
- {
- int index;
- if (_scrollType == ScrollType.Horizontal)
- index = this.currentPageX;
- else
- index = this.currentPageY;
- if (index < _pageController.pageCount)
- {
- Controller c = _pageController;
- _pageController = null; //防止HandleControllerChanged的调用
- c.selectedIndex = index;
- _pageController = c;
- }
- }
- }
- internal void AdjustMaskContainer()
- {
- float mx, my;
- if (_displayOnLeft && _vtScrollBar != null && !_floating)
- mx = Mathf.FloorToInt(_owner.margin.left + _vtScrollBar.width);
- else
- mx = _owner.margin.left;
- my = _owner.margin.top;
- mx += _owner._alignOffset.x;
- my += _owner._alignOffset.y;
- _maskContainer.SetXY(mx, my);
- }
- void SetSize(float aWidth, float aHeight)
- {
- AdjustMaskContainer();
- if (_hzScrollBar != null)
- {
- _hzScrollBar.y = aHeight - _hzScrollBar.height;
- if (_vtScrollBar != null)
- {
- _hzScrollBar.width = aWidth - _vtScrollBar.width - _scrollBarMargin.left - _scrollBarMargin.right;
- if (_displayOnLeft)
- _hzScrollBar.x = _scrollBarMargin.left + _vtScrollBar.width;
- else
- _hzScrollBar.x = _scrollBarMargin.left;
- }
- else
- {
- _hzScrollBar.width = aWidth - _scrollBarMargin.left - _scrollBarMargin.right;
- _hzScrollBar.x = _scrollBarMargin.left;
- }
- }
- if (_vtScrollBar != null)
- {
- if (!_displayOnLeft)
- _vtScrollBar.x = aWidth - _vtScrollBar.width;
- if (_hzScrollBar != null)
- _vtScrollBar.height = aHeight - _hzScrollBar.height - _scrollBarMargin.top - _scrollBarMargin.bottom;
- else
- _vtScrollBar.height = aHeight - _scrollBarMargin.top - _scrollBarMargin.bottom;
- _vtScrollBar.y = _scrollBarMargin.top;
- }
- _viewSize.x = aWidth;
- _viewSize.y = aHeight;
- if (_hzScrollBar != null && !_floating)
- _viewSize.y -= _hzScrollBar.height;
- if (_vtScrollBar != null && !_floating)
- _viewSize.x -= _vtScrollBar.width;
- _viewSize.x -= (_owner.margin.left + _owner.margin.right);
- _viewSize.y -= (_owner.margin.top + _owner.margin.bottom);
- _viewSize.x = Mathf.Max(1, _viewSize.x);
- _viewSize.y = Mathf.Max(1, _viewSize.y);
- _pageSize.x = _viewSize.x;
- _pageSize.y = _viewSize.y;
- HandleSizeChanged();
- }
- internal void SetContentSize(float aWidth, float aHeight)
- {
- if (Mathf.Approximately(_contentSize.x, aWidth) && Mathf.Approximately(_contentSize.y, aHeight))
- return;
- _contentSize.x = aWidth;
- _contentSize.y = aHeight;
- HandleSizeChanged();
- }
- /// <summary>
- /// 内部使用。由虚拟列表调用。在滚动时修改显示内容的大小,需要进行修正,避免滚动跳跃。
- /// </summary>
- /// <param name="deltaWidth"></param>
- /// <param name="deltaHeight"></param>
- /// <param name="deltaPosX"></param>
- /// <param name="deltaPosY"></param>
- internal void ChangeContentSizeOnScrolling(float deltaWidth, float deltaHeight, float deltaPosX, float deltaPosY)
- {
- bool isRightmost = _xPos == _overlapSize.x;
- bool isBottom = _yPos == _overlapSize.y;
- _contentSize.x += deltaWidth;
- _contentSize.y += deltaHeight;
- HandleSizeChanged();
- if (_tweening == 1)
- {
- //如果原来滚动位置是贴边,加入处理继续贴边。
- if (deltaWidth != 0 && isRightmost && _tweenChange.x < 0)
- {
- _xPos = _overlapSize.x;
- _tweenChange.x = -_xPos - _tweenStart.x;
- }
- if (deltaHeight != 0 && isBottom && _tweenChange.y < 0)
- {
- _yPos = _overlapSize.y;
- _tweenChange.y = -_yPos - _tweenStart.y;
- }
- }
- else if (_tweening == 2)
- {
- //重新调整起始位置,确保能够顺滑滚下去
- if (deltaPosX != 0)
- {
- _container.x -= deltaPosX;
- _tweenStart.x -= deltaPosX;
- _xPos = -_container.x;
- }
- if (deltaPosY != 0)
- {
- _container.y -= deltaPosY;
- _tweenStart.y -= deltaPosY;
- _yPos = -_container.y;
- }
- }
- else if (_dragged)
- {
- if (deltaPosX != 0)
- {
- _container.x -= deltaPosX;
- _containerPos.x -= deltaPosX;
- _xPos = -_container.x;
- }
- if (deltaPosY != 0)
- {
- _container.y -= deltaPosY;
- _containerPos.y -= deltaPosY;
- _yPos = -_container.y;
- }
- }
- else
- {
- //如果原来滚动位置是贴边,加入处理继续贴边。
- if (deltaWidth != 0 && isRightmost)
- {
- _xPos = _overlapSize.x;
- _container.x = -_xPos;
- }
- if (deltaHeight != 0 && isBottom)
- {
- _yPos = _overlapSize.y;
- _container.y = -_yPos;
- }
- }
- if (_pageMode)
- UpdatePageController();
- }
- void HandleSizeChanged()
- {
- if (_displayInDemand)
- {
- _vScrollNone = _contentSize.y <= _viewSize.y;
- _hScrollNone = _contentSize.x <= _viewSize.x;
- if (_vtScrollBar != null && _hzScrollBar != null)
- {
- if (!_hScrollNone)
- _vtScrollBar.height = _owner.height - _hzScrollBar.height - _scrollBarMargin.top - _scrollBarMargin.bottom;
- else
- _vtScrollBar.height = _owner.height - _scrollBarMargin.top - _scrollBarMargin.bottom;
- if (!_vScrollNone)
- _hzScrollBar.width = _owner.width - _vtScrollBar.width - _scrollBarMargin.left - _scrollBarMargin.right;
- else
- _hzScrollBar.width = _owner.width - _scrollBarMargin.left - _scrollBarMargin.right;
- }
- }
- if (_vtScrollBar != null)
- {
- if (_contentSize.y == 0)
- _vtScrollBar.SetDisplayPerc(0);
- else
- _vtScrollBar.SetDisplayPerc(Mathf.Min(1, _viewSize.y / _contentSize.y));
- }
- if (_hzScrollBar != null)
- {
- if (_contentSize.x == 0)
- _hzScrollBar.SetDisplayPerc(0);
- else
- _hzScrollBar.SetDisplayPerc(Mathf.Min(1, _viewSize.x / _contentSize.x));
- }
- UpdateScrollBarVisible();
- if (!_maskDisabled)
- {
- Rect rect = new Rect(-_owner._alignOffset.x, -_owner._alignOffset.y, _viewSize.x, _viewSize.y);
- if (_vScrollNone && _vtScrollBar != null)
- rect.width += _vtScrollBar.width;
- if (_hScrollNone && _hzScrollBar != null)
- rect.height += _hzScrollBar.height;
- if (_dontClipMargin)
- {
- rect.x -= _owner.margin.left;
- rect.width += (_owner.margin.left + _owner.margin.right);
- rect.y -= _owner.margin.top;
- rect.height += (_owner.margin.top + _owner.margin.bottom);
- }
- _maskContainer.clipRect = rect;
- }
- if (_scrollType == ScrollType.Horizontal || _scrollType == ScrollType.Both)
- _overlapSize.x = Mathf.CeilToInt(Math.Max(0, _contentSize.x - _viewSize.x));
- else
- _overlapSize.x = 0;
- if (_scrollType == ScrollType.Vertical || _scrollType == ScrollType.Both)
- _overlapSize.y = Mathf.CeilToInt(Math.Max(0, _contentSize.y - _viewSize.y));
- else
- _overlapSize.y = 0;
- //边界检查
- _xPos = Mathf.Clamp(_xPos, 0, _overlapSize.x);
- _yPos = Mathf.Clamp(_yPos, 0, _overlapSize.y);
- float max = _overlapSize[_refreshBarAxis];
- if (max == 0)
- max = Mathf.Max(_contentSize[_refreshBarAxis] + _footerLockedSize - _viewSize[_refreshBarAxis], 0);
- else
- max += _footerLockedSize;
- if (_refreshBarAxis == 0)
- _container.SetXY(Mathf.Clamp(_container.x, -max, _headerLockedSize), Mathf.Clamp(_container.y, -_overlapSize.y, 0));
- else
- _container.SetXY(Mathf.Clamp(_container.x, -_overlapSize.x, 0), Mathf.Clamp(_container.y, -max, _headerLockedSize));
- if (_header != null)
- {
- if (_refreshBarAxis == 0)
- _header.height = _viewSize.y;
- else
- _header.width = _viewSize.x;
- }
- if (_footer != null)
- {
- if (_refreshBarAxis == 0)
- _footer.height = _viewSize.y;
- else
- _footer.width = _viewSize.x;
- }
- UpdateScrollBarPos();
- if (_pageMode)
- UpdatePageController();
- }
- private void PosChanged(bool ani)
- {
- //只要有1处要求不要缓动,那就不缓动
- if (_aniFlag == 0)
- _aniFlag = ani ? 1 : -1;
- else if (_aniFlag == 1 && !ani)
- _aniFlag = -1;
- _needRefresh = true;
- UpdateContext.OnBegin -= _refreshDelegate;
- UpdateContext.OnBegin += _refreshDelegate;
- }
- private void Refresh()
- {
- _needRefresh = false;
- UpdateContext.OnBegin -= _refreshDelegate;
- if (_owner.displayObject == null || _owner.displayObject.isDisposed)
- return;
- if (_pageMode || _snapToItem)
- {
- Vector2 pos = new Vector2(-_xPos, -_yPos);
- AlignPosition(ref pos, false);
- _xPos = -pos.x;
- _yPos = -pos.y;
- }
- Refresh2();
- _onScroll.Call();
- if (_needRefresh) //在onScroll事件里开发者可能修改位置,这里再刷新一次,避免闪烁
- {
- _needRefresh = false;
- UpdateContext.OnBegin -= _refreshDelegate;
- Refresh2();
- }
- UpdateScrollBarPos();
- _aniFlag = 0;
- }
- void Refresh2()
- {
- if (_aniFlag == 1 && !_dragged)
- {
- Vector2 pos = new Vector2();
- if (_overlapSize.x > 0)
- pos.x = -(int)_xPos;
- else
- {
- if (_container.x != 0)
- _container.x = 0;
- pos.x = 0;
- }
- if (_overlapSize.y > 0)
- pos.y = -(int)_yPos;
- else
- {
- if (_container.y != 0)
- _container.y = 0;
- pos.y = 0;
- }
- if (pos.x != _container.x || pos.y != _container.y)
- {
- _tweenDuration = new Vector2(TWEEN_TIME_GO, TWEEN_TIME_GO);
- _tweenStart = _container.xy;
- _tweenChange = pos - _tweenStart;
- StartTween(1);
- }
- else if (_tweening != 0)
- KillTween();
- }
- else
- {
- if (_tweening != 0)
- KillTween();
- _container.SetXY((int)-_xPos, (int)-_yPos);
- LoopCheckingCurrent();
- }
- if (_pageMode)
- UpdatePageController();
- }
- private void __touchBegin(EventContext context)
- {
- if (!_touchEffect)
- return;
- InputEvent evt = context.inputEvent;
- if (evt.button != 0)
- return;
- context.CaptureTouch();
- Vector2 pt = _owner.GlobalToLocal(evt.position);
- if (_tweening != 0)
- {
- KillTween();
- Stage.inst.CancelClick(evt.touchId);
- //立刻停止惯性滚动,可能位置不对齐,设定这个标志,使touchEnd时归位
- _dragged = true;
- }
- else
- _dragged = false;
- _containerPos = _container.xy;
- _beginTouchPos = _lastTouchPos = pt;
- _lastTouchGlobalPos = evt.position;
- _isHoldAreaDone = false;
- _velocity = Vector2.zero;
- _velocityScale = 1;
- _lastMoveTime = Time.unscaledTime;
- }
- private void __touchMove(EventContext context)
- {
- if (!_touchEffect || draggingPane != null && draggingPane != this || GObject.draggingObject != null) //已经有其他拖动
- return;
- InputEvent evt = context.inputEvent;
- Vector2 pt = _owner.GlobalToLocal(evt.position);
- if (float.IsNaN(pt.x))
- return;
- int sensitivity;
- if (Stage.touchScreen)
- sensitivity = UIConfig.touchScrollSensitivity;
- else
- sensitivity = 8;
- float diff;
- bool sv = false, sh = false;
- if (_scrollType == ScrollType.Vertical)
- {
- if (!_isHoldAreaDone)
- {
- //表示正在监测垂直方向的手势
- _gestureFlag |= 1;
- diff = Mathf.Abs(_beginTouchPos.y - pt.y);
- if (diff < sensitivity)
- return;
- if ((_gestureFlag & 2) != 0) //已经有水平方向的手势在监测,那么我们用严格的方式检查是不是按垂直方向移动,避免冲突
- {
- float diff2 = Mathf.Abs(_beginTouchPos.x - pt.x);
- if (diff < diff2) //不通过则不允许滚动了
- return;
- }
- }
- sv = true;
- }
- else if (_scrollType == ScrollType.Horizontal)
- {
- if (!_isHoldAreaDone)
- {
- _gestureFlag |= 2;
- diff = Mathf.Abs(_beginTouchPos.x - pt.x);
- if (diff < sensitivity)
- return;
- if ((_gestureFlag & 1) != 0)
- {
- float diff2 = Mathf.Abs(_beginTouchPos.y - pt.y);
- if (diff < diff2)
- return;
- }
- }
- sh = true;
- }
- else
- {
- _gestureFlag = 3;
- if (!_isHoldAreaDone)
- {
- diff = Mathf.Abs(_beginTouchPos.y - pt.y);
- if (diff < sensitivity)
- {
- diff = Mathf.Abs(_beginTouchPos.x - pt.x);
- if (diff < sensitivity)
- return;
- }
- }
- sv = sh = true;
- }
- Vector2 newPos = _containerPos + pt - _beginTouchPos;
- newPos.x = (int)newPos.x;
- newPos.y = (int)newPos.y;
- if (sv)
- {
- if (newPos.y > 0)
- {
- if (!_bouncebackEffect)
- _container.y = 0;
- else if (_header != null && _header.maxHeight != 0)
- _container.y = (int)Mathf.Min(newPos.y * 0.5f, _header.maxHeight);
- else
- _container.y = (int)Mathf.Min(newPos.y * 0.5f, _viewSize.y * PULL_RATIO);
- }
- else if (newPos.y < -_overlapSize.y)
- {
- if (!_bouncebackEffect)
- _container.y = -_overlapSize.y;
- else if (_footer != null && _footer.maxHeight > 0)
- _container.y = (int)Mathf.Max((newPos.y + _overlapSize.y) * 0.5f, -_footer.maxHeight) - _overlapSize.y;
- else
- _container.y = (int)Mathf.Max((newPos.y + _overlapSize.y) * 0.5f, -_viewSize.y * PULL_RATIO) - _overlapSize.y;
- }
- else
- _container.y = newPos.y;
- }
- if (sh)
- {
- if (newPos.x > 0)
- {
- if (!_bouncebackEffect)
- _container.x = 0;
- else if (_header != null && _header.maxWidth != 0)
- _container.x = (int)Mathf.Min(newPos.x * 0.5f, _header.maxWidth);
- else
- _container.x = (int)Mathf.Min(newPos.x * 0.5f, _viewSize.x * PULL_RATIO);
- }
- else if (newPos.x < 0 - _overlapSize.x)
- {
- if (!_bouncebackEffect)
- _container.x = -_overlapSize.x;
- else if (_footer != null && _footer.maxWidth > 0)
- _container.x = (int)Mathf.Max((newPos.x + _overlapSize.x) * 0.5f, -_footer.maxWidth) - _overlapSize.x;
- else
- _container.x = (int)Mathf.Max((newPos.x + _overlapSize.x) * 0.5f, -_viewSize.x * PULL_RATIO) - _overlapSize.x;
- }
- else
- _container.x = newPos.x;
- }
- //更新速度
- float deltaTime = Time.unscaledDeltaTime;
- float elapsed = (Time.unscaledTime - _lastMoveTime) * 60 - 1;
- if (elapsed > 1) //速度衰减
- _velocity = _velocity * Mathf.Pow(0.833f, elapsed);
- Vector2 deltaPosition = pt - _lastTouchPos;
- if (!sh)
- deltaPosition.x = 0;
- if (!sv)
- deltaPosition.y = 0;
- _velocity = Vector2.Lerp(_velocity, deltaPosition / deltaTime, deltaTime * 10);
- /*速度计算使用的是本地位移,但在后续的惯性滚动判断中需要用到屏幕位移,所以这里要记录一个位移的比例。
- *后续的处理要使用这个比例但不使用坐标转换的方法的原因是,在曲面UI等异形UI中,还无法简单地进行屏幕坐标和本地坐标的转换。
- */
- Vector2 deltaGlobalPosition = _lastTouchGlobalPos - evt.position;
- if (deltaPosition.x != 0)
- _velocityScale = Mathf.Abs(deltaGlobalPosition.x / deltaPosition.x);
- else if (deltaPosition.y != 0)
- _velocityScale = Mathf.Abs(deltaGlobalPosition.y / deltaPosition.y);
- _lastTouchPos = pt;
- _lastTouchGlobalPos = evt.position;
- _lastMoveTime = Time.unscaledTime;
- //同步更新pos值
- if (_overlapSize.x > 0)
- _xPos = Mathf.Clamp(-_container.x, 0, _overlapSize.x);
- if (_overlapSize.y > 0)
- _yPos = Mathf.Clamp(-_container.y, 0, _overlapSize.y);
- //循环滚动特别检查
- if (_loop != 0)
- {
- newPos = _container.xy;
- if (LoopCheckingCurrent())
- _containerPos += _container.xy - newPos;
- }
- draggingPane = this;
- _isHoldAreaDone = true;
- _dragged = true;
- UpdateScrollBarPos();
- UpdateScrollBarVisible();
- if (_pageMode)
- UpdatePageController();
- _onScroll.Call();
- }
- private void __touchEnd(EventContext context)
- {
- if (draggingPane == this)
- draggingPane = null;
- _gestureFlag = 0;
- if (!_dragged || !_touchEffect)
- {
- _dragged = false;
- return;
- }
- _dragged = false;
- _tweenStart = _container.xy;
- Vector2 endPos = _tweenStart;
- bool flag = false;
- if (_container.x > 0)
- {
- endPos.x = 0;
- flag = true;
- }
- else if (_container.x < -_overlapSize.x)
- {
- endPos.x = -_overlapSize.x;
- flag = true;
- }
- if (_container.y > 0)
- {
- endPos.y = 0;
- flag = true;
- }
- else if (_container.y < -_overlapSize.y)
- {
- endPos.y = -_overlapSize.y;
- flag = true;
- }
- if (flag)
- {
- _tweenChange = endPos - _tweenStart;
- if (_tweenChange.x < -UIConfig.touchDragSensitivity || _tweenChange.y < -UIConfig.touchDragSensitivity)
- DispatchEvent("onPullDownRelease", null);
- else if (_tweenChange.x > UIConfig.touchDragSensitivity || _tweenChange.y > UIConfig.touchDragSensitivity)
- DispatchEvent("onPullUpRelease", null);
- if (_headerLockedSize > 0 && endPos[_refreshBarAxis] == 0)
- {
- endPos[_refreshBarAxis] = _headerLockedSize;
- _tweenChange = endPos - _tweenStart;
- }
- else if (_footerLockedSize > 0 && endPos[_refreshBarAxis] == -_overlapSize[_refreshBarAxis])
- {
- float max = _overlapSize[_refreshBarAxis];
- if (max == 0)
- max = Mathf.Max(_contentSize[_refreshBarAxis] + _footerLockedSize - _viewSize[_refreshBarAxis], 0);
- else
- max += _footerLockedSize;
- endPos[_refreshBarAxis] = -max;
- _tweenChange = endPos - _tweenStart;
- }
- _tweenDuration.Set(TWEEN_TIME_DEFAULT, TWEEN_TIME_DEFAULT);
- }
- else
- {
- //更新速度
- if (!_inertiaDisabled)
- {
- float elapsed = (Time.unscaledTime - _lastMoveTime) * 60 - 1;
- if (elapsed > 1)
- _velocity = _velocity * Mathf.Pow(0.833f, elapsed);
- //根据速度计算目标位置和需要时间
- endPos = UpdateTargetAndDuration(_tweenStart);
- }
- else
- _tweenDuration.Set(TWEEN_TIME_DEFAULT, TWEEN_TIME_DEFAULT);
- Vector2 oldChange = endPos - _tweenStart;
- //调整目标位置
- LoopCheckingTarget(ref endPos);
- if (_pageMode || _snapToItem)
- AlignPosition(ref endPos, true);
- _tweenChange = endPos - _tweenStart;
- if (_tweenChange.x == 0 && _tweenChange.y == 0)
- {
- UpdateScrollBarVisible();
- return;
- }
- //如果目标位置已调整,随之调整需要时间
- if (_pageMode || _snapToItem)
- {
- FixDuration(0, oldChange.x);
- FixDuration(1, oldChange.y);
- }
- }
- StartTween(2);
- }
- private void __mouseWheel(EventContext context)
- {
- if (!_mouseWheelEnabled)
- return;
- InputEvent evt = context.inputEvent;
- float delta = evt.mouseWheelDelta / Stage.devicePixelRatio;
- if (_snapToItem && Mathf.Abs(delta) < 1)
- delta = Mathf.Sign(delta);
- if (_overlapSize.x > 0 && _overlapSize.y == 0)
- {
- float step = _pageMode ? _pageSize.x : _scrollStep;
- SetPosX(_xPos + step * delta, false);
- }
- else
- {
- float step = _pageMode ? _pageSize.y : _scrollStep;
- SetPosY(_yPos + step * delta, false);
- }
- }
- private void __rollOver()
- {
- _hover = true;
- UpdateScrollBarVisible();
- }
- private void __rollOut()
- {
- _hover = false;
- UpdateScrollBarVisible();
- }
- internal void UpdateClipSoft()
- {
- Vector2 softness = _owner.clipSoftness;
- if (softness.x != 0 || softness.y != 0)
- {
- _maskContainer.clipSoftness = new Vector4(
- (_container.x >= 0 || !_softnessOnTopOrLeftSide) ? 0 : softness.x,
- (_container.y >= 0 || !_softnessOnTopOrLeftSide) ? 0 : softness.y,
- (-_container.x - _overlapSize.x >= 0) ? 0 : softness.x,
- (-_container.y - _overlapSize.y >= 0) ? 0 : softness.y);
- }
- else
- _maskContainer.clipSoftness = null;
- }
- private void UpdateScrollBarPos()
- {
- if (_vtScrollBar != null)
- _vtScrollBar.setScrollPerc(_overlapSize.y == 0 ? 0 : Mathf.Clamp(-_container.y, 0, _overlapSize.y) / _overlapSize.y);
- if (_hzScrollBar != null)
- _hzScrollBar.setScrollPerc(_overlapSize.x == 0 ? 0 : Mathf.Clamp(-_container.x, 0, _overlapSize.x) / _overlapSize.x);
- UpdateClipSoft();
- CheckRefreshBar();
- }
- public void UpdateScrollBarVisible()
- {
- if (_vtScrollBar != null)
- {
- if (_viewSize.y <= _vtScrollBar.minSize || _vScrollNone)
- _vtScrollBar.displayObject.visible = false;
- else
- UpdateScrollBarVisible2(_vtScrollBar);
- }
- if (_hzScrollBar != null)
- {
- if (_viewSize.x <= _hzScrollBar.minSize || _hScrollNone)
- _hzScrollBar.displayObject.visible = false;
- else
- UpdateScrollBarVisible2(_hzScrollBar);
- }
- }
- private void UpdateScrollBarVisible2(GScrollBar bar)
- {
- if (_scrollBarDisplayAuto)
- GTween.Kill(bar, TweenPropType.Alpha, false);
- if (_scrollBarDisplayAuto && !_hover && _tweening == 0 && !_dragged && !bar.gripDragging)
- {
- if (bar.displayObject.visible)
- GTween.To(1, 0, 0.5f).SetDelay(0.5f).OnComplete(_hideScrollBarDelegate).SetTarget(bar, TweenPropType.Alpha);
- }
- else
- {
- bar.alpha = 1;
- bar.displayObject.visible = true;
- }
- }
- private void __barTweenComplete(GTweener tweener)
- {
- GObject bar = (GObject)tweener.target;
- bar.alpha = 1;
- bar.displayObject.visible = false;
- }
- float GetLoopPartSize(float division, int axis)
- {
- return (_contentSize[axis] + (axis == 0 ? ((GList)_owner).columnGap : ((GList)_owner).lineGap)) / division;
- }
- /// <summary>
- /// 对当前的滚动位置进行循环滚动边界检查。当到达边界时,回退一半内容区域(循环滚动内容大小通常是真实内容大小的偶数倍)。
- /// </summary>
- /// <returns></returns>
- bool LoopCheckingCurrent()
- {
- bool changed = false;
- if (_loop == 1 && _overlapSize.x > 0)
- {
- if (_xPos < 0.001f)
- {
- _xPos += GetLoopPartSize(2, 0);
- changed = true;
- }
- else if (_xPos >= _overlapSize.x)
- {
- _xPos -= GetLoopPartSize(2, 0);
- changed = true;
- }
- }
- else if (_loop == 2 && _overlapSize.y > 0)
- {
- if (_yPos < 0.001f)
- {
- _yPos += GetLoopPartSize(2, 1);
- changed = true;
- }
- else if (_yPos >= _overlapSize.y)
- {
- _yPos -= GetLoopPartSize(2, 1);
- changed = true;
- }
- }
- if (changed)
- _container.SetXY((int)-_xPos, (int)-_yPos);
- return changed;
- }
- /// <summary>
- /// 对目标位置进行循环滚动边界检查。当到达边界时,回退一半内容区域(循环滚动内容大小通常是真实内容大小的偶数倍)。
- /// </summary>
- /// <param name="endPos"></param>
- void LoopCheckingTarget(ref Vector2 endPos)
- {
- if (_loop == 1)
- LoopCheckingTarget(ref endPos, 0);
- if (_loop == 2)
- LoopCheckingTarget(ref endPos, 1);
- }
- void LoopCheckingTarget(ref Vector2 endPos, int axis)
- {
- if (endPos[axis] > 0)
- {
- float halfSize = GetLoopPartSize(2, axis);
- float tmp = _tweenStart[axis] - halfSize;
- if (tmp <= 0 && tmp >= -_overlapSize[axis])
- {
- endPos[axis] -= halfSize;
- _tweenStart[axis] = tmp;
- }
- }
- else if (endPos[axis] < -_overlapSize[axis])
- {
- float halfSize = GetLoopPartSize(2, axis);
- float tmp = _tweenStart[axis] + halfSize;
- if (tmp <= 0 && tmp >= -_overlapSize[axis])
- {
- endPos[axis] += halfSize;
- _tweenStart[axis] = tmp;
- }
- }
- }
- void LoopCheckingNewPos(ref float value, int axis)
- {
- if (_overlapSize[axis] == 0)
- return;
- float pos = axis == 0 ? _xPos : _yPos;
- bool changed = false;
- if (value < 0.001f)
- {
- value += GetLoopPartSize(2, axis);
- if (value > pos)
- {
- float v = GetLoopPartSize(6, axis);
- v = Mathf.CeilToInt((value - pos) / v) * v;
- pos = Mathf.Clamp(pos + v, 0, _overlapSize[axis]);
- changed = true;
- }
- }
- else if (value >= _overlapSize[axis])
- {
- value -= GetLoopPartSize(2, axis);
- if (value < pos)
- {
- float v = GetLoopPartSize(6, axis);
- v = Mathf.CeilToInt((pos - value) / v) * v;
- pos = Mathf.Clamp(pos - v, 0, _overlapSize[axis]);
- changed = true;
- }
- }
- if (changed)
- {
- if (axis == 0)
- _container.x = -(int)pos;
- else
- _container.y = -(int)pos;
- }
- }
- /// <summary>
- /// 从oldPos滚动至pos,调整pos位置对齐页面、对齐item等(如果需要)。
- /// </summary>
- /// <param name="pos"></param>
- /// <param name="inertialScrolling"></param>
- void AlignPosition(ref Vector2 pos, bool inertialScrolling)
- {
- if (_pageMode)
- {
- pos.x = AlignByPage(pos.x, 0, inertialScrolling);
- pos.y = AlignByPage(pos.y, 1, inertialScrolling);
- }
- else if (_snapToItem)
- {
- float tmpX = -pos.x;
- float tmpY = -pos.y;
- float xDir = 0;
- float yDir = 0;
- if (inertialScrolling)
- {
- xDir = pos.x - _containerPos.x;
- yDir = pos.y - _containerPos.y;
- }
- _owner.GetSnappingPositionWithDir(ref tmpX, ref tmpY, xDir, yDir);
- if (pos.x < 0 && pos.x > -_overlapSize.x)
- pos.x = -tmpX;
- if (pos.y < 0 && pos.y > -_overlapSize.y)
- pos.y = -tmpY;
- }
- }
- /// <summary>
- /// 从oldPos滚动至pos,调整目标位置到对齐页面。
- /// </summary>
- /// <param name="pos"></param>
- /// <param name="axis"></param>
- /// <param name="inertialScrolling"></param>
- /// <returns></returns>
- float AlignByPage(float pos, int axis, bool inertialScrolling)
- {
- int page;
- if (pos > 0)
- page = 0;
- else if (pos < -_overlapSize[axis])
- page = Mathf.CeilToInt(_contentSize[axis] / _pageSize[axis]) - 1;
- else
- {
- page = Mathf.FloorToInt(-pos / _pageSize[axis]);
- float change = inertialScrolling ? (pos - _containerPos[axis]) : (pos - _container.xy[axis]);
- float testPageSize = Mathf.Min(_pageSize[axis], _contentSize[axis] - (page + 1) * _pageSize[axis]);
- float delta = -pos - page * _pageSize[axis];
- //页面吸附策略
- if (Mathf.Abs(change) > _pageSize[axis])//如果滚动距离超过1页,则需要超过页面的一半,才能到更下一页
- {
- if (delta > testPageSize * 0.5f)
- page++;
- }
- else //否则只需要页面的1/3,当然,需要考虑到左移和右移的情况
- {
- if (delta > testPageSize * (change < 0 ? UIConfig.defaultScrollPagingThreshold : (1 - UIConfig.defaultScrollPagingThreshold)))
- page++;
- }
- //重新计算终点
- pos = -page * _pageSize[axis];
- if (pos < -_overlapSize[axis]) //最后一页未必有pageSize那么大
- pos = -_overlapSize[axis];
- }
- //惯性滚动模式下,会增加判断尽量不要滚动超过一页
- if (inertialScrolling)
- {
- float oldPos = _tweenStart[axis];
- int oldPage;
- if (oldPos > 0)
- oldPage = 0;
- else if (oldPos < -_overlapSize[axis])
- oldPage = Mathf.CeilToInt(_contentSize[axis] / _pageSize[axis]) - 1;
- else
- oldPage = Mathf.FloorToInt(-oldPos / _pageSize[axis]);
- int startPage = Mathf.FloorToInt(-_containerPos[axis] / _pageSize[axis]);
- if (Mathf.Abs(page - startPage) > 1 && Mathf.Abs(oldPage - startPage) <= 1)
- {
- if (page > startPage)
- page = startPage + 1;
- else
- page = startPage - 1;
- pos = -page * _pageSize[axis];
- }
- }
- return pos;
- }
- /// <summary>
- /// 根据当前速度,计算滚动的目标位置,以及到达时间。
- /// </summary>
- /// <param name="orignPos"></param>
- /// <returns></returns>
- Vector2 UpdateTargetAndDuration(Vector2 orignPos)
- {
- Vector2 ret = Vector2.zero;
- ret.x = UpdateTargetAndDuration(orignPos.x, 0);
- ret.y = UpdateTargetAndDuration(orignPos.y, 1);
- return ret;
- }
- float UpdateTargetAndDuration(float pos, int axis)
- {
- float v = _velocity[axis];
- float duration = 0;
- if (pos > 0)
- pos = 0;
- else if (pos < -_overlapSize[axis])
- pos = -_overlapSize[axis];
- else
- {
- //以屏幕像素为基准
- float v2 = Mathf.Abs(v) * _velocityScale;
- //在移动设备上,需要对不同分辨率做一个适配,我们的速度判断以1136分辨率为基准
- if (Stage.touchScreen)
- v2 *= 1136f / Mathf.Max(Screen.width, Screen.height);
- //这里有一些阈值的处理,因为在低速内,不希望产生较大的滚动(甚至不滚动)
- float ratio = 0;
- if (_pageMode || !Stage.touchScreen)
- {
- if (v2 > 500)
- ratio = Mathf.Pow((v2 - 500) / 500, 2);
- }
- else
- {
- if (v2 > 1000)
- ratio = Mathf.Pow((v2 - 1000) / 1000, 2);
- }
- if (ratio != 0)
- {
- if (ratio > 1)
- ratio = 1;
- v2 *= ratio;
- v *= ratio;
- _velocity[axis] = v;
- //算法:v*(_decelerationRate的n次幂)= 60,即在n帧后速度降为60(假设每秒60帧)。
- duration = Mathf.Log(60 / v2, _decelerationRate) / 60;
- //计算距离要使用本地速度
- //理论公式貌似滚动的距离不够,改为经验公式
- //float change = (int)((v/ 60 - 1) / (1 - _decelerationRate));
- float change = (int)(v * duration * 0.4f);
- pos += change;
- }
- }
- if (duration < TWEEN_TIME_DEFAULT)
- duration = TWEEN_TIME_DEFAULT;
- _tweenDuration[axis] = duration;
- return pos;
- }
- /// <summary>
- /// 根据修改后的tweenChange重新计算减速时间。
- /// </summary>
- void FixDuration(int axis, float oldChange)
- {
- if (_tweenChange[axis] == 0 || Mathf.Abs(_tweenChange[axis]) >= Mathf.Abs(oldChange))
- return;
- float newDuration = Mathf.Abs(_tweenChange[axis] / oldChange) * _tweenDuration[axis];
- if (newDuration < TWEEN_TIME_DEFAULT)
- newDuration = TWEEN_TIME_DEFAULT;
- _tweenDuration[axis] = newDuration;
- }
- void StartTween(int type)
- {
- _tweenTime.Set(0, 0);
- _tweening = type;
- Timers.inst.AddUpdate(_tweenUpdateDelegate);
- UpdateScrollBarVisible();
- }
- void KillTween()
- {
- if (_tweening == 1) //取消类型为1的tween需立刻设置到终点
- {
- _container.xy = _tweenStart + _tweenChange;
- _onScroll.Call();
- }
- _tweening = 0;
- Timers.inst.Remove(_tweenUpdateDelegate);
- UpdateScrollBarVisible();
- _onScrollEnd.Call();
- }
- void CheckRefreshBar()
- {
- if (_header == null && _footer == null)
- return;
- float pos = _container.xy[_refreshBarAxis];
- if (_header != null)
- {
- if (pos > 0)
- {
- if (_header.displayObject.parent == null)
- _maskContainer.AddChildAt(_header.displayObject, 0);
- Vector2 vec;
- vec = _header.size;
- vec[_refreshBarAxis] = pos;
- _header.size = vec;
- }
- else
- {
- if (_header.displayObject.parent != null)
- _maskContainer.RemoveChild(_header.displayObject);
- }
- }
- if (_footer != null)
- {
- float max = _overlapSize[_refreshBarAxis];
- if (pos < -max || max == 0 && _footerLockedSize > 0)
- {
- if (_footer.displayObject.parent == null)
- _maskContainer.AddChildAt(_footer.displayObject, 0);
- Vector2 vec;
- vec = _footer.xy;
- if (max > 0)
- vec[_refreshBarAxis] = pos + _contentSize[_refreshBarAxis];
- else
- vec[_refreshBarAxis] = Mathf.Max(Mathf.Min(pos + _viewSize[_refreshBarAxis], _viewSize[_refreshBarAxis] - _footerLockedSize), _viewSize[_refreshBarAxis] - _contentSize[_refreshBarAxis]);
- _footer.xy = vec;
- vec = _footer.size;
- if (max > 0)
- vec[_refreshBarAxis] = -max - pos;
- else
- vec[_refreshBarAxis] = _viewSize[_refreshBarAxis] - _footer.xy[_refreshBarAxis];
- _footer.size = vec;
- }
- else
- {
- if (_footer.displayObject.parent != null)
- _maskContainer.RemoveChild(_footer.displayObject);
- }
- }
- }
- void TweenUpdate(object param)
- {
- if (_owner.displayObject == null || _owner.displayObject.isDisposed)
- {
- Timers.inst.Remove(_tweenUpdateDelegate);
- return;
- }
- float nx = RunTween(0);
- float ny = RunTween(1);
- _container.SetXY(nx, ny);
- if (_tweening == 2)
- {
- if (_overlapSize.x > 0)
- _xPos = Mathf.Clamp(-nx, 0, _overlapSize.x);
- if (_overlapSize.y > 0)
- _yPos = Mathf.Clamp(-ny, 0, _overlapSize.y);
- if (_pageMode)
- UpdatePageController();
- }
- if (_tweenChange.x == 0 && _tweenChange.y == 0)
- {
- _tweening = 0;
- Timers.inst.Remove(_tweenUpdateDelegate);
- LoopCheckingCurrent();
- UpdateScrollBarPos();
- UpdateScrollBarVisible();
- _onScroll.Call();
- _onScrollEnd.Call();
- }
- else
- {
- UpdateScrollBarPos();
- _onScroll.Call();
- }
- }
- float RunTween(int axis)
- {
- float newValue;
- if (_tweenChange[axis] != 0)
- {
- _tweenTime[axis] += Time.unscaledDeltaTime;
- if (_tweenTime[axis] >= _tweenDuration[axis])
- {
- newValue = _tweenStart[axis] + _tweenChange[axis];
- _tweenChange[axis] = 0;
- }
- else
- {
- float ratio = EaseFunc(_tweenTime[axis], _tweenDuration[axis]);
- newValue = _tweenStart[axis] + (int)(_tweenChange[axis] * ratio);
- }
- float threshold1 = 0;
- float threshold2 = -_overlapSize[axis];
- if (_headerLockedSize > 0 && _refreshBarAxis == axis)
- threshold1 = _headerLockedSize;
- if (_footerLockedSize > 0 && _refreshBarAxis == axis)
- {
- float max = _overlapSize[_refreshBarAxis];
- if (max == 0)
- max = Mathf.Max(_contentSize[_refreshBarAxis] + _footerLockedSize - _viewSize[_refreshBarAxis], 0);
- else
- max += _footerLockedSize;
- threshold2 = -max;
- }
- if (_tweening == 2 && _bouncebackEffect)
- {
- if (newValue > 20 + threshold1 && _tweenChange[axis] > 0
- || newValue > threshold1 && _tweenChange[axis] == 0)//开始回弹
- {
- _tweenTime[axis] = 0;
- _tweenDuration[axis] = TWEEN_TIME_DEFAULT;
- _tweenChange[axis] = -newValue + threshold1;
- _tweenStart[axis] = newValue;
- }
- else if (newValue < threshold2 - 20 && _tweenChange[axis] < 0
- || newValue < threshold2 && _tweenChange[axis] == 0)//开始回弹
- {
- _tweenTime[axis] = 0;
- _tweenDuration[axis] = TWEEN_TIME_DEFAULT;
- _tweenChange[axis] = threshold2 - newValue;
- _tweenStart[axis] = newValue;
- }
- }
- else
- {
- if (newValue > threshold1)
- {
- newValue = threshold1;
- _tweenChange[axis] = 0;
- }
- else if (newValue < threshold2)
- {
- newValue = threshold2;
- _tweenChange[axis] = 0;
- }
- }
- }
- else
- newValue = _container.xy[axis];
- return newValue;
- }
- static float EaseFunc(float t, float d)
- {
- return (t = t / d - 1) * t * t + 1;//cubicOut
- }
- }
- }
|