Robertino Mendes Santiago Junior 5 lat temu
rodzic
commit
23e56b6dae

+ 33 - 1
README.md

@@ -1 +1,33 @@
-# Webpack 4 & Babel 7 Boilerplate
+# iGeomH
+
+Versão HTML5 do iGeom
+
+## Requisitos
+Node Package Manager
+
+## Para clonar este repositório
+```bash
+git clone http://200.144.254.107/git/LInE/iGeomH.git iGeomH
+```
+
+## Para instalar as dependências
+```bash
+cd iGeomH
+```
+
+```bash
+npm install
+```
+
+## Para executar em modo de desenvolvimento
+```bash
+npm run dev
+```
+
+Acessar o site: http://localhost:8080
+
+## Para executar em modo de produção
+```bash
+npm run build
+```
+Arquivos no diretório /dist

+ 140 - 0
images/botoes/circunferencia-ponto-segmento.svg

@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="32"
+   height="32"
+   viewBox="0 0 8.4666665 8.4666669"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)"
+   sodipodi:docname="circunferencia-ponto-segmento.svg">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="16"
+     inkscape:cx="7.5794841"
+     inkscape:cy="16.489614"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="px"
+     inkscape:window-width="1366"
+     inkscape:window-height="700"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Camada 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-288.53332)">
+    <rect
+       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.0988327;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect4520"
+       width="8.3678341"
+       height="8.3678341"
+       x="-8.4172506"
+       y="288.58273"
+       transform="scale(-1,1)" />
+    <g
+       id="g4563"
+       transform="translate(1.9016924,0.82678406)">
+      <circle
+         style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle4547"
+         cx="1.6073178"
+         cy="292.78253"
+         r="0.77966017" />
+      <circle
+         r="0.77966017"
+         cy="292.75079"
+         cx="1.567682"
+         id="circle4549"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1" />
+    </g>
+    <g
+       id="g4531"
+       transform="translate(-1.3220688,0.49868958)">
+      <circle
+         id="circle4527"
+         cx="4.8284645"
+         cy="293.11197"
+         r="3.0163569"
+         style="fill:none;stroke:#cccccc;stroke-width:0.26458332;stroke-opacity:1" />
+      <circle
+         style="fill:none;stroke:#cd0000;stroke-width:0.26458332;stroke-opacity:1"
+         r="3.0163569"
+         cy="293.07755"
+         cx="4.7940578"
+         id="path17" />
+    </g>
+    <g
+       id="g4629"
+       transform="rotate(-53.526156,-0.89750286,280.6587)">
+      <circle
+         r="0.77966017"
+         cy="294.3414"
+         cx="-5.178545"
+         id="circle4572"
+         style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1" />
+      <circle
+         style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle4553"
+         cx="-5.178545"
+         cy="289.60907"
+         r="0.77966017" />
+      <g
+         transform="translate(-0.05792907)"
+         id="g4616">
+        <path
+           inkscape:connector-curvature="0"
+           id="path4600"
+           d="m -5.1270456,289.39011 -7.383e-4,4.91496 v 0"
+           style="fill:none;stroke:#cccccc;stroke-width:0.54299998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+        <path
+           style="fill:none;stroke:#000000;stroke-width:0.54299998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="m -5.1530841,289.36719 -7.383e-4,4.91496 v 0"
+           id="path4598"
+           inkscape:connector-curvature="0" />
+      </g>
+      <circle
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle4574"
+         cx="-5.2181811"
+         cy="294.30966"
+         r="0.77966017" />
+      <circle
+         r="0.77966017"
+         cy="289.57733"
+         cx="-5.2181811"
+         id="circle4555"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1" />
+    </g>
+  </g>
+</svg>

+ 118 - 0
images/botoes/circunferencia.svg

