├── .gitignore ├── public ├── images │ └── dentes │ │ ├── 18.png │ │ ├── dentes.png │ │ └── dentes.xcf ├── style.css ├── 404.html ├── aux.html ├── pincel.js ├── index.html └── odontograma.js ├── firebase.json ├── package.json ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .firebaserc 3 | .firebase 4 | -------------------------------------------------------------------------------- /public/images/dentes/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joabsonlg/odontograma/HEAD/public/images/dentes/18.png -------------------------------------------------------------------------------- /public/images/dentes/dentes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joabsonlg/odontograma/HEAD/public/images/dentes/dentes.png -------------------------------------------------------------------------------- /public/images/dentes/dentes.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joabsonlg/odontograma/HEAD/public/images/dentes/dentes.xcf -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "public", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "odontograma", 3 | "version": "1.0.0", 4 | "description": "Protótipo para estudos", 5 | "main": "public/odontograma.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Joabsonlg/odontograma.git" 12 | }, 13 | "keywords": [ 14 | "odontograma", 15 | "javascript" 16 | ], 17 | "author": "Joabson Arley", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/Joabsonlg/odontograma/issues" 21 | }, 22 | "homepage": "https://github.com/Joabsonlg/odontograma#readme" 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Joabson Arley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Odontograma 2 | 3 | #### Este é um protótipo de um odontograma digital construído com html5 e javascript. 4 | 5 | ## ☄️ Pré-requisitos 6 | 7 | Antes de começar, você vai precisar ter instalado em sua máquina o [Git](https://git-scm.com) e um editor de código como o [VSCode](https://code.visualstudio.com/) ou [WebStorm](https://www.jetbrains.com/pt-br/webstorm/). 8 | 9 | ## :rocket: Rodando o Projeto 10 | 11 | ```bash 12 | # Clone este repositório 13 | $ git clone https://github.com/Joabsonlg/odontograma.git 14 | 15 | # Entre na pasta odontograma e depois na pasta public 16 | 17 | # Abra o index.html em seu navegador 18 | ``` 19 | 20 | ## ⚖️ Contribuições 21 | Para efetivar alterações no código: 22 | ```bash 23 | # Crie uma branch 24 | $ git checkout -b nome-branch 25 | 26 | # Realize as alterações no códico e as suba para o repositório 27 | $ git add . 28 | $ git commit -m "Resumo das minhas alteracoes" 29 | $ git push origin nome-branch 30 | 31 | #No github, crie um 'pull request' para a branch master 32 | ``` 33 | Certifique-se de fazer os testes apropriados. 34 | 35 | ## :key: Licença 36 | [MIT](https://github.com/Joabsonlg/odontograma/blob/master/LICENSE) 37 | -------------------------------------------------------------------------------- /public/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --header-height: 3rem; 3 | --nav-width: 68px; 4 | --first-color: #00171b; 5 | --first-color-light: #8ac7ca; 6 | --secondary-color: #003d47; 7 | --secondary-color-light: #0c9aba; 8 | --white-color: #F7F6FB; 9 | --body-font: 'Nunito', sans-serif; 10 | --normal-font-size: 1rem; 11 | --z-fixed: 100; 12 | --backgound: linear-gradient(90deg, rgba(0, 25, 29, 1) 0%, var(--first-color) 35%, var(--secondary-color) 100%); 13 | } 14 | 15 | body { 16 | position: relative; 17 | font-family: var(--body-font); 18 | font-size: var(--normal-font-size); 19 | transition: .5s; 20 | height: 100%; 21 | /* background: var(--backgound); */ 22 | } 23 | 24 | #camada1Odontograma { 25 | z-index: 1; 26 | } 27 | 28 | #camada2Odontograma { 29 | z-index: 2; 30 | } 31 | 32 | #camada3Odontograma { 33 | z-index: 3; 34 | } 35 | 36 | #camada4Odontograma { 37 | z-index: 4; 38 | } 39 | 40 | #camadaPincel { 41 | z-index: 3; 42 | } 43 | 44 | canvas { 45 | position: absolute; 46 | border: 1px solid #9C9898; 47 | margin: 10px; 48 | } 49 | 50 | .checked { 51 | display: none; 52 | } 53 | 54 | .active .checked { 55 | display: inline-block; 56 | } 57 | 58 | .active .unchecked { 59 | display: none; 60 | } -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Not Found 7 | 8 | 23 | 24 | 25 |
26 |

404

27 |

Page Not Found

28 |

The specified file was not found on this website. Please check the URL for mistakes and try again.

29 |

Why am I seeing this?

