Accepted answer

Here is an updated codepen with your solution:

you have to apply the transformation on an group element not directly on the SVG DOM in order to allow the user have further mouse interaction with the SVG viewport.

.call(d3.behavior.zoom().on("zoom", function () {
    groupElement.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")

the changes to your original codepen was to store the reference to the word cloud group in order to be used and apply all changes to that reference

wCloud = svg.append("g");   

Also the initial transformation was removed because if the group element has a transformation value initially it will be replaced with a new transformation from the d3 event that will have large differences between x,y position and it will generate a flicker on the first transformation.

In order to avoid this the initial position of the group has no transformation but the words were placed relative to the center of the viewport:

.attr("transform", function(d) {
    return "translate(" + [bMidX + d.x, bMidY + d.y] + ")rotate(" + d.rotate + ")";

Related Query