@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="32"
+   height="32"
+   viewBox="0 0 8.4666665 8.4666669"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)"
+   sodipodi:docname="circunferencia.svg">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.534679"
+     inkscape:cx="0.317853"
+     inkscape:cy="15.044696"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="px"
+     inkscape:window-width="1366"
+     inkscape:window-height="700"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Camada 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-288.53332)">
+    <rect
+       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.0988327;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect4520"
+       width="8.3678341"
+       height="8.3678341"
+       x="-8.4172506"
+       y="288.58273"
+       transform="scale(-1,1)" />
+    <g
+       id="g4542"
+       transform="translate(0.43489151,-0.13143035)">
+      <g
+         transform="translate(2.2109421,0.41251128)"
+         id="g4563">
+        <circle
+           r="0.77966017"
+           cy="292.78253"
+           cx="1.6073178"
+           id="circle4547"
+           style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1" />
+        <circle
+           style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1"
+           id="circle4549"
+           cx="1.567682"
+           cy="292.75079"
+           r="0.77966017" />
+      </g>
+      <g
+         transform="translate(-1.0128191,0.0844168)"
+         id="g4531">
+        <circle
+           style="fill:none;stroke:#cccccc;stroke-width:0.26458332;stroke-opacity:1"
+           r="3.0163569"
+           cy="293.11197"
+           cx="4.8284645"
+           id="circle4527" />
+        <circle
+           id="path17"
+           cx="4.7940578"
+           cy="293.07755"
+           r="3.0163569"
+           style="fill:none;stroke:#cd0000;stroke-width:0.26458332;stroke-opacity:1" />
+      </g>
+      <g
+         transform="translate(-3.0807248,-2.5200066)"
+         id="g4569">
+        <circle
+           r="0.77966017"
+           cy="292.78253"
+           cx="6.8989849"
+           id="circle4553"
+           style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1" />
+        <circle
+           style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1"
+           id="circle4555"
+           cx="6.8593488"
+           cy="292.75079"
+           r="0.77966017" />
+      </g>
+    </g>
+  </g>
+</svg>

+ 114 - 0
images/botoes/ponto-medio.svg

@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="32"
+   height="32"
+   viewBox="0 0 8.4666665 8.4666669"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)"
+   sodipodi:docname="ponto-medio.svg">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.534679"
+     inkscape:cx="12.02519"
+     inkscape:cy="17.912918"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="px"
+     inkscape:window-width="1366"
+     inkscape:window-height="713"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Camada 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-288.53332)">
+    <rect
+       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.0988327;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect4520"
+       width="8.3678341"
+       height="8.3678341"
+       x="-8.4172506"
+       y="288.58273"
+       transform="scale(-1,1)" />
+    <g
+       id="g4526"
+       transform="matrix(0.34558709,0,0,0.34558709,2.790166,191.53733)">
+      <circle
+         r="2.2560453"
+         cy="292.76666"
+         cx="4.2333331"
+         id="path4518"
+         style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.64029169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2.56116663, 2.56116663;stroke-dashoffset:0;stroke-opacity:1" />
+      <circle
+         style="opacity:1;fill:#e01834;fill-opacity:1;stroke:none;stroke-width:0.64029169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2.56116663, 2.56116663;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle4522"
+         cx="4.1186419"
+         cy="292.67487"
+         r="2.2560453" />
+    </g>
+    <g
+       id="g4563"
+       transform="translate(0.52916663,2.0414886)">
+      <circle
+         style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle4547"
+         cx="1.6073178"
+         cy="292.78253"
+         r="0.77966017" />
+      <circle
+         r="0.77966017"
+         cy="292.75079"
+         cx="1.567682"
+         id="circle4549"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1" />
+    </g>
+    <g
+       id="g4569"
+       transform="translate(-0.52916673,-2.1791171)">
+      <circle
+         style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle4553"
+         cx="6.8989849"
+         cy="292.78253"
+         r="0.77966017" />
+      <circle
+         r="0.77966017"
+         cy="292.75079"
+         cx="6.8593488"
+         id="circle4555"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.22127654;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.88510612, 0.88510612;stroke-dashoffset:0;stroke-opacity:1" />
+    </g>
+  </g>
+</svg>

+ 82 - 0
images/botoes/ponto.svg

@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="32"
+   height="32"
+   viewBox="0 0 8.4666665 8.4666669"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)"
+   sodipodi:docname="ponto.svg">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.534679"
+     inkscape:cx="12.02519"
+     inkscape:cy="17.912918"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="px"
+     inkscape:window-width="1366"
+     inkscape:window-height="713"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Camada 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-288.53332)">
+    <rect
+       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.0988327;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect4520"
+       width="8.3678341"
+       height="8.3678341"
+       x="-8.4172506"
+       y="288.58273"
+       transform="scale(-1,1)" />
+    <g
+       id="g4526"
+       transform="matrix(0.34558709,0,0,0.34558709,2.790166,191.60614)">
+      <circle
+         r="2.2560453"
+         cy="292.76666"
+         cx="4.2333331"
+         id="path4518"
+         style="opacity:1;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.64029169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2.56116663, 2.56116663;stroke-dashoffset:0;stroke-opacity:1" />
+      <circle
+         style="opacity:1;fill:#e01834;fill-opacity:1;stroke:none;stroke-width:0.64029169;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:2.56116663, 2.56116663;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle4522"
+         cx="4.1186419"
+         cy="292.67487"
+         r="2.2560453" />
+    </g>
+  </g>
+</svg>

