放大镜实现代码3

#ifndef Magnifier_h

#define Magnifier_h


#include "cocos2d.h"

#include "STMacro.h"

#include "STFilter.h"

#include "STTouchableSprite.h"


NS_ST_BEGIN


USING_NS_CC;

using namespace std;



/**

 放大镜

 */

class STMagnifier : public Node

{


    STFilter *m_pFilter;

    STTouchableSprite *m_handShank;

    

public:

    

    /**

     使用图片路径来初始化

     @param handShank 放大镜手柄

     @param stencil   透视图片

     @param content   放大查看的图片

     */

    static STMagnifier * create(STTouchableSprite *handShank,Sprite *stencil, Sprite *content);

    

    /**

     使用图片路径来初始化

     @param handShank 手柄图片路径

     @param stencil   透视图片路径

     @param content   放大查看的图片路径

     */

    static STMagnifier * createWithPath(const string &handShankPath,const string &stencilPath, const string &contentPath);

    

    /**

     使用图片Frame名称来初始化

     @param handShank 手柄图片Frame名称

     @param stencil   透视图片Frame名称

     @param content   放大查看的图片Frame名称

     */

    static STMagnifier * createWithFrameName(const string &handShankName,const string &stencilName, const string &contentName);

    

    /*

     屏幕快照

     */

    static Sprite* snapshot();

    

public:

    /*

     设置放大倍数

     */

    void setZoomSize(float size);

    

    /*

     获取手柄,用于设置手柄坐标

     */

    STTouchableSprite* getHandShank();

    

    /*

     设置放大镜坐标

     */

    void setMagnifierPosition(const Vec2 &pos);

    

protected:

    

    STMagnifier();

    

    virtual ~STMagnifier();

    

    virtual bool init(STTouchableSprite *handShank,Sprite *stencil, Sprite *content);

    

    virtual bool initWithPath(const string &handShankPath,const string &stencilPath, const string &contentPath);

    

    virtual bool initWithFrameName(const string &handShankName,const string &stencilName, const string &contentName);

    

    

private:

    /*

     移动放大镜

     */

    void moveMagnifier(const Vec2 &delta);

    

    /*

     获取放大区域在屏幕的百分比[0,1]

     */

    Vec2 getZoomPosition();

};


/*

 //手柄

 auto hanshank = STTouchableSprite::createWithSpriteFrameName("stencil.png");

 //镂空区域

 auto stencil = Sprite::createWithSpriteFrameName("stencil.png");

 //放大查看的内容

 //auto content = Sprite::create("Levels/Level1/level1_body_3.jpg");

 auto content = STMagnifier::snapshot();

 //放大镜

 auto magnifier = STMagnifier::create(hanshank,stencil, content);

 

 //this->addToUILayer(magnifier,kPop);

 this->addChild(magnifier,kPop);

 

 //设置放大倍数

 magnifier->setZoomSize(2);

 //调整手柄坐标

 magnifier->getHandShank()->setAnchorPoint(Vec2(0.5f, 0.5f));

 // 设置初始坐标

 magnifier->setMagnifierPosition(Vec2(200, 200));

 */

NS_ST_END


#endif /* Magnifier_hpp */


#include "STMagnifier.h"

#include "VisibleRect.h"



USING_NS_ST;


STMagnifier * STMagnifier::create(STTouchableSprite *handShank,Sprite *stencil, Sprite *content)

{

    auto node = new (std::nothrow) STMagnifier();

    if ( node && node->init(handShank,stencil, content) )

    {

        node->autorelease();

        return node;

    }

    

    CC_SAFE_DELETE(node);

    return nullptr;

}



STMagnifier * STMagnifier::createWithPath(const string &handShankPath,const std::string &stencilPath, const std::string &contentPath)

{

    auto node = new (std::nothrow) STMagnifier();

    if ( node && node->initWithPath(handShankPath,stencilPath, contentPath) )

    {

        node->autorelease();

        return node;

    }

    

    CC_SAFE_DELETE(node);

    return nullptr;

}


STMagnifier * STMagnifier::createWithFrameName(const string &handShankName,const std::string &stencilName, const std::string &contentName)

{

    auto node = new (std::nothrow) STMagnifier();

    if ( node && node->initWithFrameName(handShankName,stencilName, contentName) )

    {

        node->autorelease();

        return node;

    }

    

    CC_SAFE_DELETE(node);

    return nullptr;

}


STMagnifier::STMagnifier()

: m_pFilter(nullptr)

, m_handShank(nullptr)

{

    

}


STMagnifier::~STMagnifier()

{

    

}


bool STMagnifier::init(STTouchableSprite *handShank,Sprite *stencil, Sprite *content)

