Ver Fonte

Added easing functions demo

Denis Shendrik há 2 anos atrás
pai
commit
503583b0f1
51 ficheiros alterados com 1434 adições e 1 exclusões
  1. 167 0
      assets/easing.atlas
  2. BIN
      assets/easing_functions/easing_inback.png
  3. BIN
      assets/easing_functions/easing_inbounce.png
  4. BIN
      assets/easing_functions/easing_incirc.png
  5. BIN
      assets/easing_functions/easing_incubic.png
  6. BIN
      assets/easing_functions/easing_inelastic.png
  7. BIN
      assets/easing_functions/easing_inexpo.png
  8. BIN
      assets/easing_functions/easing_inoutback.png
  9. BIN
      assets/easing_functions/easing_inoutbounce.png
  10. BIN
      assets/easing_functions/easing_inoutcirc.png
  11. BIN
      assets/easing_functions/easing_inoutcubic.png
  12. BIN
      assets/easing_functions/easing_inoutelastic.png
  13. BIN
      assets/easing_functions/easing_inoutexpo.png
  14. BIN
      assets/easing_functions/easing_inoutquad.png
  15. BIN
      assets/easing_functions/easing_inoutquart.png
  16. BIN
      assets/easing_functions/easing_inoutquint.png
  17. BIN
      assets/easing_functions/easing_inoutsine.png
  18. BIN
      assets/easing_functions/easing_inquad.png
  19. BIN
      assets/easing_functions/easing_inquart.png
  20. BIN
      assets/easing_functions/easing_inquint.png
  21. BIN
      assets/easing_functions/easing_insine.png
  22. BIN
      assets/easing_functions/easing_linear.png
  23. BIN
      assets/easing_functions/easing_outback.png
  24. BIN
      assets/easing_functions/easing_outbounce.png
  25. BIN
      assets/easing_functions/easing_outcirc.png
  26. BIN
      assets/easing_functions/easing_outcubic.png
  27. BIN
      assets/easing_functions/easing_outelastic.png
  28. BIN
      assets/easing_functions/easing_outexpo.png
  29. BIN
      assets/easing_functions/easing_outinback.png
  30. BIN
      assets/easing_functions/easing_outinbounce.png
  31. BIN
      assets/easing_functions/easing_outincirc.png
  32. BIN
      assets/easing_functions/easing_outincubic.png
  33. BIN
      assets/easing_functions/easing_outinelastic.png
  34. BIN
      assets/easing_functions/easing_outinexpo.png
  35. BIN
      assets/easing_functions/easing_outinquad.png
  36. BIN
      assets/easing_functions/easing_outinquart.png
  37. BIN
      assets/easing_functions/easing_outinquint.png
  38. BIN
      assets/easing_functions/easing_outinsine.png
  39. BIN
      assets/easing_functions/easing_outquad.png
  40. BIN
      assets/easing_functions/easing_outquart.png
  41. BIN
      assets/easing_functions/easing_outquint.png
  42. BIN
      assets/easing_functions/easing_outsine.png
  43. 18 0
      examples/_main/loader.go
  44. 1 1
      examples/_main/menu.gui_script
  45. 49 0
      examples/animation/easing/animator.script
  46. 60 0
      examples/animation/easing/controller.script
  47. 270 0
      examples/animation/easing/easing.collection
  48. 755 0
      examples/animation/easing/easing.gui
  49. 52 0
      examples/animation/easing/easing.gui_script
  50. 8 0
      examples/animation/easing/easing.md
  51. 54 0
      examples/animation/easing/easing_functions.lua

+ 167 - 0
assets/easing.atlas

@@ -0,0 +1,167 @@
+images {
+  image: "/assets/easing_functions/easing_inquint.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_insine.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_linear.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outback.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outcirc.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outcubic.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outexpo.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outquad.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outquart.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outquint.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outsine.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inelastic.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutback.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutbounce.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutcirc.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutcubic.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutelastic.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutexpo.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutquad.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutquart.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutquint.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inoutsine.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outbounce.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outelastic.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outinback.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outinbounce.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outincirc.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outincubic.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outinelastic.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outinexpo.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outinquad.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outinquart.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outinquint.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_outinsine.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inback.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inbounce.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_incirc.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_incubic.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inexpo.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inquad.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+images {
+  image: "/assets/easing_functions/easing_inquart.png"
+  sprite_trim_mode: SPRITE_TRIM_MODE_OFF
+}
+margin: 0
+extrude_borders: 2
+inner_padding: 0