Plik diff jest za duży
+ 893 - 476
package-lock.json


+ 15 - 13
package.json

@@ -1,5 +1,5 @@
 {
-  "name": "webpack-babel-boilerplate",
+  "name": "iGeomSVG",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
@@ -12,25 +12,27 @@
   "author": "",
   "license": "ISC",
   "devDependencies": {
-    "@babel/cli": "^7.1.5",
-    "@babel/core": "^7.1.6",
-    "@babel/node": "^7.0.0",
-    "@babel/preset-env": "^7.1.6",
+    "@babel/cli": "^7.2.3",
+    "@babel/core": "^7.2.2",
+    "@babel/node": "^7.2.2",
+    "@babel/preset-env": "^7.2.3",
     "@babel/preset-react": "^7.0.0",
     "@babel/register": "^7.0.0",
-    "babel-loader": "^8.0.4",
+    "babel-loader": "^8.0.5",
     "babel-register": "^6.26.0",
     "css-loader": "^1.0.1",
     "html-webpack-plugin": "^3.2.0",
-    "mini-css-extract-plugin": "^0.4.4",
-    "node-sass": "^4.10.0",
+    "mini-css-extract-plugin": "^0.4.5",
+    "node-sass": "^4.11.0",
     "optimize-css-assets-webpack-plugin": "^5.0.1",
     "sass-loader": "^7.1.0",
     "style-loader": "^0.23.1",
     "uglify-js": "^3.4.9",
-    "uglifyjs-webpack-plugin": "^2.0.1",
-    "webpack": "^4.25.1",
-    "webpack-cli": "^3.1.2",
-    "webpack-dev-server": "^3.1.10"
-  }
+    "uglifyjs-webpack-plugin": "^2.1.1",
+    "url-loader": "^1.1.2",
+    "webpack": "^4.28.4",
+    "webpack-cli": "^3.2.1",
+    "webpack-dev-server": "^3.1.14"
+  },
+  "dependencies": {}
 }

+ 12 - 0
scss/_footer.scss

@@ -0,0 +1,12 @@
+#footer {
+    position: fixed;
+    left: 0;
+    bottom: 0;
+    width: 100%;
+    background-color: #3c5a96;
+    color: white;
+    text-align: left;
+    font-size: 10pt;
+    font-weight: bold;
+    padding: 1px;
+  }

+ 46 - 0
scss/_navbar.scss

@@ -0,0 +1,46 @@
+#navbar {
+    width: 100%;
+    background-color: rgb(220, 220, 220);
+    
+    #navbar-top {
+        background-color: #568baf
+    }
+
+    #navbar-bottom {
+        background-color: #3c5a96;
+    }
+
+    #navbar-top, #navbar-bottom {
+        height: $navbarHeight;
+
+        ul {
+            list-style: none;
+            padding: 2px;
+
+            li {
+                color: rgb(30, 30, 30);
+                position: relative;
+                display: inline-block;
+                border: 2px outset black;
+
+                &.selecionado {
+                    border: 2px inset black;
+
+                    img {
+                        background-color: red;
+                    }
+                }
+                
+                a {
+                    display: block;
+                    text-decoration: none;
+                    
+                    img {
+                        display: block;
+                    }
+                }
+            }
+        }
+    }
+
+}

+ 52 - 0
scss/_reset.scss

@@ -0,0 +1,52 @@
+/* http://meyerweb.com/eric/tools/css/reset/
+   v4.0 | 20180602
+   License: none (public domain)
+*/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+main, menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	font-size: 100%;
+	font: inherit;
+	vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, main, menu, nav, section {
+	display: block;
+}
+/* HTML5 hidden-attribute fix for newer browsers */
+*[hidden] {
+    display: none;
+}
+body {
+	line-height: 1;
+}
+ol, ul {
+	list-style: none;
+}
+blockquote, q {
+	quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+	content: '';
+	content: none;
+}
+table {
+	border-collapse: collapse;
+	border-spacing: 0;
+}