30 |

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /public/aux.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Page Title 8 | 9 | 10 | 11 | 12 | 13 | 14 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /public/pincel.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', () => { 2 | const pincel = { 3 | ativo: false, 4 | movendo: false, 5 | origem: null, 6 | destino: { 7 | x: 0, 8 | y: 0 9 | }, 10 | cor: '#000000', 11 | espessura: '2' 12 | } 13 | 14 | const borracha = { 15 | ativo: false, 16 | movendo: false, 17 | coordenadas: { 18 | x: 0, 19 | y: 0 20 | }, 21 | espessura: '2' 22 | } 23 | 24 | const camadaPincel = document.querySelector('#camadaPincel') 25 | const contexto = camadaPincel.getContext('2d') 26 | const saveBtn = document.getElementById("saveBtn"); 27 | 28 | const desenhaLinha = (linha) => { 29 | contexto.lineWidth = pincel.espessura 30 | contexto.strokeStyle = pincel.cor 31 | contexto.beginPath() 32 | contexto.moveTo(linha.origem.x, linha.origem.y) 33 | contexto.lineTo(linha.destino.x, linha.destino.y) 34 | contexto.stroke() 35 | } 36 | 37 | const apagar = (coordenadas) => { 38 | contexto.lineWidth = borracha.espessura 39 | contexto.clearRect(coordenadas.x - 7, coordenadas.y - 7, 15, 15); 40 | } 41 | 42 | 43 | document.querySelector("#mouse").addEventListener('change', function() { 44 | usaPincel() 45 | }) 46 | 47 | document.querySelector("#pincel").addEventListener('change', function() { 48 | usaPincel() 49 | }) 50 | 51 | document.querySelector("#borracha").addEventListener('change', function() { 52 | usaBorracha() 53 | }) 54 | 55 | document.querySelector("#limparDesenho").addEventListener('click', function() { 56 | limparDesenhos() 57 | }) 58 | 59 | const usaBorracha = () => { 60 | let ativo = false 61 | const usarBorracha = document.getElementById("borracha").checked 62 | if (usarBorracha) { 63 | document.querySelector("#camadaPincel").style.zIndex = "5" 64 | document.querySelector("#configBtn").disabled = false 65 | document.querySelector("#saveBtn").disabled = false 66 | ativo = true 67 | } else if (!document.getElementById("pincel").checked) { 68 | ativo = false 69 | document.querySelector("#camadaPincel").style.zIndex = "3" 70 | document.querySelector("#configBtn").disabled = true 71 | } 72 | return ativo 73 | } 74 | 75 | const usaPincel = () => { 76 | let ativo = false 77 | const usarPincel = document.getElementById("pincel").checked 78 | if (usarPincel) { 79 | document.querySelector("#camadaPincel").style.zIndex = "5" 80 | document.querySelector("#configBtn").disabled = false 81 | document.querySelector("#saveBtn").disabled = false 82 | ativo = true 83 | } else if (!document.getElementById("borracha").checked) { 84 | ativo = false 85 | document.querySelector("#configBtn").disabled = true 86 | document.querySelector("#camadaPincel").style.zIndex = "3" 87 | } 88 | return ativo 89 | } 90 | 91 | camadaPincel.onmousedown = () => { 92 | if (usaPincel()) { 93 | pincel.ativo = true 94 | } else if (usaBorracha()) { 95 | borracha.ativo = true 96 | } 97 | } 98 | 99 | camadaPincel.onmouseup = () => { 100 | pincel.ativo = false 101 | borracha.ativo = false 102 | } 103 | 104 | camadaPincel.onmousemove = (event) => { 105 | pincel.destino.x = event.clientX - camadaPincel.offsetLeft 106 | pincel.destino.y = event.clientY - camadaPincel.offsetTop 107 | pincel.movendo = true 108 | 109 | borracha.coordenadas.x = event.clientX - camadaPincel.offsetLeft 110 | borracha.coordenadas.y = event.clientY - camadaPincel.offsetTop 111 | borracha.movendo = true 112 | } 113 | 114 | saveBtn.onclick = (event) => { 115 | localStorage.setItem('desenho', camadaPincel.toDataURL()) 116 | } 117 | 118 | const limparDesenhos = () => { 119 | contexto.clearRect(0, 0, camadaPincel.width, camadaPincel.height); 120 | } 121 | 122 | const ciclo = () => { 123 | if (pincel.ativo && pincel.movendo && pincel.origem) { 124 | desenhaLinha({ 125 | destino: pincel.destino, 126 | origem: pincel.origem 127 | }) 128 | pincel.movendo = false 129 | } 130 | pincel.origem = { 131 | ...pincel.destino 132 | } 133 | if (borracha.ativo && borracha.movendo && borracha.coordenadas) { 134 | apagar(borracha.coordenadas) 135 | borracha.movendo = false 136 | } 137 | setTimeout(ciclo, 0.1) 138 | } 139 | ciclo() 140 | 141 | document.querySelector("#tamanhoPincel").addEventListener('change', function() { 142 | if (usaBorracha()) borracha.espessura = document.querySelector("#tamanhoPincel").value 143 | else pincel.espessura = document.querySelector("#tamanhoPincel").value 144 | }) 145 | 146 | document.querySelector("#corPincel").addEventListener('change', function() { 147 | pincel.cor = document.querySelector("#corPincel").value 148 | }) 149 | 150 | document.querySelector("#tamanhoPincel").dispatchEvent(new Event('change')) 151 | document.querySelector("#corPincel").dispatchEvent(new Event('change')) 152 | }) -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Odontograma 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 | 35 | 50 |
51 | 52 |
53 |
54 |
55 |
56 | 57 | 58 | 59 | 60 | 61 | 62 |
63 | 137 | 138 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /public/odontograma.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', () => { 2 | 3 | const camada1 = document.querySelector('#camada1Odontograma') 4 | const contexto1 = camada1.getContext('2d') 5 | 6 | const camada2 = document.querySelector('#camada2Odontograma') 7 | const contexto2 = camada2.getContext('2d') 8 | 9 | const camada3 = document.querySelector('#camada3Odontograma') 10 | const contexto3 = camada3.getContext('2d') 11 | 12 | const camada4 = document.querySelector('#camada4Odontograma') 13 | const contexto4 = camada4.getContext('2d') 14 | 15 | const camadaPincel = document.querySelector('#camadaPincel') 16 | const contextoPincel = camadaPincel.getContext('2d') 17 | 18 | const modal = new bootstrap.Modal(document.getElementById('modal')) 19 | 20 | let posicoesPadrao = { 21 | posicaoYInicialDente: 180, 22 | margemXEntreDentes: 8, 23 | margemYEntreDentes: 200 24 | } 25 | 26 | const tamanhoTelaReferencia = 1895 27 | const alturaTelaReferencia = 872 28 | 29 | const itensProcedimento = [{ 30 | nome: 'Lesão branca ativa de cárie', 31 | cor: '#008000' 32 | }, { 33 | nome: 'Lesão branca inativa de cárie', 34 | cor: '#FFFF00' 35 | }, { 36 | nome: 'Lesão de cárie cavitada', 37 | cor: '#FF0000' 38 | }, { 39 | nome: 'Cárie paralisada/ pigmentação do sulco', 40 | cor: '#000000' 41 | }, { 42 | nome: 'Restaurações em bom estado', 43 | cor: '#0000FF' 44 | }, { 45 | nome: 'Restauração a ser trocada', 46 | cor: '#FFC0CB' 47 | }, { 48 | nome: 'Lesão cervical não- cariosa', 49 | cor: '#8B0000' 50 | }, { 51 | nome: 'Faceta de desgaste', 52 | cor: '#FA8072' 53 | }, { 54 | nome: 'Limpar seção', 55 | cor: '#FFFFFF' 56 | }, { 57 | nome: 'Outro', 58 | cor: '#008080' 59 | }] 60 | 61 | let procedimentos = [] 62 | class Procedimento { 63 | constructor(nome, cor, numeroDente, faceDente, informacoesAdicionais) { 64 | this.nome = nome; 65 | this.cor = cor; 66 | this.numeroDente = numeroDente; 67 | this.faceDente = faceDente; 68 | this.informacoesAdicionais = informacoesAdicionais; 69 | } 70 | valido() { 71 | const campos = ['nome', 'cor', 'numeroDente', 'faceDente'] 72 | if (this.nome === null || this.nome === undefined || this.nome === '') return false 73 | if (this.cor === null || this.cor === undefined || this.cor === '') return false 74 | if (this.numeroDente === null || this.numeroDente === undefined || this.numeroDente === '') return false 75 | if (this.faceDente === null || this.faceDente === undefined || this.faceDente === '') return false 76 | return true 77 | } 78 | criaObjeto() { 79 | return { 80 | nome: this.nome, 81 | cor: this.cor, 82 | numeroDente: this.numeroDente, 83 | faceDente: this.faceDente, 84 | informacoesAdicionais: this.informacoesAdicionais 85 | } 86 | } 87 | limpar() { 88 | this.nome = null; 89 | this.cor = null; 90 | this.numeroDente = null; 91 | this.faceDente = null; 92 | this.informacoesAdicionais = null; 93 | } 94 | salvar() { 95 | if (this.valido()) { 96 | const procedimento = procedimentos.find(prc => prc.nome === this.nome && prc.numeroDente === this.numeroDente && prc.faceDente === this.faceDente) 97 | if (procedimento === undefined) procedimentos.push(this.criaObjeto()) 98 | else procedimentos[procedimentos.indexOf(procedimento)] = this.criaObjeto() 99 | storage.save(procedimentos) 100 | } 101 | } 102 | remover() { 103 | procedimentos.splice(procedimentos.indexOf(this.criaObjeto()), 1) 104 | storage.save(procedimentos) 105 | } 106 | } 107 | 108 | let procedimento = new Procedimento() 109 | procedimento.indice = null 110 | 111 | const storage = { 112 | fetch() { 113 | return JSON.parse(localStorage.getItem('procedimentos') || '[]') 114 | }, 115 | save(procedimentos) { 116 | localStorage.setItem('procedimentos', JSON.stringify(procedimentos)) 117 | procedimentos = this.fetch() 118 | return procedimentos 119 | } 120 | }; 121 | 122 | let tamanhoColuna = camada1.width / 16 123 | let tamanhoDente = tamanhoColuna - (2 * posicoesPadrao.margemXEntreDentes) 124 | 125 | let dimensoesTrapezio = { 126 | // Base maior será a altura e largura do dente 127 | // Base menor será 3/4 da base maior 128 | // Lateral será 1/4 da base maior 129 | 130 | baseMaior: tamanhoDente, 131 | lateral: tamanhoDente / 4, 132 | baseMenor: (tamanhoDente / 4) * 3 133 | } 134 | 135 | let numeroDentes = { 136 | superior: ['18', '17', '16', '15', '14', '13', '12', '11', '21', '22', '23', '24', '25', '26', '27', '28'], 137 | inferior: ['48', '47', '46', '45', '44', '43', '42', '41', '31', '32', '33', '34', '35', '36', '37', '38'] 138 | } 139 | 140 | let numeroDenteXOrdemExibicaoDente = new Array() 141 | 142 | /** 143 | *Define a posição inicial do dente no eixo x a partir de seu índice. 144 | * 145 | * @example 146 | * definePosicaoXInicialDente(5) 147 | * 148 | * @param {Number} index Parâmetro obrigatório 149 | * @returns {Number} 150 | */ 151 | const definePosicaoXInicialDente = (index) => { 152 | if (index === 0) return (index * tamanhoDente) + (posicoesPadrao.margemXEntreDentes * index) + posicoesPadrao.margemXEntreDentes; 153 | else return (index * tamanhoDente) + (2 * posicoesPadrao.margemXEntreDentes * index) + posicoesPadrao.margemXEntreDentes; 154 | } 155 | 156 | /** 157 | * Desenha os dentes com suas respectivas faces. 158 | * 159 | * @example 160 | * desenharDente(20, 20) 161 | * 162 | * @param {Number} posicaoX Parâmetro obrigatório 163 | * @param {Number} posicaoY Parâmetro obrigatório 164 | */ 165 | const desenharDente = (posicaoX, posicaoY) => { 166 | contexto1.fillStyle = 'black'; 167 | contexto1.strokeStyle = 'black'; 168 | 169 | /* 1º trapézio */ 170 | contexto1.beginPath(); 171 | contexto1.moveTo(posicaoX, posicaoY); 172 | contexto1.lineTo(dimensoesTrapezio.baseMaior + posicaoX, posicaoY); 173 | contexto1.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 174 | contexto1.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.lateral + posicaoY); 175 | contexto1.closePath(); 176 | contexto1.stroke(); 177 | 178 | /* 2º trapézio */ 179 | contexto1.beginPath(); 180 | contexto1.moveTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 181 | contexto1.lineTo(dimensoesTrapezio.baseMaior + posicaoX, posicaoY); 182 | contexto1.lineTo(dimensoesTrapezio.baseMaior + posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 183 | contexto1.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 184 | contexto1.closePath(); 185 | contexto1.stroke(); 186 | 187 | /* 3º trapézio */ 188 | contexto1.beginPath(); 189 | contexto1.moveTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 190 | contexto1.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 191 | contexto1.lineTo(dimensoesTrapezio.baseMaior + posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 192 | contexto1.lineTo(posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 193 | contexto1.closePath(); 194 | contexto1.stroke(); 195 | 196 | /* 4º trapézio */ 197 | contexto1.beginPath(); 198 | contexto1.moveTo(posicaoX, posicaoY); 199 | contexto1.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.lateral + posicaoY); 200 | contexto1.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 201 | contexto1.lineTo(posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 202 | contexto1.closePath(); 203 | contexto1.stroke(); 204 | } 205 | 206 | /** 207 | * Faz o efeito 'hover' ao passar o mouse sobre alguma face. 208 | * 209 | * @example 210 | * marcarSecao(contexto, 2, 5) 211 | * 212 | * @param {Object} contexto Parâmetro obrigatório 213 | * @param {Number} ordemExibicaoDente Parâmetro obrigatório 214 | * @param {Number} face Parâmetro obrigatório 215 | */ 216 | const marcarSecao = (contexto, ordemExibicaoDente, face) => { 217 | contexto.lineWidth = 2 218 | let cor_linha = 'orange'; 219 | let posicaoY = 0 220 | 221 | if (ordemExibicaoDente < 17) posicaoY = posicoesPadrao.posicaoYInicialDente; 222 | else { 223 | ordemExibicaoDente -= 16; 224 | posicaoY = dimensoesTrapezio.baseMaior + posicoesPadrao.margemYEntreDentes + posicoesPadrao.posicaoYInicialDente; 225 | } 226 | 227 | let posicaoX = definePosicaoXInicialDente(ordemExibicaoDente - 1) 228 | 229 | /* 1ª zona */ 230 | if (face === 1) { 231 | if (contexto) { 232 | contexto.fillStyle = cor_linha; 233 | contexto.beginPath(); 234 | contexto.moveTo(posicaoX, posicaoY); 235 | contexto.lineTo(dimensoesTrapezio.baseMaior + posicaoX, posicaoY); 236 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 237 | contexto.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.lateral + posicaoY); 238 | contexto.closePath(); 239 | contexto.strokeStyle = 'orange'; 240 | contexto.stroke(); 241 | } 242 | } 243 | /* 2ª zona */ 244 | if (face === 2) { 245 | if (contexto) { 246 | contexto.fillStyle = cor_linha; 247 | contexto.beginPath(); 248 | contexto.moveTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 249 | contexto.lineTo(dimensoesTrapezio.baseMaior + posicaoX, posicaoY); 250 | contexto.lineTo(dimensoesTrapezio.baseMaior + posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 251 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 252 | contexto.closePath(); 253 | //contexto.fill(); 254 | contexto.strokeStyle = 'orange'; 255 | contexto.stroke(); 256 | } 257 | } 258 | /* 3ª zona */ 259 | if (face === 3) { 260 | if (contexto) { 261 | contexto.fillStyle = cor_linha; 262 | contexto.beginPath(); 263 | contexto.moveTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 264 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 265 | contexto.lineTo(dimensoesTrapezio.baseMaior + posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 266 | contexto.lineTo(posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 267 | contexto.closePath(); 268 | contexto.strokeStyle = 'orange'; 269 | contexto.stroke(); 270 | } 271 | } 272 | /* 4ª zona */ 273 | if (face === 4) { 274 | if (contexto) { 275 | contexto.fillStyle = cor_linha; 276 | contexto.beginPath(); 277 | contexto.moveTo(posicaoX, posicaoY); 278 | contexto.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.lateral + posicaoY); 279 | contexto.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 280 | contexto.lineTo(posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 281 | contexto.closePath(); 282 | contexto.strokeStyle = 'orange'; 283 | contexto.stroke(); 284 | } 285 | } 286 | /* 5ª zona(medio) */ 287 | if (face === 5) { 288 | if (contexto) { 289 | contexto.fillStyle = cor_linha; 290 | contexto.beginPath(); 291 | contexto.moveTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.lateral + posicaoY); 292 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 293 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 294 | contexto.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 295 | contexto.closePath(); 296 | contexto.strokeStyle = 'orange'; 297 | contexto.stroke(); 298 | } 299 | } 300 | } 301 | 302 | camada4.onmousemove = (event) => { 303 | let x = event.x 304 | let y = event.y 305 | 306 | x -= camada1.offsetLeft 307 | y -= camada1.offsetTop 308 | 309 | procedimento.limpar() 310 | procedimento.indice = null 311 | 312 | procedimento = getInfoDentePosicaoatual(procedimento, x, y) 313 | if (getOrdemExibicaoPorNumeroDente(procedimento.numeroDente) > 0) { 314 | if (procedimento.faceDente) { 315 | color = 'orange'; 316 | contexto3.clearRect(0, 0, camada3.width, camada3.height) 317 | marcarSecao(contexto3, getOrdemExibicaoPorNumeroDente(procedimento.numeroDente), procedimento.faceDente); 318 | } else contexto3.clearRect(0, 0, camada3.width, camada3.height) 319 | } else contexto3.clearRect(0, 0, camada3.width, camada3.height) 320 | } 321 | 322 | camada4.touchstart = (event) => { 323 | alert('touch') 324 | } 325 | 326 | camada4.onclick = (event) => { 327 | let x = event.x 328 | let y = event.y 329 | 330 | x -= camada1.offsetLeft 331 | y -= camada1.offsetTop 332 | 333 | procedimento.limpar() 334 | procedimento.indice = null 335 | 336 | procedimento = getInfoDentePosicaoatual(procedimento, x, y) 337 | 338 | if (procedimento.faceDente) modal.show() 339 | atualizaTabela() 340 | } 341 | 342 | const atualizaTabela = () => { 343 | const tbody = document.getElementById('bodyProcedimentos') 344 | let trs = '' 345 | procedimentos.filter(prc => prc.numeroDente === procedimento.numeroDente && prc.faceDente === procedimento.faceDente).forEach(item => { 346 | const tr = ` 347 | 348 | 349 | ${item.nome} 350 | 351 | 352 | 353 | 354 | 355 | ${item.informacoesAdicionais || 'NÃO INFORMADO'} 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | ` 364 | trs += tr 365 | }) 366 | tbody.innerHTML = trs 367 | } 368 | 369 | window.apagar = (nome, numeroDente, faceDente) => { 370 | const procd = procedimentos.find(prc => prc.nome === nome && prc.numeroDente === numeroDente && prc.faceDente === faceDente) 371 | procedimentos.splice(procedimentos.indexOf(procd), 1) 372 | storage.save(procedimentos) 373 | atualizaTabela() 374 | resizeCanvas() 375 | } 376 | 377 | /** 378 | * Exibe o 'esqueleto' do odontograma (os dentes e sua numeração). 379 | */ 380 | const exibirEstrutura = () => { 381 | // document.querySelector("#canva-group").style.display = 'block' 382 | 383 | for (let index = 0; index < 16; index++) { 384 | const posicaoX = definePosicaoXInicialDente(index) 385 | desenharDente(posicaoX, posicoesPadrao.posicaoYInicialDente) 386 | } 387 | 388 | for (let index = 0; index < 16; index++) { 389 | const posicaoX = definePosicaoXInicialDente(index) 390 | desenharDente(posicaoX, posicoesPadrao.margemYEntreDentes + tamanhoDente + posicoesPadrao.posicaoYInicialDente) 391 | } 392 | 393 | numeroDentes.superior.forEach((numero, index) => { 394 | const posicaoX = definePosicaoXInicialQuadrado(index) 395 | desenharQuadradoNumDente({ 396 | position: { 397 | x: posicaoX, 398 | y: (posicoesPadrao.margemYEntreDentes / 5) + tamanhoDente + posicoesPadrao.posicaoYInicialDente 399 | }, 400 | primeiroOuUltimoDente: index === 0 || index === 15, 401 | numeroDente: numero, 402 | altura: tamanhoDente / 1.8, 403 | largura: index === 0 || index === 15 ? tamanhoDente + posicoesPadrao.margemXEntreDentes : tamanhoDente + 2 * posicoesPadrao.margemXEntreDentes 404 | }) 405 | }) 406 | 407 | numeroDentes.inferior.forEach((numero, index) => { 408 | const posicaoX = definePosicaoXInicialQuadrado(index) 409 | desenharQuadradoNumDente({ 410 | position: { 411 | x: posicaoX, 412 | y: (posicoesPadrao.margemYEntreDentes / 5) + (tamanhoDente / 1.8) + tamanhoDente + posicoesPadrao.posicaoYInicialDente 413 | }, 414 | primeiroOuUltimoDente: index === 0 || index === 15, 415 | numeroDente: numero, 416 | altura: tamanhoDente / 1.8, 417 | largura: index === 0 || index === 15 ? tamanhoDente + posicoesPadrao.margemXEntreDentes : tamanhoDente + 2 * posicoesPadrao.margemXEntreDentes 418 | }) 419 | }) 420 | } 421 | 422 | /** 423 | * Define a posição inicial do quadrado no eixo x a partir de seu índice. 424 | * 425 | * @param {Number} index 426 | */ 427 | const definePosicaoXInicialQuadrado = (index) => { 428 | if (index === 0) return (index * tamanhoDente) + posicoesPadrao.margemXEntreDentes; 429 | else return (index * tamanhoDente) + (2 * index * posicoesPadrao.margemXEntreDentes); 430 | } 431 | 432 | /** 433 | * Desenha o quadrado que informa o número do dente. 434 | * 435 | * @example 436 | * desenharQuadradoNumDente(quadrado) 437 | * 438 | * @param {Object} quadrado Parâmetro obrigatório 439 | */ 440 | const desenharQuadradoNumDente = (quadrado) => { 441 | let tamanhoFonte = (40 * (quadrado.primeiroOuUltimoDente ? quadrado.largura + posicoesPadrao.margemXEntreDentes : quadrado.largura)) / 118.4375 442 | contexto1.font = `${tamanhoFonte}px arial` 443 | contexto1.strokeRect(quadrado.position.x, quadrado.position.y, quadrado.largura, quadrado.altura) 444 | contexto1.fillText(quadrado.numeroDente, quadrado.position.x + tamanhoDente / 2.8, quadrado.position.y + (tamanhoDente / 2.5)); 445 | } 446 | 447 | /** 448 | * Pinta a face do dente de acordo com o procedimento adicionado. 449 | * 450 | * @example 451 | * pintarFace(contexto, procedimento, 'black', 'orange') 452 | * 453 | * @param {Object} contexto Parâmetro obrigatório 454 | * @param {Object} procedimento Parâmetro obrigatório 455 | * @param {String} cor_linha Parâmetro obrigatório 456 | * @param {String} cor_interior Parâmetro obrigatório 457 | */ 458 | const pintarFace = (contexto, procedimento, cor_linha, cor_interior) => { 459 | let numeroDente = getOrdemExibicaoPorNumeroDente(procedimento.numeroDente) - 1 460 | contexto.fillStyle = cor_interior 461 | contexto.strokeStyle = cor_linha 462 | 463 | let posicaoY = 0 464 | 465 | if (numeroDente < 16) posicaoY = posicoesPadrao.posicaoYInicialDente; 466 | else { 467 | numeroDente -= 16; 468 | posicaoY = dimensoesTrapezio.baseMaior + posicoesPadrao.margemYEntreDentes + posicoesPadrao.posicaoYInicialDente; 469 | } 470 | 471 | const prcdms = getProcedimentosPorDente(procedimento.numeroDente, procedimento.faceDente) 472 | const numeroDivisoes = prcdms.length - 1 473 | let dividir = false 474 | if (numeroDivisoes > 0) dividir = true 475 | 476 | let posicaoX = definePosicaoXInicialDente(numeroDente) 477 | 478 | /* 1ª zona */ 479 | if (procedimento.faceDente === 1 && !dividir) { 480 | if (contexto) { 481 | contexto.beginPath(); 482 | contexto.moveTo(posicaoX, posicaoY); 483 | contexto.lineTo(dimensoesTrapezio.baseMaior + posicaoX, posicaoY); 484 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 485 | contexto.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.lateral + posicaoY); 486 | contexto.closePath(); 487 | contexto.fill(); 488 | contexto.stroke(); 489 | } 490 | } else if (procedimento.faceDente === 1 && dividir) { 491 | if (contexto) { 492 | const larguraDivisao = dimensoesTrapezio.baseMaior / (numeroDivisoes + 1) 493 | prcdms.forEach((procedimentoItem, divisao) => { 494 | contexto.fillStyle = procedimentoItem.cor 495 | const ultimo = divisao === numeroDivisoes 496 | const primeiro = divisao === 0 497 | const dentroAreaTriangular = larguraDivisao * (divisao + 1) < dimensoesTrapezio.lateral 498 | contexto.beginPath(); 499 | contexto.moveTo((larguraDivisao * divisao) + posicaoX, posicaoY); 500 | contexto.lineTo(larguraDivisao * (divisao + 1) + posicaoX, posicaoY); 501 | if (ultimo) { 502 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 503 | contexto.lineTo((larguraDivisao * divisao) + posicaoX, dimensoesTrapezio.lateral + posicaoY); 504 | } else if (!primeiro) { 505 | contexto.lineTo(larguraDivisao * (divisao + 1) + posicaoX, dimensoesTrapezio.lateral + posicaoY); 506 | contexto.lineTo((larguraDivisao * divisao) + posicaoX, dimensoesTrapezio.lateral + posicaoY); 507 | } else { 508 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 509 | contexto.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.lateral + posicaoY); 510 | } 511 | contexto.closePath(); 512 | contexto.fill(); 513 | contexto.stroke(); 514 | }) 515 | } 516 | } 517 | 518 | 519 | /* 2ª zona */ 520 | if (procedimento.faceDente === 2 && !dividir) { 521 | if (contexto) { 522 | contexto.beginPath(); 523 | contexto.moveTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 524 | contexto.lineTo(dimensoesTrapezio.baseMaior + posicaoX, posicaoY); 525 | contexto.lineTo(dimensoesTrapezio.baseMaior + posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 526 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 527 | contexto.closePath(); 528 | contexto.fill(); 529 | contexto.stroke(); 530 | } 531 | } else if (procedimento.faceDente === 2 && dividir) { 532 | if (contexto) { 533 | const larguraDivisao = dimensoesTrapezio.baseMaior / (numeroDivisoes + 1) 534 | prcdms.forEach((procedimentoItem, divisao) => { 535 | contexto.fillStyle = procedimentoItem.cor 536 | const ultimo = divisao === numeroDivisoes 537 | const primeiro = divisao === 0 538 | contexto.beginPath(); 539 | contexto.moveTo(dimensoesTrapezio.baseMaior + posicaoX, (larguraDivisao * divisao) + posicaoY); 540 | contexto.lineTo(dimensoesTrapezio.baseMaior + posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 541 | if (ultimo) { 542 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 543 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, (larguraDivisao * divisao) + posicaoY); 544 | } else if (!primeiro) { 545 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 546 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, (larguraDivisao * divisao) + posicaoY); 547 | } else { 548 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 549 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 550 | } 551 | contexto.closePath(); 552 | contexto.fill(); 553 | contexto.stroke(); 554 | }) 555 | } 556 | } 557 | 558 | /* 3ª zona */ 559 | if (procedimento.faceDente === 3 && !dividir) { 560 | if (contexto) { 561 | contexto.beginPath(); 562 | contexto.moveTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 563 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 564 | contexto.lineTo(dimensoesTrapezio.baseMaior + posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 565 | contexto.lineTo(posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 566 | contexto.closePath(); 567 | contexto.fill(); 568 | contexto.stroke(); 569 | } 570 | } else if (procedimento.faceDente === 3 && dividir) { 571 | if (contexto) { 572 | const larguraDivisao = dimensoesTrapezio.baseMaior / (numeroDivisoes + 1) 573 | prcdms.forEach((procedimentoItem, divisao) => { 574 | contexto.fillStyle = procedimentoItem.cor 575 | const ultimo = divisao === numeroDivisoes 576 | const primeiro = divisao === 0 577 | const dentroAreaTriangular = larguraDivisao * (divisao + 1) < dimensoesTrapezio.lateral 578 | contexto.beginPath(); 579 | contexto.moveTo((larguraDivisao * divisao) + posicaoX, posicaoY + tamanhoDente); 580 | contexto.lineTo(larguraDivisao * (divisao + 1) + posicaoX, posicaoY + tamanhoDente); 581 | if (ultimo) { 582 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 583 | contexto.lineTo((larguraDivisao * divisao) + posicaoX, dimensoesTrapezio.lateral + posicaoY + dimensoesTrapezio.baseMenor); 584 | } else if (!primeiro) { 585 | contexto.lineTo(larguraDivisao * (divisao + 1) + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 586 | contexto.lineTo((larguraDivisao * divisao) + posicaoX, posicaoY + dimensoesTrapezio.baseMenor); 587 | } else { 588 | contexto.lineTo((larguraDivisao * (divisao + 1)) + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 589 | contexto.lineTo(posicaoX, dimensoesTrapezio.lateral + posicaoY + dimensoesTrapezio.baseMenor); 590 | } 591 | contexto.closePath(); 592 | contexto.fill(); 593 | contexto.stroke(); 594 | }) 595 | } 596 | } 597 | 598 | /* 4ª zona */ 599 | if (procedimento.faceDente === 4 && !dividir) { 600 | if (contexto) { 601 | contexto.beginPath(); 602 | contexto.moveTo(posicaoX, posicaoY); 603 | contexto.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.lateral + posicaoY); 604 | contexto.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 605 | contexto.lineTo(posicaoX, dimensoesTrapezio.baseMaior + posicaoY); 606 | contexto.closePath(); 607 | contexto.fill(); 608 | contexto.stroke(); 609 | } 610 | } else if (procedimento.faceDente === 4 && dividir) { 611 | if (contexto) { 612 | const larguraDivisao = dimensoesTrapezio.baseMaior / (numeroDivisoes + 1) 613 | prcdms.forEach((procedimentoItem, divisao) => { 614 | contexto.fillStyle = procedimentoItem.cor 615 | const ultimo = divisao === numeroDivisoes 616 | const primeiro = divisao === 0 617 | contexto.beginPath(); 618 | contexto.moveTo(posicaoX, (larguraDivisao * divisao) + posicaoY); 619 | contexto.lineTo(posicaoX, larguraDivisao * (divisao + 1) + posicaoY); 620 | if (ultimo) { 621 | contexto.lineTo(posicaoX + dimensoesTrapezio.lateral, dimensoesTrapezio.baseMenor + posicaoY); 622 | contexto.lineTo(posicaoX + dimensoesTrapezio.lateral, (larguraDivisao * divisao) + posicaoY); 623 | } else if (!primeiro) { 624 | contexto.lineTo(posicaoX + dimensoesTrapezio.lateral, dimensoesTrapezio.baseMenor + posicaoY); 625 | contexto.lineTo(posicaoX + dimensoesTrapezio.lateral, (larguraDivisao * divisao) + posicaoY); 626 | } else { 627 | contexto.lineTo(posicaoX + dimensoesTrapezio.lateral, larguraDivisao * (divisao + 1) + posicaoY); 628 | contexto.lineTo(posicaoX + dimensoesTrapezio.lateral, dimensoesTrapezio.lateral + posicaoY); 629 | } 630 | contexto.closePath(); 631 | contexto.fill(); 632 | contexto.stroke(); 633 | }) 634 | } 635 | } 636 | 637 | /* 5ª zona(medio) */ 638 | if (procedimento.faceDente === 5 && !dividir) { 639 | if (contexto) { 640 | contexto.beginPath(); 641 | contexto.moveTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.lateral + posicaoY); 642 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.lateral + posicaoY); 643 | contexto.lineTo(dimensoesTrapezio.baseMenor + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 644 | contexto.lineTo(dimensoesTrapezio.lateral + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 645 | contexto.closePath(); 646 | contexto.fill(); 647 | contexto.stroke(); 648 | } 649 | } else if (procedimento.faceDente === 5 && dividir) { 650 | if (contexto) { 651 | const larguraDivisao = (dimensoesTrapezio.baseMenor - dimensoesTrapezio.lateral) / (numeroDivisoes + 1) 652 | prcdms.forEach((procedimentoItem, divisao) => { 653 | contexto.fillStyle = procedimentoItem.cor 654 | contexto.beginPath(); 655 | contexto.moveTo(dimensoesTrapezio.lateral + (divisao * larguraDivisao) + posicaoX, dimensoesTrapezio.lateral + posicaoY); 656 | contexto.lineTo(dimensoesTrapezio.lateral + ((divisao + 1) * larguraDivisao) + posicaoX, dimensoesTrapezio.lateral + posicaoY); 657 | contexto.lineTo(dimensoesTrapezio.lateral + ((divisao + 1) * larguraDivisao) + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 658 | contexto.lineTo(dimensoesTrapezio.lateral + (divisao * larguraDivisao) + posicaoX, dimensoesTrapezio.baseMenor + posicaoY); 659 | contexto.closePath(); 660 | contexto.fill(); 661 | contexto.stroke(); 662 | }) 663 | } 664 | } 665 | } 666 | 667 | /** 668 | * Redimensiona os canvas do odontograma e seu conteúdo proporcionalmente ao tamanho da janela. 669 | */ 670 | const resizeCanvas = () => { 671 | if (window.innerWidth >= 800) { 672 | document.querySelector("#canva-group").style.display = 'display' 673 | } else { 674 | alert("TELA MUITO PEQUENA! Acesse o odontrograma através de um dispositivo com uma tela maior!") 675 | document.querySelector("#canva-group").style.display = 'none' 676 | } 677 | 678 | camada1.width = camada2.width = camada3.width = camada4.width = window.innerWidth - 25 679 | const altura = (camada1.width * alturaTelaReferencia) / tamanhoTelaReferencia 680 | camada1.height = camada2.height = camada3.height = camada4.height = altura 681 | 682 | valoresBase = { 683 | x: (camada1.width * 24) / tamanhoTelaReferencia, 684 | y: (camada1.width * 20) / tamanhoTelaReferencia, 685 | largura: (camada1.width * 70) / tamanhoTelaReferencia, 686 | altura: (camada1.width * 150) / tamanhoTelaReferencia 687 | } 688 | 689 | base_image = new Image(); 690 | base_image.src = 'images/dentes/18.png'; 691 | base_image.onload = function() { 692 | contexto1.drawImage(base_image, valoresBase.x, valoresBase.y, valoresBase.largura, valoresBase.altura); 693 | } 694 | 695 | posicoesPadrao.margemXEntreDentes = (camada1.width * 8) / tamanhoTelaReferencia 696 | posicoesPadrao.margemYEntreDentes = (camada1.width * 200) / tamanhoTelaReferencia 697 | posicoesPadrao.posicaoYInicialDente = (camada1.width * 180) / tamanhoTelaReferencia 698 | 699 | tamanhoColuna = camada1.width / 16 700 | tamanhoDente = tamanhoColuna - (2 * posicoesPadrao.margemXEntreDentes) 701 | 702 | dimensoesTrapezio = { 703 | baseMaior: tamanhoDente, 704 | lateral: tamanhoDente / 4, 705 | baseMenor: (tamanhoDente / 4) * 3 706 | } 707 | 708 | exibeMarcacoes() 709 | exibirEstrutura() 710 | } 711 | 712 | /** 713 | * Retorna os dados do dente em relação a posição do mouse na tela 714 | * 715 | * @example 716 | * getInfoDentePosicaoatual(infoDentePosicaoAtual, 300, 255) 717 | * 718 | * @param {Object} infoDentePosicaoAtual Parâmetro obrigatório 719 | * @param {Number} x Parâmetro obrigatório 720 | * @param {Number} y Parâmetro obrigatório 721 | * @returns {Object} 722 | */ 723 | const getInfoDentePosicaoatual = (procedimento, x, y) => { 724 | if (y >= posicoesPadrao.posicaoYInicialDente && y <= posicoesPadrao.posicaoYInicialDente + tamanhoDente) { 725 | if (x >= posicoesPadrao.margemXEntreDentes && x <= posicoesPadrao.margemXEntreDentes + tamanhoDente) procedimento.numeroDente = getNumeroDentePorOrdemExibicao(1); 726 | else if (x >= (tamanhoDente + posicoesPadrao.margemXEntreDentes * 3) && x <= (30 * posicoesPadrao.margemXEntreDentes + 16 * tamanhoDente)) { 727 | procedimento.indice = parseInt(x / (tamanhoDente + 2 * posicoesPadrao.margemXEntreDentes), 10); 728 | ini = (procedimento.indice * tamanhoDente) + (2 * posicoesPadrao.margemXEntreDentes * procedimento.indice) + posicoesPadrao.margemXEntreDentes; 729 | fin = ini + tamanhoDente; 730 | if (x >= ini && x <= fin) { 731 | procedimento.numeroDente = getNumeroDentePorOrdemExibicao(procedimento.indice + 1) 732 | } 733 | } 734 | } else if (y >= (tamanhoDente + posicoesPadrao.margemYEntreDentes + posicoesPadrao.posicaoYInicialDente) && y <= (2 * tamanhoDente + posicoesPadrao.margemYEntreDentes + posicoesPadrao.posicaoYInicialDente)) { 735 | if (x >= posicoesPadrao.margemXEntreDentes && x <= posicoesPadrao.margemXEntreDentes + tamanhoDente) { 736 | procedimento.numeroDente = getNumeroDentePorOrdemExibicao(17); 737 | } else if (x >= (tamanhoDente + posicoesPadrao.margemXEntreDentes * 3) && x <= (30 * posicoesPadrao.margemXEntreDentes + 16 * tamanhoDente)) { 738 | procedimento.indice = parseInt(x / (tamanhoDente + 2 * posicoesPadrao.margemXEntreDentes), 10); 739 | ini = (procedimento.indice * tamanhoDente) + (2 * posicoesPadrao.margemXEntreDentes * procedimento.indice) + posicoesPadrao.margemXEntreDentes; 740 | fin = ini + tamanhoDente; 741 | if (x >= ini && x <= fin) procedimento.numeroDente = getNumeroDentePorOrdemExibicao(procedimento.indice + 17) 742 | } 743 | } 744 | 745 | let px = x - ((procedimento.indice * tamanhoDente) + (2 * posicoesPadrao.margemXEntreDentes * procedimento.indice) + posicoesPadrao.margemXEntreDentes) 746 | let py = y - posicoesPadrao.posicaoYInicialDente 747 | 748 | if (getOrdemExibicaoPorNumeroDente(procedimento.numeroDente) > 16) py -= (posicoesPadrao.margemYEntreDentes + tamanhoDente) 749 | 750 | if (py > 0 && py < (tamanhoDente / 4) && px > py && py < tamanhoDente - px) { 751 | procedimento.faceDente = 1; 752 | } else if (px > (tamanhoDente / 4) * 3 && px < tamanhoDente && py < px && tamanhoDente - px < py) { 753 | procedimento.faceDente = 2; 754 | } else if (py > (tamanhoDente / 4) * 3 && py < tamanhoDente && px < py && px > tamanhoDente - py) { 755 | procedimento.faceDente = 3; 756 | } else if (px > 0 && px < (tamanhoDente / 4) && py > px && px < tamanhoDente - py) { 757 | procedimento.faceDente = 4; 758 | } else if (px > (tamanhoDente / 4) && px < (tamanhoDente / 4) * 3 && py > (tamanhoDente / 4) && py < (tamanhoDente / 4) * 3) { 759 | procedimento.faceDente = 5; 760 | } 761 | 762 | return procedimento 763 | } 764 | 765 | /** 766 | * Exibe todos os procedimentos adicionados nos respectivos dentes e faces 767 | */ 768 | const exibeMarcacoes = () => { 769 | procedimentos.forEach(element => { 770 | pintarFace(contexto2, element, 'black', element.cor) 771 | }); 772 | } 773 | 774 | /** 775 | * Redimensiona o canvas do pincel e seu conteúdo proporcionalmente ao tamanho da janela. 776 | */ 777 | const resizeCanvasPincel = () => { 778 | camadaPincel.width = window.innerWidth - 25 779 | const altura = (camadaPincel.width * alturaTelaReferencia) / tamanhoTelaReferencia 780 | camadaPincel.height = altura 781 | 782 | const dataImage = localStorage.getItem('desenho') 783 | 784 | desenho = new Image(); 785 | desenho.src = dataImage; 786 | desenho.onload = function() { 787 | contextoPincel.clearRect(0, 0, camadaPincel.width, camadaPincel.height) 788 | contextoPincel.drawImage(desenho, 0, 0, camadaPincel.width, camadaPincel.height); 789 | } 790 | } 791 | 792 | /** 793 | * Dá o start no odontograma, Desenhando a estrutura, carregando os dados, etc. 794 | */ 795 | const iniciaOdontograma = () => { 796 | const options = itensProcedimento.map(problema => { 797 | return `\n` 798 | }) 799 | document.querySelector("#nomeProcedimento").innerHTML += options 800 | 801 | document.querySelector("#nomeProcedimento").addEventListener('change', (event) => { 802 | let procedimento = document.querySelector("#nomeProcedimento") 803 | if (procedimento.value !== '') { 804 | procedimento = itensProcedimento.find(problemaAtual => problemaAtual.nome === procedimento.value) 805 | document.querySelector("#cor").value = procedimento.cor 806 | if (procedimento.nome === 'Outro') { 807 | document.querySelector("#cor").disabled = false 808 | document.getElementById("colOutroProcedimento").style.display = 'block' 809 | } else { 810 | document.querySelector("#cor").disabled = true 811 | document.getElementById("colOutroProcedimento").style.display = 'none' 812 | } 813 | } else { 814 | document.querySelector("#cor").disabled = true 815 | document.getElementById("colOutroProcedimento").style.display = 'none' 816 | } 817 | }) 818 | 819 | document.querySelector("#nomeProcedimento").dispatchEvent(new Event('change')) 820 | 821 | document.querySelector("#botaoAdicionar").onclick = (event) => { 822 | procedimento.nome = document.querySelector("#nomeProcedimento").value 823 | procedimento.cor = document.querySelector("#cor").value 824 | procedimento.informacoesAdicionais = document.querySelector("#informacoesAdicionais").value 825 | 826 | procedimento.salvar() 827 | 828 | pintarFace(contexto2, procedimento, 'black', procedimento.cor) 829 | atualizaTabela() 830 | } 831 | 832 | procedimentos = storage.fetch() 833 | 834 | numeroDentes.superior.forEach((numero, index) => numeroDenteXOrdemExibicaoDente[numero] = index) 835 | numeroDentes.inferior.forEach((numero, index) => numeroDenteXOrdemExibicaoDente[numero] = index + 16) 836 | 837 | resizeCanvas() 838 | resizeCanvasPincel() 839 | } 840 | 841 | /** 842 | * Retorna a ordem de exibição do dente a partir de seu número. 843 | * 844 | * @example 845 | * getOrdemExibicaoPorNumeroDente(17); // 2 846 | * 847 | * @param {Number} numero Parâmetro obrigatório 848 | * @returns {Number} 849 | */ 850 | const getOrdemExibicaoPorNumeroDente = (numero) => { 851 | return numeroDenteXOrdemExibicaoDente[numero] + 1 852 | } 853 | 854 | /** 855 | * Retorna o número do dente a partir de sua ordem de exibição. 856 | * 857 | * @example 858 | * getNumeroDentePorOrdemExibicao(2); // 17 859 | * 860 | * @param {Number} ordem Parâmetro obrigatório 861 | * @returns {Number} 862 | */ 863 | const getNumeroDentePorOrdemExibicao = (ordem) => { 864 | return numeroDenteXOrdemExibicaoDente.indexOf(ordem - 1) 865 | } 866 | 867 | /** 868 | * Retorna Todos os procedimentos adicionados para o dente informado. 869 | * 870 | * @example 871 | * getProcedimentosPorDente(17); // [{...}] 872 | * 873 | * @param {Number} numero Parâmetro obrigatório 874 | * @returns {Array} 875 | */ 876 | const getProcedimentosPorDente = (numero, face) => { 877 | return procedimentos.filter(procedimento => procedimento.numeroDente === numero && procedimento.faceDente === face) 878 | } 879 | 880 | window.addEventListener("resize", () => { 881 | resizeCanvas() 882 | resizeCanvasPincel() 883 | }) 884 | 885 | iniciaOdontograma() 886 | }) --------------------------------------------------------------------------------