Streaming live at 10am (PST)

How to integrate this JS animation into Webflow


#1

Hello friends,

I need to integrate this code into webflow, could you tell me exactly how to do that? Thank you!


#2
  1. Add the js before the body.
    https://university.webflow.com/article/how-to-add-custom-head-and-body-code-to-a-webflow-site

  2. Add canvas (custom HTML - no canvas element by drag-&-drop):
    https://university.webflow.com/article/embed

  3. CSS - be careful from CSS conflicts (don’t copy and paste the CSS code for H1/html and so on - add styles from webflow editor)

  4. add div - wrapper for style (bg color - flexbox align for h1/p and so on):
    wrapper
    — canvas
    — h1
    — p
    /wrapper

That’s it. It will work only on you’re publish site (not in preview mode).

How to edit this code - the size of the canvas set by JS :slight_smile:

canvas.width = window.innerWidth;
canvas.height = window.innerHeight; 

The colors of line and dot:

ctx.fillStyle = "#8f9aa3";

How to destroy this code :slight_smile: if you remove h1 - you must edit the code (the counter).
change selector:
https://www.w3schools.com/jsref/met_document_queryselector.asp

You add class/id by weblow editor.

If you dont want the text animation (work with static/regular text on top of this canvas) - this is the code:

var canvas = document.querySelector("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext("2d");

var TAU = 2 * Math.PI;

var output = document.querySelector("h1");

times = [];
function loop() {
  var startTime = performance .now();
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  update();
  draw();
  times.push(performance.now() - startTime);
  if (times.length > 500) {
    times.shift()
  }
  requestAnimationFrame(loop);
}

function Ball (startX, startY, startVelX, startVelY) {
  this.x = startX || Math.random() * canvas.width;
  this.y = startY || Math.random() * canvas.height;
  this.vel = {
    x: startVelX || Math.random() * 2 - 1,
    y: startVelY || Math.random() * 2 - 1
  };
  this.update = function(canvas) {
    if (this.x > canvas.width + 50 || this.x < -50) {
      this.vel.x = -this.vel.x;
    }
    if (this.y > canvas.height + 50 || this.y < -50) {
      this.vel.y = -this.vel.y;
    }
    this.x += this.vel.x;
    this.y += this.vel.y;
  };
  this.draw = function(ctx, can) {
    ctx.beginPath();
    if (distMouse(this) > 100) {
      ctx.fillStyle = "#8f9aa3";
      ctx.globalAlpha =  .2;
    } else {
    	ctx.fillStyle = '#448fda';
      ctx.globalAlpha =  .6;
    }
    ctx.arc((0.5 + this.x) | 0, (0.5 + this.y) | 0, 3, 0, TAU, false);
    ctx.fill();
  }
}

var balls = [];
for (var i = 0; i < canvas.width * canvas.height / (65*65); i++) {
  balls.push(new Ball(Math.random() * canvas.width, Math.random() * canvas.height));
}

var lastTime = Date.now();
function update() {
  var diff = Date.now() - lastTime;
  for (var frame = 0; frame * 16.6667 < diff; frame++) {
    for (var index = 0; index < balls.length; index++) {
      balls[index].update(canvas);
    }
  }
  lastTime = Date.now();
}
var mouseX = -1e9, mouseY = -1e9;
document.addEventListener('mousemove', function(event) {
  mouseX = event.clientX;
  mouseY = event.clientY;
});

function distMouse(ball) {
  return Math.hypot(ball.x - mouseX, ball.y - mouseY);
}

function draw() {
  for (var index = 0; index < balls.length; index++) {
    var ball = balls[index];
    ball.draw(ctx, canvas);
    ctx.beginPath();
    for (var index2 = balls.length - 1; index2 > index; index2 += -1) {
      var ball2 = balls[index2];
	var dist = Math.hypot(ball.x - ball2.x, ball.y - ball2.y);
        if (dist < 100) {
          if (distMouse(ball) > 100) {
            ctx.strokeStyle = "#8f9aa3";
          	ctx.globalAlpha = .2;
          } else {
            ctx.strokeStyle = '#448fda';
            ctx.globalAlpha =  .6;
          }
          ctx.lineWidth = "2px";
          ctx.moveTo((0.5 + ball.x) | 0, (0.5 + ball.y) | 0);
          ctx.lineTo((0.5 + ball2.x) | 0, (0.5 + ball2.y) | 0);
        }
}
    ctx.stroke();
  }
}

// Start
loop();

particles.js

full js libary for this idea (more options)

the same steps only add CDNs.min before body + follow this docs: https://github.com/VincentGarreau/particles.js/


#3

I succesfully integrated the first the initial code in my question. Thank you.

However, I tried to make better visual appealing using this: http://vincentgarreau.com/particles.js/ I set up a white background and black lines and dots.

Then I tried many times to integrate it into embed page but it didn’t work. I didn’t understand how exactly to use these parts https://github.com/VincentGarreau/particles.js/

Could you give me an example, I just need to understand their order.

Thank you very much!


#4

Nice.

First particles.js is full libary with a lot of options/API and so on. You must know “how-to” use this libary outside webflow (html/css/js). docs/youtube/codepen and so on.

  1. Assets: Add cdn before body.
    <script src="https://cdn.jsdelivr.net/npm/particles.js@2.0.0/particles.min.js"></script>
  2. instilize - Add js (from codepen! not from the docs - the docs use JSON & JS)
  3. Markup - add div (drag-and-drop)
  4. ID - add id #particles-js for this div
  5. Height - Style #particles-js height: Why? the practicles works like background. So set the height to 400px, 100vh, or any value you want (the width is 100% - block element) (how? --> webflow editor)
    https://university.webflow.com/article/width-and-height-units

Now this libary add this style inline by JS to #particles-js canvas
<canvas class="particles-js-canvas-el" width="1902" height="347" style="width: 100%; height: 100%;"></canvas>

The height/width calucate by JS (match the div size with some extra / or match viewport if you dont set any height value).

  1. Background-color - #particles-js - set bg color!! to red/blue or any value you want (how? --> webflow editor). If not by deafult the particles white so the div looks empty.

Thats it. Now if you want add content inside this div and style this content like any other content (margin/padding/color and so on).

Try this steps - and add URL if something wont work.


#5

Hello, thank you for your answer.

Unfortunately, I tried several times but I have only this:


#6

Hi. Put custom code before body. Cleaner code!! (you put all of the code as embed HTML)

In the way you build this is really hard to work with webflow UI (why not drag and drop div - add to this div ID)

Anyway - In your case add this wrapper to your code (i forgot from this) - should work

document.addEventListener("DOMContentLoaded", function() {

//your js script code

});

#7

full code
(again it will work but follow my steps - not as embed html)

<style>
  /* ---- reset ---- */

body {
  margin: 0;
  font:normal 75% Arial, Helvetica, sans-serif;
}

canvas {
  display: block;
  vertical-align: bottom;
}

/* ---- particles.js container ---- */

#particles-js {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: #b61924;
  background-image: url("");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: 50% 50%;
}