+ 3 - 0
scss/_vars.scss

@@ -0,0 +1,3 @@
+$background-color: #fff;
+
+$navbarHeight: 40px;

+ 28 - 0
scss/style.scss

@@ -0,0 +1,28 @@
+@import 'reset';
+@import 'vars';
+@import 'navbar';
+@import 'footer';
+
+html, body {
+    width:100%; 
+    height:100%;
+}
+
+#app, #menu {
+  position: relative;
+  display: block;
+}
+
+svg {
+    position: absolute;
+    display: inline-block;
+}
+
+#top-svg {
+  z-index: 10;
+}
+
+body {
+  background-color: $background-color;
+
+}

+ 63 - 8
src/app.js

@@ -1,11 +1,66 @@
-import style from './scss/style.scss';
-import message from './js/message';
+import style from '../scss/style.scss';
+import AreaDeDesenho from './areaDesenho/AreaDeDesenho.js';
+import MenuSuperior from './menus/MenuSuperior.js';
 
-const header = document.createElement('h1');
-header.innerHTML = 'Webpack 4 & Babel 7';
+/**
+ * Classe App
+ * 
+ * Classe principal da aplicação. Realiza a instância dos elementos
+ * que irão compor a aplicação
+ * 
+ * @author Robertino Mendes Santiago Jr <robertino@ufpr.br>
+ */
+export default class App {
 
-const paragraph = document.createElement('p');
-paragraph.innerHTML = message;
+    /**
+     * Método construtor da classe App.
+     * São criados neste construtor:
+     * . o menu superior
+     * . a área de desenho 
+     */
+    constructor() {
+        this._menuSuperior = new MenuSuperior(this);
+        this._areaDeDesenho = new AreaDeDesenho(this);
+        this._objetos = new Array();
+    }
 
-const app = document.getElementById('app');
-app.prepend(header, paragraph);
+    /**
+     * Devolve o valor da propriedade menuSuperior
+     * @return {MenuSuperior} Valor da propriedade menuSuperior
+     */
+    get menuSuperior() {
+        return this._menuSuperior;
+    }
+
+    /**
+     * Devolve o valor da propriedade areaDeDesenho
+     * @return {AreaDeDesenho} Valor da propriedade areaDeDesenho
+     */
+    get areaDeDesenho() {
+        return this._areaDeDesenho;
+    }
+
+    /**
+     * Devolve o valor da propriedade objetos
+     * @return {Array} Valor da propriedade objetos
+     */
+    get objetos() {
+        return this._objetos;
+    }
+
+    /**
+     * Atribui um valor recebido por parâmetro à propriedade objetos
+     * @param {Array} objetos Objetos
+     */
+    set objetos(objetos) {
+        this._objetos = objetos;
+    }
+
+}
+
+/**
+ * Cria a instância da classe App após o carregamento da página
+ */
+document.addEventListener('DOMContentLoaded', function(){
+    const app = new App();
+});

+ 150 - 0
src/areaDesenho/AreaDeDesenho.js

