#!/usr/bin/php getNamespaces(true))==false) // create the dummy attribute xlink:_ = "" // which creates the namespace xmlns:xlink = "http://www.w3.org/1999/xlink" as side effect $svg->addAttribute('xlink:_', '', 'http://www.w3.org/1999/xlink'); function list_replace($list_str, $i, $str) { $e = explode(" ",$list_str); $e[$i] = $str; return implode(" ", $e);; } function abs2rel($list_str) { // probably does not work $abs = explode(" ",substr($list_str,2)); $c0 = explode(",",$abs[0]); $rel = "m"; foreach ($abs as $xy) { if ($xy == "L") $rel = $rel." ".$xy; else { $c = explode(",",$xy); $c[0] = $c[0] - $c0[0]; $c[1] = $c[1] - $c0[1]; $rel = $rel." ".$c[0].",".$c[1]; } } return $rel; } function opacity($opanim, $from, $to, $dur) { $opanim->addAttribute('dur', $dur); $opanim->addAttribute('attributeType', 'CSS'); $opanim->addAttribute('attributeName', 'opacity'); $opanim->addAttribute('from', $from); $opanim->addAttribute('to', $to); $opanim->addAttribute('fill', 'freeze'); } function appear($obj, $animate) { $appear = $obj->addChild('animate'); $appear->addAttribute('id', 'appear'.$animate['idnr']); if ($animate['begin']) $appear->addAttribute('begin', $animate['begin']); if ($animate['appear']=='') $dur = '0.5s'; else $dur = $animate['appear']; opacity($appear, '0', '1', $dur); } function vanish($obj, $animate) { $vanish = $obj->addChild('animate'); $vanish->addAttribute('id', 'vanish'.$animate['idnr']); if ($animate['begin']) $vanish->addAttribute('begin', $animate['begin']); if ($animate['vanish']=='') $dur = '0.5s'; else $dur = $animate['vanish']; opacity($vanish, '1', '0', $dur); } function motion($obj, $animate) { global $svg; $motion = $obj->addChild('animateMotion'); $motion->addAttribute('id', 'motion'.$animate['idnr']); if ($animate['appear']) $motion->addAttribute('begin', 'appear'.$animate['idnr'].'.end'); else if ($animate['begin'])$motion->addAttribute('begin', $animate['begin']); // mpath_id_dur[0] is id of mpath, // mpath_id_dur[1] is dur if (strpos($animate['mpath'], ',') == false) // attribute value string has ',' ? $mpath_id_dur = array($animate["mpath"], '3s'); // no, default dur else $mpath_id_dur = explode(",",$animate['mpath']); // yes, dur is substring after ',' $motion->addAttribute('dur', $mpath_id_dur[1]); $motion->addAttribute('fill', 'freeze'); $mpath = $motion->addChild('mpath'); $mpath->addAttribute('xlink:href', '#'.$mpath_id_dur[0], $svg->getNamespaces(true)['xlink']); // search for mpath and make it relative starting with 0,0 foreach ($svg->g[0]->path as $path) if (strcmp($path['id'], $mpath_id_dur[0])==0) // found mpath if (substr($path["d"],0,1)=="m") // already is relative, resplace start coordinates by 0,0 $path['d'] = list_replace($path["d"], 1, "0,0"); else // is absolute,convert to relative - this probably does not work $path['d'] = abs2rel($path["d"]); } function movin($obj, $animate) { $movin = $obj->addChild('animate'); $movin->addAttribute('id', 'movin'.$animate['idnr']); $movin->addAttribute('dur', '0.3s'); $movin->addAttribute('attributeType', 'XML'); $movin->addAttribute('attributeName', 'x'); $movin->addAttribute('from', '1'); if (strpos($animate['movin'], ',') == false) { // attribute value string has ',' ? $movin->addAttribute('begin', $animate['movin']); // no, use $movin->addAttribute('to', '20'); // default displacement } else { $in = explode(",",$animate['movin']); // yes, $movin->addAttribute('begin', $in[0]); $movin->addAttribute('to', $in[1]); // 'to' is substring after ',' } $movin->addAttribute('additive', 'sum'); $movin->addAttribute('fill', 'freeze'); } foreach ($ani->animate as $animate) { if (strpbrk($animate['idnr'], "-~!@#$%*^&)}]>({[<+~`|,.?/\\\"") != false) fwrite(STDERR, "Illegal character in idnr = ".$animate['idnr'].". Edit drawing in Inkscape to correct this.\n"); switch ($animate["type"]) { case "text": foreach ($svg->g as $g) // for each group foreach ($g->text as $text) if ($text['id'] == $animate['type'].$animate['idnr'] ) { // found text to be animated if ($animate['appear']) { $text['style'] = "opacity:0;".$text['style']; appear($text, $animate); } if ($animate['mpath']) motion($text, $animate); if ($animate['movin']) { $tspan = $text->tspan; // delete x and y values in tspan if ($tspan['x']) $tspan['x'] = ''; if ($tspan['y']) $tspan['y'] = ''; movin($text, $animate); } if ($animate['vanish']) vanish($text, $animate); } break; case "path": foreach ($svg->g as $g) foreach ($g->path as $path) if ($path['id'] == $animate['type'].$animate['idnr'] ) { // found path to be animated if ($animate['appear']) appear($path, $animate); if ($animate['vanish']) vanish($path, $animate); } break; case "ellipse": foreach ($svg->g as $g) foreach ($g->ellipse as $ellipse) if ($ellipse['id'] == "path".$animate['idnr'] ) { // found ellipse to be animated if ($animate['mpath']) motion($ellipse, $animate); } break; case "rect": foreach ($svg->g as $g) foreach ($g->rect as $rect) if ($rect['id'] == $animate['type'].$animate['idnr'] ) { // found rect to be animated if ($animate['appear']) appear($rect, $animate); if ($animate['vanish']) vanish($rect, $animate); } break; } } $svg->asXML($ani['animated']); ?>