kamrify commited on
Commit
22c7264
·
1 Parent(s): 5edd378

Restructure and es6-ify

Browse files
assets/scripts/src/element.js ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Position from './position';
2
+
3
+ export default class Element {
4
+ constructor(node) {
5
+ this.element = node;
6
+ this.document = document;
7
+ }
8
+
9
+ // Gets the screen co-ordinates for the current dom element
10
+ getScreenCoordinates() {
11
+ let tempNode = this.element;
12
+
13
+ let x = this.document.documentElement.offsetLeft;
14
+ let y = this.document.documentElement.offsetTop;
15
+
16
+ if (tempNode.offsetParent) {
17
+ do {
18
+ x += tempNode.offsetLeft;
19
+ y += tempNode.offsetTop;
20
+ } while (tempNode = tempNode.offsetParent);
21
+ }
22
+
23
+ return { x, y };
24
+ }
25
+
26
+ // Gets the calculated position on screen
27
+ getPosition() {
28
+ const coordinates = this.getScreenCoordinates();
29
+ const position = new Position({
30
+ left: Number.MAX_VALUE,
31
+ top: Number.MAX_VALUE,
32
+ right: 0,
33
+ bottom: 0,
34
+ });
35
+
36
+ // If we have the position for this element
37
+ // and the element is visible on screen (has some height)
38
+ if (typeof coordinates.x === 'number' && typeof coordinates.y === 'number' && (this.element.offsetWidth > 0 || this.element.offsetHeight > 0)) {
39
+ position.left = Math.min(position.left, coordinates.x);
40
+ position.top = Math.min(position.top, coordinates.y);
41
+ position.right = Math.max(position.right, coordinates.x + this.element.offsetWidth);
42
+ position.bottom = Math.max(position.bottom, coordinates.y + this.element.offsetHeight);
43
+ }
44
+
45
+ return position;
46
+ }
47
+ }
assets/scripts/src/overlay.js ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Position from './position';
2
+
3
+ /**
4
+ * Responsible for overlay creation and manipulation i.e.
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.window = window;
11
+ this.selected = new Position({});
12
+
13
+ this.prepareContext();
14
+ this.setSize();
15
+ }
16
+
17
+ // Prepares the overlay
18
+ prepareContext() {
19
+ const overlay = document.createElement('canvas');
20
+
21
+ this.overlay = overlay;
22
+ this.context = overlay.getContext('2d');
23
+
24
+ this.overlay.style.pointerEvents = 'none';
25
+ this.overlay.style.background = 'transparent';
26
+ this.overlay.style.position = 'fixed';
27
+ this.overlay.style.top = '0';
28
+ this.overlay.style.left = '0';
29
+ this.overlay.style.zIndex = '999999999';
30
+ }
31
+
32
+ // Highlights the dom element on the screen
33
+ highglight(element) {
34
+ if (!element) {
35
+ // @todo - clearing the overlay
36
+ return;
37
+ }
38
+
39
+ // get the position of element around which we need to draw
40
+ const position = element.getPosition();
41
+ if (!position.isValid()) {
42
+ return;
43
+ }
44
+
45
+ this.selected = position;
46
+ this.draw();
47
+ }
48
+
49
+ draw() {
50
+ this.context.clearRect(0, 0, this.overlay.width, this.overlay.height);
51
+ this.context.fillStyle = `rgba( 0, 0, 0, ${this.alpha})`;
52
+ this.context.fillRect(0, 0, this.overlay.width, this.overlay.height);
53
+
54
+ // Cut out the cleared region
55
+ this.context.clearRect(
56
+ this.selected.left - window.scrollX,
57
+ this.selected.top - window.scrollY,
58
+ (this.selected.right - this.selected.left),
59
+ (this.selected.bottom - this.selected.top),
60
+ );
61
+
62
+ // Append the overlay if not there already
63
+ if (!this.overlay.parentNode) {
64
+ document.body.appendChild(this.overlay);
65
+ }
66
+ }
67
+
68
+ setSize(width = null, height = null) {
69
+ // By default it is going to cover the whole page and then we will
70
+ // cut out a chunk for the element to be visible out of it
71
+ this.overlay.width = width || this.window.innerWidth;
72
+ this.overlay.height = height || this.window.innerHeight;
73
+ }
74
+ }
assets/scripts/src/position.js ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Responsible for validating positions and is used
3
+ * when manipulating positions across the application
4
+ */
5
+ export default class Position {
6
+ /**
7
+ * @param left
8
+ * @param top
9
+ * @param right
10
+ * @param bottom
11
+ */
12
+ constructor({
13
+ left = 0,
14
+ top = 0,
15
+ right = 0,
16
+ bottom = 0,
17
+ }) {
18
+ this.left = left;
19
+ this.right = right;
20
+ this.top = top;
21
+ this.bottom = bottom;
22
+ }
23
+
24
+ isValid() {
25
+ return this.left < this.right && this.top < this.bottom;
26
+ }
27
+ }
assets/scripts/src/sholo.js CHANGED
@@ -1,94 +1,27 @@
1
- let overlay;
2
- let overlayContext;
3
 