@@ -0,0 +1,150 @@
+
+import Ponto from '../objetos/Ponto.js';
+/**
+ * Classe AreaDeDesenho
+ * 
+ * Esta classe é utilizada para receber os elementos que serão desenhados na tela
+ * 
+ * @author Robertino Mendes Santiago Jr <robertino@ufpr.br>
+ */
+export default class AreaDeDesenho {
+
+    /**
+     * Método construtor da classe AreaDeDesenho.
+     * São criadas duas áreas de desenho. A área mais inferior é utilizada para
+     * receber o Objetos. A área mais superior é utilizar para controlar as
+     * interações com o mouse.
+     * @param {App} app Instância da classe App
+     */
+    constructor(app) {
+        this.app = app;       
+
+        this._area = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+        this._area.setAttribute('id', 'main-svg');
+        this._area.setAttribute('preserveAspectRatio', 'none');
+
+        this._areaTop = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+        this._areaTop.setAttribute('id', 'top-svg');
+        this._areaTop.setAttribute('preserveAspectRatio', 'none');
+        
+        this._areaTop.onmouseup = (e) => this.mouseup(e);
+        this._areaTop.onmousedown = (e) => this.mousedown(e);
+        this._areaTop.onmousemove = (e) => this.mousemove(e);
+
+        let div = document.getElementById('app');
+        div.append(this._area);
+        div.append(this._areaTop);
+
+        this.resizeArea();
+        window.addEventListener('resize', this.resizeArea.bind(this));
+
+        this._selecionado = null;
+        
+    }
+
+    /**
+     * Método que redimensiona a área de desenho ao tamanho da tela
+     */
+    resizeArea() {
+        let offset = this.area.getBoundingClientRect();
+        this._area.setAttribute('width', window.innerWidth - offset.left + 'px');
+        this._area.setAttribute('height', window.innerHeight - offset.top + 'px');
+
+        this._areaTop.setAttribute('width', window.innerWidth - offset.left + 'px');
+        this._areaTop.setAttribute('height', window.innerHeight - offset.top + 'px');
+    }
+
+    /**
+     * Método que trata quando o botão esquerdo do mouse é pressionado na área de desenho
+     * @param {Object} e - Objeto com os valores o evento disparado pelo mouse
+     */
+    mousedown(e) {
+        e.preventDefault();
+        e.stopPropagation();
+        
+        if (this.app.menuSuperior.selecionado == this.app.menuSuperior.CODE_PONTO) {
+            let offset = this.area.getBoundingClientRect();
+
+            let x = e.clientX - offset.left;
+            let y = e.clientY - offset.top;
+
+            this.adicionaObjetos(new Ponto(x, y));
+            
+        }
+
+        // let offset = this.area.getBoundingClientRect();
+
+        // let x = e.clientX - offset.left;
+        // let y = e.clientY - offset.top;
+
+        // if (this.selecionado) {
+        //     this.selecionado.selecionado = false;
+        //     this.selecionado = null;    
+        // } else {
+        //     this.app.objetos.map(objeto => {
+        //         if (objeto.contains(x, y)) {
+        //             this.selecionado = objeto;
+        //             this.selecionado.selecionado = true;
+        //         }
+        //     });
+        // }
+        
+    }
+
+    /**
+     * Método que trata quando o botão esquerdo do mouse é solto na área de desenho
+     * @param {Object} e - Objeto com os valores o evento disparado pelo mouse
+     */
+    mouseup(e) {
+        
+    }
+
+    /**
+     * Método que trata quando o mouse é movimentado pela área de desenho
+     * @param {Object} e - Objeto com os valores o evento disparado pelo mouse
+     */
+    mousemove(e) {
+        if (this.selecionado) {
+            let offset = this.area.getBoundingClientRect();
+
+            let x = e.clientX - offset.left;
+            let y = e.clientY - offset.top;
+
+            this.selecionado.mover(x, y);
+        }
+    }
+
+    /**
+     * Adiciona um objeto à área de desenho
+     * @param {ObjetoDinamico} objeto Objeto a ser inserido na área de desenho
+     */
+    adicionaObjetos(objeto) {
+        this.app.objetos.push(objeto);
+        this._area.append(objeto.draw());
+    }
+
+    /**
+     * Devolve o valor da propriedade area
+     * @return {Object} Valor da propriedade area
+     */
+    get area() {
+        return this._area;
+    }
+
+    /**
+     * Devolve o valor da propriedade selecionado
+     * @return {Object} Valor da propriedade selecionado
+     */
+    get selecionado() {
+        return this._selecionado;
+    }
+
+    /**
+     * Atribui um valor recebido por parâmetro à propriedade selecionado
+     * @param {ObjetoDinamico} selecionado Objeto selecionado na area de desenho
+     */
+    set selecionado(selecionado) {
+        this._selecionado = selecionado;
+    }
+    
+}

+ 0 - 1
src/js/message.js

@@ -1 +0,0 @@
-export default "Hello World";

+ 198 - 0
src/menus/MenuSuperior.js

