Empirical
Tween.h
Go to the documentation of this file.
1 
33 #ifndef EMP_WEB_TWEEN_H
34 #define EMP_WEB_TWEEN_H
35 
36 #include "emfunctions.h"
37 
38 #include "Widget.h"
39 
40 
41 namespace emp {
42 namespace web {
43 
44  class Tween {
45  private:
46  struct Path {
47  std::function<void(double)> set_fun; // Function to set at each step
48  double start_val; // What value should the path begin with?
49  double end_val; // What value should the path end with?
50  std::function<double(double)> timing; // Time dilation to use (e.g., to ease in and out)
51 
52  void Set(const double frac) {
53  const double cur_val = (end_val - start_val) * timing(frac) + start_val;
54  set_fun(cur_val);
55  }
56  };
57 
58  struct Event {
59  double time;
60  std::function<void()> trigger;
61  };
62 
63  double duration; // How long should this Tween take?
64  Widget default_target; // Default widget to use for specifying paths
65  emp::vector<Path*> paths; // Paths to be updated as part of this tween.
66  emp::vector<Event*> events; // Events to be triggered as specific steps.
67  emp::vector<std::function<void()>> update_funs; // Call after paths are triggered to UD screen.
68  emp::vector<Widget> dependants; // Widgets to be refreshed at each frame.
69 
70  bool running;
71  size_t callback_id;
72 
73  double start_time; // When did the most recent run start?
74  double cur_time; // What time is it now?
75  double run_time; // How long did this previously run?
76 
77  static double LINEAR(double in) { return in; }
78 
79  void AdvanceFrame() {
80  if (!running) return; // If Stop has been called, halt animating.
81 
82  cur_time = emp::GetTime();
83  double frac = (cur_time - start_time + run_time) / duration;
84 
85  // If we're done, make sure we go to the last frame and stop!
86  if (frac > 1.0) { frac = 1.0; running = false; }
87 
88  //@CAO test if any events should be triggered...
89 
90  // Loop through each path and adjust accordingly...
91  for (auto * p : paths) {
92  p->Set(frac);
93  }
94 
95  // Loop through each update function to make sure it gets triggered.
96  for (auto f : update_funs) {
97  f();
98  }
99 
100  // Loop through all dependants be redrawn and do so.
101  for (auto & w : dependants) { w.Redraw(); }
102 
103  // Setup the callback for the next frame of the Tween.
104  EM_ASM_ARGS({
105  requestAnimFrame(function() { emp.Callback($0); });
106  }, callback_id);
107  }
108 
109  public:
111  Tween(double d=1.0, const Widget & t=nullptr)
112  : duration(d*1000), default_target(t), running(false)
113  , start_time(0.0), cur_time(0.0), run_time(0.0)
114  {
115  emp::InitializeAnim(); // Make sure JS is intialized for animations.
116  callback_id = JSWrap( std::function<void()>([this](){ this->AdvanceFrame(); }) );
117  }
119  {
120  for (auto * p : paths) delete p;
121  for (auto * e : events) delete e;
122  }
123 
125  double GetDuration() const { return duration; }
126 
128  Widget GetDefaultTarget() const { return default_target; }
129 
131  Tween & SetDuration(double d) { duration = d*1000; return *this; }
132 
134  Tween & SetDefaultTarget(const Widget & w) { default_target = w; return *this; }
135 
137  Tween & AddPath(std::function<void(double)> set_fun,
138  double start_val, double end_val, std::function<double(double)> timing=LINEAR) {
139  Path * new_path = new Path({set_fun, start_val, end_val, timing});
140  paths.push_back(new_path);
141  return *this;
142  }
143 
145  Tween & AddPath(double & set_var,
146  double start_val, double end_val, std::function<double(double)> timing=LINEAR) {
147  AddPath( [&set_var](double v) { set_var = v; }, start_val, end_val, timing);
148  return *this;
149  }
150 
153  Tween & AddPath(Widget w, std::string setting, double start_val, double end_val) {
154  emp_assert(false && "need to fill in!");
155  return *this;
156  }
157 
159  Tween & AddUpdate(std::function<void(void)> ud_fun) {
160  update_funs.push_back(ud_fun);
161  return *this;
162  }
163 
165  Tween & AddDependant(Widget w) { dependants.push_back(w); return *this; }
166 
168  void Start() {
169  if (running) return; // Already running!
170  running = true;
171  start_time = emp::GetTime(); // Record the time that we started the animation.
172  cur_time = start_time; // Initialize cur_time to now.
173  AdvanceFrame(); // Take the first animation step to get going.
174  }
175 
177  void Stop() {
178  run_time += emp::GetTime() - start_time;
179  running = false;
180  }
181  };
182 
183 }
184 }
185 
186 
187 #endif
double GetTime()
Get the current time, as provided by the web browser.
Definition: emfunctions.h:53
Tween(double d=1.0, const Widget &t=nullptr)
Build a new tween, specifying the duration it should run for and the widget it should modify...
Definition: Tween.h:111
Tween & AddPath(double &set_var, double start_val, double end_val, std::function< double(double)> timing=LINEAR)
Alter the path of the change that this tween should take and the variable it should modify...
Definition: Tween.h:145
Tween & AddDependant(Widget w)
Add a dependant Widget to update as the Tween runs.
Definition: Tween.h:165
Widget GetDefaultTarget() const
Which widget does this Tween modify?
Definition: Tween.h:128
Tween & SetDefaultTarget(const Widget &w)
Change the target of this tween.
Definition: Tween.h:134
void push_back(PB_Ts &&...args)
Definition: vector.h:189
Specialized, useful function for Empirical.
void Start()
Start running this Tween, as configured.
Definition: Tween.h:168
~Tween()
Definition: Tween.h:118
Tween & AddPath(Widget w, std::string setting, double start_val, double end_val)
Definition: Tween.h:153
static bool InitializeAnim()
Stub for when Emscripten is not in use.
Definition: init.h:104
Widgets maintain individual components on a web page and link to Elements.
Definition: Tween.h:44
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Widget is effectively a smart pointer to a WidgetInfo object, plus some basic accessors.
Definition: Widget.h:78
double GetDuration() const
Retrieve the full duration of this Tween.
Definition: Tween.h:125
#define emp_assert(...)
Definition: assert.h:199
Tween & AddUpdate(std::function< void(void)> ud_fun)
Add an additional function to update as the Tween runs.
Definition: Tween.h:159
Tween & SetDuration(double d)
Change the duration of this Tween.
Definition: Tween.h:131
Tween & AddPath(std::function< void(double)> set_fun, double start_val, double end_val, std::function< double(double)> timing=LINEAR)
Alter the path of the change that this tween should take and the function it should call...
Definition: Tween.h:137
void Stop()
Pause this Tween.
Definition: Tween.h:177