码迷,mamicode.com
首页 > 其他好文 > 详细

juce动画演示分析

时间:2015-01-01 17:15:02      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:

//特别说明:只是源码进行阅读,希望能有用,我没有做总结,不过后边会陆续更改,要不然太费时间。
#include "../JuceDemoHeader.h"
//==============================================================================
/** This will be the source of our balls and can be dragged around. */
//所有的自定义控件都从component继承
class BallGeneratorComponent    : public Component
{
public:
    BallGeneratorComponent()
    {
    }
    //控件的绘制
    void paint (Graphicsgoverride
    {
        Rectangle<floatarea (getLocalBounds().toFloat().reduced (2.0f));
        g.setColour (Colours::orange);
        g.drawRoundedRectangle (area, 10.0f, 2.0f);
        AttributedString s;
        s.setJustification (Justification::centred);
        s.setWordWrap (AttributedString::none);
        s.append (L"拖动!");
        s.setColour (Colours::white);
        s.draw (garea);
    }

    void resized() override
    {
          //更新拖动限制区域。
        // Just set the limits of our constrainer so that we don‘t drag ourselves off the screen
        constrainer.setMinimumOnscreenAmounts (getHeight(), getWidth(), getHeight(), getWidth());
    }
    void mouseDown (const MouseEventeoverride
    {
        // Prepares our dragger to drag this Component
        dragger.startDraggingComponent (thise);
    }
    void mouseDrag (const MouseEventeoverride
    {
        // Moves this Component according to the mouse drag event and applies our constraints to it
        dragger.dragComponent (thise, &constrainer);
    }
private:
    ComponentBoundsConstrainer constrainer;//创建这个变量是因为dragger需要这样一个参数,当然,可以试试null是什么效果,结果当然是拖出边框。
    ComponentDragger dragger;//dragger的使用模板
  1. e.g. @code
  2. class MyDraggableComp
  3. {
  4. ComponentDragger myDragger;
  5. void mouseDown (const MouseEvent& e)
  6. {
  7. myDragger.startDraggingComponent (this, e);
  8. }
  9. void mouseDrag (const MouseEvent& e)
  10. {
  11. myDragger.dragComponent (this, e, nullptr);
  12. }
  13. };
  14. @endcode
//具体实现代码
  1. ComponentDragger::ComponentDragger() {}
  2. ComponentDragger::~ComponentDragger() {}
  3. //==============================================================================
  4. void ComponentDragger::startDraggingComponent (Component* const componentToDrag, const MouseEvent& e)
  5. {
  6. jassert (componentToDrag != nullptr);
  7. jassert (e.mods.isAnyMouseButtonDown()); // The event has to be a drag event!
  8. if (componentToDrag != nullptr)
  9. mouseDownWithinTarget = e.getEventRelativeTo (componentToDrag).getMouseDownPosition();
  10. //记录鼠标在控件中的位置
  11. }
  12. void ComponentDragger::dragComponent (Component* const componentToDrag, const MouseEvent& e,
  13. ComponentBoundsConstrainer* const constrainer)
  14. {
  15. jassert (componentToDrag != nullptr);
  16. jassert (e.mods.isAnyMouseButtonDown()); // The event has to be a drag event!
  17. if (componentToDrag != nullptr)
  18. {
  19. Rectangle<int> bounds (componentToDrag->getBounds());
  20. // If the component is a window, multiple mouse events can get queued while it‘s in the same position,
  21. // so their coordinates become wrong after the first one moves the window, so in that case, we‘ll use
  22. // the current mouse position instead of the one that the event contains...
  23. //其实就是改变控件的位置
  24. if (componentToDrag->isOnDesktop())
  25. bounds += componentToDrag->getLocalPoint (nullptr, e.source.getScreenPosition()).roundToInt() - mouseDownWithinTarget;
  26. else
  27. bounds += e.getEventRelativeTo (componentToDrag).getPosition() - mouseDownWithinTarget;
  28. if (constrainer != nullptr)
  29. constrainer->setBoundsForComponent (componentToDrag, bounds, false, false, false, false);
  30. else
  31. componentToDrag->setBounds (bounds);
  32. }
  33. }

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BallGeneratorComponent)
};
//==============================================================================
//小球组件
struct BallComponent  : public Component
    //位置、大小、颜色,移动速度,当然还可以扩展其它的属性
    BallComponent (const Point<float>& pos)
        : position (pos),
          speed (Random::getSystemRandom().nextFloat() *  4.0f - 2.0f,
                 Random::getSystemRandom().nextFloat() * -6.0f - 2.0f),
            colour (Colours::white)
    {
        setSize (20, 20);
        step();
    }
    bool step()
    {
        position += speed;
        speed.y += 0.1f;
        //这里改变了小球的位置
        setCentrePosition ((intposition.x,
                           (intposition.y);
       
       //同时判断小球是否超出来范围
        if (Componentparent = getParentComponent())
            return isPositiveAndBelow (position.x, (floatparent->getWidth()) && position.y < (floatparent->getHeight();
        
            return position.y < 400.0f && position.x >= -10.0f;
    }
    
    //绘制小球
    void paint (Graphicsg)
    {
        g.setColour (colour);
        g.fillEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f);
        g.setColour (Colours::darkgrey);
        g.drawEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, 1.0f);
    }

    Point<floatpositionspeed;
    Colour colour;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BallComponent)
};
//==============================================================================
class AnimationDemo  : public Component,
                       private Button::Listener,
                       private Timer
{
public:
    AnimationDemo()
    {
        setOpaque (true);
        setSize (620, 620);
        //添加11个按扭
        for (int i = 11; --i >= 0;)
        {
            Buttonb = createButton();
            componentsToAnimate.add (b);
            addAndMakeVisible (b);
            b->addListener (this);
        }
       
       //添加小球发生器
        addAndMakeVisible (ballGenerator);
        //初始位置居于父容器中部,设置大小为80,50
        ballGenerator.centreWithSize (80, 50);

        cycleCount = 2;
        for (int i = 0; i < componentsToAnimate.size(); ++i)
            componentsToAnimate.getUnchecked (i)->setBounds (getLocalBounds().reduced (250, 250));

       //说明,由于这里并没有进行多线程的控制,所以这里使用getUnchecked

        for (int i = 0; i < componentsToAnimate.size(); ++i)
        {
            const int newIndex = (i + 3) % componentsToAnimate.size();
            const float angle = newIndex * 2.0f * float_Pi / componentsToAnimate.size();
            const float radius = getWidth() * 0.35f;
            Rectangle<intr (getWidth()  / 2 + (int) (radius * std::sin (angle)) - 50,
                              getHeight() / 2 + (int) (radius * std::cos (angle)) - 50,
                              100, 100);

            //下边这个是如何动作的呢?这个地方东西有点多,留到下边文章分析,大体也就是从什么地方移动什么地方,同时改变属性
            animator.animateComponent (componentsToAnimate.getUnchecked(i),
                                       r.reduced (10),
                                       1.0f,
                                       500 + i * 100,
                                       false,
                                       0.0,
                                       0.0);
        }

        startTimerHz (60);
    }

    //填充背景颜色
    void paint (Graphicsgoverride
    {
        fillTiledBackground (g);
    }
private:
    OwnedArray<Component> componentsToAnimate;
    OwnedArray<BallComponentballs;
    BallGeneratorComponent ballGenerator;
    ComponentAnimator animator;
    int cycleCount;
    ButtoncreateRandomButton()
    {
        DrawablePath normalover;
        Path star1;
        star1.addStar (Point<float>(), 5, 20.0f, 50.0f, 0.2f);
        normal.setPath (star1);
        normal.setFill (Colours::red);
        Path star2;
        star2.addStar (Point<float>(), 7, 30.0f, 50.0f, 0.0f);
        over.setPath (star2);
        over.setFill (Colours::pink);
        over.setStrokeFill (Colours::black);
        over.setStrokeThickness (5.0f);
        //BinaryData这个应当是使用juce提供的工具生成的,具体我也没试过。
        Image juceIcon = ImageCache::getFromMemory (BinaryData::juce_icon_png,
                                                    BinaryData::juce_icon_pngSize);
        DrawableImage down;
        down.setImage (juceIcon);
        down.setOverlayColour (Colours::black.withAlpha (0.3f));
        if (Random::getSystemRandom().nextInt (10) > 2)
        {
            int type = Random::getSystemRandom().nextInt (3);
            DrawableButtond = new DrawableButton ("Button",
                                                    type == 0 ? DrawableButton::ImageOnButtonBackground
                                                              : (type == 1 ? DrawableButton::ImageFitted
                                                                           : DrawableButton::ImageAboveTextLabel));
            d->setImages (&normal,
                          Random::getSystemRandom().nextBool() ? &over : nullptr,
                          Random::getSystemRandom().nextBool() ? &down : nullptr);
            if (Random::getSystemRandom().nextBool())
            {
                d->setColour (DrawableButton::backgroundColourIdgetRandomBrightColour());
                d->setColour (DrawableButton::backgroundOnColourIdgetRandomBrightColour());
            }
            d->setClickingTogglesState (Random::getSystemRandom().nextBool());
            return d;
        }
        ImageButtonb = new ImageButton ("ImageButton");
        b->setImages (truetruetrue,
                      juceIcon, 0.7f, Colours::transparentBlack,
                      juceIcon, 1.0f, getRandomDarkColour().withAlpha (0.2f),
                      juceIcon, 1.0f, getRandomBrightColour().withAlpha (0.8f),
                      0.5f);
        return b;
    }

    ButtoncreateButton()
    {
        Image juceIcon = ImageCache::getFromMemory (BinaryData::juce_icon_png,
                                                    BinaryData::juce_icon_pngSize);
        ImageButtonb = new ImageButton ("ImageButton");
        b->setImages (truetruetrue,
                      juceIcon, 1.0f, Colours::transparentBlack,
                      juceIcon, 1.0f, Colours::white,
                      juceIcon, 1.0f, Colours::white,
                      0.5f);
        return b;
    }

    void buttonClicked (Button*) override
    {
        //如果是点击的话,那么重新移动
        for (int i = 0; i < componentsToAnimate.size(); ++i)
        {
            const int newIndex = (i + 3 * cycleCount) % componentsToAnimate.size();
            const float angle = newIndex * 2.0f * float_Pi / componentsToAnimate.size();
            const float radius = getWidth() * 0.35f;
            Rectangle<intr (getWidth()  / 2 + (int) (radius * std::sin (angle)) - 50,
                              getHeight() / 2 + (int) (radius * std::cos (angle)) - 50,
                              100, 100);
            animator.animateComponent (componentsToAnimate.getUnchecked(i),
                                       r.reduced (10),
                                       1.0f,
                                       900 + (int) (300 * std::sin (angle)),
                                       false,
                                       0.0,
                                       0.0);
        }
        ++cycleCount;
    }

    void timerCallback() override
    {
        //此这个方移动小球的位置
        // Go through each of our balls and update their position
        for (int i = balls.size(); --i >= 0;)
            if (! balls.getUnchecked(i)->step())
                balls.remove (i);
        // Randomly generate new balls
        if (Random::getSystemRandom().nextInt (100) < 4)
        {
            BallComponentball = new BallComponent (ballGenerator.getBounds().getCentre().toFloat());
            addAndMakeVisible (ball);
            balls.add (ball);
        }
    }
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnimationDemo)
};
// This static object will register this demo type in a global list of demos..
static JuceDemoType<AnimationDemodemo (L"10 动画演示");




juce动画演示分析

标签:

原文地址:http://www.cnblogs.com/crax/p/4197361.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!