Skip to content

Instantly share code, notes, and snippets.

@Kcnarf
Last active March 2, 2018 10:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kcnarf/cb56f9fa18efb97daa7f8ecc7f4bdaf8 to your computer and use it in GitHub Desktop.
Save Kcnarf/cb56f9fa18efb97daa7f8ecc7f4bdaf8 to your computer and use it in GitHub Desktop.
CMYK halftone printing - chrome hack
license: mit

In veltman's orignial block, Chrome 64 (and probably other versions) displays a black rectangle when any of the svg>defs>pattern (mapping values of the CMYK space) uses a circle of radius 0.

A quick fix would be to not set any CMYK value to 0, eg. in rgbToCmyk return { cyan: Math.max(0.01, value), ... };

forked from veltman's block: CMYK halftone printing

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var width = 960,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var defs = svg.append("defs");
var background = svg.append("g")
.attr("class", "dots");
var radius = d3.scaleSqrt()
.range([0, 6]);
var colors = ["yellow", "magenta", "cyan", "black"],
rotation = [0, -15, 15, 45];
var patterns = defs.selectAll("pattern")
.data(colors)
.enter()
.append("pattern")
.attr("id", Object)
.attr("patternUnits", "userSpaceOnUse")
.attr("width", 12)
.attr("height", 12)
.append("circle")
.attr("fill", Object)
.attr("cx", 6)
.attr("cy", 6);
defs.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width / 5)
.attr("height", height / 5);
svg.append("g").attr("clip-path", "url(#clip)")
.attr("transform", "translate(" + (width * 2 / 5) + " " + (height * 2 / 5) + ")")
.append("g")
.attr("class", "dots")
.attr("transform", "scale(0.1 0.1)")
.append("rect")
.attr("width", width * 2)
.attr("height", height * 2)
.attr("fill", "#fff");
d3.selectAll(".dots")
.selectAll(".color")
.data(colors)
.enter()
.append("rect")
.attr("class", "color")
.attr("width", width * 4)
.attr("height", width * 4)
.attr("x", width * -3 / 2)
.attr("y", width * -3 / 2)
.style("mix-blend-mode", "multiply")
.attr("fill", function(d){
return "url(#" + d + ")";
})
.attr("transform", function(d, i){
return rotation[i] ? "rotate(" + rotation[i] + " " + (width / 2) + " " + (height / 2) + ")" : null;
});
d3.timer(function(t){
t = t % 16000 / 8000;
if (t > 1) {
t = 2 - t;
}
var cmyk = rgbToCmyk(d3.color(d3.interpolateRainbow(t)));
patterns.attr("r", function(d){
return radius(cmyk[d]);
});
});
function rgbToCmyk(rgb) {
var r = rgb.r / 255,
g = rgb.g / 255,
b = rgb.b / 255,
k = 1 - Math.max(r, g, b);
return {
cyan: Math.max(0.01, (1 - r - k) / (1 - k)),
magenta: Math.max(0.01, (1 - g - k) / (1 - k)),
yellow: Math.max(0.01, (1 - b - k) / (1 - k)),
black: Math.max(0.01, k)
};
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment