Mostrando postagens com marcador Front-End. Mostrar todas as postagens
Mostrando postagens com marcador Front-End. Mostrar todas as postagens

quarta-feira, 8 de abril de 2020

Como fazer sua Aplicação Web transformar texto em áudios (Text-To-Speech)

       Nesse post eu vou falar sobre algo muito útil, a transformação de texto em voz em aplicações web. Sabe quando você quer fazer aqueles paineis de chamada de clientes, ou mesmo ler um texto para o usuário por questões de acessibilidade? Quando pensamos nisso achamos que pode ser algo muito complexo né? Na verdade é algo bem simples!
         
Os navegadores já trazem por padrão um reprodutor de áudio pronto para ser usado via JavaScript, basta passar as frases e o navegador irá reproduzir na linguagem na qual está configurado. Também é possível configurar outras línguas.

OBS: Por questões de privacidade, os navegadores passaram a obrigar uma interação do usuário com a página para permitir a emissão de sons. Por isso, é importante pensar em um botão que possa ser usado uma primeira vez quando a página for carregada ao invés da função onload usada no exemplo.
(editado em 03/07/2022)
         
          Vamos ver esse simples código:

<html>
        <body>
                 <h1 id="speech">Olá, bem vindo ao blog "Olá Mundo - Java"</h1>
        </body>
        <script>
        /**
         *
         * @author Daniel Oliveira
         */
       
        function reproduzirNome(){
                 var falar = document.getElementById('speech');
                 var synth = window.speechSynthesis;
                 var utterNome = new SpeechSynthesisUtterance();
                 var utterSala = new SpeechSynthesisUtterance();
       
                 utterNome.volume = 1; // 0 to 1
                 utterNome.rate = 1; // 0.1 to 10
                 utterNome.pitch = 1.5; // 0 to 2
                 utterNome.lang = "pt-PT";
                
                 for(var i = 0;i < 2; i++){
                         sleep(1000);
                         utterNome.text = falar.textContent; //campos input pega-se o "value"
                         sleep(1000);
                         synth.speak(utterNome);
                                         
                 }
                
        }
       
        function sleep(milliseconds) {
                 const date = Date.now();
                 var currentDate = null;
                 do {
                         currentDate = Date.now();
                 } while (currentDate - date < milliseconds);
        }
       
        window.onload = reproduzirNome();
        </script>
</html>

          Basta pegar esse código e colocar em um projeto seu para ver funcionando. Uma observação importante é que qualquer áudio ou vídeo para ser reproduzido automaticamente precisa de permissão do usuário. Essa permissão é dada no navegador no cadeado(se for https) ou no “i” (se for http) ao lado do endereço:







          Existem outras configurações de controles, tipo de voz, etc, basta dar uma pesquisada nos links abaixo:


          Viu como é fácil?! Isso era o que eu tinha para esse post, até a próxima!

sábado, 27 de julho de 2019

Resolvendo problema CORS no Angular

Olá, hoje vou falar sobre o CORS – Cross-Origin Resource Sharing que significa compartilhamento de recursos de origem cruzada.

Antes era muito comum o uso de iFrames ou similares para fazer com que um site acessasse diretamente conteúdo de outros o que também era válido para aplicações web mais complexas, o problema é que isso começou a ser explorado por pessoas mal intencionadas para se passarem por um site ou serviço que não são e roubar informações ou outras atividades ilícitas. Então os navegadores começaram a “bloquear” esse tipo de coisa, validando antes se a origem tem acesso ao backend vindo de um IP diferente ou não configurado em uma digamos “White list”.

Trarar o CORS é obrigação do backend ou infra, mas é possível e também uma boa prática tratar no frontend. Para isso criamos um Proxy no nosso frontend. Como funciona um proxy? Ele recebe a requisição e a repassa com uma nova configuração de rede.

Vamos criar o nosso proxy, crie um arquivo chamado proxy.config.js no mesmo diretório em que se encontra o seu package.json  com o seguinte conteúdo:

{
"/api": {
    "target": "http://localhost:8080", //endereço do backend
    "secure": false
}
}
Agora configure dentro do seu angular.json o uso do proxy:
...
"defaults"
:{
     "serve":{
          "proxyConfig":"./proxy.config.js"
      }
...


Fonte:
Para ver todas as opções da configuração de proxy veja:
https://webpack.js.org/configuration/dev-server/#devserver-proxy

terça-feira, 19 de março de 2019

Criando uma biblioteca de componentes com Angular 7, utilizando em projetos externos e publicando no NPM


Frameworks JavaScript estão sempre mudando, e geralmente são mudanças complexas que nos obrigam a reaprender como fazemos as coisas. Não foi diferente com a questão da criação de bibliotecas do Angular, que até a versão 5 era apenas um projeto comum, o qual empacotávamos no formato NPM e publicávamos. Agora, a partir da versão 7 em diante o Angular cria uma espécie de workspace, onde é possível criar vários projetos e bibliotecas, e são essas bibliotecas internas que podemos exportar e podemos usar em outros projetos, e até publicar no NPM.

Com isso, muita coisa mudou, porque essa biblioteca interna, (pelo menos por enquanto, até a versão 7.1.2 do Angular), não contém os arquivos environments.prod.ts e environments.ts para tratarmos a diferença entre algumas configurações de produção e o ambiente de desenvolvimento, também não existe a estrutura da pasta assets para colocarmos nossas imagens e o Angular conseguir encontrá-las de forma fácil.

Essas dificuldades eu contornei da seguinte forma: as imagens eu coloco em texto base64 direto na tag <img> e quando preciso pegar uma URL em uma biblioteca uso JavaScript para obter a URL de forma dinâmica: (window.location.protocol + window.location.hostname;).

Outra mudança que houve foi o arquivo angular-cli.json que teve seu nome alterado para angular.json e sua estrutura mudou um pouco, passando a conter múltiplos projetos (como o de testes e as bibliotecas) pois como disse, o que criamos com “ng new” a partir da versão 7 do Angular se comporta como um workspace.

Agora que já falamos das mudanças e alguns contratempos que tive com elas, vamos a criação do projeto. Abrindo no terminal a pasta do seu workspace, digite:

$        ng new teste --create-application=false

          Quando indagado sobre a criação do Router e do CSS escolha as opções padrão.

A opção --create-aplication usada acima também é nova, e faz com que o Angular não crie o projeto inicial, bem com a pasta src, criando apenas o Workspace Angular por assim dizer. Basicamente isso é útil para criarmos bibliotecas, pois gera um workspace de mesmo nome da biblioteca. Note que o Angular aceita tanto comandos com camelCase quanto separados por ífem (-), então poderia ser --createApplication=false.

          Aproveite e dê uma olhada nos arquivos package.json que continua com as dependências do projeto  e angular.json, que está praticamente vazio aguardando a criação de um projeto ou biblioteca.

          Vamos criar a biblioteca, posicione o terminal na nova pasta criada (teste):

$        cd ..

E crie a biblioteca com o seguinte comando:

$        ng g library teste --prefix=lib

          Na linha acima, foi criada a biblioteca “teste” e ao invés de usarmos o prefixo “app” como de costume, dissemos para o Angular usar o prefixo “lib”. Fique à vontade para escolher o prefixo que desejar, isso é importante para evitar conflitos entre a biblioteca e os apps que a usam.
         
          Note que o conteúdo do arquivo angular.json mudou, temos nele a propriedade que indica a versão do projeto: “version”, a propriedade que indica o pacote raiz que contém os projetos: “newProjectRoot”, e então temos a propriedade que indica os nossos projetos: “projects”. Dentro da propriedade “projects” há uma propriedade para cada projeto que criarmos, nesse caso haverá apenas o projeto “teste”, e dentro da propriedade “teste” teremos as propriedades de configuração deste projeto específico, como o tipo do projeto, o prefixo usado, a raiz do projeto, o source do projeto e outras configurações pertinentes.

A estrutura do projeto também foi alterada, agora existe uma pasta “projects” com a pasta “teste” que é o nosso projeto dentro dela; e dentro da pasta “teste” temos o diretório “src” que conterá tudo que pertencer a lib propriamente dita, o arquivo “package.json” da lib que especificará suas dependências que serão compiladas e posteriormente instaladas junto com ela quando um cliente usar npm install e também o arquivo ng-package.json. Os demais arquivos são de menor importância. É também no arquivo “package.json” da lib que especificamos o autor, a licença, o repositório, etc.

       A lib já foi criada contendo um componente e um service dentro de src/lib . Também vemos outro arquivo importante dentro da pasta src: public_api.ts. Nesse arquivo devemos exportar todos os módulos, componentes e services que criarmos, para que possam ser usados por quem instalar nossa biblioteca.

          export * from './lib/teste.service';
export * from './lib/teste.component';
export * from './lib/teste.module';

No diretório principal, o arquivo “tsconfig.json” tem as configurações de transpilação e build do projeto. Ele recebe o path da biblioteca que criamos para podermos usar nesse projeto, enquanto que em projetos externos ela será instalada com npm install e o conteúdo ficará em node_modules.

"paths": {
      "teste": [
        "dist/teste"
      ],
      "teste/*": [
        "dist/teste/*"
      ]
}

          Vamos buildar o projeto:

$        ng build teste   

          Veja que o projeto é buildado normalmente. Mas a frente vamos ver como usá-lo em outro projeto e também como publicar no npm. Agora vamos ver como criar novos componentes para a biblioteca. Digite o comando abaixo:

$        ng g c meu-componente --project=teste

Veja que a única coisa que mudou foi que especificamos em qual projeto o componente seria gerado pelo AngularCli. O novo componente deve ser declarado no módulo da nossa biblioteca e também no arquivo de entrada, o public_api.ts.

Com isso podemos re-buildar nossa aplicação. Uma novidade desde a versão 6.2 é o re-build pode ser automático a medida que arquivos forem alterados, para isso basta acrescentar a opção --watch no momento do build, a partir de então os demais serão disparados sozinhos.

$        ng build teste --watch

Agora vamos ver como usar a biblioteca em um projeto externo e como publicar no npm.

Para isso temos que empacotar nossa biblioteca em uma arquivo .tgz, por tanto, vamos criar um script no “package.json” raiz para facilitar este trabalho. Na seção “scripts” adicione o seguinte trecho de código:

"scripts": {
    ...
    "npm_pack_teste": "cd dist/teste && npm pack"
 }

Agora podemos usar o seguinte comando para empacotar a biblioteca “teste”:

$        npm run npm_pack_teste

Isto criou o arquivo “teste-0.0.1.tgz” dentro de “dist/teste” com a versão especificada no arquivo “package.json” da lib como já dito anteriormente. Podemos inclusive criar um script que faz o build e o empacotamento de uma só vez:

"scripts": {
    ...
    "npm_pack_teste": "cd dist/teste && npm pack",
    "package_teste": "ng build teste && npm run npm_pack_teste "
 }

E agora basta executar:

$        npm run package_teste

Pronto, temos nossa biblioteca buildada e empacotada para usarmos onde quisermos! Para usarmos em projetos próprios não precisamos publicar no npm. Isso é bom para empresas que não querem expor suas bibliotecas, pode-se criar um repositório interno para elas e quando for usar o npm install basta passar o caminho completo de onde a biblioteca está.

Uma vez instalada a biblioteca, o uso é normal como qualquer pacote npm instalado na aplicação.

Agora vamos a publicação no npm. Antes de criar uma biblioteca, se é sua intenção publicá-la no npm é bom checar se o nome que pretende dar a sua biblioteca já não existe lá, para evitar ter que mudar depois de criado todo o projeto.

O arquivo “package.json” deve estar com as informações de nome, versão, autor, licença, repositório, palavras chaves e outras além das dependências, scripts, etc... como abaixo:

...
"name": "teste",
"version": "1.0.0",
"license": "MIT",
"author": {
    "name": "seu_nome",
    "email": "seu_email",
    "url": "seu_site_ou_blog"
 },
 "bugs": {
 "url":"url_issues_git"
  },
 "homepage":"url_git",
 "keywords": [
    "angular",
    "angular2",
    "angular4",
    "p-calendar",
    "p-calendar-ptbr",
    "primeNG",
    "datepicker",
    "calendar",
    "pt-BR"
 ],
 "repository": {
    "type": "git",
    "url": "git+https://endereço_rep_git"
 },
...

O npm usará sua página de README.md com a página inicial da sua biblioteca no servidor. Como agora estamos tratando de mais de uma biblioteca por workspace, o README.md deve ser copiado para o destino onde a biblioteca é buildada. Caso haja um arquivo LICENSE também deve ser colocado lá.

É preciso criar uma conta caso você não tenha, ou fazer login para poder compartilhar seus pacotes. A criação da conta é bem simples e eles pedem um username, password e e-mail. É necessário a confirmação do e-mail antes de publicar algo caso a conta seja nova. O comando para criar uma conta é:

$       npm adduser

Ao criar a conta ele já loga no NPM. Para efetuar logins posteriores, os mesmos dados são pedidos, e o comando é:

$       npm login

Agora podemos publicar nossa biblioteca, digitando o comando npm publish e passando o caminho do arquivo .tgz gerado:

$        npm publish .\dist\teste\teste-0.0.1.tgz

Bom, o artigo ficou um pouco grande porque expliquei algumas coisas com detalhes, mas espero ter ajudado! Abraços!




Links de referência:









sábado, 16 de junho de 2018

Data Attributes – O que são e como usar


Olá, hoje eu vou falar sobre algo que eu particularmente acho muito legal do HTML 5, que são os Data Attributes, ou simplesmente atributos de dados (data-*). Não é algo novo, rsrsrs mas muitas pessoas não usam e muitas usam e nem entendem o que estão fazendo. Você já precisou recuperar no JavaScript valores de um <li>, <ul>, <div> ou qualquer outra tag que não lhe dê a opção de retornar valores como as tags<input>? Bom, com os Data Attributes isso é possível.

O HTML 5 foi desenvolvido para ser extensível, podendo ter dados associados a um elemento específico através de atributos mesmo que esses atributos não tenham sido definidos pela linguagem. Ou seja, podemos adicionar informações a atributos não padrão do HTML e depois recuperar essas informações para usá-las de alguma forma.

Esses atributos valorados não devem conter nenhuma informação confidencial, pois ficam expostos no HTML. Servem para facilitar a manipulação de informações no JavaScript e CSS. Com ele podemos adicionar informações em links, botões, formulários, etc.

A forma de usar é bastante simples, basta declarar um atributo data-* e atribuir o valor desejado. Ex:

<article
  id="carrosEletricos"
  data-columns="3"
  data-index-number="12314"
  data-parent="carros">
...
</article>

Uma vez tendo criado os atributos podemos acessá-los via JavaScript de várias formas e trabalhar em cima dos valores, inclusive alterando-os.

Podemos acessar o valor do atributo diretamente através de um método disponibilizado para varrer os atributos dos elementos HTML - element.getAttribute(“nomeDoAtributo”);. Caso o atributo não exista, o valor retornado será null ou “”. Esse método pode ser usado para atributos padrões do HTML ou os Data Attributes criados. Ex:

<script>
var artigo = document.getElementById(‘carrosEletricos’);
var atributo = artigo.getAttribute(“columns”);
</script>

Mas o padrão recomendado é usando a propriedade dataset do DOMStringMap para recuperar os dados, então teríamos:

<script>
var article = document.getElementById(‘carrosEletricos’);

var colunas = article.dataset.columns; // "3"
var index = article.dataset.indexNumber; // "12314"
var pai = article.dataset.parent; // "carros"
// setar um valor
article.dataset.columns = 5;
</script>

          É claro que podemos também acessar via JQuery:

<script>
var artigo = $("#carrosEletricos");

var colunas = artigo.data("columns"); // "3"
var index = artigo.data("indexNumber"); // "12314"
var pai = artigo.data("parent"); // "cars"
</script>

Abaixo segue um outro exemplo onde temos uma lista de funcionários onde queremos armazenar alguns valores como matricula, idade e sexo, mas não mostrá-los na tela:

<ul>
  <li data-matricula="001" data-idade="23" data-sexo="M" onclick="chamaFuncao(this)">Pedro</li>
  <li data-matricula="002" data-idade="28" data-sexo="M" onclick="chamaFuncao(this)">Daniel</li>
  <li data-matricula="003" data-idade="30" data-sexo="F" onclick="chamaFuncao(this)">Joana</li>
</ul>

Os atributos criados também podem ser usados diretamente no CSS, para isto vamos voltar ao exemplo da tag artigo. Para mostrar o atributo data-parent como conteúdo poderíamos ter o código abaixo:


article::before {
  content: attr(data-parent);
}

Ou usar os “Attribute Selectors” – atributos seletores, que correspondem a elementos com base em seu valor ou simplesmente em sua existência:

// baseado na existência:
article[data-columns] {
       border-right: 1px #bbdefb groove;
}

// baseado no valor:
article[data-columns='3'] {
       width: 400px;
}

article[data-columns='4'] {
       width: 600px;
}

Quando usado por valor, o CSS traz várias opções de comparação e não apenas o “=”. Essas opções funcionam como as Regex do Java ou RegExp do JavaScript. Veja os exemplos:
  
Consideremos o HTML abaixo:

<ul>
  <li><a href="#internal">Internal link</a></li>
  <li><a href="http://example.com">Example link</a></li>
  <li><a href="#InSensitive">Insensitive internal link</a></li>
  <li><a href="http://example.org">Example org link</a></li>
</ul>

<div lang="en-us en-gb en-au en-nz">Hello World!</div>
<div lang="pt">Olá Mundo!</div>
<div lang="zh-CN">世界您好!</div>
<div lang="zh-TW">世界您好!</div>
<div data-lang="zh-TW">?世界您好!</div>


Tendo então as seguintes regras CSS:

a {
  color: blue;
}

/* links internos, começando com "#" */
a[href^="#"] {
  background-color: gold;
}

/* Links com "example" em qualquer parte da URL */
a[href*="example"] {
  background-color: silver;
}

/* Links com "insensitive" em qualquer parte da URL,
   desconsiderando letras maiúsculas e minúsculas -> (i) */
a[href*="insensitive" i] {
  color: cyan;
}

/* Links que terminam ".org" */
a[href$=".org"] {
  color: red;
}

/* Todas as divs com atributo 'lang' são bold. */
div[lang] {
  font-weight: bold;
}

/* Todas as divs em US são azuis. */
div[lang~="en-us"] {
  color: blue;
}

/* Todas as divs em Português são verdes. */
div[lang="pt"] {
  color: green;
}

/* Representa elementos com um nome de atributo
   cujo valor pode ser exatamente igual ou pode
   começar com valor imediatamente seguido por um hífen( - ).
   É frequentemente usado para correspondências de subcódigo
   de idioma.
   Todas as divs em Chinês são vermelhas, mesmo se
    simplificado (zh-CN) ou tradicional (zh-TW). */
div[lang|="zh"] {
  color: red;
}

/* Todas as divs com 'data-lang' Chinês Traditional
   são roxas. */
div[data-lang="zh-TW"] {
  color: purple;
}

Os resultados seriam:



Espero que possa ter ajudado, seguem os links que usei para fazer esse post: