Come ruotare SVG da PHP

Voglio ruotare SVG da PHP.

Ho i file SVG e voglio ruotarli da PHP. Il metodo che ho trovato online è aggiungere qualcosa di simile

<g transform="translate(90) rotate(45 50 50)"> 

dentro <svg>.

Per esempio, voglio convertire da:

 <svg> <i-am-here+i-was-here>...</i-am-here+i-was-here> </svg> 

o

 <svg> <g transform="i-have-transform-but-no-rotate"> <i-am-here+i-was-here>...</i-am-here+i-was-here> </g> </svg> 

A:

 <svg> <g transform="svgrotate+old-transform"> <i-am-here+i-was-here>...</i-am-here+i-was-here> </g> </svg> 

ma ora non so come raggiungerlo

  1. aggiungere un <g> dentro <svg> e avvolgere tutti i vecchi nodes interni.

  2. se <g> sta già avvolgendo tutti i nodes interni, salta l'aggiunta del nuovo tag <g> ma lo si ruota di nuovo in un nuovo grado.

il seguente è un ansible codice svg prima di ruotare.

  <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="hello" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="800px" height="700px" viewBox="0 0 800 700" enable-background="new 0 0 800 700" xml:space="preserve"> <g> <path transform="rotate(-14.1173 121.2 96.1965)" id="svg_2" d="m128,25c9,14 9,204 -35,124c-44,-80 177,-52 120,-36c-57,16 -120,-77 -185,-79c-65,-2 288,166 169,128c-119,-38 -78,-151 -69,-137z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharrays="null" stroke-width="0" stroke="#3f007f" fill="#f4f438"/> <path transform="rotate(152.959 126.708 104.715)" stroke="#3f007f" id="svg_3" d="m219.4411,94.86682c-50.99725,81.80002 -148.00278,74.4472 -190.13092,50.55057c-42.12811,-23.89664 5.54315,-43.19778 18.8468,-19.30115c13.30362,23.89664 81.48468,16.54382 108.64624,0.91913c27.16156,-15.62473 50.44287,-45.95508 54.87738,-56.06519c4.43463,-10.11011 58.75769,-57.90341 7.7605,23.89664z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharrays="null" stroke-width="0" fill="#7fff00"/> </g> <path transform="rotate(9.48719 272.234 246.106)" id="svg_6" d="m214,78c0,-1 -108,23 -108,23c0,0 -85,108 23,85c108,-23 122,32 167,14c45,-18 -64,289 106,197c170,-92 -31,-310 -32,-310" stroke-linecap="null" stroke-linejoin="null" stroke-dasharrays="null" stroke-width="0" stroke="#3f007f" fill="#ffaad4"/> <path d="m342,184c-7,-2 -12.98453,-3.08075 -18,-4c-5.98309,-1.0966 -11.53976,-2.46873 -19,-4c-5.87747,-1.20639 -13,-1 -18,-1c-7,0 -14.05798,-0.83221 -20,0c-7.20975,1.00977 -14.33942,4.12776 -23,8c-7.36008,3.29077 -14.23541,7.73578 -21,14c-5.1882,4.80443 -11.03857,10.11638 -16,17c-5.22981,7.25597 -7.48169,14.87997 -9,22c-1.47472,6.91557 -1.49489,14.02045 -1,20c0.50171,6.06204 3,11 5,16c2,5 3.72398,9.22272 7,13c3.70638,4.2735 5,5 6,5l1,0l3,-1" id="svg_1" stroke-linecap="null" stroke-linejoin="null" stroke-dasharrays="null" stroke-width="0" stroke="#000000" fill="none"/> <g> <path stroke="#000000" transform="rotate(-7.76776 324.596 222.303)" id="svg_4" d="m422.29062,129.05128c-126.20798,34.85936 91.52487,198.50475 -153.18372,103.60979c-244.70862,-94.89496 238.92807,178.17014 107.90298,114.26129c-131.02509,-63.90884 65.51254,-336.00563 -15.4147,-153.96223c-80.92725,182.04341 -141.62271,231.42751 -145.47639,168.48695c-3.85367,-62.94052 213.8792,-386.35803 113.68355,-284.68486c-100.19566,101.67317 67.43936,149.12065 111.75668,227.55424c44.31729,78.43359 -92.48828,66.81381 -114.64694,62.94052c-22.15866,-3.87326 184.97659,-174.29686 23.12207,-215.93445c-161.85452,-41.63758 -53.95151,-3.87326 -52.02466,114.26129c1.92682,118.13455 1.92682,118.13455 1.92682,118.13455" stroke-linecap="null" stroke-linejoin="null" stroke-dasharrays="null" stroke-width="0" fill="#ff0000"/> <path transform="rotate(20.3513 424.5 303.53)" stroke="#000000" id="svg_5" d="m368,255.68533l113,37.43481c0,0 13.37784,104.74188 -53.79596,69.57584c-67.17383,-35.16605 32.16373,-157.30188 -21.06299,-117.59828c-53.22668,39.7036 -53.22668,39.7036 -53.22668,39.7036" stroke-linecap="null" stroke-linejoin="null" stroke-dasharrays="null" stroke-width="0" fill="#007fff"/> </g> <path transform="rotate(44.7788 399.595 115.757)" id="svg_8" d="m354,84c8,54 10,126 56,59c46,-67 42,-57 16,-76c-26,-19 -72,17 -72,17z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharrays="null" stroke-width="0" stroke="#3f007f" fill="#7f7f00"/> </svg> 

Ho cercato per un po 'e infine messo insieme. Spero che sia d'aiuto.

È ansible utilizzare la libreria SimpleXML per accedere ai nodes secondo necessità.

La mia soluzione funziona, ma potrebbe probabilmente essere semplificata.

Innanzitutto, ho aggiunto questa class (che si trova nei commenti qui) :

 class ExSimpleXMLElement extends SimpleXMLElement { public function _construct($xml){ parent::_construct($xml); } /** * Add SimpleXMLElement code into a SimpleXMLElement * @param SimpleXMLElement $append */ public function appendXML($append) { if ($append) { if (strlen(trim((string) $append))==0) { $xml = $this->addChild($append->getName()); foreach($append->children() as $child) { $xml->appendXML($child); } } else { $xml = $this->addChild($append->getName(), (string) $append); } foreach($append->attributes() as $n => $v) { $xml->addAttribute($n, $v); } } } } 

Basta includerlo prima di qualsiasi codice.

 //file $file = 'svg-nog.svg'; //http://www.webdeveloper.com/forum/showthread.php?165648-Editing-XML-using-PHP $xml = simplexml_load_file($file); //Load the File. $sxe = new EXSimpleXMLElement($xml->asXML()); //Load the child class (it will load the main one) // Get the parent node's childrens $nodeChildrens = $sxe->children(); //Check if there's more than one child and if there is more than one <g> tag if(count($nodeChildrens) > 1 and count($sxe->g) > 1){ //Add our Wrapper Node $g = $sxe->addChild("g"); //You can go ahead and add your desired transform code $g['transform'] = "rotate(90 600 600)"; //Set an ID so it's unique $g['id'] = "myWrapper"; $unsets = arrays(); //Loop through the children foreach ($nodeChildrens as $value) { //Skip our wrapper element if($value->attributes()->id == "myWrapper"){ continue; } //Append the element to the wrapper //Will recursively add elements as needed $g->appendXML($value); //Save a reference for the different elements we have $unsets[] = $value->getName(); } //Loop through the old/loose elements and remove them foreach ($unsets as $name) { $segarr = $sxe->{$name}; $count = count($segarr); $j = 0; for ($i = 0; $i < $count; $i++) { if ($segarr[$j]['id'] != 'myWrapper') { unset($segarr[$j]); $j = $j - 1; } $j = $j + 1; } } } else { //Just apply the transform $sxe->g['transform'] = "rotate(90 600 600)"; //Can also be done with: //$sxe->g->addAttribute('transform', "rotate(90 600 600)"); } //Save $sxe->asXML('test.svg'); 

Questo ha funzionato abbastanza bene per me sia per SVG avvolto in un tag che per quelli che non lo erano. Ci potrebbero essere modi più semplici per farlo, ma questo è certamente efficace.

Un'altra cosa! Questo potrebbe non essere corretto ma quando ho ruotato il mio SVG, di solito sono stati ritagliati. Quindi ho dovuto modificare gli attributi principali. Ciò che questo comportva è stato lo scambio di altezza e width, nonché la conversione di SVG per ricentrarlo. Ecco qui:

 //Set the vars of the primary attributes we want to edit $w = "width"; $h= "height"; $viewbox = "viewBox"; $bg = 'enable-background'; //Get SVG Width & Height $width = (string)$sxe->attributes()->$w; $height = (string)$sxe->attributes()->$h; //Get viewBox and background $sxe->attributes()->$viewbox = "0 0 " . str_replace('px', '', $height) . " " . str_replace('px', '', $width); $sxe->attributes()->$bg = "new 0 0 " . str_replace('px', '', $height) . " " . str_replace('px', '', $width); //Get the numberscal values for width and height $rw = floatval(str_replace("px", "", $width)); $rh = floatval(str_replace("px", "", $height)); //Get the center point $rx = $rw / 2; $ry = $rh / 2; //Logic will determine the appropiate translate value for the svg so that it will center in the new viewbox if($rw < $rh){ $trans = ($rw - $rh) / 2; } if($rw > $rh){ $trans = -1 * ($rh - $rw) / 2; } //Swap width and height $oldW = (string)$sxe->attributes()->$w; $sxe->attributes()->$w = $height; $sxe->attributes()->$h = $oldW; // Get the parents node childrens $nodeChildrens = $sxe->children(); //If the transform attribute is set, this svg has already been rotated, as such, we'll just unset it if(isset($nodeChildrens->g->attributes()->transform)){ unset($nodeChildrens->g->attributes()->transform); } else { // Otherwise, we're going to add in the transform data for the rotation and re-centering. $nodeChildrens->g->addAttribute('transform', "rotate(90 ".$rx." ".$ry.") translate(".$trans." ".$trans.")"); } //This next line will overwrite the original XML file with new data added $sxe->asXML("test.svg"); 

Si può notare verso il basso, questo codice invertirà anche il process di rotazione.

Spero possa aiutare!