void AndroidTransformAnimation::applyForProgress(LayerAndroid* layer, float progress) { // First, we need to get the from and to values int from, to; pickValues(progress, &from, &to); TransformAnimationValue* fromValue = (TransformAnimationValue*) m_operations->at(from); TransformAnimationValue* toValue = (TransformAnimationValue*) m_operations->at(to); ALOGV("[layer %d] fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f", layer->uniqueId(), fromValue, fromValue->keyTime(), toValue, toValue->keyTime(), progress); // We now have the correct two values to work with, let's compute the // progress value const TimingFunction* timingFunction = fromValue->timingFunction(); float p = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(), progress, timingFunction); ALOGV("progress %.2f => %.2f from: %.2f to: %.2f", progress, p, fromValue->keyTime(), toValue->keyTime()); progress = p; // With both values and the progress, we also need to check out that // the operations are compatible (i.e. we are animating the same number // of values; if not we do a matrix blend) TransformationMatrix transformMatrix; bool valid = true; unsigned int fromSize = fromValue->value()->size(); if (fromSize) { if (toValue->value()->size() != fromSize) valid = false; else { for (unsigned int j = 0; j < fromSize && valid; j++) { if (!fromValue->value()->operations()[j]->isSameType( *toValue->value()->operations()[j])) valid = false; } } } IntSize size(layer->getSize().width(), layer->getSize().height()); if (valid) { for (size_t i = 0; i < toValue->value()->size(); ++i) toValue->value()->operations()[i]->blend(fromValue->value()->at(i), progress)->apply(transformMatrix, size); } else { TransformationMatrix source; fromValue->value()->apply(size, source); toValue->value()->apply(size, transformMatrix); transformMatrix.blend(source, progress); } // Set the final transform on the layer layer->setTransform(transformMatrix); }
void AndroidOpacityAnimation::applyForProgress(LayerAndroid* layer, float progress) { // First, we need to get the from and to values int from, to; pickValues(progress, &from, &to); FloatAnimationValue* fromValue = (FloatAnimationValue*) m_operations->at(from); FloatAnimationValue* toValue = (FloatAnimationValue*) m_operations->at(to); ALOGV("[layer %d] opacity fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f", layer->uniqueId(), fromValue, fromValue->keyTime(), toValue, toValue->keyTime(), progress); // We now have the correct two values to work with, let's compute the // progress value const TimingFunction* timingFunction = fromValue->timingFunction(); progress = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(), progress, timingFunction); float value = fromValue->value() + ((toValue->value() - fromValue->value()) * progress); layer->setOpacity(value); }
void TextureMapperAnimation::apply(Client& client) { if (!isActive()) return; double totalRunningTime = computeTotalRunningTime(); double normalizedValue = normalizedAnimationValue(totalRunningTime, m_animation->duration(), m_animation->direction(), m_animation->iterationCount()); if (m_animation->iterationCount() != Animation::IterationCountInfinite && totalRunningTime >= m_animation->duration() * m_animation->iterationCount()) { m_state = AnimationState::Stopped; m_pauseTime = 0; if (m_animation->fillsForwards()) normalizedValue = normalizedAnimationValueForFillsForwards(m_animation->iterationCount(), m_animation->direction()); } if (!normalizedValue) { applyInternal(client, m_keyframes.at(0), m_keyframes.at(1), 0); return; } if (normalizedValue == 1.0) { applyInternal(client, m_keyframes.at(m_keyframes.size() - 2), m_keyframes.at(m_keyframes.size() - 1), 1); return; } if (m_keyframes.size() == 2) { const TimingFunction* timingFunction = timingFunctionForAnimationValue(m_keyframes.at(0), m_animation.get()); normalizedValue = applyTimingFunction(timingFunction, normalizedValue, m_animation->duration()); applyInternal(client, m_keyframes.at(0), m_keyframes.at(1), normalizedValue); return; } for (size_t i = 0; i < m_keyframes.size() - 1; ++i) { const AnimationValue& from = m_keyframes.at(i); const AnimationValue& to = m_keyframes.at(i + 1); if (from.keyTime() > normalizedValue || to.keyTime() < normalizedValue) continue; normalizedValue = (normalizedValue - from.keyTime()) / (to.keyTime() - from.keyTime()); const TimingFunction* timingFunction = timingFunctionForAnimationValue(from, m_animation.get()); normalizedValue = applyTimingFunction(timingFunction, normalizedValue, m_animation->duration()); applyInternal(client, from, to, normalizedValue); break; } }
void GraphicsLayerAnimation::apply(Client* client) { if (!isActive()) return; double totalRunningTime = m_state == PausedState ? m_pauseTime : WTF::currentTime() - m_startTime; double normalizedValue = normalizedAnimationValue(totalRunningTime, m_animation->duration(), m_animation->direction(), m_animation->iterationCount()); if (m_animation->iterationCount() != Animation::IterationCountInfinite && totalRunningTime >= m_animation->duration() * m_animation->iterationCount()) { setState(StoppedState); if (m_animation->fillsForwards()) normalizedValue = normalizedAnimationValueForFillsForwards(m_animation->iterationCount(), m_animation->direction()); } if (!normalizedValue) { applyInternal(client, m_keyframes.at(0), m_keyframes.at(1), 0); return; } if (normalizedValue == 1.0) { applyInternal(client, m_keyframes.at(m_keyframes.size() - 2), m_keyframes.at(m_keyframes.size() - 1), 1); return; } if (m_keyframes.size() == 2) { const TimingFunction* timingFunction = timingFunctionForAnimationValue(m_keyframes.at(0), m_animation.get()); normalizedValue = applyTimingFunction(timingFunction, normalizedValue, m_animation->duration()); applyInternal(client, m_keyframes.at(0), m_keyframes.at(1), normalizedValue); return; } for (size_t i = 0; i < m_keyframes.size() - 1; ++i) { const AnimationValue* from = m_keyframes.at(i); const AnimationValue* to = m_keyframes.at(i + 1); if (from->keyTime() > normalizedValue || to->keyTime() < normalizedValue) continue; normalizedValue = (normalizedValue - from->keyTime()) / (to->keyTime() - from->keyTime()); const TimingFunction* timingFunction = timingFunctionForAnimationValue(from, m_animation.get()); normalizedValue = applyTimingFunction(timingFunction, normalizedValue, m_animation->duration()); applyInternal(client, from, to, normalizedValue); break; } }