Browse code

Implement animation toolset for content elements

Benjamin Roth authored on24/04/2020 15:18:05
Showing5 changed files
... ...
@@ -36,5 +36,18 @@ class TemplateListener implements FrameworkAwareInterface
36 36
     {
37 37
       $template->class = trim($template->class . ' layout_' . $template->es_col_text);
38 38
     }
39
+    if ($template->es_animate)
40
+    {
41
+      $template->class = trim($template->class . ' is-animated ' . $template->es_animate_type);
42
+
43
+      if ($template->es_animate_children)
44
+      {
45
+          $template->class = trim($template->class . ' animate-children');
46
+      }
47
+      if ($template->es_animate_fade)
48
+      {
49
+          $template->class = trim($template->class . ' -fade');
50
+      }
51
+    }
39 52
   }
40 53
 }
... ...
@@ -17,11 +17,15 @@ foreach ($GLOBALS['TL_DCA']['tl_content']['palettes'] as $key => $palette)
17 17
     {
18 18
         \Contao\CoreBundle\DataContainer\PaletteManipulator::create()->addField('es_textAlign', 'cssID')->addField('es_spacing', 'es_textAlign')->addField('es_padding', 'es_spacing')->applyToPalette($key, 'tl_content');
19 19
         \Contao\CoreBundle\DataContainer\PaletteManipulator::create()->addField('es_col_text','text',\Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_BEFORE)->applyToPalette($key,'tl_content');
20
+        \Contao\CoreBundle\DataContainer\PaletteManipulator::create()->addField('es_animate_legend','protected_legend')->addField('es_animate','es_animate_legend',\Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND)->applyToPalette($key,'tl_content');
20 21
     }
21 22
 }
22 23
 \Contao\CoreBundle\DataContainer\PaletteManipulator::create()->addLegend('col_layout_legend','rs_columns_legend')->addField('es_rs_columns_valign','col_layout_legend',\Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND)->applyToPalette('rs_columns_start','tl_content');
23 24
 \Contao\CoreBundle\DataContainer\PaletteManipulator::create()->addLegend('col_layout_legend','protected_legend')->addField('es_rs_column_sort_large','col_layout_legend',\Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND)->addField('es_rs_column_sort_medium','es_rs_column_sort_large')->addField('es_rs_column_sort_small','es_rs_column_sort_medium')->addField('es_rs_columns_valign','es_rs_column_sort_small')->applyToPalette('rs_column_start','tl_content');
24 25
 
26
+$GLOBALS['TL_DCA']['tl_content']['palettes']['__selector__'][] = 'es_animate';
27
+$GLOBALS['TL_DCA']['tl_content']['subpalettes']['es_animate'] = 'es_animate_children,es_animate_type,es_animate_fade';
28
+
25 29
 /*
26 30
  * Add fields
27 31
  */
... ...
@@ -106,3 +110,41 @@ $GLOBALS['TL_DCA']['tl_content']['fields']['es_rs_column_sort_large'] = array
106 110
     'eval'                    => array('tl_class'=>'rs_columns_w33', 'rgxp'=>'natural','maxval'=>6),
107 111
     'sql'                     => "varchar(255) NOT NULL default ''"
108 112
 );