@@ -0,0 +1,198 @@
+import btnPonto from '../../images/botoes/ponto.svg';
+import btnPontoMedio from '../../images/botoes/ponto-medio.svg';
+import btnCincunferencia from '../../images/botoes/circunferencia.svg';
+import btnCincunferenciaPontoSegmento from '../../images/botoes/circunferencia-ponto-segmento.svg';
+
+/**
+ * Classe MenuSuperior
+ * 
+ * Esta classe é utilizada para criar os menus exibidos na parte superior da aplicação
+ * 
+ * @author Robertino Mendes Santiago Jr <robertino@ufpr.br>
+ */
+export default class MenuSuperior {
+
+    /**
+     * Método construtor da classe MenuSuperior.
+     * Os itens que serão exibidos no menu são definidos na estrutura itensMenu.
+     * @param {App} app Instância da classe App
+     */
+    constructor(app) {
+        this._selecionado = null;
+
+        this.itensMenu = [
+            {
+                id: 'menu-ponto',
+                title: 'Criação de ponto',
+                image: btnPonto,
+                options: [
+                    {
+                        id: this.CODE_PONTO,
+                        title: 'Criar ponto na área de desenho',
+                        image: btnPonto
+                    },
+                    {
+                        id: this.CODE_PONTO_MEDIO,
+                        title: 'Criar ponto entre dois pontos',
+                        image: btnPontoMedio
+                    }
+                ]
+            },
+            {
+                id: 'menu-circunferencia',
+                title: 'Criação de circunferência',
+                image: btnCincunferencia,
+                options: [
+                    {
+                        id: 'circunferencia',
+                        title: 'Criar circunferência definida por 2 pontos',
+                        image: btnCincunferencia
+                    },
+                    {
+                        id: 'circunferencia-ponto-segmento',
+                        title: 'Criar circunferência definida por ponto e segmento',
+                        image: btnCincunferenciaPontoSegmento
+                    }
+                ]
+            }
+        ];
+        let div = document.getElementById('app');
+        div.append(this.draw());
+        this.acoesMenu();
+    }
+
+    /**
+     * Método que desenha os menus na parte superior da aplicação
+     */
+    draw() {
+        let html = `
+        <div id="navbar">
+            <div id="navbar-top">
+                <ul>
+                    ${this.itensMenu.map(elem => `
+                        <li id="${elem.id}">
+                            <a class="btn" title="${elem.title}">
+                                <img src="${elem.image}">
+                            </a>
+                        </li>
+                    `).join('')}
+                </ul>
+            </div>
+            <div id="navbar-bottom"></div>
+        </div>
+        `;
+        let div = document.createElement('div');
+        div.innerHTML = html;
+        return div;
+    }
+
+    /**
+     * Método que define as ações de clique para cada item do menu primário.
+     * Ao clicar em um item, é exibido no menu secundário os itens específicos o item clicado.
+     */
+    acoesMenu() {
+        this.itensMenu.map(elem => {
+            document.getElementById(elem.id).onmousedown = (event) => this.trocaSubMenu(event, elem);
+        });
+        
+    }
+
+    /**
+     * Método que desenha os itens do menu secundário de um determinado item do menu
+     * @param {Object} event Objeto com os valores o evento disparado pelo mouse
+     * @param {Object} elem Item do menu selecionado
+     */
+    trocaSubMenu(event, elem) {
+        this.mudaSelecionadoMenuTop(elem);
+        
+        let div = document.getElementById('navbar-bottom');
+        let html = `
+            <ul>
+                ${elem.options.map(e => `
+                    <li id="${e.id}">
+                        <a class="btn" title="${e.title}">
+                            <img src="${e.image}">
+                        </a>
+                </li>
+                `).join('')}
+            </ul>
+        `;
+        div.innerHTML = html;
+        this.acoesSubMenu(elem);
+    }
+
+    /**
+     * Método que realiza a troca da propriedade CSS selecionado do menu primário
+     * @param {Object} elem Elemento que será atribuída a classe CSS selecionado
+     */
+    mudaSelecionadoMenuTop(elem) {
+        let selecionado = document.querySelectorAll('.selecionado');
+               
+        if (selecionado.length != 0) {
+            selecionado.forEach(s => {
+                s.classList.remove('selecionado');
+            });    
+        }
+        
+        let btn = document.getElementById(elem.id);
+        btn.classList.add('selecionado');
+    }
+
+    /**
+     * Método que define as ações de clique para cada item do menu secundário.
+     * Ao clicar em um item, é exibido no menu secundário os itens específicos o item clicado.
+     */
+    acoesSubMenu(objeto) {
+        objeto.options.map(elem => {
+            document.getElementById(elem.id).onmousedown = (event) => this.botaoSubMenu(event, elem);
+        })
+    }
+
+    /**
+     * Método que identifica o item do menu selecionado
+     * @param {Object} event Objeto com os valores o evento disparado pelo mouse
+     * @param {Object} elem Item do menu selecionado 
+     */
+    botaoSubMenu(event, elem) {
+        this.mudaSelecionadoMenuBottom(elem);
+        this._selecionado = elem.id;
+        
+    }
+
+    /**
+     * Método que realiza a troca da propriedade CSS selecionado do menu secundário
+     * @param {Object} elem Elemento que será atribuída a classe CSS selecionado
+     */
+    mudaSelecionadoMenuBottom(elem) {
+        let selecionado = document.querySelectorAll('#navbar-bottom .selecionado');
+               
+        if (selecionado.length != 0) {
+            selecionado.forEach(s => {
+                s.classList.remove('selecionado');
+            });    
+        }
+        
+        let btn = document.getElementById(elem.id);
+        btn.classList.add('selecionado');
+    }
+
+    /**
+     * Devolve o valor da propriedade selecionado
+     * @return {string} Valor da propriedade selecionado
+     */
+    get selecionado() {
+        return this._selecionado;
+    }
+
+    /**
+     * Constante que determina o código do menu Ponto 
+     * @return {string} Valor da constante
+     */
+    get CODE_PONTO() { return 'ponto'; }
+
+    /**
+     * Constante que determina o código do menu Ponto Médio
+     * @return {string} Valor da constante
+     */
+    get CODE_PONTO_MEDIO() { return 'ponto-medio'; }
+}

