CCPoint CCScrollView::getNodeFullyVisibleOffset(CCNode* node) { // get node bound in container CCRect nodeBound = CCRectMake(0, 0, node->getContentSize().width, node->getContentSize().height); CCAffineTransform t = node->nodeToAncestorTransform(getContainer()); nodeBound = CCRectApplyAffineTransform(nodeBound, t); // get offset float scale = getZoomScale(); CCPoint offset = ccp(-nodeBound.origin.x / scale, -nodeBound.origin.y / scale); // clamp offset const CCPoint minOffset = minContainerOffset(); const CCPoint maxOffset = maxContainerOffset(); offset.x = MAX(minOffset.x, MIN(maxOffset.x, offset.x)); offset.y = MAX(minOffset.y, MIN(maxOffset.y, offset.y)); // return return offset; }
void ScrollView::onTouchMoved(Touch* touch, Event* event) { if (!this->isVisible()) { return; } if (std::find(_touches.begin(), _touches.end(), touch) != _touches.end()) { if (_touches.size() == 1 && _dragging) { // scrolling Vec2 moveDistance, newPoint; Rect frame; float newX, newY; frame = getViewRect(); newPoint = this->convertTouchToNodeSpace(_touches[0]); moveDistance = newPoint - _touchPoint; float dis = 0.0f; if (_direction == Direction::VERTICAL) { dis = moveDistance.y; float pos = _container->getPosition().y; if (!(minContainerOffset().y <= pos && pos <= maxContainerOffset().y)) { moveDistance.y *= BOUNCE_BACK_FACTOR; } } else if (_direction == Direction::HORIZONTAL) { dis = moveDistance.x; float pos = _container->getPosition().x; if (!(minContainerOffset().x <= pos && pos <= maxContainerOffset().x)) { moveDistance.x *= BOUNCE_BACK_FACTOR; } } else { dis = sqrtf(moveDistance.x*moveDistance.x + moveDistance.y*moveDistance.y); float pos = _container->getPosition().y; if (!(minContainerOffset().y <= pos && pos <= maxContainerOffset().y)) { moveDistance.y *= BOUNCE_BACK_FACTOR; } pos = _container->getPosition().x; if (!(minContainerOffset().x <= pos && pos <= maxContainerOffset().x)) { moveDistance.x *= BOUNCE_BACK_FACTOR; } } if (!_touchMoved && fabs(convertDistanceFromPointToInch(dis)) < MOVE_INCH ) { //CCLOG("Invalid movement, distance = [%f, %f], disInch = %f", moveDistance.x, moveDistance.y); return; } if (!_touchMoved) { moveDistance = Vec2::ZERO; } _touchPoint = newPoint; _touchMoved = true; if (_dragging) { switch (_direction) { case Direction::VERTICAL: moveDistance = Vec2(0.0f, moveDistance.y); break; case Direction::HORIZONTAL: moveDistance = Vec2(moveDistance.x, 0.0f); break; default: break; } newX = _container->getPosition().x + moveDistance.x; newY = _container->getPosition().y + moveDistance.y; _scrollDistance = moveDistance; this->setContentOffset(Vec2(newX, newY)); } } else if (_touches.size() == 2 && !_dragging) { const float len = _container->convertTouchToNodeSpace(_touches[0]).getDistance( _container->convertTouchToNodeSpace(_touches[1])); this->setZoomScale(this->getZoomScale()*len/_touchLength); } } }