Changeset 201759 in webkit


Ignore:
Timestamp:
Jun 7, 2016 11:15:31 AM (8 years ago)
Author:
weinig@apple.com
Message:

Add experimental support for spring based CSS animations
https://bugs.webkit.org/show_bug.cgi?id=158403

Reviewed by Dean Jackson.

Source/WebCore:

Adds experimental support for a new CSS animation timing function that uses
spring to model the time function. To use it you replace your normal timing
function, be it cubic-bezier or steps, with a new function called spring().
For instance, for a transition you would write:

transition-timing-function: spring(1 100 10 0);


The parameters are, in order:

  • Mass
  • Stiffness
  • Damping
  • Initial Velocity

Tests: animations/spring-computed-style.html

animations/spring-function.html
animations/spring-parsing.html

  • WebCore.xcodeproj/project.pbxproj:

Add new file.

  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::createTimingFunctionValue):
Modernize and add support for the spring function.

  • css/CSSParser.cpp:

(WebCore::CSSParserContext::CSSParserContext):
(WebCore::operator==):
(WebCore::CSSParser::CSSParser):
(WebCore::CSSParser::parseTransformOriginShorthand):
(WebCore::CSSParser::isSpringTimingFunctionEnabled):
(WebCore::CSSParser::parseCubicBezierTimingFunctionValue):
(WebCore::CSSParser::parseSpringTimingFunctionValue):
(WebCore::CSSParser::parseAnimationTimingFunction):

  • css/CSSParser.h:
  • css/CSSParserMode.h:

Add parsing support for the spring() function.

  • css/CSSTimingFunctionValue.cpp:

(WebCore::CSSCubicBezierTimingFunctionValue::customCSSText):
(WebCore::CSSCubicBezierTimingFunctionValue::equals):
(WebCore::CSSStepsTimingFunctionValue::customCSSText):
(WebCore::CSSStepsTimingFunctionValue::equals):
(WebCore::CSSSpringTimingFunctionValue::customCSSText):
(WebCore::CSSSpringTimingFunctionValue::equals):

  • css/CSSTimingFunctionValue.h:

(WebCore::CSSSpringTimingFunctionValue::create):
(WebCore::CSSSpringTimingFunctionValue::mass):
(WebCore::CSSSpringTimingFunctionValue::stiffness):
(WebCore::CSSSpringTimingFunctionValue::damping):
(WebCore::CSSSpringTimingFunctionValue::initialVelocity):
(WebCore::CSSSpringTimingFunctionValue::CSSSpringTimingFunctionValue):
Modernize and add support for the spring function.

  • css/CSSToStyleMap.cpp:

(WebCore::CSSToStyleMap::mapAnimationTimingFunction):
Pipe the spring function into the animation.

  • css/CSSValue.cpp:

(WebCore::CSSValue::equals):
(WebCore::CSSValue::cssText):
(WebCore::CSSValue::destroy):

  • css/CSSValue.h:

(WebCore::CSSValue::isSpringTimingFunctionValue):
Add support for the spring function.

  • page/Settings.in:

Add a setting to control if the spring function is enabled.

  • page/animation/AnimationBase.cpp:

(WebCore::solveSpringFunction):
(WebCore::AnimationBase::progress):
Add support for solving the spring function. Since the spring requires time to be absolute,
get the real time by multiplying the ratio t, to the total duration.

  • platform/animation/TimingFunction.cpp:

(WebCore::operator<<):

  • platform/animation/TimingFunction.h:

(WebCore::TimingFunction::~TimingFunction):
(WebCore::TimingFunction::isSpringTimingFunction):
Add support for the spring timing function.

  • platform/graphics/SpringSolver.h: Added.

(WebCore::SpringSolver::SpringSolver):
(WebCore::SpringSolver::solve):
Add a Spring solver that matches the one in CoreAnimation.

  • platform/graphics/ca/GraphicsLayerCA.cpp:

(WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
(WebCore::GraphicsLayerCA::appendToUncommittedAnimations):
(WebCore::GraphicsLayerCA::createBasicAnimation):
(WebCore::GraphicsLayerCA::createSpringAnimation):
(WebCore::GraphicsLayerCA::setupAnimation):

  • platform/graphics/ca/GraphicsLayerCA.h:

Map animations with spring timing functions to CASpringAnimations.

  • platform/graphics/ca/PlatformCAAnimation.cpp:

(WebCore::operator<<):
(WebCore::PlatformCAAnimation::isBasicAnimation):

  • platform/graphics/ca/PlatformCAAnimation.h:

(WebCore::PlatformCAAnimation::setActualStartTimeIfNeeded):
(WebCore::PlatformCAAnimation::PlatformCAAnimation):

  • platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm:

(WebCore::toCAMediaTimingFunction):
(PlatformCAAnimationCocoa::PlatformCAAnimationCocoa):
(PlatformCAAnimationCocoa::setTimingFunction):
(PlatformCAAnimationCocoa::copyTimingFunctionFrom):
(PlatformCAAnimationCocoa::setFromValue):
(PlatformCAAnimationCocoa::copyFromValueFrom):
(PlatformCAAnimationCocoa::setToValue):
(PlatformCAAnimationCocoa::copyToValueFrom):
Add a new type of PlatformCAAnimation, Spring, which is a sub-type of Basic.

Source/WebKit2:

  • Shared/WebCoreArgumentCoders.cpp:

(IPC::ArgumentCoder<StepsTimingFunction>::decode):
(IPC::ArgumentCoder<SpringTimingFunction>::encode):
(IPC::ArgumentCoder<SpringTimingFunction>::decode):
(IPC::ArgumentCoder<FloatPoint>::encode):

  • Shared/WebCoreArgumentCoders.h:
  • Shared/WebPreferencesDefinitions.h:
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::updatePreferences):

  • WebProcess/WebPage/mac/PlatformCAAnimationRemote.mm:

(WebKit::PlatformCAAnimationRemote::Properties::encode):
(WebKit::PlatformCAAnimationRemote::Properties::decode):
(WebKit::addAnimationToLayer):
Pipe through support for the Spring animation.

LayoutTests:

  • animations/script-tests/spring-computed-style.js: Added.
  • animations/script-tests/spring-parsing.js: Added.
  • animations/spring-computed-style-expected.txt: Added.
  • animations/spring-computed-style.html: Added.
  • animations/spring-function-expected.txt: Added.
  • animations/spring-function.html: Added.
  • animations/spring-parsing-expected.txt: Added.
  • animations/spring-parsing.html: Added.

Add tests for the spring timing function.

