You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
5.0 KiB

  1. // The MIT License (MIT)
  2. //
  3. // Copyright (c) 2016 Luke Zhao <me@lkzhao.com>
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. import UIKit
  23. /// used to construct HeroModifier from heroModifierString
  24. extension HeroModifier: HeroStringConvertible {
  25. public static func from(node: ExprNode) -> HeroModifier? {
  26. let name: String = node.name
  27. let parameters: [ExprNode] = (node as? CallNode)?.arguments ?? []
  28. switch name {
  29. case "fade":
  30. return .fade
  31. case "opacity":
  32. return HeroModifier.opacity(CGFloat(parameters.getFloat(0) ?? 1))
  33. case "position":
  34. return .position(CGPoint(x: parameters.getCGFloat(0) ?? 0, y: parameters.getCGFloat(1) ?? 0))
  35. case "size":
  36. return .size(CGSize(width: parameters.getCGFloat(0) ?? 0, height: parameters.getCGFloat(1) ?? 0))
  37. case "scale":
  38. if parameters.count == 1 {
  39. return .scale(parameters.getCGFloat(0) ?? 1)
  40. } else {
  41. return .scale(x: parameters.getCGFloat(0) ?? 1,
  42. y: parameters.getCGFloat(1) ?? 1,
  43. z: parameters.getCGFloat(2) ?? 1)
  44. }
  45. case "rotate":
  46. if parameters.count == 1 {
  47. return .rotate(parameters.getCGFloat(0) ?? 0)
  48. } else {
  49. return .rotate(x: parameters.getCGFloat(0) ?? 0,
  50. y: parameters.getCGFloat(1) ?? 0,
  51. z: parameters.getCGFloat(2) ?? 0)
  52. }
  53. case "translate":
  54. return .translate(x: parameters.getCGFloat(0) ?? 0,
  55. y: parameters.getCGFloat(1) ?? 0,
  56. z: parameters.getCGFloat(2) ?? 0)
  57. case "overlay":
  58. return .overlay(color: UIColor(red: parameters.getCGFloat(0) ?? 1,
  59. green: parameters.getCGFloat(1) ?? 1,
  60. blue: parameters.getCGFloat(2) ?? 1,
  61. alpha: 1),
  62. opacity: parameters.getCGFloat(3) ?? 1)
  63. case "duration":
  64. if let duration = parameters.getDouble(0) {
  65. return .duration(duration)
  66. }
  67. case "durationMatchLongest":
  68. return .durationMatchLongest
  69. case "delay":
  70. if let delay = parameters.getDouble(0) {
  71. return .delay(delay)
  72. }
  73. case "spring":
  74. if #available(iOS 9, *) {
  75. return .spring(stiffness: parameters.getCGFloat(0) ?? 250, damping: parameters.getCGFloat(1) ?? 30)
  76. }
  77. case "timingFunction":
  78. if let c1 = parameters.getFloat(0),
  79. let c2 = parameters.getFloat(1),
  80. let c3 = parameters.getFloat(2),
  81. let c4 = parameters.getFloat(3) {
  82. return .timingFunction(CAMediaTimingFunction(controlPoints: c1, c2, c3, c4))
  83. } else if let name = parameters.get(0)?.name, let timingFunction = CAMediaTimingFunction.from(name: name) {
  84. return .timingFunction(timingFunction)
  85. }
  86. case "arc":
  87. return .arc(intensity: parameters.getCGFloat(0) ?? 1)
  88. case "cascade":
  89. var cascadeDirection = CascadeDirection.topToBottom
  90. if let directionString = parameters.get(1)?.name,
  91. let direction = CascadeDirection(directionString) {
  92. cascadeDirection = direction
  93. }
  94. return .cascade(delta: parameters.getDouble(0) ?? 0.02, direction: cascadeDirection, delayMatchedViews:parameters.getBool(2) ?? false)
  95. case "source":
  96. if let heroID = parameters.get(0)?.name {
  97. return .source(heroID: heroID)
  98. }
  99. case "useGlobalCoordinateSpace":
  100. return .useGlobalCoordinateSpace
  101. case "ignoreSubviewModifiers":
  102. return .ignoreSubviewModifiers(recursive:parameters.getBool(0) ?? false)
  103. case "zPosition":
  104. if let zPosition = parameters.getCGFloat(0) {
  105. return .zPosition(zPosition)
  106. }
  107. case "useOptimizedSnapshot":
  108. return .useOptimizedSnapshot
  109. case "useNormalSnapshot":
  110. return .useNormalSnapshot
  111. case "useLayerRenderSnapshot":
  112. return .useLayerRenderSnapshot
  113. case "useNoSnapshot":
  114. return .useNoSnapshot
  115. case "forceAnimate":
  116. return .forceAnimate
  117. default: break
  118. }
  119. return nil
  120. }
  121. }