(function() { var clip_paths, clip_type, cpr, height, path, paths2string, solution_paths, solutions, subj_paths, succeeded, svg, width, _i, _j, _len, _len2, _ref, _ref2; width = 960; height = 500; /* create the SVG */ svg = d3.select('body').append('svg').attr('width', width).attr('height', height); /* define subject and clip paths */ subj_paths = [ [ { X: 10, Y: 10 }, { X: 110, Y: 10 }, { X: 110, Y: 110 }, { X: 10, Y: 110 } ], [ { X: 20, Y: 20 }, { X: 20, Y: 100 }, { X: 100, Y: 100 }, { X: 100, Y: 20 } ] ]; clip_paths = [ [ { X: 50, Y: 50 }, { X: 150, Y: 50 }, { X: 150, Y: 150 }, { X: 50, Y: 150 } ], [ { X: 60, Y: 60 }, { X: 60, Y: 140 }, { X: 140, Y: 140 }, { X: 140, Y: 60 } ] ]; /* create and instruct Clipper to work with the provided paths */ cpr = new ClipperLib.Clipper(); /* true for closed paths */ cpr.AddPaths(subj_paths, ClipperLib.PolyType.ptSubject, true); cpr.AddPaths(clip_paths, ClipperLib.PolyType.ptClip, true); /* perform a UNION, a DIFFERENCE, a XOR and an INTERSECTION */ solutions = []; _ref = [ClipperLib.ClipType.ctUnion, ClipperLib.ClipType.ctDifference, ClipperLib.ClipType.ctXor, ClipperLib.ClipType.ctIntersection]; for (_i = 0, _len = _ref.length; _i < _len; _i++) { clip_type = _ref[_i]; solution_paths = new ClipperLib.Paths(); succeeded = cpr.Execute(clip_type, solution_paths, ClipperLib.PolyFillType.pftNonZero, ClipperLib.PolyFillType.pftNonZero); if (!succeeded) throw new Error('Clipper operation failed!'); solutions.push(solution_paths); } /* Converts Paths to SVG path string */ /* and scales down the coordinates */ /* from http://jsclipper.sourceforge.net/6.1.3.1/index.html?p=starter_boolean.html */ paths2string = function(paths, scale) { var i, p, path, svgpath, _j, _len2, _len3; svgpath = ''; if (!(scale != null)) scale = 1; for (_j = 0, _len2 = paths.length; _j < _len2; _j++) { path = paths[_j]; for (i = 0, _len3 = path.length; i < _len3; i++) { p = path[i]; if (i === 0) { svgpath += 'M'; } else { svgpath += 'L'; } svgpath += p.X / scale + ", " + p.Y / scale; } svgpath += 'Z'; } if (svgpath === '') svgpath = 'M0,0'; return svgpath; }; /* display all the solutions in SVG */ svg.selectAll('path').data(solutions).enter().append('path').attr('d', function(d) { return paths2string(d); }).attr('transform', function(d, i) { return "translate(" + (width / 2 + (i - 2) * 200 + 50) + "," + (height / 2 + 25) + ")"; }); /* display the original paths as reference */ _ref2 = [subj_paths, clip_paths]; for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { path = _ref2[_j]; svg.append('path').attr('class', 'original').attr('d', paths2string(path)).attr('transform', "translate(" + (width / 2 - 75) + ",50)"); } }).call(this);