113
+
114
+$GLOBALS['TL_DCA']['tl_content']['fields']['es_animate'] = array
115
+(
116
+    'label'                   => &$GLOBALS['TL_LANG']['tl_content']['es_animate'],
117
+    'exclude'                 => true,
118
+    'inputType'               => 'checkbox',
119
+    'eval'                    => array('tl_class'=>'w50 m12', 'submitOnChange'=>true),
120
+    'sql'                     => "char(1) NOT NULL default ''"
121
+);
122
+
123
+$GLOBALS['TL_DCA']['tl_content']['fields']['es_animate_children'] = array
124
+(
125
+    'label'                   => &$GLOBALS['TL_LANG']['tl_content']['es_animate_children'],
126
+    'exclude'                 => true,
127
+    'inputType'               => 'checkbox',
128
+    'eval'                    => array('tl_class'=>'w50 m12'),
129
+    'sql'                     => "char(1) NOT NULL default ''"
130
+);
131
+
132
+$GLOBALS['TL_DCA']['tl_content']['fields']['es_animate_type'] = array
133
+(
134
+    'label'                   => &$GLOBALS['TL_LANG']['tl_content']['es_animate_type'],
135
+    'exclude'                 => true,
136
+    'inputType'               => 'select',
137
+    'options'                 => array('-move','-move -move-right','-move -move-top','-move -move-bottom'),
138
+    'reference'               => &$GLOBALS['TL_LANG']['tl_content']['REF']['es_animate_type'],
139
+    'eval'                    => array('tl_class'=>'clr w50','mandatory'=>true,'includeBlankOption'=>true),
140
+    'sql'                     => "varchar(32) NOT NULL default ''"
141
+);
142
+
143
+$GLOBALS['TL_DCA']['tl_content']['fields']['es_animate_fade'] = array
144
+(
145
+    'label'                   => &$GLOBALS['TL_LANG']['tl_content']['es_animate_fade'],
146
+    'exclude'                 => true,
147
+    'inputType'               => 'checkbox',
148
+    'eval'                    => array('tl_class'=>'w50 m12'),
149
+    'sql'                     => "char(1) NOT NULL default ''"
150
+);
109 151
new file mode 100644
... ...
@@ -0,0 +1,15 @@
1
+@mixin transform($transform...) {
2
+  -webkit-transform: $transform;
3
+  -moz-transform: $transform;
4
+  -ms-transform: $transform;
5
+  -o-transform: $transform;
6
+  transform: $transform;
7
+}
8
+
9
+@mixin transition($transition...) {
10
+  -webkit-transition: $transition;
11
+  -moz-transition: $transition;
12
+  -ms-transition: $transition;
13
+  -o-transition: $transition;
14
+  transition: $transition;
15
+}
0 16
new file mode 100644
... ...
@@ -0,0 +1,69 @@
1
+@import "helper";
2
+
3
+@mixin animation-start {
4
+  @include transition(opacity 0.6s linear, transform 0.6s ease-out);
5
+
6
+  .-fade& {
7
+    opacity: 1;
8
+  }
9
+  .-move& {
10
+    @include transform(translate(0, 0));
11
+  }
12
+}
13
+
14
+@mixin animation-presets {
15
+  .-fade& {
16
+    opacity: 0;
17
+  }
18
+  .-move& {
19
+    @include transform(translate(50px, 0));
20
+  }
21
+  .-move-right& {
22
+    @include transform(translate(-50px, 0));
23
+  }
24
+  .-move-top& {
25
+    @include transform(translate(0, 50px));
26
+  }
27
+  .-move-bottom& {
28
+    @include transform(translate(0, -50px));
29
+  }
30
+}
31
+
32
+.is-animated {
33
+  &:not(.rs-columns) {
34
+    > *:not(.rs-columns) {
35
+      .-in-view& {
36
+        @include animation-start;
37
+      }
38
+      :not(.-in-view)& {
39
+        @include animation-presets;
40
+      }
41
+    }
42
+  }
43
+
44
+  &:not(.rs-columns) {
45
+    > *.rs-columns {
46
+      > * {
47
+        &.-in-view > * {
48
+          @include animation-start;
49
+        }
50
+
51
+        &:not(.-in-view) > * {
52
+          @include animation-presets;
53
+        }
54
+      }
55
+    }
56
+  }
57
+
58
+  &.rs-columns {
59
+    > * {
60
+      &.-in-view > * {
61
+        @include animation-start;
62
+      }
63
+
64
+      &:not(.-in-view) > * {
65
+        @include animation-presets;
66
+      }
67
+    }
68
+  }
69
+}
0 70
new file mode 100644
... ...
@@ -0,0 +1,83 @@
1
+(function(){
2
+
3
+  function isElementInViewport(element) {
4
+    var rect = element.getBoundingClientRect();
5
+    if (
6
+      rect.top >= 0 &&
7
+      rect.left >= 0 &&
8
+      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) + (element.offsetHeight * 0.75) &&
9
+      rect.right <= (window.innerWidth || document.documentElement.clientWidth))
10
+    {
11
+      return 1;
12
+    } else if (
13
+      rect.left >= 0 &&
14
+      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
15
+      rect.right <= (window.innerWidth || document.documentElement.clientWidth))
16
+    {
17
+      return 2;
18
+    }
19
+    return false;
20
+  }
21
+
22
+  //var elements = document.querySelectorAll(".is-animated:not(.rs-columns), .is-animated:not(.rs-columns) > .rs-columns > *, .is-animated.rs-columns > *");
23
+  function getAnimatedElements() {
24
+    var animatedWrapper = document.querySelectorAll(".is-animated"),
25
+      elements = [];
26
+
27
+    for (var i = 0; i < animatedWrapper.length; i++)
28
+    {
29
+      if (animatedWrapper[i].classList.contains("rs-columns") || animatedWrapper[i].classList.contains("animate-children"))
30
+      {
31
+        elements = animatedWrapper[i].children;
32
+      } else if (!animatedWrapper[i].classList.contains("rs-columns"))
33
+      {
34
+        for (var j = 0; j < animatedWrapper[i].children.length; j++)
35
+        {
36
+          if (animatedWrapper[i].children[j].classList.contains("rs-columns"))
37
+          {
38
+            for (var k = 0; k < animatedWrapper[i].children[j].children.length; k++)
39
+            {
40
+              elements.push(animatedWrapper[i].children[j].children[k]);
41
+            }
42
+          }
43
+        }
44
+        if (!elements.length)
45
+        {
46
+          elements = animatedWrapper;
47
+        }
48
+      }
49
+    }
50
+    return elements;
51
+  }
52
+
53
+  var elements = getAnimatedElements();
54
+  console.log(elements);
55
+
56
+  function callbackFunc() {
57
+    var delay = 0;
58
+    for (var i = 0; i < elements.length; i++)
59
+    {
60
+      if (elements[i].classList.contains('-in-view') === false && (hasDelay = isElementInViewport(elements[i])))
61
+      {
62
+        if (hasDelay === 1)
63
+        {
64
+          for (var j = 0; j < elements[i].children.length; j++)
65
+          {
66
+            elements[i].children[j].style.transitionDelay = delay + 'ms';
67
+          }
68
+          delay = delay + 125;
69
+        }
70
+        elements[i].classList.add("-in-view");
71
+      }
72
+
73
+      /* Else-Bedinung entfernen, um .visible nicht wieder zu löschen, wenn das Element den Viewport verlässt. */
74
+      /*else
75
+      {
76
+        elements[i].classList.remove("-in-view");
77
+      }*/
78
+    }
79
+  }
80
+
81
+  window.addEventListener("load", callbackFunc);
82
+  window.addEventListener("scroll", callbackFunc);
83
+})();