<html> <head> <title>gatete</title> <script type="text/javascript" src="http://code.jquery.com/jquery-2.2.0.min.js" ></script> <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> </head> <body> <script> var svg = d3.select("#test svg"); </script> <div id="test"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000px" height="1000px" style="background: black;" > <image id="cat_piano" x="400" y="-100" width="50%" height="50%" xlink:href="https://media.giphy.com/media/ymckEpq27dQ9W/giphy.gif" /> <g id="zoom" transform="translate(-10 20) scale (1)"> <g transform="translate(100, 300) scale(0.50)" id="cat1"> <path id="path8068" d="m 80,286.64792 28.57143,-31.42857 94.28571,60 5.71429,122.85714 L 200,472.3622 l 82.85714,-54.28571 194.28572,8.57143 191.42857,31.42857 48.57143,40 -11.42857,-65.71429 -48.57143,-94.28571 31.42857,-51.42857 14.28571,-88.57143 62.85715,74.28571 65.71428,0 31.42857,-82.85714 42.85715,94.28572 L 920,340.93363 897.14286,423.79078 868.57143,515.21935 800,663.79078 814.28571,795.21935 760,855.21935 734.28571,649.50506 691.42857,672.3622 714.28571,883.79078 640,895.21935 l -8.57143,-208.57143 -85.71428,71.42857 -160,-14.28571 L 317.14286,695.21935 360,838.07649 l -22.85714,65.71429 -74.28572,-200 -11.42857,162.85714 -74.28571,-17.14286 40,-217.14286 -42.85715,-17.14285 5.71429,-85.71429 -5.71429,-54.28571 -2.85714,-108.57143 -20,-42.85714 z" style="fill:none;fill-rule:evenodd;stroke: red; fill: white; stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </g> <g transform="translate(700, 500) scale(0.25)" id="cat2"> <path id="path8068" d="m 80,286.64792 28.57143,-31.42857 94.28571,60 5.71429,122.85714 L 200,472.3622 l 82.85714,-54.28571 194.28572,8.57143 191.42857,31.42857 48.57143,40 -11.42857,-65.71429 -48.57143,-94.28571 31.42857,-51.42857 14.28571,-88.57143 62.85715,74.28571 65.71428,0 31.42857,-82.85714 42.85715,94.28572 L 920,340.93363 897.14286,423.79078 868.57143,515.21935 800,663.79078 814.28571,795.21935 760,855.21935 734.28571,649.50506 691.42857,672.3622 714.28571,883.79078 640,895.21935 l -8.57143,-208.57143 -85.71428,71.42857 -160,-14.28571 L 317.14286,695.21935 360,838.07649 l -22.85714,65.71429 -74.28572,-200 -11.42857,162.85714 -74.28571,-17.14286 40,-217.14286 -42.85715,-17.14285 5.71429,-85.71429 -5.71429,-54.28571 -2.85714,-108.57143 -20,-42.85714 z" style="fill:none;fill-rule:evenodd;stroke: red; fill: white; stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </g> <g transform="translate(200, 0) scale(0.25)" id="cat3"> <path id="path8068" d="m 80,286.64792 28.57143,-31.42857 94.28571,60 5.71429,122.85714 L 200,472.3622 l 82.85714,-54.28571 194.28572,8.57143 191.42857,31.42857 48.57143,40 -11.42857,-65.71429 -48.57143,-94.28571 31.42857,-51.42857 14.28571,-88.57143 62.85715,74.28571 65.71428,0 31.42857,-82.85714 42.85715,94.28572 L 920,340.93363 897.14286,423.79078 868.57143,515.21935 800,663.79078 814.28571,795.21935 760,855.21935 734.28571,649.50506 691.42857,672.3622 714.28571,883.79078 640,895.21935 l -8.57143,-208.57143 -85.71428,71.42857 -160,-14.28571 L 317.14286,695.21935 360,838.07649 l -22.85714,65.71429 -74.28572,-200 -11.42857,162.85714 -74.28571,-17.14286 40,-217.14286 -42.85715,-17.14285 5.71429,-85.71429 -5.71429,-54.28571 -2.85714,-108.57143 -20,-42.85714 z" style="fill:none;fill-rule:evenodd;stroke: red; fill: white; stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </g> <g transform="translate(600, 0) scale(0.25)" id="cat4"> <path id="path8068" d="m 80,286.64792 28.57143,-31.42857 94.28571,60 5.71429,122.85714 L 200,472.3622 l 82.85714,-54.28571 194.28572,8.57143 191.42857,31.42857 48.57143,40 -11.42857,-65.71429 -48.57143,-94.28571 31.42857,-51.42857 14.28571,-88.57143 62.85715,74.28571 65.71428,0 31.42857,-82.85714 42.85715,94.28572 L 920,340.93363 897.14286,423.79078 868.57143,515.21935 800,663.79078 814.28571,795.21935 760,855.21935 734.28571,649.50506 691.42857,672.3622 714.28571,883.79078 640,895.21935 l -8.57143,-208.57143 -85.71428,71.42857 -160,-14.28571 L 317.14286,695.21935 360,838.07649 l -22.85714,65.71429 -74.28572,-200 -11.42857,162.85714 -74.28571,-17.14286 40,-217.14286 -42.85715,-17.14285 5.71429,-85.71429 -5.71429,-54.28571 -2.85714,-108.57143 -20,-42.85714 z" style="fill:none;fill-rule:evenodd;stroke: red; fill: white; stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> </g> </g> </svg> </div> <script type="text/javascript"> var svg = d3.select("svg #zoom"); svg .append("g") .attr("id", "circulo") .attr("transform", function(d) { return ( "translate(" + get_center_element("#cat1")[0] + " " + get_center_element("#cat1")[1] + ")" ); }) .append("circle") .attr("style", "fill: rgb(0, 255, 0);") .attr("cx", 0) .attr("cy", 0) .attr("r", 20); svg .append("g") .attr("transform", function(d) { return ( "translate(" + get_pos_element("#cat1")[0] + " " + get_pos_element("#cat1")[1] + ") scale(" + get_scale_element("#cat1") + ")" ); }) .append("rect") .attr("style", "fill:none; stroke:#ffff00;stroke-width:5") .attr("width", function(d) { return get_size_element("#cat1")[0]; }) .attr("height", function(d) { return get_size_element("#cat1")[1]; }); svg .append("g") .attr("transform", function(d) { return ( "translate(" + get_center_element("#cat1")[0] + " " + get_center_element("#cat1")[1] + ") scale(" + get_scale_element("#cat1") + ")" ); }) .append("circle") .attr("style", "fill: none; stroke-width: 5; stroke: rgb(0, 0, 255);") .attr("cx", 0) .attr("cy", 0) .attr("r", get_radius_element("#cat1")); svg .append("g") .attr("id", "circulo") .attr("transform", function(d) { return ( "translate(" + get_center_element("#cat3")[0] + " " + get_center_element("#cat3")[1] + ")" ); }) .append("circle") .attr("style", "fill: rgb(0, 255, 0);") .attr("cx", 0) .attr("cy", 0) .attr("r", 20); svg .append("g") .attr("transform", function(d) { return ( "translate(" + get_pos_element("#cat3")[0] + " " + get_pos_element("#cat3")[1] + ") scale(" + get_scale_element("#cat3") + ")" ); }) .append("rect") .attr("style", "fill:none; stroke:#ffff00;stroke-width:5") .attr("width", function(d) { return get_size_element("#cat3")[0]; }) .attr("height", function(d) { return get_size_element("#cat3")[1]; }); svg .append("g") .attr("transform", function(d) { return ( "translate(" + get_center_element("#cat3")[0] + " " + get_center_element("#cat3")[1] + ") scale(" + get_scale_element("#cat3") + ")" ); }) .append("circle") .attr("style", "fill: none; stroke-width: 5; stroke: rgb(0, 0, 255);") .attr("cx", 0) .attr("cy", 0) .attr("r", get_radius_element("#cat3")); arrow_by_pieces2("gatete_flecha", "cat1", "cat2"); arrow_by_pieces2("gatete_flecha2", "cat1", "cat4"); arrow_by_pieces2("gatete_flecha3", "cat3", "cat4"); //~ arrow_by_pieces("gatete_flecha", "cat1", "cat2"); //~ arrow_by_pieces("gatete_flecha", "cat3", "cat4"); /** * Function get_radius_element * Return float * This method get the element radius */ function get_radius_element(element) { var size = get_size_element(element); return Math.sqrt(Math.pow(size[0] / 2, 2) + Math.pow(size[1] / 2, 2)); } /** * Function get_scale_element * Return float * This method get the element escale */ function get_scale_element(element) { var element_t = d3.transform(d3.select(element).attr("transform")); var element_t_scale = parseFloat(element_t["scale"]); return element_t_scale; } /** * Function get_size_element * Return array[2] * This method get the element size [width, height] */ function get_size_element(element) { var element_b = d3 .select(element) .node() .getBBox(); return [element_b["width"], element_b["height"]]; } /** * Function get_pos_element * Return array[2] * This method get the element position [x, y] */ function get_pos_element(element) { var element_t = d3.transform(d3.select(element).attr("transform")); var element_t_scale = parseFloat(element_t["scale"]); var element_b = d3 .select(element) .node() .getBBox(); var box_x = parseFloat(element_t.translate[0]) + parseFloat(element_b["x"]) * element_t_scale; var box_y = parseFloat(element_t.translate[1]) + parseFloat(element_b["y"]) * element_t_scale; return [box_x, box_y]; } /** * Function get_center_element * Return array[2] * This method ge2t the element center point [x, y] */ function get_center_element(element) { var element_t = d3.transform(d3.select(element).attr("transform")); var element_t_scale = parseFloat(element_t["scale"]); var element_b = d3 .select(element) .node() .getBBox(); var box_x = parseFloat(element_t.translate[0]) + parseFloat(element_b["x"]) * element_t_scale; var box_y = parseFloat(element_t.translate[1]) + parseFloat(element_b["y"]) * element_t_scale; var width = element_t_scale * element_b["width"]; var height = element_t_scale * element_b["height"]; var c_x = box_x + width / 2; var c_y = box_y + height / 2; return [c_x, c_y]; } /** * Function get_distance_between_point * Return float * This method get the distance betweeen two points */ function get_distance_between_point(point1, point2) { delta_x = Math.abs(point1[0] - point2[0]); delta_y = Math.abs(point1[1] - point1[1]); return Math.sqrt(Math.pow(delta_x, 2) + Math.pow(delta_y, 2)); } /** * Function get_angle_of_line * Return float * This method get the angle of line and x axe */ function get_angle_of_line(point1, point2) { return ( (Math.atan2(point2[1] - point1[1], point2[0] - point1[0]) * 180) / Math.PI ); } function arrow_by_pieces2(id_arrow, element1, element2, step) { if (typeof step === "undefined") step = 0; step++; switch (step) { case 1: wait_for_preload_symbols( ["body_arrow.svg#body_arrow", "head_arrow.svg#head_arrow"], function() { arrow_by_pieces2(id_arrow, element1, element2, step); } ); break; case 2: var arrow = svg .append("g") .attr("id", id_arrow) .attr("style", "opacity: 0"); arrow .append("g") .attr("id", "body") .append("use") .attr("xlink:href", "body_arrow.svg#body_arrow"); arrow .append("g") .attr("id", "head") .append("use") .attr("xlink:href", "head_arrow.svg#head_arrow"); var c_elem1 = get_center_element("#" + element1); var c_elem2 = get_center_element("#" + element2); var distance = get_distance_between_point(c_elem1, c_elem2); var transform = d3.transform(); /*---------------------------------------------*/ /*--- Position of layer arrow (body + head) ---*/ /*---------------------------------------------*/ var arrow = d3.select("#" + id_arrow); var arrow_body = d3.select("#" + id_arrow + " #body"); var arrow_body_b = arrow_body.node().getBBox(); transform.translate[0] = c_elem1[0]; transform.translate[1] = c_elem1[1] - arrow_body_b["height"] / 2; transform.rotate = get_angle_of_line(c_elem1, c_elem2); arrow.attr("transform", transform.toString()); /*---------------------------------------------*/ /*-------- Resize the body arrow width --------*/ /*---------------------------------------------*/ var arrow_body = d3.select("#" + id_arrow + " #body"); var arrow_body_b = arrow_body.node().getBBox(); var arrow_head = d3.select("#" + id_arrow + " #head"); var arrow_head_b = arrow_head.node().getBBox(); var body_width = distance - arrow_head_b["width"]; transform = d3.transform(); transform.scale[0] = body_width / arrow_body_b["width"]; arrow_body.attr("transform", transform.toString()); /*---------------------------------------------*/ /*---------- Position of head arrow -----------*/ /*---------------------------------------------*/ transform = d3.transform(); var arrow_body_t = d3.transform(arrow_body.attr("transform")); var scale = arrow_body_t.scale[0]; var x = 0 + arrow_body_b["width"] * scale; var y = 0 + (arrow_body_b["height"] / 2 - arrow_head_b["height"] / 2); transform.translate[0] = x; transform.translate[1] = y; arrow_head.attr("transform", transform.toString()); /*---------------------------------------------*/ /*------- Show the result in one time ---------*/ /*---------------------------------------------*/ arrow.attr("style", "opacity: 1"); break; } } function wait_for_preload_symbols(symbols, callback) { var count_symbols = symbols.length; function wait(symbol, callback) { switch (is_preload_symbol(symbol)) { case -1: preload_symbol(symbol); setTimeout(function() { wait(symbol, callback); }, 100); break; case 0: // Wait setTimeout(function() { wait(symbol, callback); }, 100); break; case 1: count_symbols--; break; } if (count_symbols == 0) { //~ setTimeout(function() { //~ callback(); //~ }, 1000); callback(); } } for (var i in symbols) { wait(symbols[i], callback); } } function preload_symbol(symbol, param_step) { var step; if (typeof param_step == "undefined") { step = 1; param_step = 1; } else { step = param_step; } step++; var base64symbol = btoa(symbol).replace(/=/g, ""); var callback = function(e) { preload_symbol(symbol, step); }; switch (param_step) { case 1: d3.select("svg") .append("g") .attr("id", base64symbol) .attr("data-loaded", 0) .style("opacity", 0) .append("use") .attr("xlink:href", symbol) .on("load", callback); break; case 2: d3.select("#" + base64symbol).attr("data-loaded", 1); break; } } function is_preload_symbol(symbol) { var base64symbol = btoa(symbol).replace(/=/g, ""); if (d3.select("#" + base64symbol).node() === null) return -1; return parseInt(d3.select("#" + base64symbol).attr("data-loaded")); } </script> </body> </html>