<html> <head> <title>Javascript Clipper Library / Boolean operations, ExPolygons / SVG example</title> <script src="clipper.js"></script> <script> function draw() { var 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}]]; var 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}]]; var scale = 100; ClipperLib.JS.ScaleUpPaths(subj_paths, scale); ClipperLib.JS.ScaleUpPaths(clip_paths, scale); var cpr = new ClipperLib.Clipper(); cpr.AddPaths(subj_paths, ClipperLib.PolyType.ptSubject, true); cpr.AddPaths(clip_paths, ClipperLib.PolyType.ptClip, true); var subject_fillType = ClipperLib.PolyFillType.pftNonZero; var clip_fillType = ClipperLib.PolyFillType.pftNonZero; var clipTypes = [ClipperLib.ClipType.ctUnion, ClipperLib.ClipType.ctDifference, ClipperLib.ClipType.ctXor, ClipperLib.ClipType.ctIntersection]; var clipTypesTexts = ["Union", "Difference", "Xor", "Intersection"]; var solution_paths, solution_polytree, solution_expolygons; var svg, cont = document.getElementById('svgcontainer'), i; svg = '<table><tr>'; for(i = 0; i < clipTypes.length; i++) { solution_polytree = new ClipperLib.PolyTree(); cpr.Execute(clipTypes[i], solution_polytree, subject_fillType, clip_fillType); solution_expolygons = ClipperLib.JS.PolyTreeToExPolygons(solution_polytree); var solution_paths = ClipperLib.Clipper.PolyTreeToPaths(solution_polytree); svg += '<tr><td>'; svg += '<svg style="margin-top:10px; margin-right:10px;margin-bottom:10px;background-color:#dddddd" width="160" height="160">'; svg += '<path stroke="black" fill="yellow" stroke-width="2" d="' + paths2string (solution_paths, scale) + '"/>'; svg += '</svg></td><td>'; svg += '<b>' + clipTypesTexts[i] + ':</b><br>' + JSON.stringify(scaleDownExPolygon(solution_expolygons, scale)); svg += '</td></tr>'; } svg += '</table>'; cont.innerHTML += svg; } function scaleDownExPolygon(exPolygons, scale) { var a, i, j, exPolygon, holes, outer, polygon; if (!scale) scale = 1; for (a = 0, alen = exPolygons.length; a < alen; a++) { exPolygon = exPolygons[a]; holes = exPolygon.holes; outer = exPolygon.outer; for (i = 0, ilen = holes.length; i < ilen; i++) { polygon = holes[i]; for (j = 0, jlen = polygon.length; j < jlen; j++) { point = polygon[j]; point.X = Number(point.X) / scale; point.Y = Number(point.Y) / scale; } } for (j = 0, jlen = outer.length; j < jlen; j++) { point = outer[j]; point.X = Number(point.X) / scale; point.Y = Number(point.Y) / scale; } } return exPolygons; } // Converts Paths to SVG path string // and scales down the coordinates function paths2string(paths, scale, isline) { var svgpath = "", i, j; if (!scale) scale = 1; for (i = 0; i < paths.length; i++) { for (j = 0; j < paths[i].length; j++) { if (!j) svgpath += "M"; else svgpath += "L"; svgpath += (paths[i][j].X / scale) + ", " + (paths[i][j].Y / scale); } if (!isline) svgpath += "Z"; } if (svgpath == "") svgpath = "M0,0"; return svgpath; } </script> </head> <body onload="draw()"> <h2>Javascript Clipper Library / Boolean operations, ExPolygons / SVG example</h2> This page shows an example of boolean operations on ExPolygons and drawing them using SVG. <div id="svgcontainer"></div> </body> </html>