BIN
assets/easing_functions/easing_inback.png


BIN
assets/easing_functions/easing_inbounce.png


BIN
assets/easing_functions/easing_incirc.png


BIN
assets/easing_functions/easing_incubic.png


BIN
assets/easing_functions/easing_inelastic.png


BIN
assets/easing_functions/easing_inexpo.png


BIN
assets/easing_functions/easing_inoutback.png


BIN
assets/easing_functions/easing_inoutbounce.png


BIN
assets/easing_functions/easing_inoutcirc.png


BIN
assets/easing_functions/easing_inoutcubic.png


BIN
assets/easing_functions/easing_inoutelastic.png


BIN
assets/easing_functions/easing_inoutexpo.png


BIN
assets/easing_functions/easing_inoutquad.png


BIN
assets/easing_functions/easing_inoutquart.png


BIN
assets/easing_functions/easing_inoutquint.png


BIN
assets/easing_functions/easing_inoutsine.png


BIN
assets/easing_functions/easing_inquad.png


BIN
assets/easing_functions/easing_inquart.png


BIN
assets/easing_functions/easing_inquint.png


BIN
assets/easing_functions/easing_insine.png


BIN
assets/easing_functions/easing_linear.png


BIN
assets/easing_functions/easing_outback.png


BIN
assets/easing_functions/easing_outbounce.png


BIN
assets/easing_functions/easing_outcirc.png


BIN
assets/easing_functions/easing_outcubic.png


BIN
assets/easing_functions/easing_outelastic.png


BIN
assets/easing_functions/easing_outexpo.png


BIN
assets/easing_functions/easing_outinback.png


BIN
assets/easing_functions/easing_outinbounce.png


BIN
assets/easing_functions/easing_outincirc.png


BIN
assets/easing_functions/easing_outincubic.png


BIN
assets/easing_functions/easing_outinelastic.png


BIN
assets/easing_functions/easing_outinexpo.png


BIN
assets/easing_functions/easing_outinquad.png


BIN
assets/easing_functions/easing_outinquart.png


BIN
assets/easing_functions/easing_outinquint.png


BIN
assets/easing_functions/easing_outinsine.png


BIN
assets/easing_functions/easing_outquad.png


BIN
assets/easing_functions/easing_outquart.png


BIN
assets/easing_functions/easing_outquint.png


BIN
assets/easing_functions/easing_outsine.png


+ 18 - 0
examples/_main/loader.go

@@ -1018,3 +1018,21 @@ embedded_components {
     w: 1.0
   }
 }
