PageSourceSearch

https://topserve.ca/assets/js/main.js

js topserve.ca collected 2026-10-08 12:07:30 UTC 5,823 bytes, 181 lines download raw bytes

1(function () {
2  const doc = document
3  const rootEl = doc.documentElement
4  const body = doc.body
5  /* global ScrollReveal */
6  const sr = window.sr = ScrollReveal({ mobile: false })
7
8  rootEl.classList.remove('no-js')
9  rootEl.classList.add('js')
10
11  window.addEventListener('load', function () {
12    body.classList.add('is-loaded')
13  })
14
15  // Reveal animations
16  function revealAnimations () {
17    sr.reveal('.feature-extended .device-mockup', {
18      duration: 600,
19      distance: '100px',
20      easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
21      origin: 'bottom',
22      viewFactor: 0.6
23    })
24    sr.reveal('.feature-extended .feature-extended-body', {
25      duration: 600,
26      distance: '40px',
27      easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
28      origin: 'top',
29      viewFactor: 0.6
30    })
31  }
32
33  if (body.classList.contains('has-animations')) {
34    window.addEventListener('load', revealAnimations)
35  }
36
37  // Particle animation
38  let Bubble = function (parentNode) {
39    let self = this
40    self.parentNode = parentNode
41    self.getCanvasSize()
42    window.addEventListener('resize', function () {
43      self.getCanvasSize()
44    })
45    self.mouseX = 0
46    self.mouseY = 0
47    window.addEventListener('mousemove', function (e) {
48      self.mouseX = e.clientX
49      self.mouseY = e.clientY
50    })
51    self.randomise()
52  }
53
54  Bubble.prototype.getCanvasSize = function () {
55    let self = this
56    self.canvasWidth = self.parentNode.clientWidth
57    self.canvasHeight = self.parentNode.clientHeight
58  }
59
60  Bubble.prototype.generateDecimalBetween = function (min, max) {
61    return (Math.random() * (min - max) + max).toFixed(2)
62  }
63
64  Bubble.prototype.update = function () {
65    let self = this
66    self.translateX = self.translateX - self.movementX
67    self.translateY = self.translateY - self.movementY
68    self.posX += ((self.mouseX / (self.staticity / self.magnetism)) - self.posX) / self.smoothFactor
69    self.posY += ((self.mouseY / (self.staticity / self.magnetism)) - self.posY) / self.smoothFactor
70
71    if (self.translateY + self.posY < 0 || self.translateX + self.posX < 0 || self.translateX + self.posX > self.canvasWidth) {
72      self.randomise()
73      self.translateY = self.canvasHeight
74    }
75  }
76
77  Bubble.prototype.randomise = function () {
78    let self = this
79    self.colors = ['85,107,139', '38,141,247', '66,52,248', '255,108,80', '243, 244, 255', '96, 100, 131']
80    self.velocity = 30 // Bubble levitation velocity (the higher the slower)
81    self.smoothFactor = 50 // The higher, the smoother
82    self.staticity = 30 // Increase value to make bubbles move slower on mousemove
83    self.magnetism = 0.1 + Math.random() * 4
84    self.color = self.colors[Math.floor(Math.random() * self.colors.length)]
85    self.alpha = self.generateDecimalBetween(5, 10) / 10
86    self.size = self.generateDecimalBetween(1, 4)
87    self.posX = 0
88    self.posY = 0
89    self.movementX = self.generateDecimalBetween(-2, 2) / self.velocity
90    self.movementY = self.generateDecimalBetween(1, 20) / self.velocity
91    self.translateX = self.generateDecimalBetween(0, self.canvasWidth)
92    self.translateY = self.generateDecimalBetween(0, self.canvasHeight)
93  }
94
95  let Background = function (selector) {
96    let self = this
97    self.canvas = document.getElementById(selector)
98    self.ctx = this.canvas.getContext('2d')
99    self.dpr = window.devicePixelRatio
100  }
101
102  Background.prototype.start = function () {
103    let self = this
104    self.canvasSize()
105    window.addEventListener('resize', function () {
106      self.canvasSize()
107    })
108    self.bubblesList = []
109    self.generateBubbles()
110    self.animate()
111  }
112
113  Background.prototype.canvasSize = function () {
114    let self = this
115    self.container = self.canvas.parentNode
116    // Determine window width and height
117    self.w = self.container.offsetWidth
118    self.h = self.container.offsetHeight
119    self.wdpi = self.w * self.dpr
120    self.hdpi = self.h * self.dpr
121    // Set canvas width and height
122    self.canvas.width = self.wdpi
123    self.canvas.height = self.hdpi
124    // Set width and height attributes
125    self.canvas.style.width = self.w + 'px'
126    self.canvas.style.height = self.h + 'px'
127    // Scale down canvas
128    self.ctx.scale(self.dpr, self.dpr)
129  }
130
131  Background.prototype.animate = function () {
132    let self = this
133    self.ctx.clearRect(0, 0, self.canvas.clientWidth, self.canvas.clientHeight)
134    self.bubblesList.forEach(function (bubble) {
135      bubble.update()
136      self.ctx.translate(bubble.translateX, bubble.translateY)
137      self.ctx.beginPath()
138      self.ctx.arc(bubble.posX, bubble.posY, bubble.size, 0, 2 * Math.PI)
139      self.ctx.fillStyle = 'rgba(' + bubble.color + ',' + bubble.alpha + ')'
140      self.ctx.fill()
141      self.ctx.setTransform(self.dpr, 0, 0, self.dpr, 0, 0)
142    })
143    /* global requestAnimationFrame */
144    requestAnimationFrame(this.animate.bind(this))
145  }
146
147  Background.prototype.addBubble = function (bubble) {
148    return this.bubblesList.push(bubble)
149  }
150
151  Background.prototype.generateBubbles = function () {
152    let self = this
153    for (let i = 0; i < self.bubbleDensity(); i++) {
154      self.addBubble(new Bubble(self.canvas.parentNode))
155    }
156  }
157
158  Background.prototype.bubbleDensity = function () {
159    return 15
160  }
161
162  window.addEventListener('load', function () {
163    const heroParticles = new Background('hero-particles')
164    const footerParticles = new Background('footer-particles')
165    heroParticles.start()
166    footerParticles.start()
167  })
168
169  window.requestAnimFrame = (function () {
170    return (
171      window.requestAnimationFrame ||
172      window.webkitRequestAnimationFrame ||
173      window.mozRequestAnimationFrame ||
174      window.oRequestAnimationFrame ||
175      window.msRequestAnimationFrame ||
176      function (callback) {
177        window.setTimeout(callback, 1000 / 60)
178      }
179    )
180  })()
181}())

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.