4
- // overlay is going to cover the whole page and then we will
5
- // cut out a chunk for the element to be visible out of it
6
- function createOverlay() {
7
- overlay = document.createElement('canvas');
8
- overlayContext = overlay.getContext('2d');
9
 
10
- overlay.style.pointerEvents = 'none';
11
- overlay.style.background = 'transparent';
12
- overlay.style.position = 'fixed';
13
- overlay.style.top = '0';
14
- overlay.style.left = '0';
15
- overlay.style.zIndex = '999999999';
16
- overlay.width = window.innerWidth;
17
- overlay.height = window.innerHeight;
18
-
19
- overlayContext.clearRect(0, 0, overlay.width, overlay.height);
20
- overlayContext.fillStyle = 'rgba( 0, 0, 0, 0.7)';
21
- overlayContext.fillRect(0, 0, overlay.width, overlay.height);
22
- }
23
-
24
- // Finds the correct position of node on screen
25
- function getNodePosition(node) {
26
- let x = document.documentElement.offsetLeft;
27
- let y = document.documentElement.offsetTop;
28
-
29
- if (node.offsetParent) {
30
- do {
31
- x += node.offsetLeft;
32
- y += node.offsetTop;
33
- } while (node = node.offsetParent);
34
  }
35
 
36
- return { x, y };
37
- }
38
 
39
- // selects the node on the screen
40
- function selectNode(node) {
41
- if (!node) {
42
- return;
43
- }
44
-
45
- // Default to non-existing space
46
- const currentRegion = {
47
- left: Number.MAX_VALUE, top: Number.MAX_VALUE, right: 0, bottom: 0,
48
- };
49
- const nodePosition = getNodePosition(node);
50
 
51
- // If we have the position and has some height
52
- if (typeof nodePosition.x === 'number' && typeof nodePosition.y === 'number' && (node.offsetWidth > 0 || node.offsetHeight > 0)) {
53
- currentRegion.left = Math.min(currentRegion.left, nodePosition.x);
54
- currentRegion.top = Math.min(currentRegion.top, nodePosition.y);
55
- currentRegion.right = Math.max(currentRegion.right, nodePosition.x + node.offsetWidth);
56
- currentRegion.bottom = Math.max(currentRegion.bottom, nodePosition.y + node.offsetHeight);
57
  }
58
-
59
-
60
- const isValidRegion = currentRegion.left < currentRegion.right && currentRegion.top < currentRegion.bottom;
61
- if (!isValidRegion) {
62
- return;
63
- }
64
-
65
- const overlayAlpha = 0.7;
66
-
67
- // Reset the overlay
68
- overlayContext.clearRect(0, 0, overlay.width, overlay.height);
69
- overlayContext.fillStyle = `rgba( 0, 0, 0, ${overlayAlpha} )`;
70
- overlayContext.fillRect(0, 0, overlay.width, overlay.height);
71
-
72
- // Cut out the cleared region
73
- overlayContext.clearRect(
74
- currentRegion.left - window.scrollX,
75
- currentRegion.top - window.scrollY,
76
- (currentRegion.right - currentRegion.left),
77
- (currentRegion.bottom - currentRegion.top),
78
- );
79
-
80
- document.body.appendChild(overlay);
81
  }
82
-
83
- const nodesToSelect = [
84
- document.querySelector('.section__header'),
85
- document.querySelector('.section__how'),
86
- ];
87
-
88
- createOverlay();
89
-
90
- nodesToSelect.forEach((nodeToSelect, index) => {
91
- window.setTimeout(() => {
92
- selectNode(nodeToSelect);
93
- }, index * 1000);
94
- });
 
1
+ import Overlay from './overlay';
2
+ import Element from './element';
3
 
 
 
 
 
 
4
 
5
+ /**
6
+ * Plugin class that drives the plugin
7
+ */
8
+ export default class Sholo {
9
+ constructor({ alpha = 0.75 } = {}) {
10
+ this.overlay = new Overlay({ alpha });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
12
 
13
+ highlight(selector) {
14
+ let domElement;
15
 
16
+ if (typeof selector === 'string') {
17
+ domElement = document.querySelector(selector);
18
+ } else if (typeof selector === 'object') {
19
+ domElement = selector;
20
+ } else {
21
+ throw new Error('Element can only be string or the dom element');
22
+ }
 
 
 
 
23
 
24
+ const element = new Element(domElement);
25
+ this.overlay.highglight(element);
 
 
 
 
26
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
index.html CHANGED
@@ -43,5 +43,19 @@
43
  </div>
44
 
45
  <script src="./assets/scripts/dist/sholo.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  </body>
47
  </html>
 
43
  </div>
44
 
45
  <script src="./assets/scripts/dist/sholo.js"></script>
46
+ <script>
47
+ const nodesToSelect = [
48
+ '.section__header',
49
+ '.section__how',
50
+ ];
51
+
52
+ const sholo = new Sholo();
53
+
54
+ nodesToSelect.forEach((nodeToSelect, index) => {
55
+ window.setTimeout(() => {
56
+ sholo.highlight(nodeToSelect);
57
+ }, index * 1000);
58
+ });
59
+ </script>
60
  </body>
61
  </html>
package.json CHANGED
@@ -13,6 +13,7 @@
13
  "babel-core": "^6.26.0",
14
  "babel-eslint": "^8.2.2",
15
  "babel-loader": "^7.1.3",
 
16
  "babel-preset-env": "^1.6.1",
17
  "css-loader": "^0.28.10",
18
  "eslint": "^4.18.2",
@@ -21,6 +22,7 @@
21
  "eslint-plugin-import": "^2.9.0",
22
  "eslint-plugin-node": "^6.0.1",
23
  "extract-loader": "^1.0.2",
 
24
  "file-loader": "^1.1.11",
25
  "node-sass": "^4.7.2",
26
  "opn": "^5.2.0",
@@ -29,9 +31,7 @@
29
  "style-loader": "^0.20.2",
30
  "webpack": "^4.0.1",
31
  "webpack-cli": "^2.0.10",
32
- "webpack-dev-server": "^3.1.0",
33
- "extract-text-webpack-plugin": "next"
34
  },
35
- "dependencies": {
36
- }
37
  }
 
13
  "babel-core": "^6.26.0",
14
  "babel-eslint": "^8.2.2",
15
  "babel-loader": "^7.1.3",
16
+ "babel-plugin-add-module-exports": "^0.2.1",
17
  "babel-preset-env": "^1.6.1",
18
  "css-loader": "^0.28.10",
19
  "eslint": "^4.18.2",
 
22
  "eslint-plugin-import": "^2.9.0",
23
  "eslint-plugin-node": "^6.0.1",
24
  "extract-loader": "^1.0.2",
25
+ "extract-text-webpack-plugin": "next",
26
  "file-loader": "^1.1.11",
27
  "node-sass": "^4.7.2",
28
  "opn": "^5.2.0",
 
31
  "style-loader": "^0.20.2",
32
  "webpack": "^4.0.1",
33
  "webpack-cli": "^2.0.10",
34
+ "webpack-dev-server": "^3.1.0"
 
35
  },
36
+ "dependencies": {}
 
37
  }
webpack.config.dev.js CHANGED
@@ -5,8 +5,8 @@ module.exports = {
5
  mode: 'development',
6
  entry: [
7
  'webpack-dev-server/client?http://localhost:3000',
8
- './assets/scripts/src/sholo.js',
9
  './assets/styles/scss/demo.scss',
 
10
  ],
11
  output: {
12
  path: path.join(__dirname, '/assets'),
@@ -33,6 +33,7 @@ module.exports = {
33
  loader: 'babel-loader',
34
  options: {
35
  presets: ['env'],
 
36
  },
37
  },
38
  {
 
5
  mode: 'development',
6
  entry: [
7
  'webpack-dev-server/client?http://localhost:3000',
 
8
  './assets/styles/scss/demo.scss',
9
+ './assets/scripts/src/sholo.js',
10
  ],
11
  output: {
12
  path: path.join(__dirname, '/assets'),
 
33
  loader: 'babel-loader',
34
  options: {
35
  presets: ['env'],
36
+ plugins: ['babel-plugin-add-module-exports'],
37
  },
38
  },
39
  {
yarn.lock CHANGED
@@ -546,6 +546,10 @@ babel-messages@^6.23.0:
546
  dependencies:
547
  babel-runtime "^6.22.0"
548
 
 
 
 
 
549
  babel-plugin-check-es2015-constants@^6.22.0:
550
  version "6.22.0"
551
  resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a"
 
546
  dependencies:
547
  babel-runtime "^6.22.0"
548
 
549
+ babel-plugin-add-module-exports@^0.2.1:
550
+ version "0.2.1"
551
+ resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz#9ae9a1f4a8dc67f0cdec4f4aeda1e43a5ff65e25"
552
+
553
  babel-plugin-check-es2015-constants@^6.22.0:
554
  version "6.22.0"
555
  resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a"