Eol Nuha
Eol Nuha

Reputation: 85

Fibonacci Sphere with svg(images) instead of points

I am trying to do a Fibonacci Sphere with a canvas like the following code, but instead of the same point showing everywhere I want to show different images, possibly svgs like logos and other images. I've done some research in google like visiting codepen and other places but couldn't find anything that worked. I imagine it would be something like the one in this website here. Any idea on how to approach this?

var cant = 100;
var offset = 2 / cant;
var increment = Math.PI * (3 - Math.sqrt(5));
var canvas = document.getElementById("canvas");

var i;
var circle;

//---Build the elements
for(i = 0; i < cant; i++){
  
  circle = document.createElement("div");
  circle.className = "point";
  circle.setAttribute("data-index", i);
  
  canvas.appendChild(circle);
  
};

//---Apply transformations to points
function updatePoints(evt){
  
  var x, y, z, r, a, scale, opacity, point, style;
  
  var angle = (evt) ? (-evt.pageX / 4) * Math.PI / 180 : 0;
  
  for(i = 0; i < cant; i++){

    y = (i * offset - 1) + (offset / 2);
    r = Math.sqrt(1 - Math.pow(y, 2));
    a = ((i + 1) % cant) * increment + angle;
    x = Math.cos(a) * r;
    z = Math.sin(a) * r;

    scale = Math.round(z * 20000) / 100;
    opacity = (1 + z) / 1.5;
    
    style = "translate3d(" + (125 + x * 100) + "px, " + (125 + y * 100) + "px, " + scale + "px)";
    
    point = canvas.querySelectorAll("[data-index='" + i +"']");    
    point[0].style.WebkitTransform = style;
    point[0].style.msTransform = style;
    point[0].style.transform = style;
    point[0].style.opacity = opacity;

  }
  
}

//---Update the points at start
updatePoints();

//---Update the points on mouse move
document.addEventListener("mousemove", updatePoints);
body, html{
  height: 100%;
  position: relative;
}

body{
  background-color: #232B2B;
  margin: 0;
  padding: 0;
}

#canvas{
  height: 250vh;
  margin: 0 0;
  position: relative;
  width: 250vh;
}

.point{
  background: red;
  border-radius: 50%;
  height: 4px;
  position: absolute;
  transform-style: preserve-3d;
  width: 4px;
}
<div id="canvas">
  
</div>

Any help would be most helpful.

Upvotes: 0

Views: 224

Answers (1)

disinfor
disinfor

Reputation: 11533

You can continue using the createElement method.

I added this, to show a random image (from picsum) for each dot:

// Create a new img element
img = document.createElement('img');
// Add the src to each img element. 
//Here using the iterator variable to 
//change the id of the photo we are retrieving
img.src = 'https://picsum.photos/id/' + i +'/20/20'
// Append the img to the div
circle.appendChild(img);

And I made the circles a bit larger in the CSS (20px) so you can see it.

If you want specific images, you could create an array inside your JS, or pull from a folder on your server.

var cant = 100;
var offset = 2 / cant;
var increment = Math.PI * (3 - Math.sqrt(5));
var canvas = document.getElementById("canvas");

var i;
var circle;

//---Build the elements
for(i = 0; i < cant; i++){
  
  circle = document.createElement("div");
  img = document.createElement('img');
  img.src = 'https://picsum.photos/id/' + i +'/20/20'
  circle.appendChild(img);
  circle.className = "point";
  circle.setAttribute("data-index", i);
  
  canvas.appendChild(circle);
  
};

//---Apply transformations to points
function updatePoints(evt){
  
  var x, y, z, r, a, scale, opacity, point, style;
  
  var angle = (evt) ? (-evt.pageX / 4) * Math.PI / 180 : 0;
  
  for(i = 0; i < cant; i++){

    y = (i * offset - 1) + (offset / 2);
    r = Math.sqrt(1 - Math.pow(y, 2));
    a = ((i + 1) % cant) * increment + angle;
    x = Math.cos(a) * r;
    z = Math.sin(a) * r;

    scale = Math.round(z * 20000) / 100;
    opacity = (1 + z) / 1.5;
    
    style = "translate3d(" + (125 + x * 100) + "px, " + (125 + y * 100) + "px, " + scale + "px)";
    
    point = canvas.querySelectorAll("[data-index='" + i +"']");    
    point[0].style.WebkitTransform = style;
    point[0].style.msTransform = style;
    point[0].style.transform = style;
    point[0].style.opacity = opacity;

  }
  
}

//---Update the points at start
updatePoints();

//---Update the points on mouse move
document.addEventListener("mousemove", updatePoints);
body, html{
  height: 100%;
  position: relative;
}

body{
  background-color: #232B2B;
  margin: 0;
  padding: 0;
}

#canvas{
  height: 250vh;
  margin: 0 0;
  position: relative;
  width: 250vh;
}

.point{
  background: red;
  border-radius: 50%;
  height: 20px;
  position: absolute;
  transform-style: preserve-3d;
  width: 20px;
  overflow: hidden;
}
<div id="canvas">
  
</div>

Upvotes: 1

Related Questions