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?
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.