Search code examples
d3.jssafaricolor-spacehsl

d3.hsl fails on Safari


I put together a simple HTML page:

$(document).ready(function() {  
  var canvas = document.getElementById("myCanvas");
  var ctx = canvas.getContext("2d");

  canvas.width  = window.innerWidth;
  canvas.height = window.innerHeight;
 
  //ctx.fillStyle = "gray";
  ctx.fillStyle = d3.hsl(120, 0.5, 0.5);
  
  ctx.fillRect(0,0, canvas.width, canvas.height);  
});
html, body {
  width:  100%;
  height: 100%;
  margin: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>

<canvas id="myCanvas"> </canvas>

On Chrome it correctly gives a green background. On Safari (8.0.6 -- current at time of writing) however it gives a black background.

What's going wrong?


Solution

  • Looks like the issue has to do with String coercion. Basically, the proper way to get d3.hsl to return a color string ("#40bf40" in your case) is to call .toString() on the HSL object (see here). So in your case, it would be

    ctx.fillStyle = d3.hsl(120, 0.5, 0.5).toString()
    

    which will fix the Safari issue.

    The reason it worked in Chrome without the .toString() is because Chrome's JS engine chose to convert it to a String for you - much like JS converts a number to a string in something like this: 5 + "2" // "52". Internally it's actually calling (5).toString() + "2". Safari happened to not decide to .toString() it, which is why it didn't work.