Esempio n. 1
0
bool GraphicsLayerAndroid::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList,
                                                                  const Animation* animation,
                                                                  const String& keyframesName,
                                                                  double beginTime,
                                                                  const IntSize& boxSize)
{
    ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
    TLOG("createTransformAnimationFromKeyframes, name(%s) beginTime(%.2f)",
        keyframesName.latin1().data(), beginTime);

    KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyWebkitTransform);
    for (unsigned int i = 0; i < valueList.size(); i++) {
        TransformAnimationValue* originalValue = (TransformAnimationValue*)valueList.at(i);
        PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
        TransformAnimationValue* value = new TransformAnimationValue(originalValue->keyTime(),
                                                                     originalValue->value(),
                                                                     timingFunction);
        operationsList->insert(value);
    }

    RefPtr<AndroidTransformAnimation> anim = AndroidTransformAnimation::create(animation,
                                                                               operationsList,
                                                                               beginTime);

    if (keyframesName.isEmpty())
        anim->setName(propertyIdToString(valueList.property()));
    else
        anim->setName(keyframesName);


    m_contentLayer->addAnimation(anim.release());

    needsNotifyClient();
    return true;
}
bool GraphicsLayerTextureMapper::addAnimation(const KeyframeValueList& valueList, const FloatSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
{
    ASSERT(!keyframesName.isEmpty());

    if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2 || (valueList.property() != AnimatedPropertyTransform && valueList.property() != AnimatedPropertyOpacity))
        return false;

    if (valueList.property() == AnimatedPropertyFilter) {
        int listIndex = validateFilterOperations(valueList);
        if (listIndex < 0)
            return false;

        const auto& filters = static_cast<const FilterAnimationValue&>(valueList.at(listIndex)).value();
        if (!filtersCanBeComposited(filters))
            return false;
    }

    bool listsMatch = false;
    bool hasBigRotation;

    if (valueList.property() == AnimatedPropertyTransform)
        listsMatch = validateTransformOperations(valueList, hasBigRotation) >= 0;

    const double currentTime = monotonicallyIncreasingTime();
    m_animations.add(TextureMapperAnimation(keyframesName, valueList, boxSize, *anim, listsMatch, currentTime - timeOffset, 0, TextureMapperAnimation::AnimationState::Playing));
    // m_animationStartTime is the time of the first real frame of animation, now or delayed by a negative offset.
    if (timeOffset > 0)
        m_animationStartTime = currentTime;
    else
        m_animationStartTime = currentTime - timeOffset;
    notifyChange(AnimationChange);
    notifyChange(AnimationStarted);
    return true;
}
Esempio n. 3
0
bool GraphicsLayerAndroid::createAnimationFromKeyframes(const KeyframeValueList& valueList,
     const Animation* animation, const String& keyframesName, double beginTime)
{
    bool isKeyframe = valueList.size() > 2;
    TLOG("createAnimationFromKeyframes(%d), name(%s) beginTime(%.2f)",
        isKeyframe, keyframesName.latin1().data(), beginTime);

    switch (valueList.property()) {
    case AnimatedPropertyInvalid: break;
    case AnimatedPropertyWebkitTransform: break;
    case AnimatedPropertyBackgroundColor: break;
    case AnimatedPropertyOpacity: {
        MLOG("ANIMATEDPROPERTYOPACITY");

        KeyframeValueList* operationsList = new KeyframeValueList(AnimatedPropertyOpacity);
        for (unsigned int i = 0; i < valueList.size(); i++) {
            FloatAnimationValue* originalValue = (FloatAnimationValue*)valueList.at(i);
            PassRefPtr<TimingFunction> timingFunction(const_cast<TimingFunction*>(originalValue->timingFunction()));
            FloatAnimationValue* value = new FloatAnimationValue(originalValue->keyTime(),
                                                                 originalValue->value(),
                                                                 timingFunction);
            operationsList->insert(value);
        }

        RefPtr<AndroidOpacityAnimation> anim = AndroidOpacityAnimation::create(animation,
                                                                               operationsList,
                                                                               beginTime);
        if (keyframesName.isEmpty())
            anim->setName(propertyIdToString(valueList.property()));
        else
            anim->setName(keyframesName);

        m_contentLayer->addAnimation(anim.release());
        needsNotifyClient();
        return true;
    } break;
    }
    return false;
}
PassOwnPtr<WebKit::WebAnimation> createWebAnimation(const KeyframeValueList& valueList, const CSSAnimationData* animation, int animationId, double timeOffset, Curve* curve, WebKit::WebAnimation::TargetProperty targetProperty, const FloatSize& boxSize)
{
    bool alternate = false;
    bool reverse = false;
    if (animation && animation->isDirectionSet()) {
        CSSAnimationData::AnimationDirection direction = animation->direction();
        if (direction == CSSAnimationData::AnimationDirectionAlternate || direction == CSSAnimationData::AnimationDirectionAlternateReverse)
            alternate = true;
        if (direction == CSSAnimationData::AnimationDirectionReverse || direction == CSSAnimationData::AnimationDirectionAlternateReverse)
            reverse = true;
    }

    for (size_t i = 0; i < valueList.size(); i++) {
        size_t index = reverse ? valueList.size() - i - 1 : i;
        const Value* originalValue = static_cast<const Value*>(valueList.at(index));
        const Value* lastOriginalValue = 0;
        if (valueList.size() > 1 && ((reverse && index + 1 < valueList.size()) || (!reverse && index > 0)))
            lastOriginalValue = static_cast<const Value*>(valueList.at(reverse ? index + 1 : index - 1));

        const TimingFunction* originalTimingFunction = originalValue->timingFunction();

        // If there hasn't been a timing function associated with this keyframe, use the
        // animation's timing function, if we have one.
        if (!originalTimingFunction && animation->isTimingFunctionSet())
            originalTimingFunction = animation->timingFunction().get();

        // Ease is the default timing function.
        WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType = WebKit::WebAnimationCurve::TimingFunctionTypeEase;

        bool isUsingCustomBezierTimingFunction = false;
        double x1 = 0;
        double y1 = 0;
        double x2 = 1;
        double y2 = 1;

        if (originalTimingFunction) {
            switch (originalTimingFunction->type()) {
            case TimingFunction::StepsFunction:
                // FIXME: add support for steps timing function.
                return nullptr;
            case TimingFunction::LinearFunction:
                timingFunctionType = WebKit::WebAnimationCurve::TimingFunctionTypeLinear;
                break;
            case TimingFunction::CubicBezierFunction:
                const CubicBezierTimingFunction* originalBezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(originalTimingFunction);
                isUsingCustomBezierTimingFunction = true;
                x1 = originalBezierTimingFunction->x1();
                y1 = originalBezierTimingFunction->y1();
                x2 = originalBezierTimingFunction->x2();
                y2 = originalBezierTimingFunction->y2();
                break;
            } // switch
        }

        double duration = (animation && animation->isDurationSet()) ? animation->duration() : 1;
        double keyTime = originalValue->keyTime() * duration;

        if (reverse)
            keyTime = duration - keyTime;

        bool addedKeyframe = false;
        if (isUsingCustomBezierTimingFunction)
            addedKeyframe = appendKeyframeWithCustomBezierTimingFunction<Value, Keyframe, Curve>(curve, keyTime, originalValue, lastOriginalValue, x1, y1, x2, y2, boxSize);
        else
            addedKeyframe = appendKeyframeWithStandardTimingFunction<Value, Keyframe, Curve>(curve, keyTime, originalValue, lastOriginalValue, timingFunctionType, boxSize);
        if (!addedKeyframe)
            return nullptr;
    }

    OwnPtr<WebKit::WebAnimation> webAnimation = adoptPtr(Platform::current()->compositorSupport()->createAnimation(*curve, targetProperty, animationId));

    int iterations = (animation && animation->isIterationCountSet()) ? animation->iterationCount() : 1;
    webAnimation->setIterations(iterations);
    webAnimation->setAlternatesDirection(alternate);

    // If timeOffset > 0, then the animation has started in the past.
    webAnimation->setTimeOffset(timeOffset);

    return webAnimation.release();
}