kamrify commited on
Commit
bcf9be5
·
1 Parent(s): 37f5ac4

Add easing towards the different element

Browse files
assets/scripts/src/overlay.js CHANGED
@@ -5,10 +5,14 @@ import Position from './position';
5
  * cutting out the visible part, animating between the sections etc
6
  */
7
  export default class Overlay {
8
- constructor({ alpha = 0.75 }) {
9
- this.alpha = alpha;
10
- this.selectedPosition = new Position({});
11
- this.lastSelectedPosition = new Position({});
 
 
 
 
12
 
13
  this.window = window;
14
  this.document = document;
@@ -40,11 +44,12 @@ export default class Overlay {
40
 
41
  // get the position of element around which we need to draw
42
  const position = element.getPosition();
43
- if (!position.isValid()) {
44
  return;
45
  }
46
 
47
- this.selectedPosition = position;
 
48
  this.draw();
49
  }
50
 
@@ -52,24 +57,90 @@ export default class Overlay {
52
  this.document.body.removeChild(this.overlay);
53
  }
54
 
 
 
 
 
 
55
  draw() {
56
- // Reset the overlay
57
- this.context.clearRect(0, 0, this.overlay.width, this.overlay.height);
58
- this.context.fillStyle = `rgba( 0, 0, 0, ${this.alpha})`;
59
- this.context.fillRect(0, 0, this.overlay.width, this.overlay.height);
60
-
61
- // Cut out the cleared region
62
- this.context.clearRect(
63
- this.selectedPosition.left - this.window.scrollX,
64
- this.selectedPosition.top - this.window.scrollY,
65
- (this.selectedPosition.right - this.selectedPosition.left),
66
- (this.selectedPosition.bottom - this.selectedPosition.top),
67
- );
68
-
69
- // Append the overlay if not there already
70
- if (!this.overlay.parentNode) {
71
- this.document.body.appendChild(this.overlay);
 
 
 
 
 
 
72
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
 
75
  setSize(width = null, height = null) {
 
5
  * cutting out the visible part, animating between the sections etc
6
  */
7
  export default class Overlay {
8
+ constructor({ opacity = 0.75 }) {
9
+ this.opacity = opacity;
10
+ this.overlayAlpha = 0;
11
+ this.positionToHighlight = new Position({});
12
+ this.highlightedPosition = new Position({});
13
+ this.redrawAnimation = null;
14
+
15
+ this.draw = this.draw.bind(this);
16
 
17
  this.window = window;
18
  this.document = document;
 
44
 
45
  // get the position of element around which we need to draw
46
  const position = element.getPosition();
47
+ if (!position.canHighlight()) {
48
  return;
49
  }
50
 
51
+ this.highlightedElement = element;
52
+ this.positionToHighlight = position;
53
  this.draw();
54
  }
55
 
 
57
  this.document.body.removeChild(this.overlay);
58
  }
59
 
60
+ /**
61
+ * `draw` is called for in requestAnimationFrame. Here is what it does
62
+ * - Puts back the filled overlay on body (i.e. while clearing existing highlight if any)
63
+ * - Slowly eases towards the item to be selected
64
+ */
65
  draw() {
66
+ // Cache the response of this for re-use below
67
+ const canHighlight = this.positionToHighlight.canHighlight();
68
+
69
+ // Remove the existing cloak from the body
70
+ // it might be torn i.e. have patches from last highlight
71
+ this.removeCloak();
72
+ // Add the overlay on top of the whole body
73
+ this.addCloak();
74
+
75
+ if (canHighlight) {
76
+ const isFadingIn = this.overlayAlpha < 0.1;
77
+
78
+ if (isFadingIn) {
79
+ // Ignore the animation, just highlight the item
80
+ this.highlightedPosition = this.positionToHighlight;
81
+ } else {
82
+ // Slowly move towards the position to highlight
83
+ this.highlightedPosition.left += (this.positionToHighlight.left - this.highlightedPosition.left) * 0.18;
84
+ this.highlightedPosition.top += (this.positionToHighlight.top - this.highlightedPosition.top) * 0.18;
85
+ this.highlightedPosition.right += (this.positionToHighlight.right - this.highlightedPosition.right) * 0.18;
86
+ this.highlightedPosition.bottom += (this.positionToHighlight.bottom - this.highlightedPosition.bottom) * 0.18;
87
+ }
88
  }
89
+
90
+ // Remove the cloak from the position to highlight
91
+ this.removeCloak({
92
+ posX: this.highlightedPosition.left - window.scrollX - 5,
93
+ posY: this.highlightedPosition.top - window.scrollY - 5,
94
+ width: (this.highlightedPosition.right - this.highlightedPosition.left) + (5 * 2),
95
+ height: (this.highlightedPosition.bottom - this.highlightedPosition.top) + (5 * 2),
96
+ });
97
+
98
+ if (canHighlight) {
99
+ // Fade the overlay in if we can highlight
100
+ this.overlayAlpha += (this.opacity - this.overlayAlpha) * 0.08;
101
+ } else {
102
+ // otherwise fade out
103
+ this.overlayAlpha = Math.max((this.overlayAlpha * 0.85) - 0.02, 0);
104
+ }
105
+
106
+ // cancel any existing animation frames
107
+ // to avoid the overlapping of frames
108
+ this.window.cancelAnimationFrame(this.redrawAnimation);
109
+
110
+ // Continue drawing while we can highlight or we are still fading out
111
+ if (canHighlight || this.overlayAlpha > 0) {
112
+ console.log(this.overlayAlpha);
113
+ // Add the overlay if not already there
114
+ if (!this.overlay.parentNode) {
115
+ document.body.appendChild(this.overlay);
116
+ }
117
+
118
+ // Stage a new animation frame
119
+ this.redrawAnimation = this.window.requestAnimationFrame(this.draw);
120
+ } else {
121
+ this.document.body.removeChild(this.overlay);
122
+ }
123
+ }
124
+
125
+ // Removes the patch of given width and height from the given position (x,y)
126
+ removeCloak({
127
+ posX = 0,
128
+ posY = 0,
129
+ width = this.overlay.width,
130
+ height = this.overlay.height,
131
+ } = {}) {
132
+ this.context.clearRect(posX, posY, width, height);
133
+ }
134
+
135
+ // Adds the cloak i.e. covers the given position with dark overlay
136
+ addCloak({
137
+ posX = 0,
138
+ posY = 0,
139
+ width = this.overlay.width,
140
+ height = this.overlay.height,
141
+ } = {}) {
142
+ this.context.fillStyle = `rgba( 0, 0, 0, ${this.overlayAlpha} )`;
143
+ this.context.fillRect(posX, posY, width, height);
144
  }
145
 
146
  setSize(width = null, height = null) {
assets/scripts/src/position.js CHANGED
@@ -21,7 +21,7 @@ export default class Position {
21
  this.bottom = bottom;
22
  }
23
 
24
- isValid() {
25
  return this.left < this.right && this.top < this.bottom;
26
  }
27
  }
 
21
  this.bottom = bottom;
22
  }
23
 
24
+ canHighlight() {
25
  return this.left < this.right && this.top < this.bottom;
26
  }
27
  }
index.html CHANGED
@@ -46,7 +46,6 @@
46
  <script>
47
  const nodesToSelect = [
48
  '.section__header',
49
- 'asdfsfd',
50
  '.section__how',
51
  '.section__examples'
52
  ];
@@ -56,7 +55,7 @@
56
  nodesToSelect.forEach((nodeToSelect, index) => {
57
  window.setTimeout(() => {
58
  sholo.highlight(nodeToSelect);
59
- }, index * 5000);
60
  });
61
  </script>
62
  </body>
 
46
  <script>
47
  const nodesToSelect = [
48
  '.section__header',
 
49
  '.section__how',
50
  '.section__examples'
51
  ];
 
55
  nodesToSelect.forEach((nodeToSelect, index) => {
56
  window.setTimeout(() => {
57
  sholo.highlight(nodeToSelect);
58
+ }, index * 1000);
59
  });
60
  </script>
61
  </body>