animationbase.cpp

来自「linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自Web」· C++ 代码 · 共 1,080 行 · 第 1/4 页

CPP
1,080
字号
/* * Copyright (C) 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1.  Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer.  * 2.  Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in the *     documentation and/or other materials provided with the distribution.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of *     its contributors may be used to endorse or promote products derived *     from this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "AnimationBase.h"#include "AnimationControllerPrivate.h"#include "CSSMutableStyleDeclaration.h"#include "CSSPropertyLonghand.h"#include "CSSPropertyNames.h"#include "CString.h"#include "CompositeAnimation.h"#include "Document.h"#include "EventNames.h"#include "FloatConversion.h"#include "Frame.h"#include "IdentityTransformOperation.h"#include "ImplicitAnimation.h"#include "KeyframeAnimation.h"#include "MatrixTransformOperation.h"#include "Matrix3DTransformOperation.h"#include "RenderBox.h"#include "RenderStyle.h"#include "UnitBezier.h"#include <algorithm>using namespace std;namespace WebCore {// The epsilon value we pass to UnitBezier::solve given that the animation is going to run over |dur| seconds. The longer the// animation, the more precision we need in the timing function result to avoid ugly discontinuities.static inline double solveEpsilon(double duration){    return 1.0 / (200.0 * duration);}static inline double solveCubicBezierFunction(double p1x, double p1y, double p2x, double p2y, double t, double duration){    // Convert from input time to parametric value in curve, then from    // that to output time.    UnitBezier bezier(p1x, p1y, p2x, p2y);    return bezier.solve(t, solveEpsilon(duration));}static inline int blendFunc(const AnimationBase*, int from, int to, double progress){      return int(from + (to - from) * progress);}static inline double blendFunc(const AnimationBase*, double from, double to, double progress){      return from + (to - from) * progress;}static inline float blendFunc(const AnimationBase*, float from, float to, double progress){      return narrowPrecisionToFloat(from + (to - from) * progress);}static inline Color blendFunc(const AnimationBase* anim, const Color& from, const Color& to, double progress){    // We need to preserve the state of the valid flag at the end of the animation    if (progress == 1 && !to.isValid())        return Color();    return Color(blendFunc(anim, from.red(), to.red(), progress),                 blendFunc(anim, from.green(), to.green(), progress),                 blendFunc(anim, from.blue(), to.blue(), progress),                 blendFunc(anim, from.alpha(), to.alpha(), progress));}static inline Length blendFunc(const AnimationBase*, const Length& from, const Length& to, double progress){      return to.blend(from, progress);}static inline IntSize blendFunc(const AnimationBase* anim, const IntSize& from, const IntSize& to, double progress){      return IntSize(blendFunc(anim, from.width(), to.width(), progress),                   blendFunc(anim, from.height(), to.height(), progress));}static inline ShadowData* blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress){      ASSERT(from && to);    return new ShadowData(blendFunc(anim, from->x, to->x, progress), blendFunc(anim, from->y, to->y, progress),                           blendFunc(anim, from->blur, to->blur, progress), blendFunc(anim, from->color, to->color, progress));}static inline TransformOperations blendFunc(const AnimationBase* anim, const TransformOperations& from, const TransformOperations& to, double progress){        TransformOperations result;    // If we have a transform function list, use that to do a per-function animation. Otherwise do a Matrix animation    if (anim->isTransformFunctionListValid()) {        unsigned fromSize = from.operations().size();        unsigned toSize = to.operations().size();        unsigned size = max(fromSize, toSize);        for (unsigned i = 0; i < size; i++) {            RefPtr<TransformOperation> fromOp = (i < fromSize) ? from.operations()[i].get() : 0;            RefPtr<TransformOperation> toOp = (i < toSize) ? to.operations()[i].get() : 0;            RefPtr<TransformOperation> blendedOp = toOp ? toOp->blend(fromOp.get(), progress) : (fromOp ? fromOp->blend(0, progress, true) : 0);            if (blendedOp)                result.operations().append(blendedOp);            else {                RefPtr<TransformOperation> identityOp = IdentityTransformOperation::create();                if (progress > 0.5)                    result.operations().append(toOp ? toOp : identityOp);                else                    result.operations().append(fromOp ? fromOp : identityOp);            }        }    } else {        // Convert the TransformOperations into matrices        IntSize size = anim->renderer()->isBox() ? toRenderBox(anim->renderer())->borderBoxRect().size() : IntSize();        TransformationMatrix fromT;        TransformationMatrix toT;        from.apply(size, fromT);        to.apply(size, toT);                toT.blend(fromT, progress);                // Append the result        result.operations().append(Matrix3DTransformOperation::create(toT));    }    return result;}static inline EVisibility blendFunc(const AnimationBase* anim, EVisibility from, EVisibility to, double progress){    // Any non-zero result means we consider the object to be visible.  Only at 0 do we consider the object to be    // invisible.   The invisible value we use (HIDDEN vs. COLLAPSE) depends on the specified from/to values.    double fromVal = from == VISIBLE ? 1. : 0.;    double toVal = to == VISIBLE ? 1. : 0.;    if (fromVal == toVal)        return to;    double result = blendFunc(anim, fromVal, toVal, progress);    return result > 0. ? VISIBLE : (to != VISIBLE ? to : from);}class PropertyWrapperBase;static void addShorthandProperties();static PropertyWrapperBase* wrapperForProperty(int propertyID);class PropertyWrapperBase {public:    PropertyWrapperBase(int prop)        : m_prop(prop)    {    }    virtual ~PropertyWrapperBase() { }        virtual bool isShorthandWrapper() const { return false; }    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const = 0;    virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const = 0;    int property() const { return m_prop; }#if USE(ACCELERATED_COMPOSITING)    virtual bool animationIsAccelerated() const { return false; }#endifprivate:    int m_prop;};template <typename T>class PropertyWrapperGetter : public PropertyWrapperBase {public:    PropertyWrapperGetter(int prop, T (RenderStyle::*getter)() const)        : PropertyWrapperBase(prop)        , m_getter(getter)    {    }    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const    {       // If the style pointers are the same, don't bother doing the test.       // If either is null, return false. If both are null, return true.       if (!a && !b || a == b)           return true;       if (!a || !b)            return false;        return (a->*m_getter)() == (b->*m_getter)();    }protected:    T (RenderStyle::*m_getter)() const;};template <typename T>class PropertyWrapper : public PropertyWrapperGetter<T> {public:    PropertyWrapper(int prop, T (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T))        : PropertyWrapperGetter<T>(prop, getter)        , m_setter(setter)    {    }        virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const    {        (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<T>::m_getter)(), (b->*PropertyWrapperGetter<T>::m_getter)(), progress));    }protected:    void (RenderStyle::*m_setter)(T);};#if USE(ACCELERATED_COMPOSITING)class PropertyWrapperAcceleratedOpacity : public PropertyWrapper<float> {public:    PropertyWrapperAcceleratedOpacity()        : PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity)    {    }    virtual bool animationIsAccelerated() const { return true; }    virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const    {        float fromOpacity = a->opacity();                // This makes sure we put the object being animated into a RenderLayer during the animation        dst->setOpacity(blendFunc(anim, (fromOpacity == 1) ? 0.999999f : fromOpacity, b->opacity(), progress));    }};class PropertyWrapperAcceleratedTransform : public PropertyWrapper<const TransformOperations&> {public:    PropertyWrapperAcceleratedTransform()        : PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform)    {    }        virtual bool animationIsAccelerated() const { return true; }    virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const    {        dst->setTransform(blendFunc(anim, a->transform(), b->transform(), progress));    }};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?