+embedded_components {
+  id: "animation/easing"
+  type: "collectionproxy"
+  data: "collection: \"/examples/animation/easing/easing.collection\"\n"
+  "exclude: false\n"
+  ""
+  position {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+}

+ 1 - 1
examples/_main/menu.gui_script

@@ -104,7 +104,7 @@ function init(self)
 	self.index["factory"] = { "basic", "bullets" }
 	self.index["movement"] = { "simple_move", "follow", "move_to", "move_forward", "movement_speed", "look_at" }
 	self.index["physics"] = { "dynamic", "kinematic", "raycast", "trigger", "hinge_joint", "pendulum", "knockback"}
-	self.index["animation"] = { "spinner", "flipbook", "chained_tween", "basic_tween", "spine", "cursor" }
+	self.index["animation"] = { "spinner", "flipbook", "chained_tween", "basic_tween", "spine", "cursor", "easing" }
 	self.index["gui"] = { "button", "stencil", "load_texture", "progress", "pointer_over", "color", "slice9" }
 	self.index["input"] = { "move", "text", "down_duration", "mouse_and_touch" }
 	self.index["particles"] = { "particlefx", "modifiers", "fire_and_smoke" }

+ 49 - 0
examples/animation/easing/animator.script

@@ -0,0 +1,49 @@
+go.property("start_position", vmath.vector3())
+go.property("end_position", vmath.vector3())
+go.property("start_rotation", vmath.vector3())
+go.property("end_rotation", vmath.vector3())
+go.property("start_scale", vmath.vector3(1, 1, 1))
+go.property("end_scale", vmath.vector3(1, 1, 1))
+go.property("duration", 2)
+
+local function should_animate_position(self)
+	return self.start_position ~= self.end_position
+end
+local function should_animate_rotation(self)
+	return self.start_rotation ~= self.end_rotation
+end
+local function should_animate_scale(self)
+	return self.start_scale ~= self.end_scale
+end
+
+local function reset_position_rotation_scale(self)
+	if should_animate_position(self) then
+		go.set_position(self.start_position)
+	end
+	if should_animate_rotation(self) then
+		go.set(".", "euler", self.start_rotation)
+	end
+	if should_animate_scale(self) then
+		go.set_scale(self.start_scale)
+	end
+end
+
+local function animate(self)
+	reset_position_rotation_scale(self)
+	if should_animate_position(self) then
+		go.animate(".", "position", go.PLAYBACK_LOOP_PINGPONG, self.end_position, self.easing, self.duration)
+	end
+	if should_animate_rotation(self) then
+		go.animate(".", "euler", go.PLAYBACK_LOOP_PINGPONG, self.end_rotation, self.easing, self.duration)
+	end
+	if should_animate_scale(self) then
+		go.animate(".", "scale", go.PLAYBACK_LOOP_PINGPONG, self.end_scale, self.easing, self.duration)
+	end
+end
+
+function on_message(self, message_id, message, sender)
+	if message_id == hash("restart") then
+		self.easing = message.easing
+		animate(self)
+	end
+end

+ 60 - 0
examples/animation/easing/controller.script

@@ -0,0 +1,60 @@
+local lookup = require "examples.animation.easing.easing_functions"
+
+local PREVIOUS = -1; local NEXT = 1
+
+local function change_index_by(index, delta)
+	index = (index + delta) % #lookup
+	if index < 1 then
+		index = #lookup
+	end
+	return index
+end
+
+local function restart_demo_animations(easing)
+	msg.post("position_demo", "restart", { easing = easing.value })
+	msg.post("rotation_demo", "restart", { easing = easing.value })
+	msg.post("scale_demo", "restart", { easing = easing.value })
+end
+
+local function update_gui(self)
+	msg.post("/hud#gui", "demo_changed", {
+		index = self.index,
+		total = #lookup,
+		easing_name = self.easing.name
+	})
+end
+
+local function change_easing_demo(self, index_change)
+	self.index = change_index_by(self.index, index_change)
+	self.easing = lookup.get_by_index(self.index)
+	restart_demo_animations(self.easing)
+	update_gui(self)
+end
+
+function init(self)
+	msg.post(".", "acquire_input_focus")
+	self.index = 1
+	self.easing = lookup.get_by_index(self.index)
+	restart_demo_animations(self.easing)
+	update_gui(self)
+end
+
+function final(self)
+	msg.post(".", "release_input_focus")
+end
+
+function on_message(self, message_id, message, sender)
+	if message_id == hash("prev_easing_demo") then
+		change_easing_demo(self, PREVIOUS)
+	elseif message_id == hash("next_easing_demo") then
+		change_easing_demo(self, NEXT)
+	end
+end
+
+function on_input(self, action_id, action)
+	if action_id == hash("left") and action.pressed then
+		change_easing_demo(self, PREVIOUS)
+	elseif action_id == hash("right") and action.pressed then
+		change_easing_demo(self, NEXT)
+	end
+end

+ 270 - 0
examples/animation/easing/easing.collection

@@ -0,0 +1,270 @@
+name: "default"
+scale_along_z: 0
+embedded_instances {
+  id: "hud"
+  data: "components {\n"
+  "  id: \"gui\"\n"
+  "  component: \"/examples/animation/easing/easing.gui\"\n"
+  "  position {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "  }\n"
+  "  rotation {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "    w: 1.0\n"
+  "  }\n"
+  "  property_decls {\n"
+  "  }\n"
+  "}\n"
+  ""
+  position {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale3 {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+  }
+}
+embedded_instances {
+  id: "demo"
+  children: "position_demo"
+  children: "rotation_demo"
+  children: "scale_demo"
+  data: "components {\n"
+  "  id: \"controller\"\n"
+  "  component: \"/examples/animation/easing/controller.script\"\n"
+  "  position {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "  }\n"
+  "  rotation {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "    w: 1.0\n"
+  "  }\n"
+  "  property_decls {\n"
+  "  }\n"
+  "}\n"
+  ""
+  position {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale3 {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+  }
+}
+embedded_instances {
+  id: "position_demo"
+  data: "components {\n"
+  "  id: \"animator\"\n"
+  "  component: \"/examples/animation/easing/animator.script\"\n"
+  "  position {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "  }\n"
+  "  rotation {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "    w: 1.0\n"
+  "  }\n"
+  "  properties {\n"
+  "    id: \"start_position\"\n"
+  "    value: \"200.0, 400.0, 0.0\"\n"
+  "    type: PROPERTY_TYPE_VECTOR3\n"
+  "  }\n"
+  "  properties {\n"
+  "    id: \"end_position\"\n"
+  "    value: \"550.0, 400.0, 0.0\"\n"
+  "    type: PROPERTY_TYPE_VECTOR3\n"
+  "  }\n"
+  "  property_decls {\n"
+  "  }\n"
+  "}\n"
+  "embedded_components {\n"
+  "  id: \"sprite\"\n"
+  "  type: \"sprite\"\n"
+  "  data: \"tile_set: \\\"/assets/sprites.atlas\\\"\\n"
+  "default_animation: \\\"logo-color\\\"\\n"
+  "material: \\\"/builtins/materials/sprite.material\\\"\\n"
+  "blend_mode: BLEND_MODE_ALPHA\\n"
+  "\"\n"
+  "  position {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "  }\n"
+  "  rotation {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "    w: 1.0\n"
+  "  }\n"
+  "}\n"
+  ""
+  position {
+    x: 200.0
+    y: 400.0
+    z: 0.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale3 {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+  }
+}
+embedded_instances {
+  id: "rotation_demo"
+  data: "components {\n"
+  "  id: \"animator\"\n"
+  "  component: \"/examples/animation/easing/animator.script\"\n"
+  "  position {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "  }\n"
+  "  rotation {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "    w: 1.0\n"
+  "  }\n"
+  "  properties {\n"
+  "    id: \"end_rotation\"\n"
+  "    value: \"0.0, 0.0, 180.0\"\n"
+  "    type: PROPERTY_TYPE_VECTOR3\n"
+  "  }\n"
+  "  property_decls {\n"
+  "  }\n"
+  "}\n"
+  "embedded_components {\n"
+  "  id: \"sprite\"\n"
+  "  type: \"sprite\"\n"
+  "  data: \"tile_set: \\\"/assets/sprites.atlas\\\"\\n"
+  "default_animation: \\\"logo-color\\\"\\n"
+  "material: \\\"/builtins/materials/sprite.material\\\"\\n"
+  "blend_mode: BLEND_MODE_ALPHA\\n"
+  "\"\n"
+  "  position {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "  }\n"
+  "  rotation {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "    w: 1.0\n"
+  "  }\n"
+  "}\n"
+  ""
+  position {
+    x: 200.0
+    y: 600.0
+    z: 0.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale3 {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+  }
+}
+embedded_instances {
+  id: "scale_demo"
+  data: "components {\n"
+  "  id: \"animator\"\n"
+  "  component: \"/examples/animation/easing/animator.script\"\n"
+  "  position {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "  }\n"
+  "  rotation {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "    w: 1.0\n"
+  "  }\n"
+  "  properties {\n"
+  "    id: \"end_scale\"\n"
+  "    value: \"1.7, 1.7, 1.0\"\n"
+  "    type: PROPERTY_TYPE_VECTOR3\n"
+  "  }\n"
+  "  property_decls {\n"
+  "  }\n"
+  "}\n"
+  "embedded_components {\n"
+  "  id: \"sprite\"\n"
+  "  type: \"sprite\"\n"
+  "  data: \"tile_set: \\\"/assets/sprites.atlas\\\"\\n"
+  "default_animation: \\\"logo-color\\\"\\n"
+  "material: \\\"/builtins/materials/sprite.material\\\"\\n"
+  "blend_mode: BLEND_MODE_ALPHA\\n"
+  "\"\n"
+  "  position {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "  }\n"
+  "  rotation {\n"
+  "    x: 0.0\n"
+  "    y: 0.0\n"
+  "    z: 0.0\n"
+  "    w: 1.0\n"
+  "  }\n"
+  "}\n"
+  ""
+  position {
+    x: 500.0
+    y: 600.0
+    z: 0.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale3 {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+  }
+}

