Carlos Aguni

Highly motivated self-taught IT analyst. Always learning and ready to explore new skills. An eternal apprentice.


D3js Own animation showcase

01 Oct 2021 »

Tween1

more

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
 
  <script>
    const svg = d3.select('body')
                  .append('svg')
                  .attr('width', '500px')
                  .attr('height', '500px')
                  .style('border', '1px solid black')


    let size = 100
    let color = d3.scaleSequential()
        .domain([0,size])
        .interpolator(d3.interpolateRainbow);

    svg.selectAll('circle')
        .data(d3.range(size))
        .enter()
        .append('circle')
        .attr('r', 20)
        .attr('fill', (d,i) => color(i))
        .attr('cy', (d,i) => 50+(i*5))
        .attr('cx', 120)
        .transition()
        .duration(1000)
      .delay((d,i) => i*50)
        .on("start", started)

    function started(){
      d3.active(this)
        .attr('cx', 400)
        .transition()
          .attr('cx', 120)
        .transition()
          .on('start', started)
    }
  </script>
</body>
</html>

Tween2

more

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
 
  <script>
    const svg = d3.select('body')
                  .append('svg')
                  .attr('width', '800px')
                  .attr('height', '500px')
                  .style('border', '1px solid black')

    let size = 100
    let color = d3.scaleSequential()
        .domain([0,size])
        .interpolator(d3.interpolateRainbow);

    const loop = () => {
      setTimeout(() => {
        for (let i = 0; i < 100; i++){
          svg.append('circle')
              .attr('fill', color(Math.floor(Math.random()*size)))
              .attr('cx', -20)
              .attr('cy', 180+Math.random()*200)
              .attr('r', 10)
              .transition()
              .duration((3+Math.random()*8)*1000)
              .delay(Math.random()*10)
              .attrTween('transform', runPath(Math.random()*50))
              .delay(100)
              .remove()
        }
        loop()
      }, 500)
    }

    loop()

    function runPath(x){
      return function(d,i,a) {
        return function(t) {
          return `translate(${t*900}, ${Math.sin(t*20)*100})`
          if (x < 25)
            return `translate(${t*900}, ${Math.sin(t*20)*100})`
          else
            return `translate(${t*900}, ${Math.cos(t*20)*100})`
        }
      }
    }

  </script>
</body>
</html>

Demo0 Teams

more

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
</head>
<body>
  <script>
    let opts = ['👏', '💖', '🍦', '👾']
    setInterval(() => {
      d3.select('body')
        .append('span')
        .text(d => opts[Math.floor(Math.random()*opts.length)])
        .style('position', 'fixed')
        .style('bottom', '-20px')
        .style('left', Math.random()*1400+'px')
        .transition()
        .duration(2000)
        .style('bottom', 100+Math.random()*500+'px')
        .transition()
        .duration(2000)
        .style('bottom', Math.random()*200+'px')
        .style('opacity', '0')
        .transition()
        .duration(2000)
        .remove()
    }, 8)
  </script>
</body>
</html>

Infinity Symbol

https://crashlaker.github.io/d3js-static/infinity/index0-infinity-symbol.html

<summary>more</summary>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    #container {
      width: 1000px;
      height: 1000px;
      margin: auto;
    }
  </style>
</head>
<body>
  <div id="container"></div>
  <script>
    const container = d3.select('#container')
    const canvas = container.append('canvas')
                      .attr('width', '300px')
                      .attr('height', '300px')
                      .style('border', '1px solid black')
    const ctx = canvas.node().getContext('2d')
    ctx.strokeStyle = 'red'
    ctx.fillStyle = 'red'
    ctx.lineWidth = 2

    const scaleX = d3.scaleLinear().domain([-1,1]).range([20, 280])
    const scaleY = d3.scaleLinear().domain([-1,1]).range([20, 280])

    let m = 10
    let oldx = oldy = 0
    let x, y
    let i = 1
    setInterval(() => {
      x = Math.cos(i)
      y = Math.sin(i) * Math.cos(i)
      console.log(scaleX(x), scaleY(y))
      ctx.moveTo(scaleX(oldx), scaleY(oldy))
      ctx.lineTo(scaleX(x), scaleY(y))
      oldx = x
      oldy = y
      ctx.stroke()
      i+=1
    }, 30);
  </script>
</body>
</html>

Force Infinity Symbol Path

https://crashlaker.github.io/d3js-static/infinity/index1.html

more

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    #container {
      width: 1000px;
      height: 1000px;
      margin: auto;
    }
  </style>
</head>
<body>
  <div id="container"></div>
  <script>
    const container = d3.select('#container')
    const svg = container.append('svg')
                          .attr('width', '1000px')
                          .attr('height', '1000px')
                          .style('border', '1px solid black')

    const scaleX = d3.scaleLinear().domain([-1,1]).range([200, 800])
    const scaleY = d3.scaleLinear().domain([-1,1]).range([200, 800])

    const nodes = d3.range(100).map((d,i) => {
      return { id: i, r: 8 }
    })

    const cnodes = svg.selectAll('circle')
                        .data(nodes)
                        .enter()
                        .append('circle')
                        .attr('fill', 'red')
                        .attr('r', d => d.r)
                        .attr('cx', d => d.x)
                        .attr('cy', d => d.y)

    const ticked = () => {
      cnodes
          .attr('cx', d => d.x)
          .attr('cy', d => d.y)
    }

    const simulation = d3.forceSimulation(nodes)
                          .force('collide', d3.forceCollide())
                          .force('charge', d3.forceManyBody())
                          .alphaTarget(0.3)
                          .velocityDecay(0.1)
                          .on("tick", ticked)

    const scale2 = d3.scaleLinear().domain([0,210]).range([1,0])
    const div = 20
    let m = 10
    let oldx = oldy = 0
    let x, y
    let i = 1
    let step = 0.2
    let t = 100
    let pp = 0.3
    const infPos = (t) => {
      return [scaleX(Math.cos(t)), scaleY(Math.cos(t)*Math.sin(t))]
    }
    setInterval(() => {
      simulation
        .force("x", d3.forceX().x( 
            (d,i) => {
              return infPos(t-Math.floor(i%div)*step)[0]
            }
            //scale(coords[coords.length-1].x2)
          //)
          ).strength((d,i) => {
            return scale2(i)*pp
          })
        )
        .force("y", d3.forceY().y(
            (d,i) => {
              return infPos(t-Math.floor(i%div)*step)[1]
            }
          ).strength((d,i) => {
            return scale2(i)*pp
          })
        )
      t += step
    }, 100)
  </script>
</body>
</html>