• 风火轮 –动画效果:擦除、形状、轮子、随机线条、翻转远近、缩放、旋转、弹跳效果


    今天再花了一个白天时间,把PPT动画的进入效果全部实现。

    1. 浮入效果

    头文件

    class TCbwAnimationEffect_Erase : public TCbwAnimationEffect { // 擦除

        virtual void __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

            TRect displayRect);

    public:

        __fastcall TCbwAnimationEffect_Erase();

        static TCbwAnimationEffect * Build();

    };

    class TCbwAnimationEffect_Shape : public TCbwAnimationEffect { // 形状

        virtual void __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

            TRect displayRect);

    public:

        __fastcall TCbwAnimationEffect_Shape();

        static TCbwAnimationEffect * Build();

    };

    class TCbwAnimationEffect_Wheel : public TCbwAnimationEffect { // 轮子

        virtual void __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

            TRect displayRect);

    public:

        __fastcall TCbwAnimationEffect_Wheel();

        static TCbwAnimationEffect * Build();

    };

    class TCbwAnimationEffect_RandomLine : public TCbwAnimationEffect { // 随机线

        virtual void __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat,

            TRect displayRect);

        BYTE * FOccurredLines;

    public:

        __fastcall TCbwAnimationEffect_RandomLine();

        static TCbwAnimationEffect * Build();

    };

    class TCbwAnimationEffect_RotateToNear : public TCbwAnimationEffect_SameMask

    { // 翻转式由远及近

        virtual void __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat,

            TRect displayRect);

    public:

        __fastcall TCbwAnimationEffect_RotateToNear();

        static TCbwAnimationEffect * Build();

    };

    class TCbwAnimationEffect_Zoom : public TCbwAnimationEffect_SameMask { // 缩放

        virtual void __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat,

            TRect displayRect);

    public:

        __fastcall TCbwAnimationEffect_Zoom();

        static TCbwAnimationEffect * Build();

    };

    class TCbwAnimationEffect_Rotate : public TCbwAnimationEffect_SameMask { // 旋转

        virtual void __fastcall BuildDisplayMat(cv::Mat& destMat, cv::Mat& srcMat,

            TRect displayRect);

    public:

        __fastcall TCbwAnimationEffect_Rotate();

        static TCbwAnimationEffect * Build();

    };

    class TCbwAnimationEffect_Bounce : public TCbwAnimationEffect { // 随机线

        virtual TRect __fastcall BuildDisplayRect(OBJECTMAT * m);

    public:

        __fastcall TCbwAnimationEffect_Bounce();

        static TCbwAnimationEffect * Build();

    };

    实现:

    // ***************************** 擦除效果 **************************************

    __fastcall TCbwAnimationEffect_Erase::TCbwAnimationEffect_Erase()

        : TCbwAnimationEffect() {

        EffectType = cetErase;

    }

    TCbwAnimationEffect * TCbwAnimationEffect_Erase::Build() {

        return new TCbwAnimationEffect_Erase;

    }

    void __fastcall TCbwAnimationEffect_Erase::BuildMaskMat(cv::Mat& destMat,

        cv::Mat& srcMat, TRect displayRect) {

        int effectOptionType = MyOptionType.Items[1].CurrentValue * 2;

        // 为了共用CbwEffectDirection类型

        TRect wholeRect(0, 0, displayRect.right - displayRect.left,

            displayRect.bottom - displayRect.top);

        TRect partRect = wholeRect;

        bool vertFlag =

            (cedFromBottom == effectOptionType || cedFromTop == effectOptionType);

        double delta = double(FCurrentIndex + 1) / FPeriodLength * (vertFlag ?

            partRect.bottom : partRect.right);

        if (cedFromBottom == effectOptionType) // 自底部

                partRect.top = partRect.bottom - delta;

        if (cedFromLeft == effectOptionType) // 自左侧

                partRect.right = partRect.left + delta;

        if (cedFromTop == effectOptionType) // 自顶部

                partRect.bottom = partRect.top + delta;

        if (cedFromRight == effectOptionType) // 自右侧

                partRect.left = partRect.right - delta;

        BYTE * pSrc = srcMat.data;

        BYTE * pDst = destMat.data;

        for (int row = 0; row < destMat.rows; ++row)

            for (int col = 0; col < destMat.cols; ++col) {

                bool hasValueFlag = (*pSrc++ != 0);

                if (!hasValueFlag)

                    * pDst = 0;

                int y = (row - partRect.top) * (partRect.bottom - row);

                int x = (col - partRect.left) * (partRect.right - col);

                bool inFlag = (y >= 0 && x >= 0);

                *pDst++ = (inFlag ? 255 : 0);

            }

    }

    // ***************************** 擦除效果 **************************************

    // ***************************** 形状效果 **************************************

    __fastcall TCbwAnimationEffect_Shape::TCbwAnimationEffect_Shape()

        : TCbwAnimationEffect() {

        EffectType = cetShape;

    }

    TCbwAnimationEffect * TCbwAnimationEffect_Shape::Build() {

        return new TCbwAnimationEffect_Shape;

    }

    void __fastcall TCbwAnimationEffect_Shape::BuildMaskMat(cv::Mat& destMat,

        cv::Mat& srcMat, TRect displayRect) {

        int zoomType = MyOptionType.Items[1].CurrentValue; // 放大、缩小

        int shapeType = MyOptionType.Items[2].CurrentValue; // 类型

        TRect wholeRect(0, 0, displayRect.right - displayRect.left,

            displayRect.bottom - displayRect.top);

        double cx = wholeRect.right / 2.0, cy = wholeRect.bottom / 2.0;

        double deltaX = double(FCurrentIndex + 1) / FPeriodLength * cx;

        double deltaY = double(FCurrentIndex + 1) / FPeriodLength * cy;

        double startX = deltaX, startY = deltaY;

        double endX = wholeRect.right - deltaX, endY = wholeRect.bottom - deltaY;

        if (zoomType == csdZoomOut) {

            startX = cx - deltaX;

            startY = cy - deltaY;

            endX = cx + deltaX;

            endY = cy + deltaY;

        }

        BYTE * pSrc = srcMat.data;

        BYTE * pDst = destMat.data;

        for (int row = 0; row < destMat.rows; ++row)

            for (int col = 0; col < destMat.cols; ++col) {

                bool hasValueFlag = (*pSrc++ != 0);

                if (!hasValueFlag)

                    * pDst = 0;

                bool inFlag = false;

                double a = (cx - startX) * 1.5, b = (cy - startY) * 1.5;

                if (shapeType == cstCircle) { // 圆

                    if (a > 0 && b > 0) {

                        double v = (row - cy) * (row - cy) / (b * b) +

                            (col - cx) * (col - cx) / (a * a);

                        inFlag = (v <= 1);

                    }

                }

                if (shapeType == cstRect) { // 方框

                    inFlag =

                        (fabs(cx - startX) >= fabs(cx - col) && fabs(cy - startY) >=

                        fabs(cy - row));

                }

                if (shapeType == cstDiamond) { // 菱形

                    if (a > 0 && b > 0) {

                        if (zoomType == csdZoomOut) {

                            a *= 2;

                            b *= 2;

                        }

                        bool lr1 = (col < (((-a) * (1 - (row - cy) / (b))) + cx));

                        bool lr2 = (col < (((-a) * (1 - (row - cy) / (-b))) + cx));

                        bool lr3 = (col < (((a) * (1 - (row - cy) / (-b))) + cx));

                        bool lr4 = (col < (((a) * (1 - (row - cy) / (b))) + cx));

                        inFlag = (!lr1 && !lr2 && lr3 && lr4);

                    }

                }

                if (shapeType == cstPlus) { // 加号

                    inFlag =

                        (fabs(cx - startX) > fabs(cx - col) || fabs(cy - startY) >

                        fabs(cy - row));

                }

                *pDst++ = (inFlag != (zoomType == csdZoomOut) ? 0 : 255);

            }

    }

    // ***************************** 形状效果 **************************************

    // ***************************** 轮子效果 **************************************

    __fastcall TCbwAnimationEffect_Wheel::TCbwAnimationEffect_Wheel()

        : TCbwAnimationEffect() {

        EffectType = cetWheel;

    }

    TCbwAnimationEffect * TCbwAnimationEffect_Wheel::Build() {

        return new TCbwAnimationEffect_Wheel;

    }

    void __fastcall TCbwAnimationEffect_Wheel::BuildMaskMat(cv::Mat& destMat,

        cv::Mat& srcMat, TRect displayRect) {

        bool clockwiseFlag = (MyOptionType.Items[1].CurrentValue == 0); // 方向

        int pattern = MyOptionType.Items[2].CurrentValue + 1; // 轮辐图案

        if (pattern == 5)

            pattern = 8;

        TRect wholeRect(0, 0, displayRect.right - displayRect.left,

            displayRect.bottom - displayRect.top);

        double cx = wholeRect.right / 2.0, cy = wholeRect.bottom / 2.0;

        TCbwFloatPoint centerPoint(cx, cy);

        double unitDegree = 360 / pattern;

        double deltaDegree = double(FCurrentIndex + 1) / FPeriodLength * unitDegree;

        BYTE * pSrc = srcMat.data;

        BYTE * pDst = destMat.data;

        for (int row = 0; row < destMat.rows; ++row)

            for (int col = 0; col < destMat.cols; ++col) {

                TCbwFloatPoint p(col, row);

                double theta = p.ThetaToPoint(centerPoint);

                if (clockwiseFlag)

                    theta = 360 - theta;

                bool inFlag = false;

                for (int i = 0; i < pattern; ++i) {

                    if (theta >= unitDegree * i && (theta - unitDegree * i) <=

                        deltaDegree)

                        inFlag = true;

                }

                *pDst++ = inFlag ? 255 : 0;

            }

    }

    // ***************************** 轮子效果 **************************************

    // ***************************** 随机线效果 **************************************

    __fastcall TCbwAnimationEffect_RandomLine::TCbwAnimationEffect_RandomLine()

        : TCbwAnimationEffect() {

        EffectType = cetRandomLine;

        FOccurredLines = NULL;

    }

    TCbwAnimationEffect * TCbwAnimationEffect_RandomLine::Build() {

        return new TCbwAnimationEffect_RandomLine;

    }

    void __fastcall TCbwAnimationEffect_RandomLine::BuildMaskMat(cv::Mat& destMat,

        cv::Mat& srcMat, TRect displayRect) {

        bool horzFlag = (MyOptionType.Items[1].CurrentValue == 0); // 方向

        TRect wholeRect(0, 0, displayRect.right - displayRect.left,

            displayRect.bottom - displayRect.top);

        int totalLineNumber = (horzFlag ? wholeRect.bottom : wholeRect.right);

        int number = double(FCurrentIndex + 1) / FPeriodLength * totalLineNumber;

        if (!FOccurredLines) {

            FOccurredLines = new BYTE[totalLineNumber];

            ZeroMemory(FOccurredLines, totalLineNumber);

        }

        int destNumber =

            number -int(double(FCurrentIndex) / FPeriodLength * totalLineNumber);

        BYTE * pSrc = srcMat.data;

        BYTE * pDst = destMat.data;

        vector<int>totalLines;

        for (int i = 0; i < totalLineNumber; ++i)

            totalLines.push_back(i);

        while (destNumber-- > 0 && totalLines.size()) {

            int n = random(totalLines.size());

            while (FOccurredLines[totalLines[n]]) {

                totalLines.erase(totalLines.begin() + n);

                n = random(totalLines.size());

            }

            FOccurredLines[totalLines[n]] = 1;

            totalLines.erase(totalLines.begin() + n);

        }

        for (int row = 0; row < destMat.rows; ++row)

            for (int col = 0; col < destMat.cols; ++col) {

                bool inFlag = (horzFlag ? FOccurredLines[row] :

                    FOccurredLines[col]);

                *pDst++ = inFlag ? 255 : 0;

            }

        if (FCurrentIndex == FPeriodLength - 1) {

            delete FOccurredLines;

            FOccurredLines = NULL;

        }

    }

    // ***************************** 随机线效果 **************************************

    // ***************************** 翻转式由远及近效果 **************************************

    __fastcall TCbwAnimationEffect_RotateToNear::TCbwAnimationEffect_RotateToNear()

        : TCbwAnimationEffect_SameMask() {

        EffectType = cetRotateToNear;

    }

    TCbwAnimationEffect * TCbwAnimationEffect_RotateToNear::Build() {

        return new TCbwAnimationEffect_RotateToNear;

    }

    void __fastcall TCbwAnimationEffect_RotateToNear::BuildDisplayMat

        (cv::Mat& destMat, cv::Mat& srcMat, TRect displayRect) {

        bool clockwiseFlag = (MyOptionType.Items[1].CurrentValue == 0); // 顺时针

        cv::Point2f center = cv::Point2f(srcMat.cols / 2, srcMat.rows / 2); // 旋转中心

        double angle = -45 * (1-double(FCurrentIndex + 1) / FPeriodLength); // 旋转角度

        if (clockwiseFlag)

            angle *= -1;

        double scale = 0.5 * (1+double(FCurrentIndex + 1) / FPeriodLength); // 缩放尺度

        cv::Mat rotateMat = cv::getRotationMatrix2D(center, angle, scale);

        cv::warpAffine(srcMat, destMat, rotateMat, srcMat.size());

    }

    // ***************************** 翻转式由远及近效果 **************************************

    // ***************************** 缩放效果 **************************************

    __fastcall TCbwAnimationEffect_Zoom::TCbwAnimationEffect_Zoom()

        : TCbwAnimationEffect_SameMask() {

        EffectType = cetZoomEffect;

    }

    TCbwAnimationEffect * TCbwAnimationEffect_Zoom::Build() {

        return new TCbwAnimationEffect_Zoom;

    }

    void __fastcall TCbwAnimationEffect_Zoom::BuildDisplayMat(cv::Mat& destMat,

        cv::Mat& srcMat, TRect displayRect) {

        bool clockwiseFlag = (MyOptionType.Items[1].CurrentValue == 0); // 顺时针

        cv::Point2f center = cv::Point2f(srcMat.cols / 2, srcMat.rows / 2); // 旋转中心

        double scale = 0.5 * (1+double(FCurrentIndex + 1) / FPeriodLength); // 缩放尺度

        cv::Mat rotateMat = cv::getRotationMatrix2D(center, 0, scale);

        cv::warpAffine(srcMat, destMat, rotateMat, srcMat.size());

    }

    // ***************************** 缩放效果 **************************************

    // ***************************** 旋转效果 **************************************

    __fastcall TCbwAnimationEffect_Rotate::TCbwAnimationEffect_Rotate()

        : TCbwAnimationEffect_SameMask() {

        EffectType = cetRotateEffect;

    }

    TCbwAnimationEffect * TCbwAnimationEffect_Rotate::Build() {

        return new TCbwAnimationEffect_Rotate;

    }

    void __fastcall TCbwAnimationEffect_Rotate::BuildDisplayMat(cv::Mat& destMat,

        cv::Mat& srcMat, TRect displayRect) {

        bool horzFlag = (MyOptionType.Items[1].CurrentValue == 0); // 方向

        double periodLength = FPeriodLength / 2.0;

        double value = (FCurrentIndex + 1) / periodLength;

        int segment = value;

        value -= int(value);

        double scale = fabs(value - 0.5) * 2;

        int cols = srcMat.cols * scale, rows = srcMat.rows;

        if (!horzFlag) {

            cols = srcMat.cols;

            rows = srcMat.rows * scale;

        }

        if (cols == 0 || rows == 0)

            return;

        cv::Mat partMat = destMat(cv::Rect((destMat.cols - cols) / 2,

            (destMat.rows - rows) / 2, cols, rows));

        cv::Size dsize = cv::Size(cols, rows);

        resize(srcMat, partMat, dsize);

        if (value > 0.5 != (segment % 2))

            flip(partMat, partMat, horzFlag ? 1 : 0);

    }

    // ***************************** 旋转效果 **************************************

    // ***************************** 弹跳效果 **************************************

    __fastcall TCbwAnimationEffect_Bounce::TCbwAnimationEffect_Bounce()

        : TCbwAnimationEffect() {

        EffectType = cetBounce;

    }

    TCbwAnimationEffect * TCbwAnimationEffect_Bounce::Build() {

        return new TCbwAnimationEffect_Bounce;

    }

    TRect __fastcall TCbwAnimationEffect_Bounce::BuildDisplayRect(OBJECTMAT * m) {

        double x = double(FCurrentIndex + 1) / FPeriodLength;

        double v = sin((x - 1) * 3 * PI);

        double y = fabs(200 * v / exp(0.3 * (x - 1)));

        y = m->LeftTopPosition.y - y;

        x = m->LeftTopPosition.x + (x - 1) * 500;

        TRect result(x, y, x + m->Mat.cols, y + m->Mat.rows);

        return result;

    }

    // ***************************** 弹跳效果 **************************************

    配置:

    图标

    实现完成后,发现弹跳的效果没有达到预期。

     

    先解决有问题,先完成,再完善。

    本周按计划完成PPT动画效果框架设计与实现。年也过完了,下周把电子黑板的功能更上一层楼。

  • 相关阅读:
    Openssl和PKCS#11的故事
    SSL连接建立过程分析(5)
    SSL连接建立过程分析(1)
    关于OpenSSL支持USBKEY证书的尝试
    install the CLEARCASE with eclipse 3.4,duplicate location
    10种技巧可提升Android应用运行效果
    专访实战专家 揭秘iOS神奇开发之路
    win objc codeblocks
    redeclared as different kind of symbol ,undefined reference to `__objc_class_name_Rectangle12'
    201203NEWS
  • 原文地址:https://www.cnblogs.com/drgraph/p/4318548.html
Copyright © 2020-2023  润新知