+ 755 - 0
examples/animation/easing/easing.gui

@@ -0,0 +1,755 @@
+script: "/examples/animation/easing/easing.gui_script"
+fonts {
+  name: "text24"
+  font: "/assets/text24.font"
+}
+textures {
+  name: "easing"
+  texture: "/assets/easing.atlas"
+}
+textures {
+  name: "ui"
+  texture: "/assets/ui.atlas"
+}
+background_color {
+  x: 0.0
+  y: 0.0
+  z: 0.0
+  w: 0.0
+}
+nodes {
+  position {
+    x: 360.0
+    y: 25.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 200.0
+    y: 100.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  type: TYPE_BOX
+  blend_mode: BLEND_MODE_ALPHA
+  texture: ""
+  id: "container"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  adjust_mode: ADJUST_MODE_FIT
+  layer: "graphics"
+  inherit_alpha: true
+  slice9 {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 0.0
+  }
+  clipping_mode: CLIPPING_MODE_NONE
+  clipping_visible: true
+  clipping_inverted: false
+  alpha: 1.0
+  template_node_child: false
+  size_mode: SIZE_MODE_AUTO
+  custom_type: 0
+  enabled: true
+  visible: false
+}
+nodes {
+  position {
+    x: 0.0
+    y: 135.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 230.0
+    y: 210.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 0.3019608
+    y: 0.3019608
+    z: 0.3019608
+    w: 1.0
+  }
+  type: TYPE_BOX
+  blend_mode: BLEND_MODE_ALPHA
+  texture: ""
+  id: "function_graph_box"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  adjust_mode: ADJUST_MODE_FIT
+  parent: "container"
+  layer: "graphics"
+  inherit_alpha: true
+  slice9 {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 0.0
+  }
+  clipping_mode: CLIPPING_MODE_NONE
+  clipping_visible: true
+  clipping_inverted: false
+  alpha: 1.0
+  template_node_child: false
+  size_mode: SIZE_MODE_MANUAL
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: 0.0
+    y: 13.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 200.0
+    y: 200.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  type: TYPE_BOX
+  blend_mode: BLEND_MODE_ALPHA
+  texture: "easing/easing_inback"
+  id: "function_graph"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  adjust_mode: ADJUST_MODE_FIT
+  parent: "function_graph_box"
+  layer: "graphics"
+  inherit_alpha: true
+  slice9 {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 0.0
+  }
+  clipping_mode: CLIPPING_MODE_NONE
+  clipping_visible: true
+  clipping_inverted: false
+  alpha: 1.0
+  template_node_child: false
+  size_mode: SIZE_MODE_AUTO
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: 0.0
+    y: 104.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 200.0
+    y: 20.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  type: TYPE_BOX
+  blend_mode: BLEND_MODE_ALPHA
+  texture: ""
+  id: "hide_name"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  adjust_mode: ADJUST_MODE_FIT
+  parent: "function_graph_box"
+  layer: "graphics"
+  inherit_alpha: true
+  slice9 {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 0.0
+  }
+  clipping_mode: CLIPPING_MODE_NONE
+  clipping_visible: true
+  clipping_inverted: false
+  alpha: 1.0
+  template_node_child: false
+  size_mode: SIZE_MODE_MANUAL
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: -59.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 113.0
+    y: 40.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 0.3019608
+    y: 0.3019608
+    z: 0.3019608
+    w: 1.0
+  }
+  type: TYPE_BOX
+  blend_mode: BLEND_MODE_ALPHA
+  texture: ""
+  id: "prev_button"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  adjust_mode: ADJUST_MODE_FIT
+  parent: "container"
+  layer: "graphics"
+  inherit_alpha: true
+  slice9 {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 0.0
+  }
+  clipping_mode: CLIPPING_MODE_NONE
+  clipping_visible: true
+  clipping_inverted: false
+  alpha: 1.0
+  template_node_child: false
+  size_mode: SIZE_MODE_MANUAL
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: 0.0
+    y: 1.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 120.0
+    y: 50.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  type: TYPE_TEXT
+  blend_mode: BLEND_MODE_ALPHA
+  text: "Previous"
+  font: "text24"
+  id: "text"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  outline {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  shadow {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  adjust_mode: ADJUST_MODE_FIT
+  line_break: false
+  parent: "prev_button"
+  layer: "text"
+  inherit_alpha: true
+  alpha: 1.0
+  outline_alpha: 1.0
+  shadow_alpha: 1.0
+  template_node_child: false
+  text_leading: 1.0
+  text_tracking: 0.0
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: 59.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 113.0
+    y: 40.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 0.3019608
+    y: 0.3019608
+    z: 0.3019608
+    w: 1.0
+  }
+  type: TYPE_BOX
+  blend_mode: BLEND_MODE_ALPHA
+  texture: ""
+  id: "next_button"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  adjust_mode: ADJUST_MODE_FIT
+  parent: "container"
+  layer: "graphics"
+  inherit_alpha: true
+  slice9 {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 0.0
+  }
+  clipping_mode: CLIPPING_MODE_NONE
+  clipping_visible: true
+  clipping_inverted: false
+  alpha: 1.0
+  template_node_child: false
+  size_mode: SIZE_MODE_MANUAL
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: 0.0
+    y: 1.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 120.0
+    y: 50.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  type: TYPE_TEXT
+  blend_mode: BLEND_MODE_ALPHA
+  text: "Next"
+  font: "text24"
+  id: "text1"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  outline {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  shadow {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  adjust_mode: ADJUST_MODE_FIT
+  line_break: false
+  parent: "next_button"
+  layer: "text"
+  inherit_alpha: true
+  alpha: 1.0
+  outline_alpha: 1.0
+  shadow_alpha: 1.0
+  template_node_child: false
+  text_leading: 1.0
+  text_tracking: 0.0
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: 0.0
+    y: 40.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 230.0
+    y: 30.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 0.3019608
+    y: 0.3019608
+    z: 0.3019608
+    w: 1.0
+  }
+  type: TYPE_BOX
+  blend_mode: BLEND_MODE_ALPHA
+  texture: ""
+  id: "index"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  adjust_mode: ADJUST_MODE_FIT
+  parent: "container"
+  layer: ""
+  inherit_alpha: true
+  slice9 {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 0.0
+  }
+  clipping_mode: CLIPPING_MODE_NONE
+  clipping_visible: true
+  clipping_inverted: false
+  alpha: 1.0
+  template_node_child: false
+  size_mode: SIZE_MODE_MANUAL
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 0.8
+    y: 0.8
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 288.0
+    y: 40.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  type: TYPE_TEXT
+  blend_mode: BLEND_MODE_ALPHA
+  text: "1/40"
+  font: "text24"
+  id: "index_text"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  outline {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  shadow {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  adjust_mode: ADJUST_MODE_FIT
+  line_break: false
+  parent: "index"
+  layer: "text"
+  inherit_alpha: true
+  alpha: 1.0
+  outline_alpha: 1.0
+  shadow_alpha: 1.0
+  template_node_child: false
+  text_leading: 1.0
+  text_tracking: 0.0
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: 0.0
+    y: 247.0
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 230.0
+    y: 30.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 0.3019608
+    y: 0.3019608
+    z: 0.3019608
+    w: 1.0
+  }
+  type: TYPE_BOX
+  blend_mode: BLEND_MODE_ALPHA
+  texture: ""
+  id: "easing_name"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  adjust_mode: ADJUST_MODE_FIT
+  parent: "container"
+  layer: "graphics"
+  inherit_alpha: true
+  slice9 {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 0.0
+  }
+  clipping_mode: CLIPPING_MODE_NONE
+  clipping_visible: true
+  clipping_inverted: false
+  alpha: 1.0
+  template_node_child: false
+  size_mode: SIZE_MODE_MANUAL
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+nodes {
+  position {
+    x: 0.0
+    y: 1.25
+    z: 0.0
+    w: 1.0
+  }
+  rotation {
+    x: 0.0
+    y: 0.0
+    z: 0.0
+    w: 1.0
+  }
+  scale {
+    x: 0.8
+    y: 0.8
+    z: 1.0
+    w: 1.0
+  }
+  size {
+    x: 288.0
+    y: 30.0
+    z: 0.0
+    w: 1.0
+  }
+  color {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  type: TYPE_TEXT
+  blend_mode: BLEND_MODE_ALPHA
+  text: "go.EASING_NAME"
+  font: "text24"
+  id: "easing_text"
+  xanchor: XANCHOR_NONE
+  yanchor: YANCHOR_NONE
+  pivot: PIVOT_CENTER
+  outline {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  shadow {
+    x: 1.0
+    y: 1.0
+    z: 1.0
+    w: 1.0
+  }
+  adjust_mode: ADJUST_MODE_FIT
+  line_break: false
+  parent: "easing_name"
+  layer: "text"
+  inherit_alpha: true
+  alpha: 1.0
+  outline_alpha: 1.0
+  shadow_alpha: 1.0
+  template_node_child: false
+  text_leading: 1.0
+  text_tracking: 0.0
+  custom_type: 0
+  enabled: true
+  visible: true
+}
+layers {
+  name: "graphics"
+}
+layers {
+  name: "text"
+}
+material: "/builtins/materials/gui.material"
+adjust_reference: ADJUST_REFERENCE_PARENT
+max_nodes: 512

+ 52 - 0
examples/animation/easing/easing.gui_script

@@ -0,0 +1,52 @@
+local function update_index_text(index, total)
+	local index_text = gui.get_node("index_text")
+	gui.set_text(index_text, index .."/".. total)
+end
+
+local function update_easing_text(easing_name)
+	local easing_text = gui.get_node("easing_text")
+	gui.set_text(easing_text, "go.".. easing_name)
+end
+
+local function change_function_graph(easing_name)
+	local node = gui.get_node("function_graph")
+	gui.play_flipbook(node, string.lower(easing_name))
+end
+
+local function prev_button_clicked(self)
+	msg.post("/demo#controller", "prev_easing_demo")
+end
+
+local function next_button_clicked(self)
+	msg.post("/demo#controller", "next_easing_demo")
+end
+
+function init(self)
+	msg.post(".", "acquire_input_focus")
+end
+
+function final(self)
+	msg.post(".", "release_input_focus")
+end
+
+function on_message(self, message_id, message)
+	if message_id == hash("demo_changed") then
+		update_index_text(message.index, message.total)
+		update_easing_text(message.easing_name)
+		change_function_graph(message.easing_name)
+	end
+end
+
+function on_input(self, action_id, action)
+	if not action_id then return end -- ignore mouse/finger position
+
+	if action_id == hash("touch") and action.pressed then
+		local prev = gui.get_node("prev_button")
+		local next = gui.get_node("next_button")
+		if gui.pick_node(prev, action.x, action.y) then
+			prev_button_clicked(self)
+		elseif gui.pick_node(next, action.x, action.y) then
+			next_button_clicked(self)
+		end
+	end
+end

+ 8 - 0
examples/animation/easing/easing.md

@@ -0,0 +1,8 @@
+---
+title: Easing functions (tweens)
+brief: This example demonstrates different easing functions available in Defold.
+---
+
+This example demonstrates different easing functions available in Defold.
+
+Read more about property animations in the [manual](https://defold.com/manuals/property-animation/).

+ 54 - 0
examples/animation/easing/easing_functions.lua

@@ -0,0 +1,54 @@
+local M = {}
+
+M[go.EASING_LINEAR] = { name = "EASING_LINEAR", value = go.EASING_LINEAR, description = "linear interpolation" }
+M[go.EASING_INQUAD] = { name = "EASING_INQUAD", value = go.EASING_INQUAD, description = "in-quadratic" }
+M[go.EASING_OUTQUAD] = { name = "EASING_OUTQUAD", value = go.EASING_OUTQUAD, description = "out-quadratic" }
+M[go.EASING_INOUTQUAD] = { name = "EASING_INOUTQUAD", value = go.EASING_INOUTQUAD, description = "in-out-quadratic" }
+M[go.EASING_OUTINQUAD] = { name = "EASING_OUTINQUAD", value = go.EASING_OUTINQUAD, description = "out-in-quadratic" }
+M[go.EASING_INCUBIC] = { name = "EASING_INCUBIC", value = go.EASING_INCUBIC, description = "in-cubic" }
+M[go.EASING_OUTCUBIC] = { name = "EASING_OUTCUBIC", value = go.EASING_OUTCUBIC, description = "out-cubic" }
+M[go.EASING_INOUTCUBIC] = { name = "EASING_INOUTCUBIC", value = go.EASING_INOUTCUBIC, description = "in-out-cubic" }
+M[go.EASING_OUTINCUBIC] = { name = "EASING_OUTINCUBIC", value = go.EASING_OUTINCUBIC, description = "out-in-cubic" }
+M[go.EASING_INQUART] = { name = "EASING_INQUART", value = go.EASING_INQUART, description = "in-quartic" }
+M[go.EASING_OUTQUART] = { name = "EASING_OUTQUART", value = go.EASING_OUTQUART, description = "out-quartic" }
+M[go.EASING_INOUTQUART] = { name = "EASING_INOUTQUART", value = go.EASING_INOUTQUART, description = "in-out-quartic" }
+M[go.EASING_OUTINQUART] = { name = "EASING_OUTINQUART", value = go.EASING_OUTINQUART, description = "out-in-quartic" }
+M[go.EASING_INQUINT] = { name = "EASING_INQUINT", value = go.EASING_INQUINT, description = "in-quintic" }
+M[go.EASING_OUTQUINT] = { name = "EASING_OUTQUINT", value = go.EASING_OUTQUINT, description = "out-quintic" }
+M[go.EASING_INOUTQUINT] = { name = "EASING_INOUTQUINT", value = go.EASING_INOUTQUINT, description = "in-out-quintic" }
+M[go.EASING_OUTINQUINT] = { name = "EASING_OUTINQUINT", value = go.EASING_OUTINQUINT, description = "out-in-quintic" }
+M[go.EASING_INSINE] = { name = "EASING_INSINE", value = go.EASING_INSINE, description = "in-sine" }
+M[go.EASING_OUTSINE] = { name = "EASING_OUTSINE", value = go.EASING_OUTSINE, description = "out-sine" }
+M[go.EASING_INOUTSINE] = { name = "EASING_INOUTSINE", value = go.EASING_INOUTSINE, description = "in-out-sine" }
+M[go.EASING_OUTINSINE] = { name = "EASING_OUTINSINE", value = go.EASING_OUTINSINE, description = "out-in-sine" }
+M[go.EASING_INEXPO] = { name = "EASING_INEXPO", value = go.EASING_INEXPO, description = "in-exponential" }
+M[go.EASING_OUTEXPO] = { name = "EASING_OUTEXPO", value = go.EASING_OUTEXPO, description = "out-exponential" }
+M[go.EASING_INOUTEXPO] = { name = "EASING_INOUTEXPO", value = go.EASING_INOUTEXPO, description = "in-out-exponential" }
+M[go.EASING_OUTINEXPO] = { name = "EASING_OUTINEXPO", value = go.EASING_OUTINEXPO, description = "out-in-exponential" }
+M[go.EASING_INCIRC] = { name = "EASING_INCIRC", value = go.EASING_INCIRC, description = "in-circlic" }
+M[go.EASING_OUTCIRC] = { name = "EASING_OUTCIRC", value = go.EASING_OUTCIRC, description = "out-circlic" }
+M[go.EASING_INOUTCIRC] = { name = "EASING_INOUTCIRC", value = go.EASING_INOUTCIRC, description = "in-out-circlic" }
+M[go.EASING_OUTINCIRC] = { name = "EASING_OUTINCIRC", value = go.EASING_OUTINCIRC, description = "out-in-circlic" }
+M[go.EASING_INELASTIC] = { name = "EASING_INELASTIC", value = go.EASING_INELASTIC, description = "in-elastic" }
+M[go.EASING_OUTELASTIC] = { name = "EASING_OUTELASTIC", value = go.EASING_OUTELASTIC, description = "out-elastic" }
+M[go.EASING_INOUTELASTIC] = { name = "EASING_INOUTELASTIC", value = go.EASING_INOUTELASTIC, description = "in-out-elastic" }
+M[go.EASING_OUTINELASTIC] = { name = "EASING_OUTINELASTIC", value = go.EASING_OUTINELASTIC, description = "out-in-elastic" }
+M[go.EASING_INBACK] = { name = "EASING_INBACK", value = go.EASING_INBACK, description = "in-back" }
+M[go.EASING_OUTBACK] = { name = "EASING_OUTBACK", value = go.EASING_OUTBACK, description = "out-back" }
+M[go.EASING_INOUTBACK] = { name = "EASING_INOUTBACK", value = go.EASING_INOUTBACK, description = "in-out-back" }
+M[go.EASING_OUTINBACK] = { name = "EASING_OUTINBACK", value = go.EASING_OUTINBACK, description = "out-in-back" }
+M[go.EASING_INBOUNCE] = { name = "EASING_INBOUNCE", value = go.EASING_INBOUNCE, description = "in-bounce" }
+M[go.EASING_OUTBOUNCE] = { name = "EASING_OUTBOUNCE", value = go.EASING_OUTBOUNCE, description = "out-bounce" }
+M[go.EASING_INOUTBOUNCE] = { name = "EASING_INOUTBOUNCE", value = go.EASING_INOUTBOUNCE, description = "in-out-bounce" }
+M[go.EASING_OUTINBOUNCE] = { name = "EASING_OUTINBOUNCE", value = go.EASING_OUTINBOUNCE, description = "out-in-bounce" }
+
+function M.get_by_index(index)
+	for i, v in ipairs(M) do
+		if i == index then
+			return v
+		end
+	end
+	return nil
+end
+
+return M