+ 26 - 0
src/objetos/ObjetoDinamico.js

@@ -0,0 +1,26 @@
+/**
+ * Classe ObjetoDinamico
+ * 
+ * Super classe utilizada para agrupar as propriedades em comum dos objetos
+ * que podem ser inseridos na área de desenho.
+ * 
+ * @author Robertino Mendes Santiago Jr <robertino@ufpr.br>
+ */
+export default class ObjetoDinamico {
+
+    /**
+     * Construtor da classe ObjetoDinamico
+     */
+    constructor() {
+        this.svgNS = "http://www.w3.org/2000/svg";
+        this._draggable = false;
+    }
+
+    get draggable() {
+        return this._draggable;
+    }
+
+    set draggable(draggable) {
+        this._draggable = draggable;
+    }
+}

+ 164 - 0
src/objetos/Ponto.js

@@ -0,0 +1,164 @@
+import ObjetoDinamico from './ObjetoDinamico.js';
+
+/**
+ * Classe Ponto
+ * 
+ * Utilizada para representar um Ponto no desenho geométrico
+ * 
+ * @author Robertino Mendes Santiago Jr <robertino@ufpr.br>
+ */
+export default class Ponto extends ObjetoDinamico {
+
+    /**
+     * Método construtor da classe Ponto
+     * @param {number} x Posição relativa ao eixo x onde o ponto será criado
+     * @param {number} y Posição relativa ao eixo y onde o ponto será criado
+     */
+    constructor(x, y) {
+        super();
+        this._x = x;
+        this._y = y;
+        this._raio = 4;
+        this._espessura = 1;
+        this._selecionado = false;
+
+        this._elemento = this.criaPonto();
+    }
+
+    /**
+     * Método que devolve o elemento Ponto.
+     * @return {Object} Retorna o elemento que representa um Ponto em formato SVG
+     */
+    draw() {
+        return this._elemento;
+    }
+
+    /**
+     * Verifica se existe um ponto na posição especificada por x e y
+     * @param {number} x - Valor da posição no eixo x
+     * @param {number} y - Valor da posição no eixo y
+     * @return {boolean} Retorna verdadeiro se existe um ponto na posição especificada. Caso contrário, retorna falso.
+     */
+    contains(x, y) {
+        let xDiff = Math.abs(this.x - x);
+        let yDiff = Math.abs(this.y - y);
+        let dist = Math.sqrt(Math.pow(xDiff,2) + Math.pow(yDiff,2)); 
+        return dist <= this.raio;
+    }
+
+    /**
+     * Método que cria um elemento SVG que representa um Ponto
+     * @return {Object} Retorna o elemento SVG criado que representa o Ponto
+     */
+    criaPonto() {
+        let elemento = document.createElementNS(this.svgNS,'circle');
+        elemento.setAttribute('id','mycircle');
+        elemento.setAttribute('cx',this.x);
+        elemento.setAttribute('cy',this.y);
+        elemento.setAttribute('r',this.raio);
+        elemento.setAttribute('fill','lightgreen');
+        elemento.setAttribute('stroke','black');
+        elemento.setAttribute('stroke-width', this.espessura);
+        return elemento;
+    }
+
+    /**
+     * Método que realiza a movimentação do Ponto
+     * @param {number} x Posição relativa ao eixo x onde o ponto será movimentado
+     * @param {number} y Posição relativa ao eixo y onde o ponto será movimentado
+     */
+    mover(x, y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Devolve o valor da propriedade x
+     * @return {number} Valor da propriedade x
+     */
+    get x() {
+        return this._x;
+    }
+
+    /**
+     * Atribui um valor recebido por parâmetro à propriedade x
+     * @param {number} x Posição relativa ao eixo x
+     */
+    set x(x) {
+        this._x = x;
+        this._elemento.setAttribute('cx', x);
+    }
+
+    /**
+     * Devolve o valor da propriedade y
+     * @return {number} Valor da propriedade y
+     */
+    get y() {
+        return this._y;
+    }
+
+    /**
+     * Atribui um valor recebido por parâmetro à propriedade y
+     * @param {number} y Posição relativa ao eixo y
+     */
+    set y(y) {
+        this._y = y;
+        this._elemento.setAttribute('cy', y);
+    }
+
+    /**
+     * Devolve o valor da propriedade raio
+     * @return {number} Valor da propriedade raio
+     */
+    get raio() {
+        return this._raio;
+    }
+
+    /**
+     * Atribui um valor recebido por parâmetro à propriedade raio
+     * @param {number} raio Valor do raio do Ponto
+     */
+    set raio(raio) {
+        this._raio = raio;
+        this._elemento.setAttribute('r', raio);
+    }
+
+    /**
+     * Devolve o valor da propriedade espessura da borda
+     * @return {number} Valor da propriedade da espessura da borda
+     */
+    get espessura() {
+        return this._espessura;
+    }
+
+    /**
+     * Atribui um valor recebido por parâmetro à propriedade espessura
+     * @param {number} espessura Valor da espessura da borda
+     */
+    set espessura(espessura) {
+        this._espessura = espessura; 
+        this._elemento.setAttribute('stroke-width', espessura);
+    }
+
+    /**
+     * Devolve o valor da propriedade selecionado
+     * @return {boolean} Valor da propriedade selecionado
+     */
+    get selecionado() {
+        return this._selecionado;
+    }
+
+    /**
+     * Atribui um valor recebido por parâmetro à propriedade selecionado
+     * @param {boolean} selecionado Verdadeiro se o objeto está selecionado ou falso caso contrário
+     */
+    set selecionado(selecionado) {
+        this._selecionado = selecionado;
+        if (selecionado) {
+            this._elemento.setAttribute('stroke', 'red');
+        } else {
+            this._elemento.setAttribute('stroke', 'black');
+        }
+    }
+    
+}

+ 0 - 11
src/scss/style.scss

@@ -1,11 +0,0 @@
-body {
-  background-color: #ccc;
-
-  h1 {
-    color: darkred;
-  }
-
-  p {
-    color: darkblue;
-  }
-}

+ 5 - 2
src/template.html

@@ -2,9 +2,12 @@
 <html lang="en" dir="ltr">
   <head>
     <meta charset="utf-8">
-    <title>Webpack Babel Boilerplate</title>
+    <title>iGeom</title>
   </head>
   <body>
-    <div id="app"></div>
+    <div id="app">
+        
+    </div>
+    <div id="footer">aaa</div>
   </body>
 </html>

+ 23 - 2
webpack.config.js

@@ -24,7 +24,12 @@ const config = {
       new UglifyJsPlugin({
         cache: true,
         parallel: true,
-        sourceMap: true // set to true if you want JS source maps
+        sourceMap: true, // set to true if you want JS source maps
+        uglifyOptions: {
+          output: {
+            comments: false
+          }
+        }
       }),
       new OptimizeCSSAssetsPlugin({})
     ],
@@ -51,7 +56,12 @@ const config = {
       {
         test: /\.js$/,
         exclude: /node_modules/,
-        use: ['babel-loader']
+        use: {
+          loader: 'babel-loader',
+          options: {
+            presets: ['@babel/preset-env']
+          }
+        }
       },
       // CSS Files
       {
@@ -62,6 +72,17 @@ const config = {
           //'postcss-loader',
           'sass-loader',
         ]
+      },
+      {
+        test: /\.(png|jpg|gif|svg)$/i,
+        use: [
+          {
+            loader: 'url-loader',
+            options: {
+              limit: 8192
+            }
+          }
+        ]
       }
     ]
   },