block by harrystevens 7e733ac8ae4e8076c30c7b86cadcd346

Fun with Linear Gradients I

Full Screen

This block uses SVG’s linearGradient element to create a linear gradient that you can update.

Use the color picker to change the colors. Drag the circles to change the gradient’s orientation.

Libraries used: D3, jQuery, Spectrum, Font Awesome

index.html

<html>
  <head>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/spectrum/1.8.0/spectrum.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/fonts/FontAwesome.otf" />
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/spectrum/1.8.0/spectrum.min.js"></script>
    <script src="scripts.js"></script>
  </body>
</html>

scripts.js

var width = window.innerWidth, height = window.innerHeight;

var colors = ["#00fdff", "#ff0083"];

var position = [[.25, .25],[.75, .75]];

d3.select("body").append("div")
    .attr("class","controls");

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

svg.append("rect")
    .attr("class", "gradient-rectangle")
    .attr("x", "0")
    .attr("y", "0")
    .attr("width", width)
    .attr("height", height);

var defs = svg.append("defs");

var gradient = defs.append("linearGradient")
    .attr("id", "linear-gradient");

// change orientation
changeOrientation(position);

var radius = 20;

position.forEach(function(d, i){

  var offset = [];
  i == 0 ? offset = [radius,-radius/2] : offset = [-radius,-radius/2];

  svg.append("circle")
      .attr("class", "position-circle")
      .attr("data-which", i)
      .attr("cx", width * position[i][0] + offset[0])
      .attr("cy", height * position[i][1] + offset[1])
      .attr("r", radius)
      .call(d3.drag(d)
          .on("drag", function(){

            var x = d3.event.x, y = d3.event.y;
            d3.select(this).attr("cx", x);
            d3.select(this).attr("cy", y);

            if (d3.select(this).attr("data-which") == 0) {
              position[0][0] = x / width;
              position[0][1] = y / height;
            } else {
              position[1][0] = x / width;
              position[1][1] = y / height;
            }

            changeOrientation(position);

          }));

});

//change colors

colors.forEach(function(d, i){
  gradient.append("stop")
      .attr("class", "stop-" + i);

  $(".controls").append("<div class='spectrum' id='spectrum-" + i + "'></div>");
  $("#spectrum-" + i).spectrum({
    flat: true,
    color: colors[i],
    preferredFormat: "hex",
    showInitial: true,
    showInput: true,
    move: function(color){
      colors[i] = color;
      changeColors(colors);
    }
  });

});

changeColors(colors);

$(".controls").css("left", width / 2 - $(".sp-container").width());
$(".sp-container").hide();
$(".controls").append("<div class='hide-show'><i class='fa fa-caret-down' aria-hidden='true'></i></div>");
$(".hide-show").css({
  "top": $(".controls").height(),
  "left": $(".sp-container").width() - ( $(".hide-show").width() / 2 )
});
$(".hide-show").click(function(){
  if ($(".sp-container").hasClass("show")){
    $(".sp-container").hide().removeClass("show");
    $(this).html("<i class='fa fa-caret-down' aria-hidden='true'></i>").css("top", 0);
  } else {
    $(".sp-container").show().addClass("show");
    $(this).html("<i class='fa fa-caret-up' aria-hidden='true'></i>").css("top", $(".controls").height());
  }
});

// functions
function changeOrientation(position){
  gradient
      .attr("x1", position[0][0] * 100 + "%")
      .attr("y1", position[0][1] * 100 + "%")
      .attr("x2", position[1][0] * 100 + "%")
      .attr("y2", position[1][1] * 100 + "%");
}

function changeColors(colors){

  colors.forEach(function(d, i){

    d3.select(".stop-" + i)
        .attr("offset", i * 100 + "%")
        .attr("stop-color", colors[i]);

  });

  d3.select(".gradient-rectangle")
      .style("fill", "url(#linear-gradient)");
}

styles.css

body {
  margin: 0;
}

.controls, .hide-show {
  position: absolute;
}
.hide-show {
  width: 30px;
  text-align: center;
  cursor: pointer;
}
.hide-show, .sp-container {
  border: 1px solid #eee;
  background-color: #fff;
}
.sp-palette-row-initial span.sp-thumb-el:first-of-type, .sp-button-container {
  display: none !important;
}
.sp-initial span {
  width: 170px;
}
.sp-input-container {
  width: 172px;
}
.sp-container input {
  font-family: "Helvetica Neue", sans-serif;
}

.position-circle {
  stroke: #000;
  stroke-width: 2px;
  fill: #3a403d;
  cursor: all-scroll;
}