の cocos2dx life from scratch (X) ScrollView

Brief introduction

scrollView is within a visible range by a method of scrolling to see a wider range of the visual range of the view on the rolling container binding.

There are two limits container, a container is offset, to a length extending resilient set.

Underlying variable

ScrollViewDelegate

Setting delegate function instance, inheritance and override the following methods, you can use the callback function when scrolling and zooming

virtual void scrollViewDidScroll(ScrollView* view) {}; virtual void scrollViewDidZoom(ScrollView* view) {};
//使用
scrollView->setDelegate(this);   ///<添加委托
virtual void scrollViewDidScroll(ScrollView* view) { /* */ }

Direction

Set the scroll direction

enum class Direction
    {
        NONE = -1, HORIZONTAL = 0, VERTICAL, BOTH };

_dragging

Whether you begin dragging flag, when onTouchBegan will be set to true, indicates the start of the drag, set to false in onTouchEnded, onTouchCancelled in

_container

All contents as a child scrollView, storage display, scroll box scroll view is scrolling in the above. Inset

and inset into _minInset _maxInset, if the setting is provided to the rebound boundary offset plus 20% of the visible range

_touchMoved

Mark being dragged flag is set to true when onTouchMoved, set to false in onTouchEnded, onTouchCancelled in

_bounceable

Rebound, the default is set to true in the initialization, refers to the border after the slide in the container, we will continue to slide length and finally back to playing an effect at the boundary.

_touchLength

Used to calculate the distance between two touch points, it will be converted into scaled multiples

method

create

You can set the time to create a good set good container as a parameter, the binding container to scroll the view, and then call initWithViewSize method to initialize the scroll view

initWithViewSize

When calling initialization

If no incoming parameters will create a container

setContentSize

This method is mainly to set the size of the container, but also set the size of the Inset, before calling setContentSize, minInset and maxInset are 0, is not set, setContentSize calls updateInset method for minInset and maxInset been set, so back bombs can be carried out, so that deaccelerateScrolling can get the correct value.

void ScrollView::setContentSize(const Size & size)
{
    if (this->getContainer() != nullptr) { this->getContainer()->setContentSize(size); this->updateInset(); } }
void ScrollView::updateInset()
{
    if (this->getContainer() != nullptr)
    {
      _maxInset = this->maxContainerOffset(); _maxInset.set(_maxInset.x + _viewSize.width * INSET_RATIO, _maxInset.y + _viewSize.height * INSET_RATIO); _minInset = this->minContainerOffset(); _minInset.set(_minInset.x - _viewSize.width * INSET_RATIO, _minInset.y - _viewSize.height * INSET_RATIO); } }

deaccelerateScrolling

In onTouchEnded will call this method to achieve thrown effect. OnTouchMoved provided in the scrollDistance parameters, let go of the previous frame means that the distance moved by the touch point, each time the current position of the container will update plus scrollDisdtance position, then the distance is multiplied by a parameter to make it smaller, to achieve thrown gradual deceleration effect.

void ScrollView::deaccelerateScrolling(float /*dt*/)
{
    if (_dragging)
    {
        this->unschedule(CC_SCHEDULE_SELECTOR(ScrollView::deaccelerateScrolling)); return; } float newX, newY; Vec2 maxInset, minInset; //设置容器的位置 _container->setPosition(_container->getPosition() + _scrollDistance); //有回弹就使用延伸出去的距离 if (_bounceable) { maxInset = _maxInset; minInset = _minInset; } //没有回弹就是用最大偏移的距离 else { maxInset = this->maxContainerOffset(); minInset = this->minContainerOffset(); } newX = _container->getPosition().x; newY = _container->getPosition().y; //逐渐缩小 _scrollDistance = _scrollDistance * SCROLL_DEACCEL_RATE; this->setContentOffset(Vec2(newX,newY)); //减速并回弹至设定最大偏移处 //移动是否小于预定值 //位置是否超出设定的延伸量 if ((fabsf(_scrollDistance.x) <= SCROLL_DEACCEL_DIST && fabsf(_scrollDistance.y) <= SCROLL_DEACCEL_DIST) || ((_direction == Direction::BOTH || _direction == Direction::VERTICAL) && (newY >= maxInset.y || newY <= minInset.y)) || ((_direction == Direction::BOTH || _direction == Direction::HORIZONTAL) && (newX >= maxInset.x || newX <= minInset.x))) { //取消每帧减速刷新 this->unschedule(CC_SCHEDULE_SELECTOR(ScrollView::deaccelerateScrolling)); //重新设置容器的偏移 this->relocateContainer(true); } }

maxContainerOffset 和 minContainerOffset

Code anchors and anchor ignored the impact of container in some places re-set, but no matter how set its anchor point is (0, 0).

So you can always know maxContainerOffset are (0, 0), unless it is again set.

Here are some easy to understand, the largest container offset refers to the fact that the finger (mouse) Hold down the slide to the right, container offset relative to the left edge of the left border of view.

For minContainerOffset container is also offset with respect to the left edge of the left edge of the view, which is a negative value, the code is run from viewSize - size of the container.

Slide left is minContainerOffset

Slide to the right is maxContainerOffset

Various stages of touch

onTouchBegan

Region 1, claim touch point is one or two, not moving, is contained in the view

2, if not added touches the array, it is added to the list for later use determines the touch point number

3, if a single touch touchMoved set to false, dragging is set to true, scrollDistance set to 0, touchLength set to 0

4, if the zoom points, records midpoint distance between two points and two points at the initial state

onTouchMoved

Single-touch

1, acquires a moving distance of the touch point of the frame

2, for three different drag direction, a drag distance exceeds a determined offset range

3, if the length is less than the first set and touchMoved value returned directly

4, if it is the first time touchMoved will moveDistance set to 0, the impact is moved to the movement of the first frame 0, actually can not see

5, record a new touch point, touchMoved set to true

6, three different drag direction, moving distance are provided

7, set the new offset movement

Two Zoom

1, to obtain the distance between the current two

2, with the current zoomScale * current distance between two points at the beginning points obtained from the set of scaling parameters / proceeds to the setZoomScale

setZoomScale

1, obtaining the midpoint of the current two touch points, the touch if the length is zero, the midpoint is the midpoint of the visible region, for the two touch points at the midpoints

2、

//在缩放前将触摸点中点坐标转换到节点坐标系
oldCenter = _container->convertToNodeSpace(center);
//执行缩放
 _container->setScale(MAX(_minScale, MIN(_maxScale, s)));
//因为是按照(0,0)点缩放的,原来的触摸中点会发生改变,这个时候重新转换触摸中点的位置到世界坐标系
newCenter = _container->convertToWorldSpace(oldCenter);

3, the difference between before and after the touch point calculated scaling midpoint, as an offset

4, use of the container plus an offset position of new offset as a container

onTouchEnded

With the use of accelerateScrolling, each touch end calls accelerateScrolling thrown to achieve results.

Guess you like

Origin www.cnblogs.com/douyins/p/12117812.html