How can D3 be utilized to create unique and dynamic organic shapes like this?

While experimenting with a d3 radar chart for a different project, I discovered that using a basis interpolation on a polar line produced an incredibly smooth curve reminiscent of an organic shape. This led me to wonder if there is a way to achieve similar results with D3.js. The shapes I aim to replicate can be seen here:

https://i.sstatic.net/Kz3KI.png

Answer №1

Does this look good to you? =)

https://i.sstatic.net/viSqg.gif

card('https://i.sstatic.net/EK1my.png?s=128')
card('https://i.sstatic.net/EK1my.png?s=128')
card('https://i.sstatic.net/EK1my.png?s=128')

function card(url) {

  let s = 500;            // size
  let step = 100;         // x-axis step
  let range = [-50, 50];  // y-axis range
    
  // add new svg to document.body with origin at 0  
  let svg = d3.select('body')
              .append('svg')
              .attr('viewBox', `0 0 ${s} ${s}`);

  // interpolation algorithm for points used to form masking shape
  let line = d3.line()
               .curve(d3.curveCardinalClosed);

  // random values generator function
  let rnd = d3.randomUniform.apply(0, range);
  
  // image goes first
  svg.append("svg:image")
     .attr('mask', 'url(#mask)')
     .attr('width', s)
     .attr('height', s)
     .attr("xlink:href", url)

  // here i place points with fixed `step` by `x` axis  
  // and random value in `range` by `y` axis
  // which forms the "original path"
  let pts = d3.range(-1, s/step+2).map(i => [i*step, rnd()]);

  // shift points down from "original path", 
  // amount of shift depends from point index 
  let pts1 = pts.map((p, i) => [
      p[0], p[1] + s*0.3 - i*s*0.08
  ]);
  
  // reverse order of original and shift points down on 
  // bigger values, depending from point index
  let pts2 = pts.reverse().map((p, i) => [
      p[0], p[1] + s*0.8 - i*s*0.03
  ]);

  // forming single interpolated path for all 
  // points from prev steps concatenated in single array
  let d = line(pts2.concat(pts1));
  
  // append rect sized as viewport with hole formed by interpolated path
  // with random color from hsl palette and opacity 0.9
  svg.append('path')
     .attr('opacity', 0.9)
     .attr('fill', `hsl(${Math.random()*255}, 55%, 55%)`)
     .attr('d', `M0,0 v${s} h${s} v${-s} z ${d}`)
}
svg {
    height: 150px;
    margin: 10px;
    box-shadow: 0 2px 10px 2px lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Are certain browsers unable to play dynamically generated HTML5 audio files?

While working on my project, I encountered an issue with creating and controlling an audio element in JavaScript. The element works perfectly fine in Firefox, Chrome, and Opera; however, it fails to function properly in IE and Safari. In these browsers, ...

Interactive auto-suggest feature in JavaScript while typing

I am currently working on an HTML page that includes a text field for users to input text in any language. I have a javascript file containing a list of world languages that I want the text field to autocomplete from. Despite linking the javascript file to ...

Utilize PHP to incorporate a dynamic JavaScript navigation menu

I'm giving this question another shot, so please be patient with me. How can a JS menu be included in a PHP page? Every time I use an include statement for nav which contains HTML, nothing appears. index.php includes a statement that should fetch t ...

faulty JavaScript Object notation

I am currently working on setting up a JavaScript array specifically for Google Analytics integration. Below you can find the code I have been using. Although the initial part of the syntax appears to be correct, such as 'purchase', I seem to be ...

Error: Unable to change the value of "name" as it is set to read-only

Whenever I need to update the input value, I rely on the handleDepartmentChange function. const handleDepartmentChange = (companyIndex, departmentIndex, e) => { const newCompanies = [...companies]; newCompanies[companyIndex].children[departmen ...

Having trouble getting my Leaflet map to display even after meticulously following the quick-start guide

I am experiencing an issue where the map is not displaying at all, leaving a blank space where it should be. Despite following Leaflet's quick-start guide, I have been unable to determine the cause of this problem. Here is the code that I currently h ...

What is the best way to remove a CSS style using JavaScript?

For my website automation using Selenium, I encountered a challenging dropdown that was not the standard native one but a custom-designed version. To tackle this issue, I needed to set its CSS class to hidden in order to access the native functionality smo ...

Is there a way to automatically activate the "Add" button when I hit the enter key in the text box?

Being someone who relies on to-do lists, I implemented a system where you can input tasks into a textbox and click the add button to see them listed below. However, I found it cumbersome to keep clicking the add button every time I wanted to quickly add mu ...

Utilizing Typescript for Promises and leveraging Async-Await for dependent calls

I am currently exploring ways to enhance the performance of data loading by running requests in parallel or considering alternative methods. My background is in Java and I am relatively new to coding in Javascript/Typescript. I recently came across Async-A ...

Connect the mileage tracker to a Datalist or grid view component

I recently downloaded the Odometer Sample from , however, I am facing an issue where only the first element in the Datalist is getting the Odometer display, while others are not displaying it. Here is the snippet of code: <script type="text/javascript" ...

Verify that the select field has been chosen using Protractor

Currently, I am in the process of developing a test that places importance on whether a select field has already been populated. it('should automatically select a field if it hasn't been selected previously', function() { var usersField = ...

What is the process of integrating a translator navigational bar into Swiper.js?

After spending 2 days researching, I have been unable to find the information I need on a common feature found in many mobile apps and websites. So, I have decided to seek advice from someone else. The feature I am referring to is a "translator" navigation ...

using a unique first argument in Javascript when calling the apply method

In this particular scenario, the output varies depending on the first argument passed to apply The snippet of code looks like this: var fruitarray = []; fruitarray[0] = ['strawberry', 'orange']; fruitarray[1] = ['lime', &a ...

Utilizing a click event in Vue.js to dynamically populate form inputs within a modal

I am currently working on an HTML modal form that allows me to update the selected post. I have set up a click event that retrieves the data for the chosen post, and then passes it to the form to populate the fields. However, I encountered an issue when tr ...

Retrieving HTML data from a NodeJS server utilizing AJAX technology

I have created a login interface that sends user data to a NodeJS server for authentication. Below is the code for the form. <form action="http://127.0.0.1:8080/" method="POST" id="login_form"> <div class="input"> <input class=" ...

Associating the object key and value with distinct attributes within the component

person = {name: 'Alice', age: '19', weight: 52} I'm looking to display both the keys and values from the object in one label and input field respectively. I attempted using Object.entries, but couldn't figure out how to sepa ...

Is it possible for me to use ts files just like I use js files in the same manner?

So I recently stumbled upon TypeScript and found it intriguing, especially since I enjoy adding annotations in my code. The only downside is that I would have to change all my .js files to .ts files in order to fully utilize TypeScript's capabilities. ...

The use of a Bootstrap row is leading to incorrect dimensions for FullPageJS

Within the body tag, I have included the following code snippet: <div id="container"> <div class="section profile"> <div class="row"> <div class="col-sm-6"> A </div> ...

What methods can be used to stop a page from reloading with selenium web driver or Javascript?

None of the options provided seem to be working. Are there any alternative approaches that can be utilized in Selenium using C# or JavaScript? I attempted the following statements without success: driver.findElement(By.tagName("body")).sendKeys("Keys.ESCA ...

JavaScript code to extract and parse query parameters

In my JavaScript function, I am parsing a URL to create a map of (paramName, value). The snippet of code looks like this: var search = location.search.substring(1); var data = {} if(search!="") { var urlParams = JSON.parse('{"' + decodeURI( ...