SVG Symbol Element

Create a SVG symbol element: <Symbol />. It includes a circle, rect, and ellipse. Each symbol includes a transform attribute, used to locate and scale each. 5,000 symbols are rendered. Select the 'Rotate Symbols' to find the first and last symbol, then set their scale to 1.5 plus rotate.


Babel Script (code):
  1. const svgRoot=ReactDOM.render(<svg className="svg-root" width="800" height="500" id="mySVG" overflow="visible" xmlns="http://www.w3.org/2000/svg" />, svgDiv);
  2.  
  3. //---initialize Symbol element w/ desired svg elements and props attributes---
  4.     class Symbol extends React.Component {
  5.         render()
  6.         {
  7.             return (
  8.             <g className="symbol-svg" id={this.props.id} stroke={"black"} strokeWidth={1}  transform={this.props.transform}>
  9.                 <circle className="circle-svg"  cx={0} cy={0} r={15} fill={"red"} />
  10.                 <rect className="rect-svg"  x={-10} y={-10} width={20} height={20} fill={"blue"} />
  11.                 <ellipse className="ellipse-svg"  cx={0} cy={0} rx={15} ry={7} fill={"yellow"} />
  12.             </g>
  13.             );
  14.         }
  15.     }
  16.  
  17.     //--- add super state: props = state ---
  18.     class AddSuperState extends React.Component
  19.     {
  20.         constructor()
  21.         {
  22.             super();
  23.             this.state =
  24.             {
  25.                id: null,
  26.                transform: null
  27.             };
  28.         }
  29.  
  30.         render()
  31.         {
  32.             return (
  33.                 <Symbol className="symbol-svg"  id={this.state.id} transform={this.state.transform}  stroke={"black"} strokeWidth={1}   />
  34.             );
  35.         }
  36.     }
  37.  
  38.     //---random integer---
  39.     function getRandomInt(min, max)
  40.     {
  41.         return Math.floor(Math.random() * (max - min + 1)) + min;
  42.     }
  43.     //---dynamically build an array of locations for each Symbol---
  44.     var symbolIdArray=[]
  45.     for(var k=0;k<5000;k++)  //---provide a id/key value for each element---
  46.     {
  47.         var transX=getRandomInt(0, 800)
  48.         var transY=getRandomInt(0, 500)
  49.         symbolIdArray.push(<Symbol  className="symbol-svg" id={"symbol"+k} key={"symbol"+k}   transform={"translate("+transX+","+transY+")scale(.5)"}  stroke={"black"} strokeWidth={1}   />)
  50.     }
  51.  
  52.     ReactDOM.render(  //---encapsulate in <g> container---
  53.      <g>{ symbolIdArray }</g>
  54.         ,mySVG
  55.     )
  56.  
  57. //---------------ROTATE----------------
  58. //---button onClick-------
  59. function rotateSymbols()
  60. {
  61.     var myFirstSymbol=document.getElementById("symbol0")
  62.     rotateMe(myFirstSymbol)
  63.  
  64.     var myLastSymbol=document.getElementById("symbol4999")
  65.     rotateMe(myLastSymbol)
  66. }
  67. window["rotateSymbols"]=rotateSymbols
  68.  
  69. //----Animate Object---
  70. var AnimateJS=function(options)
  71. {
  72.     this.options=options
  73.     var start = new Date
  74.     var iT = setInterval(
  75.     function(){
  76.     var timePassed = new Date - start
  77.     var progress = timePassed / options.duration
  78.     if (progress > 1) progress = 1
  79.     this.progress=progress
  80.     var delta = options.delta(progress)
  81.     options.output(delta)
  82.     if (progress == 1)clearInterval(iT);
  83.     },options.delay)
  84. }
  85.  
  86. function rotateMe(symbol)
  87. {
  88.     //---place at top---
  89.     mySVG.appendChild(symbol)
  90.     //---its current translate ---
  91.     var trans=symbol.getAttribute("transform").split("scale")[0]
  92.  
  93.     var range=360 //---degrees rotation---
  94.     var FPS=80   //---frames per second---
  95.     var duration=500 //---ms, 1/2 second---
  96.     var delta=function linear(p){return p}//---linear---
  97.  
  98.     //----core animation function---
  99.     new AnimateJS(
  100.     {
  101.         delay: 1000/FPS,
  102.         duration: duration,
  103.         delta: delta, //---linear---
  104.         output: function(delta)
  105.         {
  106.             symbol.setAttribute("transform",trans+"scale(1.5)rotate("+(range*delta)+")")
  107.             if(progress==1)
  108.                 rotateMe(symbol) //---run again---
  109.         }
  110.     })
  111. }