{

    bool bRet = false;

    

    do

    {

        CC_BREAK_IF(!handShank);

        

        CC_BREAK_IF(!stencil);

        

        CC_BREAK_IF(!content);

        

        CC_BREAK_IF( !Node::init() );


        m_pFilter = STFilter::create(stencil, content);

        

        CC_BREAK_IF( !m_pFilter);

        

        m_pFilter->setLimitedInScreen(false);

        

        this->addChild(m_pFilter);

        

        m_handShank = handShank;

        

        this->addChild(m_handShank);

        

        this->setZoomSize(2);

        

        m_handShank->setPosition(VisibleRect::center());

        

        m_handShank->

        setTouchEnable(// began

                       [this](Touch *touch, Event *event)

                       {

                           auto node = event->getCurrentTarget();

                           

                           if ( node->isVisible() )

                           {

                               Rect _rect = Rect(0,0,node->getContentSize().width,node->getContentSize().height);

                               _rect = RectApplyTransform(_rect,node->getNodeToWorldTransform());


                               if ( _rect.containsPoint(touch->getLocation()) )

                               {

                                   return true;

                               }

                           }

                           

                           return false;

                       },

                       

                       // move

                       [this](Touch *touch, Event *event)

                       {

                           if ( !m_handShank->isVisible() )

                               return;

                           

                           this->moveMagnifier(touch->getDelta());

                       }

                       

                       );

        

        // 屏蔽事件

        auto touchListener = EventListenerTouchOneByOne::create();

        touchListener->setSwallowTouches(true);

        touchListener->onTouchBegan = [this](Touch*, Event*)

        {

            return true;

        };

        

        _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);


        bRet = true;

        

    } while (false);

    

    return bRet;

}


bool STMagnifier::initWithPath(const string &handShankPath,const std::string &stencilPath, const std::string &contentPath)

{

    auto handShank = STTouchableSprite::create(handShankPath);

    

    if (!handShank)

        return false;


    

    auto stencil = Sprite::create(stencilPath);

    

    if (!stencil)

        return false;

    

    auto content = Sprite::create(contentPath);

    

    if (!content)

        return false;

    

    return init(handShank,stencil, content);

}


bool STMagnifier::initWithFrameName(const string &handShankName,const std::string &stencilName, const std::string &contentName)

{

    auto handShank = STTouchableSprite::createWithSpriteFrameName(handShankName);

    

    if (!handShank)

        return false;

    

    auto stencil = Sprite::createWithSpriteFrameName(stencilName);

    

    if (!stencil)

        return false;

    

    auto content = Sprite::createWithSpriteFrameName(contentName);

    

    if (!content)

        return false;

    

    return init(handShank,stencil, content);

}


Sprite* STMagnifier::snapshot()

{

    Sprite *screenCotent = nullptr;

    

    auto pRender = RenderTexture::create(VisibleRect::getVisibleRect().size.width, VisibleRect::getVisibleRect().size.height);

    

    pRender->begin();

    

    Director::getInstance()->getRunningScene()->visit();

    

    pRender->end();

    

    Director::getInstance()->getRenderer()->render();

    

    pRender->getSprite()->getTexture()->setAliasTexParameters();


    Image* image = pRender->newImage();

    

    Texture2D* texture = new Texture2D();

    

    if( texture && texture->initWithImage(image) )

    {

        screenCotent = Sprite::createWithTexture(texture);

    }

    

    // clean

    CC_SAFE_RELEASE(image);

    CC_SAFE_RELEASE(texture);

    

    return screenCotent;

}


void STMagnifier::setZoomSize(float size)

{

    m_pFilter->getContent()->setScale(size);

}


STTouchableSprite* STMagnifier::getHandShank()

{

    return this->m_handShank;

}


void STMagnifier::setMagnifierPosition(const Vec2 &pos)

{

    Vec2 delta = pos - m_handShank->getPosition();

    

    m_handShank->setPosition(pos);

    m_pFilter->move(delta);


    //before

    Vec2 anchpoint1 = this->m_pFilter->getContent()->getAnchorPoint();

    Vec2 pos1 = this->m_pFilter->getContent()->getPosition();

    Size size = this->m_pFilter->getContent()->getContentSize();

    

    //after

    Vec2 anchpoint2 = this->getZoomPosition();

    Vec2 pos2;

    

    pos2.x = pos1.x +(anchpoint2.x - anchpoint1.x) * size.width;

    pos2.y = pos1.y +(anchpoint2.y - anchpoint1.y) * size.height;

    

    m_pFilter->getContent()->setAnchorPoint(anchpoint2);

    m_pFilter->getContent()->setPosition(pos2);


}


void STMagnifier::moveMagnifier(const Vec2 &delta)

{

    Vec2 pos = m_handShank->getPosition() + delta;

    

    this->setMagnifierPosition(pos);

}


Vec2 STMagnifier::getZoomPosition()

{

    Vec2 pos = m_pFilter->getClippingNode()->convertToWorldSpace(m_pFilter->getStencil()->getPosition());

    

    return Vec2(pos.x/VisibleRect::getVisibleRect().size.width, pos.y/VisibleRect::getVisibleRect().size.height);

}


转载于:https://my.oschina.net/yizhangxyz/blog/657939

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值