/* ---- stats.js ---- */

.count-particles{
  background: #000022;
  position: absolute;
  top: 48px;
  left: 0;
  width: 80px;
  color: #13E8E9;
  font-size: .8em;
  text-align: left;
  text-indent: 4px;
  line-height: 14px;
  padding-bottom: 2px;
  font-family: Helvetica, Arial, sans-serif;
  font-weight: bold;
}

.js-count-particles{
  font-size: 1.1em;
}

#stats,
.count-particles{
  -webkit-user-select: none;
}

#stats{
  border-radius: 3px 3px 0 0;
  overflow: hidden;
}

.count-particles{
  border-radius: 0 0 3px 3px;
}
</style>
<!-- particles.js container -->
<div id="particles-js"></div>

<!-- stats - count particles -->
<div class="count-particles">
  <span class="js-count-particles">--</span> particles
</div>

<!-- particles.js lib (JavaScript CodePen settings): https://github.com/VincentGarreau/particles.js -->

  <script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js" ></script>

<script>
  

  
  /* ---- particles.js config ---- */
document.addEventListener("DOMContentLoaded", function() {
particlesJS("particles-js", {
  "particles": {
    "number": {
      "value": 380,
      "density": {
        "enable": true,
        "value_area": 800
      }
    },
    "color": {
      "value": "#ffffff"
    },
    "shape": {
      "type": "circle",
      "stroke": {
        "width": 0,
        "color": "#000000"
      },
      "polygon": {
        "nb_sides": 5
      },
      "image": {
        "src": "img/github.svg",
        "width": 100,
        "height": 100
      }
    },
    "opacity": {
      "value": 0.5,
      "random": false,
      "anim": {
        "enable": false,
        "speed": 1,
        "opacity_min": 0.1,
        "sync": false
      }
    },
    "size": {
      "value": 3,
      "random": true,
      "anim": {
        "enable": false,
        "speed": 40,
        "size_min": 0.1,
        "sync": false
      }
    },
    "line_linked": {
      "enable": true,
      "distance": 150,
      "color": "#ffffff",
      "opacity": 0.4,
      "width": 1
    },
    "move": {
      "enable": true,
      "speed": 6,
      "direction": "none",
      "random": false,
      "straight": false,
      "out_mode": "out",
      "bounce": false,
      "attract": {
        "enable": false,
        "rotateX": 600,
        "rotateY": 1200
      }
    }
  },
  "interactivity": {
    "detect_on": "canvas",
    "events": {
      "onhover": {
        "enable": true,
        "mode": "grab"
      },
      "onclick": {
        "enable": true,
        "mode": "push"
      },
      "resize": true
    },
    "modes": {
      "grab": {
        "distance": 140,
        "line_linked": {
          "opacity": 1
        }
      },
      "bubble": {
        "distance": 400,
        "size": 40,
        "duration": 2,
        "opacity": 8,
        "speed": 3
      },
      "repulse": {
        "distance": 200,
        "duration": 0.4
      },
      "push": {
        "particles_nb": 4
      },
      "remove": {
        "particles_nb": 2
      }
    }
  },
  "retina_detect": true
});


/* ---- stats.js config ---- */

var count_particles, stats, update;
stats = new Stats;
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);
count_particles = document.querySelector('.js-count-particles');
update = function() {
  stats.begin();
  stats.end();
  if (window.pJSDom[0].pJS.particles && window.pJSDom[0].pJS.particles.array) {
    count_particles.innerText = window.pJSDom[0].pJS.particles.array.length;
  }
  requestAnimationFrame(update);
};
requestAnimationFrame(update);
  
  });	
</script>