diff --git a/src/.vuepress/ParticleNetworkAnimation.js b/src/.vuepress/ParticleNetworkAnimation.js new file mode 100644 index 0000000..6151071 --- /dev/null +++ b/src/.vuepress/ParticleNetworkAnimation.js @@ -0,0 +1,315 @@ +/** + * Particle Network Animation https://codepen.io/franky/pen/LGMWPK + * Inspiration: https://github.com/JulianLaval/canvas-particle-network + */ + +class ParticleNetworkAnimation { + constructor(element, options) { + this.$el = element; + + this.container = element; + //this.canvas = document.createElement('canvas'); + this.canvas = element; + this.sizeCanvas(); + //this.container.appendChild(this.canvas); + this.ctx = this.canvas.getContext('2d'); + this.particleNetwork = new ParticleNetwork(this, options); + + this.bindUiActions(); + + return this; + } + + bindUiActions() { + window.addEventListener('resize', () => { + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + this.sizeCanvas(); + this.particleNetwork.createParticles(); + }); + } + sizeCanvas() { + this.canvas.width = this.container.offsetWidth; + this.canvas.height = this.container.offsetHeight; + } +} + +class Particle{ + constructor(parent, x, y) { + this.network = parent; + this.canvas = parent.canvas; + this.ctx = parent.ctx; + this.particleColor = returnRandomArrayitem(this.network.options.particleColors); + this.radius = getLimitedRandom(1.5, 2.5); + this.opacity = 0; + this.x = x || Math.random() * this.canvas.width; + this.y = y || Math.random() * this.canvas.height; + this.velocity = { + x: (Math.random() - 0.5) * parent.options.velocity, + y: (Math.random() - 0.5) * parent.options.velocity + }; + } + + update(){ + if (this.opacity < 1) { + this.opacity += 0.01; + } else { + this.opacity = 1; + } + // Change dir if outside map + if (this.x > this.canvas.width + 100 || this.x < -100) { + this.velocity.x = -this.velocity.x; + } + if (this.y > this.canvas.height + 100 || this.y < -100) { + this.velocity.y = -this.velocity.y; + } + + // Update position + this.x += this.velocity.x; + this.y += this.velocity.y; + } + draw(){ + // Draw particle + this.ctx.beginPath(); + this.ctx.fillStyle = this.particleColor; + this.ctx.globalAlpha = this.opacity; + this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); + this.ctx.fill(); + } + +} + +class ParticleNetwork{ + constructor(parent, options = { + velocity: 2, // the higher the faster + density: 10000, // the lower the denser + netLineDistance: 200, + netLineColor: '#929292', + particleColors: ['#aaa'] // ['#6D4E5C', '#aaa', '#FFC458' ] + }) { + this.options = options; + this.canvas = parent.canvas; + this.ctx = parent.ctx; + + this.init(); + } + + init(){ + // Create particle objects + this.createParticles(false); + + // Update canvas + this.animationFrame = requestAnimationFrame(this.update.bind(this)); + + this.bindUiActions(); + } + + createParticles(isInitial) { + // Initialise / reset particles + let me = this; + this.particles = []; + let quantity = this.canvas.width * this.canvas.height / this.options.density; + + if (isInitial) { + let counter = 0; + clearInterval(this.createIntervalId); + this.createIntervalId = setInterval(function() { + if (counter < quantity - 1) { + // Create particle object + this.particles.push(new Particle(this)); + } + else { + clearInterval(me.createIntervalId); + } + counter++; + }.bind(this), 250); + } + else { + // Create particle objects + for (let i = 0; i < quantity; i++) { + this.particles.push(new Particle(this)); + } + } + } + + createInteractionParticle() { + // Add interaction particle + this.interactionParticle = new Particle(this); + this.interactionParticle.velocity = { + x: 0, + y: 0 + }; + this.particles.push(this.interactionParticle); + return this.interactionParticle; + } + + removeInteractionParticle() { + // Find it + let index = this.particles.indexOf(this.interactionParticle); + if (index > -1) { + // Remove it + this.interactionParticle = undefined; + this.particles.splice(index, 1); + } + } + + update() { + if (this.canvas) { + + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + this.ctx.globalAlpha = 1; + + // Draw connections + for (let i = 0; i < this.particles.length; i++) { + for (let j = this.particles.length - 1; j > i; j--) { + let distance, p1 = this.particles[i], p2 = this.particles[j]; + + // check very simply if the two points are even a candidate for further measurements + distance = Math.min(Math.abs(p1.x - p2.x), Math.abs(p1.y - p2.y)); + if (distance > this.options.netLineDistance) { + continue; + } + + // the two points seem close enough, now let's measure precisely + distance = Math.sqrt( + Math.pow(p1.x - p2.x, 2) + + Math.pow(p1.y - p2.y, 2) + ); + if (distance > this.options.netLineDistance) { + continue; + } + + this.ctx.beginPath(); + this.ctx.strokeStyle = this.options.netLineColor; + this.ctx.globalAlpha = (this.options.netLineDistance - distance) / this.options.netLineDistance * p1.opacity * p2.opacity; + this.ctx.lineWidth = 0.7; + this.ctx.moveTo(p1.x, p1.y); + this.ctx.lineTo(p2.x, p2.y); + this.ctx.stroke(); + } + } + + // Draw particles + this.particles.forEach(k => { + k.update(); + k.draw(); + }) + + if (this.options.velocity !== 0) { + this.animationFrame = requestAnimationFrame(this.update.bind(this)); + } + + } + else { + cancelAnimationFrame(this.animationFrame); + } + } + + bindUiActions() { + // Mouse / touch event handling + this.spawnQuantity = 3; + this.mouseIsDown = false; + this.touchIsMoving = false; + + this.onMouseMove = function(e) { + if (!this.interactionParticle) { + this.createInteractionParticle(); + } + this.interactionParticle.x = e.offsetX; + this.interactionParticle.y = e.offsetY; + }.bind(this); + + this.onTouchMove = function(e) { + e.preventDefault(); + this.touchIsMoving = true; + if (!this.interactionParticle) { + this.createInteractionParticle(); + } + this.interactionParticle.x = e.changedTouches[0].clientX; + this.interactionParticle.y = e.changedTouches[0].clientY; + }.bind(this); + + this.onMouseDown = function() { + this.mouseIsDown = true; + let counter = 0; + let quantity = this.spawnQuantity; + let intervalId = setInterval(function() { + if (this.mouseIsDown) { + if (counter === 1) { + quantity = 1; + } + for (let i = 0; i < quantity; i++) { + if (this.interactionParticle) { + this.particles.push(new Particle(this, this.interactionParticle.x, this.interactionParticle.y)); + } + } + } + else { + clearInterval(intervalId); + } + counter++; + }.bind(this), 50); + }.bind(this); + + this.onTouchStart = function(e) { + e.preventDefault(); + setTimeout(function() { + if (!this.touchIsMoving) { + for (let i = 0; i < this.spawnQuantity; i++) { + this.particles.push(new Particle(this, e.changedTouches[0].clientX, e.changedTouches[0].clientY)); + } + } + }.bind(this), 200); + }.bind(this); + + this.onMouseUp = function() { + this.mouseIsDown = false; + }.bind(this); + + this.onMouseOut = function() { + this.removeInteractionParticle(); + }.bind(this); + + this.onTouchEnd = function(e) { + e.preventDefault(); + this.touchIsMoving = false; + this.removeInteractionParticle(); + }.bind(this); + + this.canvas.addEventListener('mousemove', this.onMouseMove); + this.canvas.addEventListener('touchmove', this.onTouchMove); + //this.canvas.addEventListener('mousedown', this.onMouseDown); + this.canvas.addEventListener('touchstart', this.onTouchStart); + this.canvas.addEventListener('mouseup', this.onMouseUp); + this.canvas.addEventListener('mouseout', this.onMouseOut); + this.canvas.addEventListener('touchend', this.onTouchEnd); + } + + unbindUiActions() { + if (this.canvas) { + this.canvas.removeEventListener('mousemove', this.onMouseMove); + this.canvas.removeEventListener('touchmove', this.onTouchMove); + this.canvas.removeEventListener('mousedown', this.onMouseDown); + this.canvas.removeEventListener('touchstart', this.onTouchStart); + this.canvas.removeEventListener('mouseup', this.onMouseUp); + this.canvas.removeEventListener('mouseout', this.onMouseOut); + this.canvas.removeEventListener('touchend', this.onTouchEnd); + } + } +} + + +let getLimitedRandom = function(min, max, roundToInteger) { + let number = Math.random() * (max - min) + min; + if (roundToInteger) { + number = Math.round(number); + } + return number; +}; + +let returnRandomArrayitem = function(array) { + return array[Math.floor(Math.random()*array.length)]; +}; + +export { + ParticleNetworkAnimation +}; diff --git a/src/.vuepress/assets/fonts/roboto-mono-v22-latin-100.woff b/src/.vuepress/assets/fonts/roboto-mono-v22-latin-100.woff new file mode 100644 index 0000000..814ec26 Binary files /dev/null and b/src/.vuepress/assets/fonts/roboto-mono-v22-latin-100.woff differ diff --git a/src/.vuepress/assets/fonts/roboto-mono-v22-latin-100.woff2 b/src/.vuepress/assets/fonts/roboto-mono-v22-latin-100.woff2 new file mode 100644 index 0000000..a2ed61e Binary files /dev/null and b/src/.vuepress/assets/fonts/roboto-mono-v22-latin-100.woff2 differ diff --git a/src/.vuepress/assets/fonts/roboto-mono-v22-latin-regular.woff b/src/.vuepress/assets/fonts/roboto-mono-v22-latin-regular.woff new file mode 100644 index 0000000..be3eb4c Binary files /dev/null and b/src/.vuepress/assets/fonts/roboto-mono-v22-latin-regular.woff differ diff --git a/src/.vuepress/assets/fonts/roboto-mono-v22-latin-regular.woff2 b/src/.vuepress/assets/fonts/roboto-mono-v22-latin-regular.woff2 new file mode 100644 index 0000000..f8894ba Binary files /dev/null and b/src/.vuepress/assets/fonts/roboto-mono-v22-latin-regular.woff2 differ diff --git a/src/.vuepress/components/BannerWrapperNetwork.vue b/src/.vuepress/components/BannerWrapperNetwork.vue new file mode 100644 index 0000000..93a9d3f --- /dev/null +++ b/src/.vuepress/components/BannerWrapperNetwork.vue @@ -0,0 +1,122 @@ + + + + + \ No newline at end of file diff --git a/src/.vuepress/components/FolderList.vue b/src/.vuepress/components/FolderList.vue index a548a5d..23d3033 100644 --- a/src/.vuepress/components/FolderList.vue +++ b/src/.vuepress/components/FolderList.vue @@ -1,11 +1,16 @@ diff --git a/src/.vuepress/components/HomeContent.vue b/src/.vuepress/components/HomeContent.vue new file mode 100644 index 0000000..c8cb04f --- /dev/null +++ b/src/.vuepress/components/HomeContent.vue @@ -0,0 +1,29 @@ + + + + + \ No newline at end of file diff --git a/src/.vuepress/components/SocialIcons.vue b/src/.vuepress/components/SocialIcons.vue index 614a68e..415e24f 100644 --- a/src/.vuepress/components/SocialIcons.vue +++ b/src/.vuepress/components/SocialIcons.vue @@ -1,7 +1,7 @@