Location:
trunk
Files:
9 added
29 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r201757 r201759  
     12016-06-05  Sam Weinig  <sam@webkit.org>
     2
     3        Add experimental support for spring based CSS animations
     4        https://bugs.webkit.org/show_bug.cgi?id=158403
     5
     6        Reviewed by Dean Jackson.
     7
     8        * animations/script-tests/spring-computed-style.js: Added.
     9        * animations/script-tests/spring-parsing.js: Added.
     10        * animations/spring-computed-style-expected.txt: Added.
     11        * animations/spring-computed-style.html: Added.
     12        * animations/spring-function-expected.txt: Added.
     13        * animations/spring-function.html: Added.
     14        * animations/spring-parsing-expected.txt: Added.
     15        * animations/spring-parsing.html: Added.
     16        Add tests for the spring timing function.
     17
    1182016-06-07  Chris Dumez  <cdumez@apple.com>
    219
  • trunk/Source/WebCore/ChangeLog

    r201757 r201759  
     12016-06-06  Sam Weinig  <sam@webkit.org>
     2
     3        Add experimental support for spring based CSS animations
     4        https://bugs.webkit.org/show_bug.cgi?id=158403
     5
     6        Reviewed by Dean Jackson.
     7
     8        Adds experimental support for a new CSS animation timing function that uses
     9        spring to model the time function. To use it you replace your normal timing
     10        function, be it cubic-bezier or steps, with a new function called spring().
     11        For instance, for a transition you would write:
     12
     13            transition-timing-function: spring(1 100 10 0);
     14       
     15        The parameters are, in order:
     16            - Mass
     17            - Stiffness
     18            - Damping
     19            - Initial Velocity
     20
     21        Tests: animations/spring-computed-style.html
     22               animations/spring-function.html
     23               animations/spring-parsing.html
     24
     25        * WebCore.xcodeproj/project.pbxproj:
     26        Add new file.
     27
     28        * css/CSSComputedStyleDeclaration.cpp:
     29        (WebCore::createTimingFunctionValue):
     30        Modernize and add support for the spring function.
     31
     32        * css/CSSParser.cpp:
     33        (WebCore::CSSParserContext::CSSParserContext):
     34        (WebCore::operator==):
     35        (WebCore::CSSParser::CSSParser):
     36        (WebCore::CSSParser::parseTransformOriginShorthand):
     37        (WebCore::CSSParser::isSpringTimingFunctionEnabled):
     38        (WebCore::CSSParser::parseCubicBezierTimingFunctionValue):
     39        (WebCore::CSSParser::parseSpringTimingFunctionValue):
     40        (WebCore::CSSParser::parseAnimationTimingFunction):
     41        * css/CSSParser.h:
     42        * css/CSSParserMode.h:
     43        Add parsing support for the spring() function.
     44
     45        * css/CSSTimingFunctionValue.cpp:
     46        (WebCore::CSSCubicBezierTimingFunctionValue::customCSSText):
     47        (WebCore::CSSCubicBezierTimingFunctionValue::equals):
     48        (WebCore::CSSStepsTimingFunctionValue::customCSSText):
     49        (WebCore::CSSStepsTimingFunctionValue::equals):
     50        (WebCore::CSSSpringTimingFunctionValue::customCSSText):
     51        (WebCore::CSSSpringTimingFunctionValue::equals):
     52        * css/CSSTimingFunctionValue.h:
     53        (WebCore::CSSSpringTimingFunctionValue::create):
     54        (WebCore::CSSSpringTimingFunctionValue::mass):
     55        (WebCore::CSSSpringTimingFunctionValue::stiffness):
     56        (WebCore::CSSSpringTimingFunctionValue::damping):
     57        (WebCore::CSSSpringTimingFunctionValue::initialVelocity):
     58        (WebCore::CSSSpringTimingFunctionValue::CSSSpringTimingFunctionValue):
     59        Modernize and add support for the spring function.
     60
     61        * css/CSSToStyleMap.cpp:
     62        (WebCore::CSSToStyleMap::mapAnimationTimingFunction):
     63        Pipe the spring function into the animation.
     64
     65        * css/CSSValue.cpp:
     66        (WebCore::CSSValue::equals):
     67        (WebCore::CSSValue::cssText):
     68        (WebCore::CSSValue::destroy):
     69        * css/CSSValue.h:
     70        (WebCore::CSSValue::isSpringTimingFunctionValue):
     71        Add support for the spring function.
     72       
     73        * page/Settings.in:
     74        Add a setting to control if the spring function is enabled.
     75
     76        * page/animation/AnimationBase.cpp:
     77        (WebCore::solveSpringFunction):
     78        (WebCore::AnimationBase::progress):
     79        Add support for solving the spring function. Since the spring requires time to be absolute,
     80        get the real time by multiplying the ratio t, to the total duration.
     81
     82        * platform/animation/TimingFunction.cpp:
     83        (WebCore::operator<<):
     84        * platform/animation/TimingFunction.h:
     85        (WebCore::TimingFunction::~TimingFunction):
     86        (WebCore::TimingFunction::isSpringTimingFunction):
     87        Add support for the spring timing function.
     88
     89        * platform/graphics/SpringSolver.h: Added.
     90        (WebCore::SpringSolver::SpringSolver):
     91        (WebCore::SpringSolver::solve):
     92        Add a Spring solver that matches the one in CoreAnimation.
     93
     94        * platform/graphics/ca/GraphicsLayerCA.cpp:
     95        (WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
     96        (WebCore::GraphicsLayerCA::appendToUncommittedAnimations):
     97        (WebCore::GraphicsLayerCA::createBasicAnimation):
     98        (WebCore::GraphicsLayerCA::createSpringAnimation):
     99        (WebCore::GraphicsLayerCA::setupAnimation):
     100        * platform/graphics/ca/GraphicsLayerCA.h:
     101        Map animations with spring timing functions to CASpringAnimations.
     102
     103        * platform/graphics/ca/PlatformCAAnimation.cpp:
     104        (WebCore::operator<<):
     105        (WebCore::PlatformCAAnimation::isBasicAnimation):
     106        * platform/graphics/ca/PlatformCAAnimation.h:
     107        (WebCore::PlatformCAAnimation::setActualStartTimeIfNeeded):
     108        (WebCore::PlatformCAAnimation::PlatformCAAnimation):
     109        * platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm:
     110        (WebCore::toCAMediaTimingFunction):
     111        (PlatformCAAnimationCocoa::PlatformCAAnimationCocoa):
     112        (PlatformCAAnimationCocoa::setTimingFunction):
     113        (PlatformCAAnimationCocoa::copyTimingFunctionFrom):
     114        (PlatformCAAnimationCocoa::setFromValue):
     115        (PlatformCAAnimationCocoa::copyFromValueFrom):
     116        (PlatformCAAnimationCocoa::setToValue):
     117        (PlatformCAAnimationCocoa::copyToValueFrom):
     118        Add a new type of PlatformCAAnimation, Spring, which is a sub-type of Basic.
     119
     1202016-06-05  Sam Weinig  <sam@webkit.org>
     121
     122        Add experimental support for spring based CSS animations
     123        https://bugs.webkit.org/show_bug.cgi?id=158403
     124
     125        Reviewed by Dean Jackson.
     126
     127        Adds experimental support for a new CSS animation timing function that uses
     128        spring to model the time function. To use it you replace your normal timing
     129        function, be it cubic-bezier or steps, with a new function called spring().
     130        For instance, for a transition you would write:
     131
     132            transition-timing-function: spring(1 100 10 0);
     133       
     134        The parameters are, in order:
     135            - Mass
     136            - Stiffness
     137            - Damping
     138            - Initial Velocity
     139
     140        Tests: animations/spring-computed-style.html
     141               animations/spring-function.html
     142               animations/spring-parsing.html
     143
     144        * WebCore.xcodeproj/project.pbxproj:
     145        Add new file.
     146
     147        * css/CSSComputedStyleDeclaration.cpp:
     148        (WebCore::createTimingFunctionValue):
     149        Modernize and add support for the spring function.
     150
     151        * css/CSSParser.cpp:
     152        (WebCore::CSSParserContext::CSSParserContext):
     153        (WebCore::operator==):
     154        (WebCore::CSSParser::CSSParser):
     155        (WebCore::CSSParser::parseTransformOriginShorthand):
     156        (WebCore::CSSParser::isSpringTimingFunctionEnabled):
     157        (WebCore::CSSParser::parseCubicBezierTimingFunctionValue):
     158        (WebCore::CSSParser::parseSpringTimingFunctionValue):
     159        (WebCore::CSSParser::parseAnimationTimingFunction):
     160        * css/CSSParser.h:
     161        * css/CSSParserMode.h:
     162        Add parsing support for the spring() function.
     163
     164        * css/CSSTimingFunctionValue.cpp:
     165        (WebCore::CSSCubicBezierTimingFunctionValue::customCSSText):
     166        (WebCore::CSSCubicBezierTimingFunctionValue::equals):
     167        (WebCore::CSSStepsTimingFunctionValue::customCSSText):
     168        (WebCore::CSSStepsTimingFunctionValue::equals):
     169        (WebCore::CSSSpringTimingFunctionValue::customCSSText):
     170        (WebCore::CSSSpringTimingFunctionValue::equals):
     171        * css/CSSTimingFunctionValue.h:
     172        (WebCore::CSSSpringTimingFunctionValue::create):
     173        (WebCore::CSSSpringTimingFunctionValue::mass):
     174        (WebCore::CSSSpringTimingFunctionValue::stiffness):
     175        (WebCore::CSSSpringTimingFunctionValue::damping):
     176        (WebCore::CSSSpringTimingFunctionValue::initialVelocity):
     177        (WebCore::CSSSpringTimingFunctionValue::CSSSpringTimingFunctionValue):
     178        Modernize and add support for the spring function.
     179
     180        * css/CSSToStyleMap.cpp:
     181        (WebCore::CSSToStyleMap::mapAnimationTimingFunction):
     182        Pipe the spring function into the animation.
     183
     184        * css/CSSValue.cpp:
     185        (WebCore::CSSValue::equals):
     186        (WebCore::CSSValue::cssText):
     187        (WebCore::CSSValue::destroy):
     188        * css/CSSValue.h:
     189        (WebCore::CSSValue::isSpringTimingFunctionValue):
     190        Add support for the spring function.
     191       
     192        * page/Settings.in:
     193        Add a setting to control if the spring function is enabled.
     194
     195        * page/animation/AnimationBase.cpp:
     196        (WebCore::solveSpringFunction):
     197        (WebCore::AnimationBase::progress):
     198        Add support for solving the spring function. Since the spring requires time to be absolute,
     199        get the real time by multiplying the ratio t, to the total duration.
     200
     201        * platform/animation/TimingFunction.cpp:
     202        (WebCore::operator<<):
     203        * platform/animation/TimingFunction.h:
     204        (WebCore::TimingFunction::~TimingFunction):
     205        (WebCore::TimingFunction::isSpringTimingFunction):
     206        Add support for the spring timing function.
     207
     208        * platform/graphics/SpringSolver.h: Added.
     209        (WebCore::SpringSolver::SpringSolver):
     210        (WebCore::SpringSolver::solve):
     211        Add a Spring solver that matches the one in CoreAnimation.
     212
     213        * platform/graphics/ca/GraphicsLayerCA.cpp:
     214        (WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
     215        (WebCore::GraphicsLayerCA::appendToUncommittedAnimations):
     216        (WebCore::GraphicsLayerCA::createBasicAnimation):
     217        (WebCore::GraphicsLayerCA::createSpringAnimation):
     218        (WebCore::GraphicsLayerCA::setupAnimation):
     219        * platform/graphics/ca/GraphicsLayerCA.h:
     220        Map animations with spring timing functions to CASpringAnimations.
     221
     222        * platform/graphics/ca/PlatformCAAnimation.cpp:
     223        (WebCore::operator<<):
     224        (WebCore::PlatformCAAnimation::isBasicAnimation):
     225        * platform/graphics/ca/PlatformCAAnimation.h:
     226        (WebCore::PlatformCAAnimation::setActualStartTimeIfNeeded):
     227        (WebCore::PlatformCAAnimation::PlatformCAAnimation):
     228        * platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm:
     229        (WebCore::toCAMediaTimingFunction):
     230        (PlatformCAAnimationCocoa::PlatformCAAnimationCocoa):
     231        (PlatformCAAnimationCocoa::setTimingFunction):
     232        (PlatformCAAnimationCocoa::copyTimingFunctionFrom):
     233        (PlatformCAAnimationCocoa::setFromValue):
     234        (PlatformCAAnimationCocoa::copyFromValueFrom):
     235        (PlatformCAAnimationCocoa::setToValue):
     236        (PlatformCAAnimationCocoa::copyToValueFrom):
     237        Add a new type of PlatformCAAnimation, Spring, which is a sub-type of Basic.
     238
    12392016-06-07  Chris Dumez  <cdumez@apple.com>
    2240
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r201715 r201759  
    27652765                7C7941E41C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */; };
    27662766                7C7941E51C56C29300A4C58E /* DataDetectorsCoreSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C7941E31C56C29300A4C58E /* DataDetectorsCoreSoftLink.h */; };
     2767                7C83DE861D04CC5D00FEBCF3 /* SpringSolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C83DE851D04CBD400FEBCF3 /* SpringSolver.h */; };
    27672768                7C91A38F1B498ABE003F9EFA /* JSNodeOrString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C91A38D1B498ABE003F9EFA /* JSNodeOrString.cpp */; };
    27682769                7C91A3901B498ABE003F9EFA /* JSNodeOrString.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C91A38E1B498ABE003F9EFA /* JSNodeOrString.h */; };
     
    1043110432                7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorsCoreSoftLink.mm; sourceTree = "<group>"; };
    1043210433                7C7941E31C56C29300A4C58E /* DataDetectorsCoreSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataDetectorsCoreSoftLink.h; sourceTree = "<group>"; };
     10434                7C83DE851D04CBD400FEBCF3 /* SpringSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpringSolver.h; sourceTree = "<group>"; };
    1043310435                7C91A38D1B498ABE003F9EFA /* JSNodeOrString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNodeOrString.cpp; sourceTree = "<group>"; };
    1043410436                7C91A38E1B498ABE003F9EFA /* JSNodeOrString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNodeOrString.h; sourceTree = "<group>"; };
     
    2206522067                                CD641EB21818F5ED00EE4C41 /* SourceBufferPrivate.h */,
    2206622068                                CDC8B5AC1804AE5D0016E685 /* SourceBufferPrivateClient.h */,
     22069                                7C83DE851D04CBD400FEBCF3 /* SpringSolver.h */,
    2206722070                                B23540F00D00782E002382FA /* StringTruncator.cpp */,
    2206822071                                B23540F10D00782E002382FA /* StringTruncator.h */,
     
    2784127844                                BC14028B0E83680800319717 /* ScrollbarThemeComposite.h in Headers */,
    2784227845                                44C991860F3D1EBE00586670 /* ScrollbarThemeIOS.h in Headers */,
     27846                                7C83DE861D04CC5D00FEBCF3 /* SpringSolver.h in Headers */,
    2784327847                                BC8B853E0E7C7F1100AB6984 /* ScrollbarThemeMac.h in Headers */,
    2784427848                                0FE71406142170B800DB33BA /* ScrollbarThemeMock.h in Headers */,
  • trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp

    r201715 r201759  
    14991499    switch (timingFunction->type()) {
    15001500    case TimingFunction::CubicBezierFunction: {
    1501         const CubicBezierTimingFunction* bezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction);
    1502         if (bezierTimingFunction->timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
     1501        auto& function = *static_cast<const CubicBezierTimingFunction*>(timingFunction);
     1502        if (function.timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
    15031503            CSSValueID valueId = CSSValueInvalid;
    1504             switch (bezierTimingFunction->timingFunctionPreset()) {
     1504            switch (function.timingFunctionPreset()) {
    15051505            case CubicBezierTimingFunction::Ease:
    15061506                valueId = CSSValueEase;
     
    15131513                break;
    15141514            default:
    1515                 ASSERT(bezierTimingFunction->timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
     1515                ASSERT(function.timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
    15161516                valueId = CSSValueEaseInOut;
    15171517                break;
     
    15191519            return CSSValuePool::singleton().createIdentifierValue(valueId);
    15201520        }
    1521         return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2());
     1521        return CSSCubicBezierTimingFunctionValue::create(function.x1(), function.y1(), function.x2(), function.y2());
    15221522    }
    15231523    case TimingFunction::StepsFunction: {
    1524         const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction);
    1525         return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
     1524        auto& function = *static_cast<const StepsTimingFunction*>(timingFunction);
     1525        return CSSStepsTimingFunctionValue::create(function.numberOfSteps(), function.stepAtStart());
     1526    }
     1527    case TimingFunction::SpringFunction: {
     1528        auto& function = *static_cast<const SpringTimingFunction*>(timingFunction);
     1529        return CSSSpringTimingFunctionValue::create(function.mass(), function.stiffness(), function.damping(), function.initialVelocity());
    15261530    }
    15271531    default:
  • trunk/Source/WebCore/css/CSSParser.cpp

    r201715 r201759  
    271271        textAutosizingEnabled = settings->textAutosizingEnabled();
    272272#endif
     273        springTimingFunctionEnabled = settings->springTimingFunctionEnabled();
    273274    }
    274275
     
    292293        && a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks
    293294        && a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode
    294         && a.useLegacyBackgroundSizeShorthandBehavior == b.useLegacyBackgroundSizeShorthandBehavior;
     295        && a.useLegacyBackgroundSizeShorthandBehavior == b.useLegacyBackgroundSizeShorthandBehavior
     296        && a.springTimingFunctionEnabled == b.springTimingFunctionEnabled;
    295297}
    296298
     
    51585160}
    51595161
    5160 bool CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList& args, double& result)
     5162bool CSSParser::isSpringTimingFunctionEnabled() const
     5163{
     5164    return m_context.springTimingFunctionEnabled;
     5165}
     5166
     5167Optional<double> CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList& args)
    51615168{
    51625169    ValueWithCalculation argumentWithCalculation(*args.current());
    51635170    if (!validateUnit(argumentWithCalculation, FNumber))
    5164         return false;
    5165     result = parsedDouble(argumentWithCalculation);
     5171        return Nullopt;
     5172    Optional<double> result = parsedDouble(argumentWithCalculation);
    51665173    CSSParserValue* nextValue = args.next();
    51675174    if (!nextValue) {
    51685175        // The last number in the function has no comma after it, so we're done.
    5169         return true;
     5176        return result;
    51705177    }
    51715178    if (!isComma(nextValue))
    5172         return false;
     5179        return Nullopt;
    51735180    args.next();
    5174     return true;
     5181    return result;
     5182}
     5183
     5184Optional<double> CSSParser::parseSpringTimingFunctionValue(CSSParserValueList& args)
     5185{
     5186    ValueWithCalculation argumentWithCalculation(*args.current());
     5187    if (!validateUnit(argumentWithCalculation, FNumber))
     5188        return Nullopt;
     5189    Optional<double> result = parsedDouble(argumentWithCalculation);
     5190    args.next();
     5191    return result;
    51755192}
    51765193
     
    52205237
    52215238    if (equalLettersIgnoringASCIICase(value.function->name, "cubic-bezier(")) {
    5222         // For cubic bezier, 4 values must be specified.
     5239        // For cubic bezier, 4 values must be specified (comma-separated).
    52235240        if (!args || args->size() != 7)
    52245241            return nullptr;
    52255242
    52265243        // There are two points specified. The x values must be between 0 and 1 but the y values can exceed this range.
    5227         double x1, y1, x2, y2;
    5228 
    5229         if (!parseCubicBezierTimingFunctionValue(*args, x1))
     5244
     5245        auto x1 = parseCubicBezierTimingFunctionValue(*args);
     5246        if (!x1 || x1.value() < 0 || x1.value() > 1)
    52305247            return nullptr;
    5231         if (x1 < 0 || x1 > 1)
     5248
     5249        auto y1 = parseCubicBezierTimingFunctionValue(*args);
     5250        if (!y1)
    52325251            return nullptr;
    5233         if (!parseCubicBezierTimingFunctionValue(*args, y1))
     5252
     5253        auto x2 = parseCubicBezierTimingFunctionValue(*args);
     5254        if (!x2 || x2.value() < 0 || x2.value() > 1)
    52345255            return nullptr;
    5235         if (!parseCubicBezierTimingFunctionValue(*args, x2))
     5256
     5257        auto y2 = parseCubicBezierTimingFunctionValue(*args);
     5258        if (!y2)
    52365259            return nullptr;
    5237         if (x2 < 0 || x2 > 1)
     5260
     5261        return CSSCubicBezierTimingFunctionValue::create(x1.value(), y1.value(), x2.value(), y2.value());
     5262    }
     5263
     5264    if (isSpringTimingFunctionEnabled() && equalLettersIgnoringASCIICase(value.function->name, "spring(")) {
     5265        // For a spring, 4 values must be specified (space-separated).
     5266        // FIXME: Make the arguments all optional.
     5267        if (!args || args->size() != 4)
    52385268            return nullptr;
    5239         if (!parseCubicBezierTimingFunctionValue(*args, y2))
     5269       
     5270        // Mass must be greater than 0.
     5271        auto mass = parseSpringTimingFunctionValue(*args);
     5272        if (!mass || mass.value() <= 0)
    52405273            return nullptr;
    52415274
    5242         return CSSCubicBezierTimingFunctionValue::create(x1, y1, x2, y2);
     5275        // Stiffness must be greater than 0.
     5276        auto stiffness = parseSpringTimingFunctionValue(*args);
     5277        if (!stiffness || stiffness.value() <= 0)
     5278            return nullptr;
     5279
     5280        // Damping coefficient must be greater than or equal to 0.
     5281        auto damping = parseSpringTimingFunctionValue(*args);
     5282        if (!damping || damping.value() < 0)
     5283            return nullptr;
     5284
     5285        // Initial velocity may have any value.
     5286        auto initialVelocity = parseSpringTimingFunctionValue(*args);
     5287        if (!initialVelocity)
     5288            return nullptr;
     5289
     5290        return CSSSpringTimingFunctionValue::create(mass.value(), stiffness.value(), damping.value(), initialVelocity.value());
    52435291    }
    52445292
  • trunk/Source/WebCore/css/CSSParser.h

    r201715 r201759  
    215215
    216216    bool parseTransformOriginShorthand(RefPtr<CSSPrimitiveValue>&, RefPtr<CSSPrimitiveValue>&, RefPtr<CSSValue>&);
    217     bool parseCubicBezierTimingFunctionValue(CSSParserValueList& args, double& result);
     217    Optional<double> parseCubicBezierTimingFunctionValue(CSSParserValueList&);
     218    Optional<double> parseSpringTimingFunctionValue(CSSParserValueList&);
    218219    bool parseAnimationProperty(CSSPropertyID, RefPtr<CSSValue>&, AnimationParseContext&);
    219220    bool parseTransitionShorthand(CSSPropertyID, bool important);
    220221    bool parseAnimationShorthand(CSSPropertyID, bool important);
     222
     223    bool isSpringTimingFunctionEnabled() const;
    221224
    222225    RefPtr<CSSPrimitiveValue> parseColumnWidth();
  • trunk/Source/WebCore/css/CSSParserMode.h

    r201715 r201759  
    7474    bool enforcesCSSMIMETypeInNoQuirksMode { true };
    7575    bool useLegacyBackgroundSizeShorthandBehavior { false };
     76    bool springTimingFunctionEnabled { false };
    7677};
    7778
  • trunk/Source/WebCore/css/CSSTimingFunctionValue.cpp

    r201715 r201759  
    11/*
    2  * Copyright (C) 2007, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2013, 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#include "CSSTimingFunctionValue.h"
    2828
    29 #include <wtf/text/WTFString.h>
     29#include <wtf/text/StringBuilder.h>
    3030
    3131namespace WebCore {
     
    3333String CSSCubicBezierTimingFunctionValue::customCSSText() const
    3434{
    35     return "cubic-bezier("
    36         + String::number(m_x1) + ", "
    37         + String::number(m_y1) + ", "
    38         + String::number(m_x2) + ", "
    39         + String::number(m_y2) + ')';
     35    StringBuilder builder;
     36    builder.appendLiteral("cubic-bezier(");
     37    builder.appendNumber(m_x1);
     38    builder.appendLiteral(", ");
     39    builder.appendNumber(m_y1);
     40    builder.appendLiteral(", ");
     41    builder.appendNumber(m_x2);
     42    builder.appendLiteral(", ");
     43    builder.appendNumber(m_y2);
     44    builder.append(')');   
     45    return builder.toString();
    4046}
    4147
     
    4551}
    4652
    47 
    4853String CSSStepsTimingFunctionValue::customCSSText() const
    4954{
    50     return "steps(" + String::number(m_steps) + ", " + (m_stepAtStart ? "start" : "end") + ')';
     55    StringBuilder builder;
     56    builder.appendLiteral("steps(");
     57    builder.appendNumber(m_steps);
     58    if (m_stepAtStart)
     59        builder.appendLiteral(", start)");
     60    else
     61        builder.appendLiteral(", end)");
     62    return builder.toString();
    5163}
    5264
     
    5668}
    5769
     70String CSSSpringTimingFunctionValue::customCSSText() const
     71{
     72    StringBuilder builder;
     73    builder.appendLiteral("spring(");
     74    builder.appendNumber(m_mass);
     75    builder.append(' ');
     76    builder.appendNumber(m_stiffness);
     77    builder.append(' ');
     78    builder.appendNumber(m_damping);
     79    builder.append(' ');
     80    builder.appendNumber(m_initialVelocity);
     81    builder.append(')');
     82    return builder.toString();
     83}
     84
     85bool CSSSpringTimingFunctionValue::equals(const CSSSpringTimingFunctionValue& other) const
     86{
     87    return m_mass == other.m_mass && m_stiffness == other.m_stiffness && m_damping == other.m_damping && m_initialVelocity == other.m_initialVelocity;
     88}
     89
     90
    5891} // namespace WebCore
  • trunk/Source/WebCore/css/CSSTimingFunctionValue.h

    r201715 r201759  
    11/*
    2  * Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2012, 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    9090};
    9191
     92class CSSSpringTimingFunctionValue : public CSSValue {
     93public:
     94    static Ref<CSSSpringTimingFunctionValue> create(double mass, double stiffness, double damping, double initialVelocity)
     95    {
     96        return adoptRef(*new CSSSpringTimingFunctionValue(mass, stiffness, damping, initialVelocity));
     97    }
     98
     99    double mass() const { return m_mass; }
     100    double stiffness() const { return m_stiffness; }
     101    double damping() const { return m_damping; }
     102    double initialVelocity() const { return m_initialVelocity; }
     103
     104    String customCSSText() const;
     105
     106    bool equals(const CSSSpringTimingFunctionValue&) const;
     107
     108private:
     109    CSSSpringTimingFunctionValue(double mass, double stiffness, double damping, double initialVelocity)
     110        : CSSValue(SpringTimingFunctionClass)
     111        , m_mass(mass)
     112        , m_stiffness(stiffness)
     113        , m_damping(damping)
     114        , m_initialVelocity(initialVelocity)
     115    {
     116    }
     117
     118    double m_mass;
     119    double m_stiffness;
     120    double m_damping;
     121    double m_initialVelocity;
     122};
     123
    92124} // namespace WebCore
    93125
    94126SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSCubicBezierTimingFunctionValue, isCubicBezierTimingFunctionValue())
    95127SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSStepsTimingFunctionValue, isStepsTimingFunctionValue())
     128SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSSpringTimingFunctionValue, isSpringTimingFunctionValue())
    96129
    97130#endif // CSSTimingFunctionValue_h
  • trunk/Source/WebCore/css/CSSToStyleMap.cpp

    r201715 r201759  
    511511        auto& stepsTimingFunction = downcast<CSSStepsTimingFunctionValue>(value);
    512512        animation.setTimingFunction(StepsTimingFunction::create(stepsTimingFunction.numberOfSteps(), stepsTimingFunction.stepAtStart()));
     513    } else if (is<CSSSpringTimingFunctionValue>(value)) {
     514        auto& springTimingFunction = downcast<CSSSpringTimingFunctionValue>(value);
     515        animation.setTimingFunction(SpringTimingFunction::create(springTimingFunction.mass(), springTimingFunction.stiffness(), springTimingFunction.damping(), springTimingFunction.initialVelocity()));
    513516    }
    514517}
  • trunk/Source/WebCore/css/CSSValue.cpp

    r201715 r201759  
    227227        case StepsTimingFunctionClass:
    228228            return compareCSSValues<CSSStepsTimingFunctionValue>(*this, other);
     229        case SpringTimingFunctionClass:
     230            return compareCSSValues<CSSSpringTimingFunctionValue>(*this, other);
    229231        case UnicodeRangeClass:
    230232            return compareCSSValues<CSSUnicodeRangeValue>(*this, other);
     
    333335    case StepsTimingFunctionClass:
    334336        return downcast<CSSStepsTimingFunctionValue>(*this).customCSSText();
     337    case SpringTimingFunctionClass:
     338        return downcast<CSSSpringTimingFunctionValue>(*this).customCSSText();
    335339    case UnicodeRangeClass:
    336340        return downcast<CSSUnicodeRangeValue>(*this).customCSSText();
     
    457461    case StepsTimingFunctionClass:
    458462        delete downcast<CSSStepsTimingFunctionValue>(this);
     463        return;
     464    case SpringTimingFunctionClass:
     465        delete downcast<CSSSpringTimingFunctionValue>(this);
    459466        return;
    460467    case UnicodeRangeClass:
  • trunk/Source/WebCore/css/CSSValue.h

    r201715 r201759  
    105105    bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; }
    106106    bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; }
     107    bool isSpringTimingFunctionValue() const { return m_classType == SpringTimingFunctionClass; }
    107108    bool isWebKitCSSTransformValue() const { return m_classType == WebKitCSSTransformClass; }
    108109    bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; }
     
    162163        CubicBezierTimingFunctionClass,
    163164        StepsTimingFunctionClass,
     165        SpringTimingFunctionClass,
    164166
    165167        // Other class types.
  • trunk/Source/WebCore/page/Settings.in

    r201715 r201759  
    268268
    269269shouldConvertInvalidURLsToBlank initial=true
     270
     271springTimingFunctionEnabled initial=false
  • trunk/Source/WebCore/page/animation/AnimationBase.cpp

    r201715 r201759  
    4242#include "RenderStyle.h"
    4343#include "RenderView.h"
     44#include "SpringSolver.h"
    4445#include "UnitBezier.h"
    4546#include <algorithm>
     
    6970        return std::min(1.0, (floor(numSteps * t) + 1) / numSteps);
    7071    return floor(numSteps * t) / numSteps;
     72}
     73
     74static inline double solveSpringFunction(double mass, double stiffness, double damping, double initialVelocity, double t, double duration)
     75{
     76    SpringSolver solver(mass, stiffness, damping, initialVelocity);
     77    return solver.solve(t * duration);
    7178}
    7279
     
    649656    switch (timingFunction->type()) {
    650657    case TimingFunction::CubicBezierFunction: {
    651         const CubicBezierTimingFunction* function = static_cast<const CubicBezierTimingFunction*>(timingFunction);
    652         return solveCubicBezierFunction(function->x1(), function->y1(), function->x2(), function->y2(), fractionalTime, m_animation->duration());
     658        auto& function = *static_cast<const CubicBezierTimingFunction*>(timingFunction);
     659        return solveCubicBezierFunction(function.x1(), function.y1(), function.x2(), function.y2(), fractionalTime, m_animation->duration());
    653660    }
    654661    case TimingFunction::StepsFunction: {
    655         const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction);
    656         return solveStepsFunction(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart(), fractionalTime);
     662        auto& function = *static_cast<const StepsTimingFunction*>(timingFunction);
     663        return solveStepsFunction(function.numberOfSteps(), function.stepAtStart(), fractionalTime);
     664    }
     665    case TimingFunction::SpringFunction: {
     666        auto& function = *static_cast<const SpringTimingFunction*>(timingFunction);
     667        return solveSpringFunction(function.mass(), function.stiffness(), function.damping(), function.initialVelocity(), fractionalTime, m_animation->duration());
    657668    }
    658669    case TimingFunction::LinearFunction:
  • trunk/Source/WebCore/platform/animation/TimingFunction.cpp

    r201715 r201759  
    3838        break;
    3939    case TimingFunction::CubicBezierFunction: {
    40         const CubicBezierTimingFunction& cubicBezierFunction = static_cast<const CubicBezierTimingFunction&>(timingFunction);
    41         ts << "cubic-bezier(" << cubicBezierFunction.x1() << ", " << cubicBezierFunction.y1() << ", " <<  cubicBezierFunction.x2() << ", " << cubicBezierFunction.y2() << ")";
     40        auto& function = static_cast<const CubicBezierTimingFunction&>(timingFunction);
     41        ts << "cubic-bezier(" << function.x1() << ", " << function.y1() << ", " <<  function.x2() << ", " << function.y2() << ")";
    4242        break;
    4343    }
    4444    case TimingFunction::StepsFunction: {
    45         const StepsTimingFunction& stepsFunction = static_cast<const StepsTimingFunction&>(timingFunction);
    46         ts << "steps(" << stepsFunction.numberOfSteps() << ", " << (stepsFunction.stepAtStart() ? "start" : "end") << ")";
     45        auto& function = static_cast<const StepsTimingFunction&>(timingFunction);
     46        ts << "steps(" << function.numberOfSteps() << ", " << (function.stepAtStart() ? "start" : "end") << ")";
     47        break;
     48    }
     49    case TimingFunction::SpringFunction: {
     50        auto& function = static_cast<const SpringTimingFunction&>(timingFunction);
     51        ts << "spring(" << function.mass() << " " << function.stiffness() << " " <<  function.damping() << " " << function.initialVelocity() << ")";
    4752        break;
    4853    }
  • trunk/Source/WebCore/platform/animation/TimingFunction.h

    r201715 r201759  
    3737
    3838    enum TimingFunctionType {
    39         LinearFunction, CubicBezierFunction, StepsFunction
     39        LinearFunction, CubicBezierFunction, StepsFunction, SpringFunction
    4040    };
    4141   
     
    4747    bool isCubicBezierTimingFunction() const { return m_type == CubicBezierFunction; }
    4848    bool isStepsTimingFunction() const { return m_type == StepsFunction; }
     49    bool isSpringTimingFunction() const { return m_type == SpringFunction; }
    4950   
    5051    virtual bool operator==(const TimingFunction& other) = 0;
     
    5960};
    6061
    61 class LinearTimingFunction : public TimingFunction {
     62class LinearTimingFunction final : public TimingFunction {
    6263public:
    6364    static PassRefPtr<LinearTimingFunction> create()
     
    8586};
    8687
    87 class CubicBezierTimingFunction : public TimingFunction {
     88class CubicBezierTimingFunction final : public TimingFunction {
    8889public:
    8990    enum TimingFunctionPreset {
     
    186187};
    187188
    188 class StepsTimingFunction : public TimingFunction {
     189class StepsTimingFunction final : public TimingFunction {
    189190public:
    190191   
     
    232233};
    233234
     235class SpringTimingFunction final : public TimingFunction {
     236public:
     237    static Ref<SpringTimingFunction> create(double mass, double stiffness, double damping, double initialVelocity)
     238    {
     239        return adoptRef(*new SpringTimingFunction(mass, stiffness, damping, initialVelocity));
     240    }
     241
     242    static Ref<SpringTimingFunction> create()
     243    {
     244        // This create() function should only be used by the argument decoders, and it is expected that
     245        // real values will be filled in using setValues().
     246        return create(0, 0, 0, 0);
     247    }
     248   
     249    bool operator==(const TimingFunction& other) override
     250    {
     251        if (other.isSpringTimingFunction()) {
     252            const SpringTimingFunction& otherString = *static_cast<const SpringTimingFunction*>(&other);
     253            return m_mass == otherString.m_mass && m_stiffness == otherString.m_stiffness && m_damping == otherString.m_damping && m_initialVelocity == otherString.m_initialVelocity;
     254        }
     255        return false;
     256    }
     257
     258    double mass() const { return m_mass; }
     259    double stiffness() const { return m_stiffness; }
     260    double damping() const { return m_damping; }
     261    double initialVelocity() const { return m_initialVelocity; }
     262   
     263    void setValues(double mass, double stiffness, double damping, double initialVelocity)
     264    {
     265        m_mass = mass;
     266        m_stiffness = stiffness;
     267        m_damping = damping;
     268        m_initialVelocity = initialVelocity;
     269    }
     270
     271private:
     272    explicit SpringTimingFunction(double mass, double stiffness, double damping, double initialVelocity)
     273        : TimingFunction(SpringFunction)
     274        , m_mass(mass)
     275        , m_stiffness(stiffness)
     276        , m_damping(damping)
     277        , m_initialVelocity(initialVelocity)
     278    {
     279    }
     280
     281    PassRefPtr<TimingFunction> clone() const override
     282    {
     283        return adoptRef(new SpringTimingFunction(m_mass, m_stiffness, m_damping, m_initialVelocity));
     284    }
     285
     286    double m_mass;
     287    double m_stiffness;
     288    double m_damping;
     289    double m_initialVelocity;
     290};
     291
    234292class TextStream;
    235293WEBCORE_EXPORT TextStream& operator<<(TextStream&, const TimingFunction&);
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r201715 r201759  
    27442744        valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
    27452745    } else {
    2746         caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
     2746        if (animation->timingFunction()->isSpringTimingFunction())
     2747            caAnimation = createSpringAnimation(animation, propertyIdToString(valueList.property()), additive);
     2748        else
     2749            caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
    27472750        valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get());
    27482751    }
     
    27682771        validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
    27692772    } else {
    2770         caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
     2773        if (animation->timingFunction()->isSpringTimingFunction())
     2774            caAnimation = createSpringAnimation(animation, propertyIdToString(valueList.property()), additive);
     2775        else
     2776            caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
    27712777        validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
    27722778    }
     
    29022908}
    29032909
    2904 PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
     2910PassRefPtr<PlatformCAAnimation> GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
    29052911{
    29062912    RefPtr<PlatformCAAnimation> keyframeAnim = createPlatformCAAnimation(PlatformCAAnimation::Keyframe, keyPath);
    29072913    setupAnimation(keyframeAnim.get(), anim, additive);
    29082914    return keyframeAnim;
     2915}
     2916
     2917RefPtr<PlatformCAAnimation> GraphicsLayerCA::createSpringAnimation(const Animation* anim, const String& keyPath, bool additive)
     2918{
     2919    auto basicAnim = createPlatformCAAnimation(PlatformCAAnimation::Spring, keyPath);
     2920    setupAnimation(basicAnim.get(), anim, additive);
     2921    return basicAnim;
    29092922}
    29102923
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h

    r201715 r201759  
    243243    PassRefPtr<PlatformCAAnimation> createBasicAnimation(const Animation*, const String& keyPath, bool additive);
    244244    PassRefPtr<PlatformCAAnimation> createKeyframeAnimation(const Animation*, const String&, bool additive);
     245    RefPtr<PlatformCAAnimation> createSpringAnimation(const Animation*, const String&, bool additive);
    245246    void setupAnimation(PlatformCAAnimation*, const Animation*, bool additive);
    246247   
  • trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.cpp

    r201715 r201759  
    3636    case PlatformCAAnimation::Basic: ts << "basic"; break;
    3737    case PlatformCAAnimation::Keyframe: ts << "keyframe"; break;
     38    case PlatformCAAnimation::Spring: ts << "spring"; break;
    3839    }
    3940    return ts;
     
    7071}
    7172
     73bool PlatformCAAnimation::isBasicAnimation() const
     74{
     75    return animationType() == Basic || animationType() == Spring;
     76}
     77
    7278} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h

    r201715 r201759  
    4242class PlatformCAAnimation : public RefCounted<PlatformCAAnimation> {
    4343public:
    44     enum AnimationType { Basic, Keyframe };
     44    enum AnimationType { Basic, Keyframe, Spring };
    4545    enum FillModeType { NoFillMode, Forwards, Backwards, Both };
    4646    enum ValueFunctionType { NoValueFunction, RotateX, RotateY, RotateZ, ScaleX, ScaleY, ScaleZ, Scale, TranslateX, TranslateY, TranslateZ, Translate };
     
    124124            setBeginTime(t);
    125125    }
     126
     127    bool isBasicAnimation() const;
    126128   
    127129protected:
  • trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm

    r201715 r201759  
    2424 */
    2525
    26 #include "config.h"
     26#import "config.h"
    2727#import "PlatformCAAnimationCocoa.h"
    2828
    2929#import "FloatConversion.h"
    3030#import "PlatformCAFilters.h"
     31#import "QuartzCoreSPI.h"
    3132#import "TimingFunction.h"
    3233#import <QuartzCore/QuartzCore.h>
     
    162163    : PlatformCAAnimation(type)
    163164{
    164     if (type == Basic)
     165    switch (type) {
     166    case Basic:
    165167        m_animation = [CABasicAnimation animationWithKeyPath:keyPath];
    166     else
     168        break;
     169    case Keyframe:
    167170        m_animation = [CAKeyframeAnimation animationWithKeyPath:keyPath];
     171        break;
     172    case Spring:
     173        m_animation = [CASpringAnimation animationWithKeyPath:keyPath];
     174        break;
     175    }
    168176}
    169177
    170178PlatformCAAnimationCocoa::PlatformCAAnimationCocoa(PlatformAnimationRef animation)
    171179{
    172     if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CABasicAnimation class]])
    173         setType(Basic);
    174     else if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CAKeyframeAnimation class]])
     180    if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CABasicAnimation class]]) {
     181        if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CASpringAnimation class]])
     182            setType(Spring);
     183        else
     184            setType(Basic);
     185    } else if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CAKeyframeAnimation class]])
    175186        setType(Keyframe);
    176187    else {
    177         ASSERT(0);
     188        ASSERT_NOT_REACHED();
    178189        return;
    179190    }
     
    306317void PlatformCAAnimationCocoa::setTimingFunction(const TimingFunction* value, bool reverse)
    307318{
    308     [m_animation setTimingFunction:toCAMediaTimingFunction(value, reverse)];
     319    switch (animationType()) {
     320    case Basic:
     321    case Keyframe:
     322        [m_animation setTimingFunction:toCAMediaTimingFunction(value, reverse)];
     323        break;
     324    case Spring:
     325        if (value->isSpringTimingFunction()) {
     326            // FIXME: Handle reverse.
     327            auto& function = *static_cast<const SpringTimingFunction*>(value);
     328            CASpringAnimation *springAnimation = (CASpringAnimation *)m_animation.get();
     329            springAnimation.mass = function.mass();
     330            springAnimation.stiffness = function.stiffness();
     331            springAnimation.damping = function.damping();
     332#if PLATFORM(IOS) || PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
     333            springAnimation.initialVelocity = function.initialVelocity();
     334#else
     335            springAnimation.velocity = function.initialVelocity();
     336#endif
     337        }
     338        break;
     339    }
    309340}
    310341
     
    347378void PlatformCAAnimationCocoa::setFromValue(float value)
    348379{
    349     if (animationType() != Basic)
     380    if (!isBasicAnimation())
    350381        return;
    351382    [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:[NSNumber numberWithDouble:value]];
     
    354385void PlatformCAAnimationCocoa::setFromValue(const WebCore::TransformationMatrix& value)
    355386{
    356     if (animationType() != Basic)
     387    if (!isBasicAnimation())
    357388        return;
    358389
     
    362393void PlatformCAAnimationCocoa::setFromValue(const FloatPoint3D& value)
    363394{
    364     if (animationType() != Basic)
     395    if (!isBasicAnimation())
    365396        return;
    366397
     
    375406void PlatformCAAnimationCocoa::setFromValue(const WebCore::Color& value)
    376407{
    377     if (animationType() != Basic)
     408    if (!isBasicAnimation())
    378409        return;
    379410
     
    395426void PlatformCAAnimationCocoa::copyFromValueFrom(const PlatformCAAnimation& value)
    396427{
    397     if (animationType() != Basic || value.animationType() != Basic)
     428    if (!isBasicAnimation() || !value.isBasicAnimation())
    398429        return;
    399430
     
    404435void PlatformCAAnimationCocoa::setToValue(float value)
    405436{
    406     if (animationType() != Basic)
     437    if (!isBasicAnimation())
    407438        return;
    408439    [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:[NSNumber numberWithDouble:value]];
     
    411442void PlatformCAAnimationCocoa::setToValue(const WebCore::TransformationMatrix& value)
    412443{
    413     if (animationType() != Basic)
     444    if (!isBasicAnimation())
    414445        return;
    415446
     
    419450void PlatformCAAnimationCocoa::setToValue(const FloatPoint3D& value)
    420451{
    421     if (animationType() != Basic)
     452    if (!isBasicAnimation())
    422453        return;
    423454
     
    432463void PlatformCAAnimationCocoa::setToValue(const WebCore::Color& value)
    433464{
    434     if (animationType() != Basic)
     465    if (!isBasicAnimation())
    435466        return;
    436467
     
    452483void PlatformCAAnimationCocoa::copyToValueFrom(const PlatformCAAnimation& value)
    453484{
    454     if (animationType() != Basic || value.animationType() != Basic)
     485    if (!isBasicAnimation() || !value.isBasicAnimation())
    455486        return;
    456487
  • trunk/Source/WebCore/platform/spi/cocoa/QuartzCoreSPI.h

    r201633 r201759  
    142142@end
    143143
     144#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED <= 101000
     145@interface CASpringAnimation : CABasicAnimation
     146@property CGFloat mass;
     147@property CGFloat stiffness;
     148@property CGFloat damping;
     149@property CGFloat velocity;
     150@end
     151#else
     152@interface CASpringAnimation (Private)
     153@property CGFloat velocity;
     154@end
     155#endif
     156
    144157#endif // __OBJC__
    145158
  • trunk/Source/WebKit2/ChangeLog

    r201749 r201759  
     12016-06-05  Sam Weinig  <sam@webkit.org>
     2
     3        Add experimental support for spring based CSS animations
     4        https://bugs.webkit.org/show_bug.cgi?id=158403
     5
     6        Reviewed by Dean Jackson.
     7
     8        * Shared/WebCoreArgumentCoders.cpp:
     9        (IPC::ArgumentCoder<StepsTimingFunction>::decode):
     10        (IPC::ArgumentCoder<SpringTimingFunction>::encode):
     11        (IPC::ArgumentCoder<SpringTimingFunction>::decode):
     12        (IPC::ArgumentCoder<FloatPoint>::encode):
     13        * Shared/WebCoreArgumentCoders.h:
     14        * Shared/WebPreferencesDefinitions.h:
     15        * WebProcess/WebPage/WebPage.cpp:
     16        (WebKit::WebPage::updatePreferences):
     17        * WebProcess/WebPage/mac/PlatformCAAnimationRemote.mm:
     18        (WebKit::PlatformCAAnimationRemote::Properties::encode):
     19        (WebKit::PlatformCAAnimationRemote::Properties::decode):
     20        (WebKit::addAnimationToLayer):
     21        Pipe through support for the Spring animation.
     22
    1232016-06-07  Michael Catanzaro  <mcatanzaro@igalia.com>
    224
  • trunk/Source/WebKit2/Shared/CoordinatedGraphics/CoordinatedGraphicsArgumentCoders.cpp

    r201715 r201759  
    366366        break;
    367367    }
     368    case TimingFunction::SpringFunction: {
     369        const SpringTimingFunction* spring = static_cast<const SpringTimingFunction*>(timingFunction);
     370        encoder << spring->mass();
     371        encoder << spring->stiffness();
     372        encoder << spring->damping();
     373        encoder << spring->initialVelocity();
     374        break;
     375    }
    368376    }
    369377}
     
    412420
    413421        timingFunction = StepsTimingFunction::create(numberOfSteps, stepAtStart);
     422        return true;
     423    }
     424    case TimingFunction::SpringFunction: {
     425        double mass;
     426        if (!decoder.decode(mass))
     427            return false;
     428        double stiffness;
     429        if (!decoder.decode(stiffness))
     430            return false;
     431        double damping;
     432        if (!decoder.decode(damping))
     433            return false;
     434        double initialVelocity;
     435        if (!decoder.decode(initialVelocity))
     436            return false;
     437
     438        timingFunction = SpringTimingFunction::create(mass, stiffness, damping, initialVelocity);
    414439        return true;
    415440    }
  • trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp

    r201715 r201759  
    266266}
    267267
     268void ArgumentCoder<SpringTimingFunction>::encode(ArgumentEncoder& encoder, const SpringTimingFunction& timingFunction)
     269{
     270    encoder.encodeEnum(timingFunction.type());
     271   
     272    encoder << timingFunction.mass();
     273    encoder << timingFunction.stiffness();
     274    encoder << timingFunction.damping();
     275    encoder << timingFunction.initialVelocity();
     276}
     277
     278bool ArgumentCoder<SpringTimingFunction>::decode(ArgumentDecoder& decoder, SpringTimingFunction& timingFunction)
     279{
     280    // Type is decoded by the caller.
     281    double mass;
     282    if (!decoder.decode(mass))
     283        return false;
     284
     285    double stiffness;
     286    if (!decoder.decode(stiffness))
     287        return false;
     288
     289    double damping;
     290    if (!decoder.decode(damping))
     291        return false;
     292
     293    double initialVelocity;
     294    if (!decoder.decode(initialVelocity))
     295        return false;
     296
     297    timingFunction.setValues(mass, stiffness, damping, initialVelocity);
     298
     299    return true;
     300}
     301
    268302void ArgumentCoder<FloatPoint>::encode(ArgumentEncoder& encoder, const FloatPoint& floatPoint)
    269303{
  • trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h

    r201715 r201759  
    6161class ResourceResponse;
    6262class SessionID;
     63class SpringTimingFunction;
    6364class StepsTimingFunction;
    6465class StickyPositionViewportConstraints;
     
    152153};
    153154
     155template<> struct ArgumentCoder<WebCore::SpringTimingFunction> {
     156    static void encode(ArgumentEncoder&, const WebCore::SpringTimingFunction&);
     157    static bool decode(ArgumentDecoder&, WebCore::SpringTimingFunction&);
     158};
     159
    154160template<> struct ArgumentCoder<WebCore::CertificateInfo> {
    155161    static void encode(ArgumentEncoder&, const WebCore::CertificateInfo&);
  • trunk/Source/WebKit2/Shared/WebPreferencesDefinitions.h

    r201715 r201759  
    294294    macro(CustomElementsEnabled, customElementsEnabled, Bool, bool, true, "Custom Elements", "HTML Custom Elements prototype") \
    295295    macro(WebGL2Enabled, webGL2Enabled, Bool, bool, true, "WebGL 2.0", "WebGL 2 prototype") \
     296    macro(SpringTimingFunctionEnabled, springTimingFunctionEnabled, Bool, bool, true, "CSS Spring Animations", "CSS Spring Animation prototype") \
    296297    \
    297298
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r201715 r201759  
    31513151#endif
    31523152
     3153    settings.setSpringTimingFunctionEnabled(store.getBoolValueForKey(WebPreferencesKey::springTimingFunctionEnabledKey()));
     3154
    31533155    bool processSuppressionEnabled = store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey());
    31543156    if (m_processSuppressionEnabled != processSuppressionEnabled) {
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCAAnimationRemote.mm

    r201715 r201759  
    197197            encoder << *static_cast<StepsTimingFunction*>(timingFunction.get());
    198198            break;
     199
     200        case TimingFunction::SpringFunction:
     201            encoder << *static_cast<SpringTimingFunction*>(timingFunction.get());
     202            break;
    199203        }
    200204    }
     
    283287                    return false;
    284288                break;
     289
     290            case TimingFunction::SpringFunction:
     291                timingFunction = SpringTimingFunction::create();
     292                if (!decoder.decode(*static_cast<SpringTimingFunction*>(timingFunction.get())))
     293                    return false;
     294                break;
    285295            }
    286296           
     
    755765        break;
    756766    }
     767    case PlatformCAAnimation::Spring: {
     768        RetainPtr<CASpringAnimation> springAnimation;
     769        springAnimation = [CASpringAnimation animationWithKeyPath:properties.keyPath];
     770       
     771        if (properties.keyValues.size() > 1) {
     772            [springAnimation setFromValue:animationValueFromKeyframeValue(properties.keyValues[0])];
     773            [springAnimation setToValue:animationValueFromKeyframeValue(properties.keyValues[1])];
     774        }
     775       
     776        if (properties.timingFunctions.size()) {
     777            auto& timingFunction = properties.timingFunctions[0];
     778            if (timingFunction->isSpringTimingFunction()) {
     779                auto& function = *static_cast<const SpringTimingFunction*>(timingFunction.get());
     780                [springAnimation setMass:function.mass()];
     781                [springAnimation setStiffness:function.stiffness()];
     782                [springAnimation setDamping:function.damping()];
     783                [springAnimation setInitialVelocity:function.initialVelocity()];
     784            }
     785        }
     786        caAnimation = springAnimation;
     787        break;
     788    }
    757789    }
    758790   
Note: See TracChangeset for help on using the changeset viewer.