samedi 24 juillet 2021

Widen radius of SVG curves with JavaScript

The snippet below draws random connected curves over the document a certain number of times:

function createPath() {
  const 
    dimensions = getWindowDimensions(), svg = document.querySelector( `svg` ),
    path = document.createElementNS( `http://www.w3.org/2000/svg`, `path` );
  
  dimensions[0] = dimensions[0]; dimensions[1] = dimensions[1];
  svg.appendChild( path );
  
  path.setAttribute(
    `d`,
    `M ` +
    `${getRandomNumber(dimensions[0])} ` + `${getRandomNumber(dimensions[1])} ` +
    `C ` + 
    `${getRandomNumber(dimensions[0])} `+`${getRandomNumber( dimensions[1])}, ` +  
    
    `${getRandomNumber(dimensions[0] )} `+`${getRandomNumber( dimensions[1])}, ` +
    
    `${getRandomNumber(dimensions[0])} ` + `${getRandomNumber( dimensions[ 1 ])} `
  )
  
  for( let i = 0; i < 100; i++  ) {
    path.setAttribute(
      `d`,
      path.getAttribute( `d` ) + 
      `S`+`${getRandomNumber(dimensions[0])} `+`${getRandomNumber(dimensions[1])}, `+
      
      `${getRandomNumber(dimensions[0])} ` + `${getRandomNumber(dimensions[1])} `
    )
  }
}

setInterval( setSVGDimensions, 10 ); setInterval( positionPath, 10 );
createPath();
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  display: flex; justify-content: center; align-items: center;
}
svg {
  border-radius: 1rem; background-color: rgba( 95%,95%,95%,0.5 );
  filter: blur( 1rem );

  animation-name: blur; animation-duration: 1s;
  animation-timing-function: ease-in-out; animation-fill-mode: forwards;

  stroke-linecap: round; stroke-linejoin: round;
  stroke-width: 0.25rem; fill: none;
}

@keyframes blur {
  100% { filter: blur( 0rem ); }
}

path {
  animation-name: grow;
  animation-duration: 2500s;
  animation-timing-function: cubic-bezier( 0.75,0.25,0.25,1 );

  stroke-dasharray: 1000000;
  stroke-dashoffset: 1000000;  
  stroke: rgba( 0%,100%,75%,0.75 );
}

@keyframes grow {
  100% { stroke-dashoffset: 0; }
}
<svg></svg>
<script>
  function getRandomNumber( max ) { return Math.floor( Math.random() * max ); }

  function getWindowDimensions() {
    const 
      dimensions = [],
      windowWidth = document.documentElement.clientWidth,
      windowHeight = document.documentElement.clientHeight;

    dimensions.push( windowWidth, windowHeight );
    return dimensions;
  }
  
  function setSVGDimensions() {
    const 
      dimensions = getWindowDimensions(), svg = document.querySelector( `svg` );

    svg.style.width = dimensions[ 0 ] - 10; svg.style.height = dimensions[ 1 ] - 10;
  }  
  
  function positionPath() {
    const
      dimensions = getWindowDimensions(), path = document.querySelector( `path` );

      path.setAttribute( 
        `transform`, 
        `
          scale( 0.5 ) translate( ${ dimensions[ 0 ] / 2 },${ dimensions[ 1 ] / 3 } )
        ` 
      )
  }  
</script>

This is the desired behavior except for the sharpness of some curves. The radius is too small, the angle is too acute. We want wider smoother curves. For example in this screenshot the problem areas are circled.

In the picture below notice the red circles have very sharp curves whereas the green circled are wider smoother curves:

enter image description here

Is there a way we could use JavaScript to prevent the creation of the sharp curves ( circled in red ) and have the algorithm only create wider curves ( circled in green )?




Aucun commentaire:

Enregistrer un commentaire