Transcrições
1. Projeto 1: efeitos de fatias e dados em imagens: Quero apresentar a vocês uma fórmula especial de
física do movimento. E quando souber como funciona, você estará pronto para criar os efeitos
interativos mais épicos. A compreensão completa
do que o código está fazendo é muito
importante se você quiser ter um controle total
e poder
experimentar e criar seus próprios efeitos novos e exclusivos. É por isso que, como sempre, não
estamos usando estruturas
nem bibliotecas, apenas Javascript simples e programação orientada a objetos Vamos aprender algumas animações de corte e
dados
em imagens
para iniciantes animações de corte e
dados
em imagens
para e abordar
três técnicas muito importantes e três técnicas muito importantes e fundamentais
que o prepararão para o conjunto definitivo de imagens Como sempre, essa aula
é amigável para iniciantes, mas é necessário um conhecimento básico
de HTML, CSS e Javascript para
poder acompanhar e
realmente entender
2. Configuração de HTML, CSS e JavaScript: Eu crio três arquivos na pasta
do meu projeto, índice HTML, estilo CSS e script
S. Dentro do índice HTML, eu crio uma página web
simples padrão. Eu lhe dou um título. Eu vinculo minha folha de estilo, crio um elemento HTML de cinco
telas com um ID de tela um. E eu vinculo meu arquivo de script. Vou atribuir a ele o atributo
defer para garantir que todo o
conteúdo da página seja
carregado antes que o script seja executado no tySSS Eu dou uma borda ao meu elemento de tela Eu o centralizo no
meio da página da web, vertical
e horizontalmente Usando a técnica de
posição absoluta. Assim, no script GS, fazemos a tela HTML padrão, configuramos quatro linhas de código
que são sempre iguais. Primeiro, apontamos o script Java para o
elemento canvas usando seu ID. Em seguida, pegamos essa referência de
tela e chamamos um método especial de
obtenção de contexto. E instanciamos uma API
embutida na tela como essa. Agora podemos usar essa variável
CTX para chamar todos os métodos de desenho em tela
para acessar suas propriedades Para este projeto,
defini a largura da tela 500 pixels e a altura
será de 700 pixels. Eu me certifico de definir
o tamanho aqui no script
Java e não no
estilo CSS para garantir que tamanho do elemento
e o tamanho da superfície de
desenho do meu elemento de tela estejam
definidos com esses valores. Para evitar distorções, dividiremos as
imagens em uma Cada célula nessa grade
será um objeto separado. Aqui eu tenho uma planta
para esse objeto celular. Também criaremos uma turma. Eu chamo, por exemplo, afetar o cérebro principal
da base de código. Vamos gerenciar o estado
de todo o efeito. A partir daqui, o construtor
esperará que a tela um argumento dentro de I
convertê-la em uma propriedade de classe Sim, posso extrair a variável canvas da linha um
diretamente para minha classe. Mas eu prefiro fazer isso dessa
forma para manter minhas aulas mais independentes
dessa referência de tela. Extrairemos a
largura e a altura porque quero que as dimensões do efeito correspondam
ao tamanho da tela. Eu crio uma instância da
classe usando a nova palavra-chave. Ele espera canvas
como argumento, eu passo a
variável canvas da linha um. Se eu tiver um efeito de console, podemos ver que ele tem
três propriedades, largura e altura da
tela Tudo funciona bem até agora.
3. Como organizar qualquer coisa em uma grade: Queremos dividir a área de
tela disponível em uma grade. A largura de cada célula
será a largura da tela dividida por,
digamos, 35. Queremos 35 células por linha. A altura de cada célula será altura da
tela dividida por 55. Queremos 55 linhas, 35 colunas, 55 linhas. Vamos usar a
classe de célula da linha seis para primeiro criar
apenas um objeto de célula. Todo o código dentro
do construtor da classe é executado linha por linha quando criamos uma instância dessa classe usando
a nova palavra-chave Se eu fizer isso, uma instância da classe de célula será
criada automaticamente. No momento em que eu crio uma instância da classe de efeito, consolo a
célula Ok para que possamos ver suas propriedades
aparecerem no console à
medida que as criamos É uma boa maneira de
verificar se tudo está funcionando à medida que construímos
o projeto Cada célula na grade
precisará
acessar as propriedades da classe de efeito
principal. Uma maneira de fazer isso é criar uma referência apontando o efeito para o
espaço na memória. células do objeto
de efeito principal
serão organizadas em uma grade para
cobrir toda a área da tela. Cada célula espera coordenadas
x e Y para que ela saiba exatamente onde ela deve estar
na grade. Passei essa palavra-chave referenciando
toda essa classe de efeito Primeiro, quero desenhar
essa célula na coordenada 00. canto superior esquerdo da tela, podemos ver o
objeto da célula
recebendo corretamente as propriedades
aqui no console. Quero que todas as células tenham
a mesma largura e altura, para que todas
tenham acesso à
largura e altura da célula a
partir do objeto de efeito principal. Agora temos informações suficientes
sobre cada célula para
podermos realmente desenhá-la no método de desenho personalizado da
cannabis Esperaremos o contexto
como argumento. Novamente, eu poderia
extrair o CTX diretamente da linha dois, mas prefiro tornar minhas aulas mais independentes em
seu escopo léxico Eu vou fazer isso dessa maneira. Cada célula será apenas um retângulo preto Por enquanto, posso desenhá-lo
daqui se eu quiser, mas não seria prático. Uma vez que a imagem pode ser
feita a partir de milhares de células. Vamos desenhar todos eles a partir de um
método de renderização personalizado como esse. Agora eu chamo esse método
de renderização a partir da minha variável de efeito. Eu passo o CTX da linha dois. Queremos desenhar várias células e eu quero
organizá-las em uma grade. A primeira célula
estará aqui horizontalmente. A segunda célula estará aqui. Saltaremos
horizontalmente pela largura da célula até
cobrirmos toda a linha Em seguida, saltaremos pela altura da
célula verticalmente
para a próxima linha Vamos repetir isso até
cobrirmos toda a área da tela. Vou manter todas as
células em uma matriz. Vou chamá-la de grade de imagens. Para conseguir esse efeito,
você precisa entender duas codificações criativas fundamentais e duas, as técnicas de
animação Ambos são extremamente importantes e podem ser usados para milhares de coisas diferentes apenas para o efeito que
estamos construindo hoje. A primeira técnica
que precisamos entender é como organizar
qualquer coisa em uma grade. Faremos isso aqui dentro de um método
personalizado de criação de grade. Para criar uma grade,
usaremos dois quatro loops aninhados. Aninhado significa que há um loop
dentro de outro loop. O loop externo
manipulará as linhas na grade. Cobriremos a tela de
cima para baixo, linha por linha. Começaremos de cima a partir da coordenada
vertical zero. Executaremos
esses quatro voltas até atingirmos a
altura da tela, que significa que até
chegarmos ao fundo, em vez de pular por um, sempre
pularemos pela altura da
célula para garantir que cada
linha tenha a altura correta Sempre que saltarmos para uma nova linha, usaremos mais
quatro voltas para
percorrer todas as
células horizontais dessa linha, da esquerda para a direita, de
zero até a largura da tela. Vamos escrever
tudo isso e recapitularemos rapidamente como
a lógica funciona Organizar objetos em uma grade é uma técnica extremamente útil de
entender para codificação criativa e também para criar dois jogos D. Por exemplo, toda vez que pulamos para uma nova
célula na grade, pegamos uma matriz de grade de imagem e
inserimos uma nova célula lá, passando a referência
ao objeto de efeito. Desta vez, passamos o índice X do loop interno e o índice Y do loop externo
para colocar a célula na grade enquanto a
criamos linha por linha, de cima para baixo. Para recapitular, o
loop externo manipula as linhas, o loop interno manipula as colunas, as células que ficam horizontalmente
próximas umas Dentro de cada linha,
digamos que estamos na linha zero, Y é zero, estamos no topo. Aqui, entramos no loop
interno e empurramos uma célula horizontal uma
ao lado da outra, pulando pela largura da célula até
atingirmos a largura da tela Saímos do circuito interno. O loop externo
aumentará y pela altura da célula. Saltamos para uma nova linha novamente, entramos no loop interno, colocamos todas as células
nessa linha da esquerda para a direita. Quando atingimos a largura, saímos do loop interno, aumentamos Y em um entramos em outra linha. E repetimos esse processo
até termos as
coordenadas x e y para cada célula
na grade que cobre toda
a tela. É uma
técnica muito útil se você iniciante e é a
primeira vez que vê isso Não se preocupe, fará mais sentido se você
usar isso com mais frequência. Como dissemos, todo o código
no construtor é
executado automaticamente quando
criamos uma instância dessa classe usando
a nova palavra-chave Por esse motivo, posso acionar métodos
automaticamente. A partir daqui, chamarei create grid para que, quando criarmos
uma instância da classe de efeito, uma grade de objetos de célula seja criada
automaticamente receba um erro porque
não temos essa célula aqui. Em vez dessa linha,
chamarei cada método na grade de
imagem na
matriz a partir da linha 26. Para cada objeto de célula que
acabamos de inserir nessa matriz, chamarei seu método draw. Quero desenhar todas as células que
acabamos
de criar no console. Eu posso ver que minha matriz
contém 1.980 objetos de células. Em vez disso, vou acariciá-los para que
possamos ver melhor a
grade que acabamos de criar. Bom trabalho. Posso
alterar esses valores para aumentar ou diminuir
o tamanho das minhas células.
4. Como desenhar, cortar e cortar imagens com código.: Agora eu tiro uma foto. O ideal é que a imagem tenha
o mesmo tamanho da tela. No meu caso, isso é
500 vezes 700 pixels. Eu coloquei a imagem dentro da pasta do
meu projeto e a
referenciei aqui. Eu dou uma ideia
da imagem do projeto. Não quero desenhar
o elemento IMG real. Eu não lhe dou nenhuma exibição. Queremos desenhar essa
imagem na tela. Em vez disso, eu o trago para meu projeto aqui na classe de efeito
principal. Essa propriedade de imagem
dentro da renderização, eu chamo de método de
desenho de imagem embutido. E passo a
imagem que quero
desenhar e as coordenadas X e Y. Onde desenhar, posso mover
a imagem assim. Também posso fornecer argumentos opcionais de
largura e altura. E a imagem
será esticada ou comprimida para caber
nessa Eu quero cortar a
imagem em pedaços. Então, em vez disso, usarei
a versão mais longa do método de desenho de imagem
com nove argumentos Esta versão
nos dá o maior controle sobre a imagem que estamos
desenhando ou animando Passamos a imagem que
queremos desenhar,
fonte x, fonte Y, largura da
fonte e altura da fonte, a área que queremos
recortar da imagem de origem e
do
destino X, destino Y, largura do
destino e altura do
destino para definir onde desenhar aquela parte
recortada da imagem No destino Cannavas,
digamos que eu queira
recortar essa área entre as
coordenadas E eu quero esticar essa peça recortada
em toda a tela Estamos estendendo-o da
coordenada 00 para a tela. Com a altura da tela,
temos controle total agora. Esses quatro valores
determinam a área de corte Esses quatro valores
determinam onde desenhar aquela parte
recortada da imagem No Destination Canavas, quero que cada célula contenha
uma pequena parte da imagem Vou cortar essa linha. Em vez disso, colocarei essa propriedade de
imagem na célula. Agora estamos desenhando
a imagem várias vezes, uma vez para cada célula na grade. Não podemos nos dar ao luxo de
fazer isso porque tela é, na verdade, muito
eficiente para desenhar imagens. Não precisa
calcular nada. Ele apenas pega os
dados da imagem e os desenha. É uma operação barata
em comparação com desenhar uma forma. Se eu desenhar a mesma imagem nas coordenadas
x e y de
cada célula, obteremos isso. Se eu der com altura, cada célula contém
a imagem inteira. Já sabemos que precisamos de mais
quatro argumentos para
recortar um pedaço dessa imagem. Fonte X, fonte Y, largura e altura da fonte. Já organizamos
essas células em um grau. Já temos os valores
do corte em coordenadas. Podemos fazer isso de forma simples. Agora, parece que estamos apenas desenhando uma única imagem novamente. Mas, na verdade, neste momento, estamos desenhando um pedaço
da imagem de cada célula. E as células combinadas
criam a imagem completa. Como posso provar
isso? Por exemplo, usarei o índice gerado automaticamente Aqui, dois argumentos,
precisamos de colchetes. Desenhe apenas a célula com
índice de 300 ou 500. Desenhe somente as células
com um índice
maior que 500 ou menor que 500. Menos de 600, 801.000 e 201.300, acho que
provamos isso Não é mais
uma imagem única, é feita de muitas peças.
5. Como animar imagens com código: Para a próxima etapa,
criarei um loop de animação. Atualizaremos alguns
valores e redesenharemos as células repetidamente para criar uma ilusão
de movimento Eu coloquei a renderização dentro do quadro de
animação de solicitação integrado que chamo. E eu chamo animate para
iniciar a animação. Parece estático, mas já
estamos animando. Eu posso provar isso. Eu atribuo propriedades X e Y ao
slide de
cada célula. Coisas muito diferentes
acontecerão dependendo onde, dentro do
método de desenho, as adicionamos. Vou adicioná-los às coordenadas da
fonte X e da fonte Y que determinam
a área de corte Mas também podemos
adicioná-los ao destino X e destino Y para obter um conjunto de efeitos completamente
diferente. Se cada célula tiver o
mesmo valor mínimo, a imagem inteira se moverá. Mas o que acontecerá
se os classificarmos aleatoriamente? Isso os torna aleatórios apenas
uma vez no carregamento da primeira página. E se eu criar um método de
atualização e eu randomizar para
cada quadro de animação Para cada
quadro de animação, chamamos de atualização e redesenharemos todas as
células repetidamente. Interessante. Espero que isso não
dê dor de cabeça a alguém. Também posso randomizar o
slide Y como esse lindo caos, a codificação
criativa Também posso fazer a
imagem deslizar para o lado. Valor mais alto, eu acho. Sim, mova-se mais rápido. Mova-se na
direção oposta, certo? Acho que provamos que
estamos realmente animando. Também podemos tornar a
grade visível aqui.
6. Interatividade com mouse: Eu posso deletar esse console. Eu quero capturar as coordenadas
do mouse. Eu crio um objeto aqui
que os guardará para mim. raio será a
área de interação ao redor do mouse na qual as células reagem à presença
do mouse de alguma forma Eu pego essa
referência de tela da linha 28 e adiciono o ouvinte de eventos de
movimento do mouse Eu posso declarar ouvintes de eventos aqui dentro do construtor Já sabemos que isso significa que
eles serão
aplicados automaticamente quando criarmos uma
instância da classe de efeito. A única coisa aqui é que a função de retorno de chamada não pode
ser uma função normal Ela precisa ser uma função ES de
seis setas para nos permitir usar essa palavra-chave que aponta para esse objeto de
efeito e suas propriedades de
dentro dessa chamada de retorno. Caso contrário, seria indefinido. As funções de seta herdam
essa referência, essa palavra-chave
do escopo pai Eu posso consologar o objeto de evento
gerado automaticamente. Se eu abri-lo, queremos as coordenadas x e y
do cursor do mouse. importante aqui é
que esses valores
só são bons para nós se a
tela estiver em tela cheia. Como minha tela
não está em tela cheia, preciso das coordenadas X e Y que
representem a
área branca ao redor da tela. Terei que usar valores de deslocamento
X e deslocamento Y. Em vez disso, essas
propriedades
representam o espaço em branco entre a página da web e a
tela para nos dar a posição correta do mouse
em relação à tela Como usei uma função de
seta aqui, posso acessar domus x de
dentro do callback
e configurá-la para fazer
offset x. Eu faço o mesmo com a coordenada Y vertical que
testei ao
consologar testei ao
consologar Eu passo o mouse sobre a tela e estou obtendo as coordenadas.
7. Como encontrar a distância entre 2 pontos: Agora, a segunda
técnica mais importante que usaremos hoje. Queremos calcular
a distância entre dois pontos
em um espaço de dois D, neste caso, entre o
mouse e a célula. Para fazer isso, precisarei de
D X a distância entre o mouse e esse objeto celular
no eixo x horizontal. Eu terei uma
propriedade auxiliar aqui. Eu chamo de velocidade x
no eixo x horizontal. Se eu fizer slide x plus é igual a dx, teremos Vamos acabar com isso.
Também preciso de D Y, a distância entre
esses dois pontos no eixo y vertical. Para calcular a distância entre esses dois pontos
em um espaço de dois D, preciso calcular um hipoteno Temos esse lado e esse lado. A distância entre esses
dois pontos é o hipoteno, o lado mais longo
do triângulo retângulo O que significa que eu posso usar a fórmula do teorema de
Pitagora, que ficaria
assim em Mas como estamos no ambiente Java
Script, também
podemos usar o método embutido de
hipoteno,
que nos dará
o mesmo valor, a distância entre
o
mouse e Eu digo se a distância
for menor que o valor do raio que definimos
no objeto do mouse Faremos um pouco de física emocional. Criaremos uma variável
auxiliar. Eu chamo, por exemplo, força. Será igual à razão entre
a distância atual
e
o raio, que representa a distância
máxima possível dentro da qual as células
reagirão ao mouse Eu disse velocidade x para forçar
para cada quadro de animação, aumentamos a área de
corte horizontal do slide para cada célula nessa velocidade
horizontal V X. Conforme eu movo o mouse, fica claro que já estamos detectando a distância Eu digo L. Se a
distância for maior, certifique-se de que as células
parem de deslizar A velocidade vertical
também será igual à força. Nós o adicionamos aqui. Eu
defino isso aqui em cima. Vou parar de deslizar
na declaração L novamente. Ok, estamos chegando lá
no carregamento da primeira página, estamos recebendo algum movimento
no canto superior esquerdo
vindo da coordenada 00 Isso ocorre porque
estou configurando o mouse x e y como nulos no início, mas neste caso, o Javascript os
vê como 00 Embora seja melhor
definir manualmente o nulo, nesse caso, tenho que
definir como indefinido Agora,
inicialmente, não há nenhum movimento no canto superior esquerdo que o tenha corrigido. Além disso, quando o mouse
sair da tela, a última posição conhecida do mouse
continuará interagindo. Eu copio esse bloco de código e o transformo em um evento de saída do mouse. Aqui, também
os definiremos como indefinidos. Agora temos animação. Somente quando passamos
o mouse sobre a tela. Estamos fazendo um grande progresso.
8. Como obter direção do ponto A para o ponto B: Agora quero que as fatias da imagem se expandam na direção
correta, diretamente ou
em direção ao mouse. Isso é bastante avançado. Se você nunca usou o
math 82 antes, tive que usar esse método alguns projetos antes de
entendê-lo melhor. Não se preocupe se não estiver totalmente claro depois de
usá-lo uma vez. Se você é iniciante em
animação, pode simplesmente assistir novamente esta parte Ou você pode assistir a
muitos outros tutoriais que fiz onde uso
essa técnica Essa técnica é algo que
um programador criativo usa muito. E ficará claro
quando você começar a usá-lo e brincar com os
valores para ver o que eles fazem. Construído em matemática, o método 8102 nos
dará um
ângulo em radianos Podemos usar esse valor de ângulo para obter um ângulo
entre dois pontos em um espaço de dois D e fazer com que dois objetos se aproximem
ou se afastem um do outro. Nesse caso, os
dois objetos são o cursor do mouse e a célula que contém a
fatia da imagem Já estamos
calculando DX e DY, distância
horizontal e vertical entre o mouse e a célula O método 82 espera que
esses argumentos nos
forneçam o
ângulo direcional entre eles. Ele espera y primeiro
e D x segundo. É importante lembrar que é assim que esse método
incorporado funciona. O método 82 nos dá um ângulo entre dois
pontos, mouse e célula. Nesse caso, ele
retorna o ângulo em radianos entre o eixo x
positivo E um raio de 00
em direção a um certo ponto. Da forma como usamos isso, o
raio vai do objeto um da célula para
X e Y do mouse. Lembre-se de que o mouse pode estar à direita ou à esquerda
da célula, o que significa que podemos obter valores
positivos ou negativos. O intervalo de valores está entre mais pi e menos pi. Usar o mouse primeiro ou o segundo aqui
nesta fórmula resultará em
um conjunto diferente de valores Os valores dos ângulos resultantes
serão organizados de forma diferente, mas na codificação criativa, não
nos
importamos porque, depois de
obtermos a animação, se os objetos se moverem um
em direção ao outro, podemos trocar sua direção
multiplicando os
valores por multiplicando os
valores O que estou dizendo é que podemos
ajustar o código posteriormente para quaisquer valores que o método
e two nos seja fornecido. Eu vou te mostrar para recapitular. Para nossos propósitos, o método
e two considera DY e dx, a distância entre dois pontos no eixo vertical e horizontal Com base nesses dois valores, ele nos dará um ângulo
entre menos pi e mais pi A partir desse ângulo, sabemos em
qual direção queremos
empurrar os objetos para que eles
se aproximem ou se
afastem uns dos outros. O intervalo de valores
entre menos pi e mais pi cobre toda a área
circular Como o círculo completo tem dois pi, 360 graus, isso significa que estamos cobrindo todas as
direções possíveis em um plano de dois D. Eu sei que isso é
muita matemática para iniciantes, não sinta a pressão de
entender tudo isso completamente neste momento. A prática deixará claro que uma vez que você entenda
essa técnica, você pode criar muitos efeitos
muito legais. Vale a pena o esforço. Ok, agora vamos passar esse valor de ângulo resultante
para os métodos de seno e cosseno, que mapearão sua posição
ao longo de uma área circular O seno e o cosseno podem trabalhar
juntos se ambos obtiverem a mesma entrada de ângulo para criar um movimento circular
ou uma emoção ondulatória, dependendo de como os usamos Como o seno e o cosseno convertem esses valores de ângulo entre uma faixa de menos
um a mais um, quase não
veríamos nenhum movimento Com esses pequenos valores, estamos multiplicando esse
pequeno vetor
direcional esses valores de ângulo entre
uma faixa de menos
um a mais um, quase não
veríamos nenhum movimento
. Com esses pequenos valores,
estamos multiplicando esse
pequeno vetor
direcional pela força aumentando seu raio. Sabemos que a força está
diretamente relacionada
à razão entre
a distância atual entre os dois objetos, mouse e célula, e sua distância
máxima possível. Isso adicionará muita
física interessante ao nosso projeto, e o movimento parecerá
suave e natural. Estamos no ponto em que eu
verifico qual movimento recebemos. Depois, vou ajustar os valores para obter
o movimento que desejo. Eu sincronizo a saída de seno e cosseno
trocando-os,
obtemos esse movimento em vez disso obtemos É assim que você pode obter um movimento
circular irradiando para
longe do ponto central Nesse caso, nosso
ponto central é o cursor do mouse. Eu tenho essa declaração L
aqui para fazer a imagem deslizar de volta ao lugar quando
o mouse se afasta. Mas para obter um movimento completamente
suave onde as peças da imagem
deslizam para frente e para trás. Idealmente, tudo deve ser calculado como um valor único. E então aplicamos
esse valor final às propriedades do slide x e do
slide y. Isso nos dará um resultado
muito melhor, mas como fazemos isso?
9. Fórmula de física de movimento (fricção e facilidade): Eu quero ter um
cálculo aqui que seja resultado de
duas forças concorrentes. A primeira parte aqui
é se afastar do mouse se o mouse e a célula estiverem próximos
o suficiente um do outro. A segunda parte
desse cálculo será uma força que desliza as imagens de volta ao
seu lugar original. Como essas duas forças farão parte de
uma única fórmula, evitaremos
qualquer movimento
para frente e para trás porque apenas
um único valor será calculado
aqui no final. Vamos expandir essa
fórmula e explicá-la. A primeira parte é a força que
desloca as peças. E a segunda parte
tentará colocá-los de volta onde estavam
originalmente em suas posições iniciais. Agora eles recuam muito rápido. Lembre-se de que
todo esse método de atualização é executado 60 vezes por
segundo, repetidamente. Recalcular esses valores
para cada quadro de animação. Não quero empurrar o
slide totalmente para trás, mas apenas por uma fração
da diferença entre a posição atual e a posição padrão
original. Eu multipliquei facilitando a criação dessas etapas individuais
intermediárias, assim Eu quero que eles
voltem lentamente para onde estavam. Eu tento valores diferentes e
vejo o que acontece agora. Ao mesmo tempo,
quero que a força de impulso
diminua com o tempo, ficando
gradualmente mais fraca No mundo real da física, chamamos essa força de atrito. Para cada quadro de animação, quero que a força tenha
apenas 80% da potência de impulso. O que significa que ela
ficará cada vez mais fraca e
acabará por dominada pela segunda metade da fórmula que está
trabalhando contra ela, tentando deslizar a célula de volta ao seu
lugar original por uma fração da diferença entre sua posição atual e sua posição original
inicial Eu faço o mesmo com a coordenada y
vertical. Deslizamos a área de corte de cada célula aplicando duas forças
concorrentes nela Essas forças trabalham umas
contra as outras, mas ambas fazem parte
de uma única fórmula. Recebemos um movimento suave. Como resultado, se a
distância entre a célula e o mouse for menor que o valor do
raio que predefinimos, calculamos a força vertical
e horizontal empurrando os slides para
longe do Essa força de pressão é aplicada
aos valores do slide x e do slide Y como a primeira
parte da fórmula. E essa força de impulso diminui para cada
quadro de animação por atrito, a velocidade dessa
decadência pode ser modificada dando a esse atrito Então, estamos aplicando uma força
na direção oposta. Se houver um sinal de mais aqui, precisamos de um sinal de menos aqui E essa
força oposta é uma fração
da diferença
entre as partículas originais e a posição
atual. À medida que a força de pressão
diminui lentamente e a animação é executada, eventualmente esse
lado direito da fórmula
assume o controle e os slides retornam
ao seu lugar original Eu encorajo você a jogar
com todos esses valores. Troque, seno e cosseno, troque mais e menos,
forneça atrito e alivie forneça atrito você também pode aplicar essa fórmula Em vez disso, você também pode aplicar essa fórmula
às células x e y, para obter um efeito completamente
diferente. Depois de realizar seus
próprios experimentos e criar
aleatoriamente efeitos
interessantes e exclusivos, esses cálculos
farão ainda mais sentido Posso comentar os
retângulos que estamos desenhando porque isso
tornará o efeito mais eficiente. Desenhar imagens em
tela é barato, mas desenhar formas é caro. Mesmo retângulos que têm
uma das formas mais simples, o valor que atribuímos
à facilidade definirá rapidez com que as peças se
encaixam novamente O valor que atribuímos ao
atrito definirá a rapidez com que a força de impulso
decai por quadro de animação atrito sempre precisa ser menor que um e
maior que zero Se você der mais de um, a força de pressão
se
acumulará
indefinidamente e a imagem nunca mais
se
remontará Não apenas esses
valores em si, mas também a razão entre esses dois valores
afetará o movimento. Agora, a força de pressão diminui apenas 1.000
por quadro de animação, o que significa que ela permanece
alta por muito tempo O ponto é basicamente
cortar a distância
entre a posição
original base
e a posição atual em várias partes
e movê-la de volta para a
posição original, uma fatia por vez Se esses pontos forem 0,01 nos movemos em direção à posição
original 100% da distância entre a posição
original e a posição atual por quadro de animação Mas, à medida que o impulso força a caixa em 10%
por quadro de animação, isso acabará permitindo que as células
voltem ao lugar certo. Não tenho certeza se minhas
explicações
no final ajudaram ou tornaram
tudo mais confuso A melhor maneira é jogar você mesmo
com os valores, ver qual movimento você obtém e isso começará a fazer sentido. Agora que abordamos
essa técnica, você está pronto para uma
versão mais avançada desse efeito, em
que transformamos cada
pixel da imagem em uma partícula e aplicamos uma fórmula
física semelhante a eles. Também podemos aumentar o número de células que compõem a imagem. Quanto mais células,
maior será o desempenho exigente do efeito. É claro que, no momento, estou pedindo ao Javascript que desenhe 3.500 imagens 60
vezes por segundo e deslize suas áreas de corte calculando a
física do movimento para Ainda funciona bem
no meu computador, mas eu provavelmente não deveria
usar tantas células. Isso apenas mostra como a tela
é boa na renderização de imagens.
10. Movendo as células ao redor: Ok, essa foi a versão da aula
para iniciantes versão da aula
para Estou voltando para lhe dar
alguns experimentos rápidos com fogo. Eu excluo esse console, temos essas quatro
variáveis para mover
a área de corte
dentro de cada célula e deslizá-la Vou criar
mais quatro variáveis. E esses quatro moverão a posição X da célula e a posição Y para a
posição horizontal e vertical de cada célula. E velocidade X e velocidade
Y para seu movimento. velocidade, o slide X e o slide Y são aplicados aqui à fonte
X e à fonte Y. Os argumentos passados para o método de
desenho de imagem determinam a posição
do corte na área Estamos deslizando essa safra
na área usando VX e VY. Agora eu tomo a posição X e a
posição Y como um conjunto separado de variáveis e as aplico aos argumentos de
destino X e destino Y. Esta área será para
os efeitos da colheita, esta área será para
as posições e movimentos das células. Eles funcionarão bem juntos. Se fizermos isso, bem,
vamos ver no que acontece. A velocidade X será a posição
final do alvo menos a posição inicial Faremos a flexibilização novamente. Vamos dividir essa
jornada em dez partes. E moveremos a célula
em direção à sua posição
alvo um décimo da distância
por quadro de animação velocidade Y também é a posição
alvo menos a posição inicial dividida
por alguma facilidade no valor Agora eu posso pegar esses valores e aplicá-los na posição
X e na posição Y, já que estamos usando
aqueles aqui dentro da imagem de
desenho como destino
X e destino Y. Isso realmente moverá
as próprias células dessa forma Todos eles se movem ao mesmo tempo, então ele se expande assim. Podemos tornar isso muito mais interessante de muitas maneiras
diferentes. Deixe-me mostrar alguns deles. Por exemplo, cada célula terá um valor aleatório de
2 a 12. E atenuaremos
cada célula com sua própria facilidade aleatória, no valor 2,52, podemos alterar as As células sairão
de pontos diferentes, cantos
diferentes da tela, por exemplo,
dependendo do que fizermos aqui. Canto inferior direito, meio
inferior. Bom, eu te disse, vamos
tornar isso mais interessante. Observe que as
imagens ainda reagem ao mouse deslizando
a área de corte
11. Otimizações de desempenho: Também posso acariciá-los, mas preciso usar a posição
X e a posição Y aqui. Sim, isso é muito legal. Acariciar esses retângulos
afeta o desempenho. Vamos reduzir o
número de células aqui. Isso ainda parece ótimo, você
não acha? Vamos tentar encontrar
um bom tamanho de célula. O único problema é que esse bloco de código
é executado o tempo todo. Quero economizar um pouco de
desempenho e parar de calcular esses
pequenos valores de pix As células estão próximas o suficiente de suas
posições de destino originais no ponto que a imagem
foi montada ou, pelo menos, quase
montada perto o suficiente. Eu digo somente se a velocidade
x for maior que 0,1 ou a velocidade Y for maior que 0,1
Só então mova-os. Caso contrário, presumimos que eles
já montaram a imagem. Esses cálculos não
são necessários. Agora, não temos nenhuma
velocidade x e velocidade Y. Precisamos configurá-las quando
a célula for criada Vamos dar a cada célula um método de início
personalizado. Aqui vamos definir as velocidades. Chamaremos automaticamente esse método de início a
partir do construtor O problema é que as células podem estar
à esquerda ou à direita. As velocidades podem ser
negativas ou positivas. Basicamente, quero
executar esse código somente quando as velocidades forem
menores que -0,1 e maiores que
mais 0,1 , o que
significa que as células estão
longe o suficiente de suas posições de
destino e eu quero que elas se movam Vamos apenas remover o sinal negativo. Ao envolvê-los
no método absoluto, assim, ele retornará
o número absoluto Ok, esse bloco de código está
movendo cada célula de sua posição inicial
para sua posição de destino. Quando as células estão próximas o suficiente e a imagem é
montada, não
executamos
mais esse bloco de código para garantir o desempenho.
12. Experimentos de codificação criativa: Quero testar se
esse bloco de código realmente para de ser executado. Estávamos passando o
valor do índice das células do para cada loop. Aqui, quero que cada célula tenha um valor de índice exclusivo que aumente em um para
cada nova célula que criamos. Eu passo esse valor para o construtor da classe de
célula. Como quarto argumento, garanto que seja esperado aqui e seja convertido em
uma propriedade de classe. Vou consolar o índice
de cada célula aqui. Quero ter certeza de que
todos eles parem de executar esse cálculo
em algum momento, quando as células estiverem próximas o suficiente suas posições de destino e
a imagem tiver sido montada O limite de quão
perto queremos que elas estejam pode ser alterado aqui e aqui. Sim, podemos ver todos os índices
pararem de ser bloqueados em algum momento Um console como esse
atrasará seu projeto. Precisamos ter certeza de
removê-lo quando não precisarmos dele. Nós podemos fazer muitas outras coisas. Cada célula tem um valor de índice
exclusivo. Chamamos o método start automaticamente quando
criamos cada célula. Também poderíamos atrasá-los
definindo o tempo limite. Aqui, passamos a função de
retorno de chamada. Quanto tempo devo esperar
antes que isso aconteça? Não quero atrasar todos
eles em 500 milissegundos. Cada um será atrasado
por seu próprio valor de índice. retorno de chamada executará
o método start e isso nos dará um erro O motivo é essa palavra-chave, ela se torna indefinida no
escopo dessa chamada de retorno Já enfrentamos esse
problema com retornos de chamada e essa palavra-chave aqui,
dentro dos ouvintes de eventos Sabemos que existe uma solução
simples porque as funções de
seta herdam
isso do escopo principal Transformamos a chamada de
volta em uma função de seta
e, vamos lá,
temos um atraso personalizado. Podemos aumentar esse atraso
multiplicando o índice aqui, a área de corte das células
ainda Enquanto todas essas
coisas estão acontecendo, ótimo, agora eu posso mudar as
posições iniciais aqui para obter um conjunto de diferentes efeitos
interessantes. Que tal no meio? Em vez de empurrar as
células para dentro da matriz, eu as desdeslocarei, preencherei a matriz
de células pela outra extremidade, e isso
resultará nas células vindo da parte de trás
da imagem desta forma Se você estiver enfrentando problemas de
desempenho, recomendo remover o carvão retangular de
traçado da linha 32 ou você
pode desenhar menos células Ao ajustar a célula com propriedades de altura da
célula
no vidro de efeito, podemos fazer com que elas venham
da parte superior central. Assim. Também podemos randomizar seu X inicial e
obter um efeito diferente Que tal X aleatório e Y inferior? Também podemos limpar a tinta
antiga entre cada quadro de animação para
obter um efeito como esse. Que tal X aleatório e Y0x
aleatório e Y negativo X
aleatório e Y0x aleatório
e Todos eles se movem com uma facilidade
consistente. Então, posso obter padrões mais
organizados ajustando esses dois valores Eu te dei muitos outros
valores que você pode ajustar. Agora é hora de
você pegar o que
aprendemos e criar
sua própria combinação exclusiva. Temos um controle completo e entendemos como
esse código funciona. Se você não tiver certeza
de alguns deles, brinque com os valores
e observe o que acontece Começará a fazer mais sentido. Eventualmente, podemos levar
isso a um nível totalmente novo. Ao transformar cada célula em apenas um
pequeno pixel na imagem, podemos ter imagens
feitas de muitas outras peças. Transforme imagens em efeitos de
partículas e até chuva de partículas ou fogo de
partículas, Se você estiver pronto para levar suas
imagens para o próximo nível, nos vemos na próxima parte.
13. Volume 106 intro menor: O Javascript é uma ferramenta poderosa. Vamos explorar os segredos das
técnicas de desenho e animação no desenvolvimento
web de front-end
moderno. Nesta aula,
começaremos desenhando um retângulo e uma
imagem simples em telas HTML Vamos descobrir como transformar esses retângulos em
um sistema de partículas. Será um sistema de
partículas inteligente que pode recriar e lembrar
formas com base em dados de pixels A partir de qualquer imagem,
mostrarei como fornecer física a cada partícula,
como atrito e atenuação, e adicionaremos algumas interações
do mouse nas quais podemos dividir
a imagem em pixels
individuais e ela
se recompõe
automaticamente se recompõe
automaticamente Junte-se a mim e vamos
aprender como transformar imagens em obras de arte
digitais interativas
14. Aula 1: Começamos criando
três arquivos, índice HTML, estilo
CSS e script GS. Eu abro o índice HTML. No meu navegador da Internet, usarei o Google Chrome. Dentro do índice HTML, eu crio
uma marcação básica de página da web. Estou usando o
editor de código do Visual Studio com a extensão met, então posso simplesmente pressionar o ponto de
exclamação e a
tecla tab e obter um clichê básico de
página da web Este vídeo é uma introdução à
tela HTML. Mas espero que você saiba
algumas noções básicas de Java Script. Dê um título à minha página da web. Por exemplo, incríveis efeitos de
Javascript. Eu vinculo minha estase a
um arquivo como este. Eu crio o elemento HTML de cinco
telas com uma ideia de tela um. elemento de tela HTML é usado para desenhar gráficos
em uma página da web. Podemos desenhar formas estáticas, bem
como animações
interativas dinâmicas que reagem à entrada do usuário, que é o que faremos hoje O elemento de tela é um
recipiente para nossas obras de arte, é nosso quadro de arte Podemos usar Javascript
para desenhar formas, linhas, texto ou imagens nele. Pode parecer muito básico, mas depois de entender
como a tela funciona, você pode fazer uma
variedade infinita de arte digital, jogos
interativos
e gráficos para a web. Neste curso, exploraremos o que pode ser feito com imagens e passaremos do básico a alguns efeitos
avançados muito legais Espero criar um elemento diff
com uma classe de controles
e, dentro, teremos
um botão com uma ideia do botão Warp e um texto
que diz Quando clicamos nele, ele
divide a imagem em partículas
individuais
e a imagem se recompõe novamente. Automaticamente,
poderemos controlar a velocidade e
o peso
das partículas à medida que elas se movem. Este projeto também
conterá cerca de duas físicas D. Não se preocupe, não é tão
complicado se você seguir passo a passo comigo
enquanto escrevemos o código. Também vincularemos o
arquivo de script G aqui embaixo. Para vincular nossa
lógica de script Java no StysSSS, começo com a
redefinição global para garantir que nossa página apareça da mesma forma
em todos os navegadores diferentes Eu uso o seletor de asterisco para segmentar todos os
elementos na página e defino a margem como zero E preenchendo até zero tela
com um ID de tela, uma terá
um fundo azul Isso é apenas temporário
para que eu possa ver onde ele está na página quando eu
o estiver
posicionando com uma classe de controles configurada
para a posição absoluta. Isso o removerá
do fluxo de documentos
e o colocará sobre
o elemento de tela. Precisamos garantir que
os botões que ele conterá não
estejam cobertos por nada
e sejam sempre clicáveis Então eu defini seu índice z para 100, colocando-o
no topo , na frente de todos os
outros elementos.
15. Aula 2: Eu volto para indexar o HTML e
crio um elemento de imagem. Eu dou a ele um ID da imagem com
a fonte da imagem. Teremos que fazer
um pequeno truque. Eu tenho meus arquivos de imagem
prontos no meu desktop. É apenas uma imagem normal no formato
PNG com fundo
transparente. Se eu simplesmente colocar essa imagem
na pasta do meu projeto e apontar o
atributo fonte da imagem para ela como
faríamos normalmente, poderemos desenhar
essa imagem na tela, mas não poderemos
analisá-la em busca dados de
pixels e
dividi-la em partículas. Se tentarmos fazer isso,
obteremos um erro que
diz que a tela foi contaminada
por dados de origem cruzada Esse erro só deve ocorrer quando você executa seu código localmente. Depois de carregar
o projeto em um servidor on-line, o arquivo PNG na fonte será considerado
da mesma origem. Mas queremos que esse projeto
funcione o tempo todo. Não queremos
acionar nenhum erro mesmo quando trabalhamos
localmente dessa forma. Para ignorar o aviso de
tela contaminada, converteremos a própria
imagem em código. Atribuímos esse código
como fonte aqui. E dessa forma, a imagem em si fará parte do arquivo HTML de índice. Portanto, será considerada mesma origem em todas as
circunstâncias A maioria das pessoas não sabe que
as imagens na web podem ser divididas em uma única linha de código
muito longa. Chamamos isso de string de base 64. Essa linha de código contém
todos os dados da imagem. Substituindo completamente o arquivo
PNG que temos aqui. Posso converter minha imagem no formato
base 64
desenhando a imagem na
tela e, em seguida, chamando o método de URL de
dois dados incorporados no elemento da tela, transformando a tela inteira com imagem desenhada
nela em uma tela de dados. Hoje, usaremos uma opção
ainda mais simples para fazer isso e
usaremos um dos muitos sites
disponíveis que farão isso rapidamente para nós Abro outra janela
do navegador e pesquiso no Google a frase PNG two base 64. Eu seleciono o primeiro
link do Png
tools.com online . Se você quiser usar
as mesmas imagens que eu estou usando, você pode baixá-las na descrição do
vídeo. As imagens são inimigos do tutorial do
jogo Steampunk Fish tutorial do
jogo Eu posso simplesmente pegar a
imagem e arrastá-la e soltá-la aqui no lado
direito. Ele gera código base
64 para mim. Para que o código funcione,
preciso garantir que
a string comece com
a imagem de dois pontos de dados, PNG base 64, assim Se não começar
assim para você, certifique-se de marcar esta caixa de seleção Pegamos um arquivo de imagem PNG e
convertemos a imagem inteira
em uma linha de código. Essa string agora contém todas as posições de pixels
e valores de cores, substituindo
completamente
o próprio arquivo de imagem. Qualquer navegador da Internet
pode entender essa string e desenhar
a imagem a partir dela. Você quer aprender a usar o outro método e
gerar essa string dinamicamente com
Javascript sem usar um site externo Eu faço isso em meu outro curso, onde geramos formas fractais
complexas
e as transformamos em flocos de neve
caindo Eu destaco essa string muito longa de base 64 e a
copio no índice HTML. Eu coloco meu cursor do mouse
entre as aspas no atributo
SRC e colo
tudo isso dentro Se eu salvar as alterações em que
estamos desenhando a imagem, você pode ver que a string base 64
contém a imagem inteira. Não há necessidade do arquivo PNG real. Dessa forma, podemos
manipulá-lo com Javascript da maneira que quisermos Você pode clicar em Exibir quebra de palavras para
alternar entre uma visualização em
que ela quebra linhas como essa, podemos ver todo o código E outra visão em que tudo está em
uma linha como essa, você pode ver
que há muito código. Anos atrás, lancei uma
versão simples desse algoritmo. E só funcionaria
com imagens pequenas, 100 vezes 100 pixels. Qualquer coisa maior do que isso
se tornaria muito lenta e lenta Essa versão funciona até mesmo com imagens
maiores porque
controlaremos quantas partículas a imagem quebra com o script Java. Essa base de código tem muitas
melhorias e otimizações. Você verá que
quanto maior a imagem usada, mais longa será
a
string de base 64. Em vez de apontar a
fonte da imagem diretamente para um arquivo PNG, convertemos nossa imagem
Angular Fish em uma string de base 64. Isso nos permitirá
analisar a imagem em busca dados de
pixels e fazer todos os tipos de efeitos e
animações
interessantes nela sem precisar lidar com
erros de origem cruzada Eu realmente não quero desenhar o elemento de imagem
na minha página da web. Quero desenhar essa imagem
no meu elemento de tela azul. Vou pegar a etiqueta IMG e
mostrá-la,
nenhuma, a imagem está oculta Mas ainda podemos acessá-lo com Java Script para desenhá-lo na
tela quando precisarmos. Ainda está
aqui no índice HTML.
16. Aula 3: No script GS, eu crio um ouvinte de
eventos para o evento de carregamento. Todo o código deste
projeto será escrito dentro desse ouvinte de
eventos evento de carregamento garantirá
que todo o site, incluindo todos os recursos
dependentes como folhas de estilo e imagens, esteja totalmente carregado e disponível antes de executarmos qualquer código
Javascript. Ao trabalhar com código
Javascript que depende de uma imagem, é um erro comum que aconteceu comigo muitas
vezes: eu não
esperei que a imagem fosse carregada e estava recebendo uma tela em branco. O código Javascript é
executado muito rapidamente. As imagens podem levar
mais alguns milissegundos para serem carregadas. Não podemos perceber essa
diferença a olho nu, mas se o código Javascript for executado
antes do carregamento da imagem, obteremos o
carregamento da tela em branco. O ouvinte de eventos é uma das maneiras de
lidar com esse atraso Começamos com uma
simples configuração de tela. Eu crio uma variável constante. Eu chamo, por exemplo, de tela. E eu apontei para o elemento de tela HTML que
criamos no arquivo HTML de índice. Ao usar get element by ID, atribuímos a ele um ID de canvas one. Como essa variável, eu chamo de CTX. atalho para contexto é essa variável de tela da
linha dois get context O contexto é um método especial
que só pode ser chamado em uma variável que contém
uma referência ao HTML. get
context de cinco elementos de tela método get
context de cinco elementos de tela
espera um argumento, chamamos de tipo de contexto, podemos passar dois D ou web GL. Hoje, trabalharemos
com dois D quando chamados dessa forma. O
método get context criará uma instância de um objeto chamado canvas Rendering Context
two D. Esse objeto contém todas as
configurações de tela e todos os métodos de desenho
em tela incorporados que
precisaremos hoje Eu posso consoloc CTX
para dar uma olhada nele .
Eu posso ver isso aqui. Se o abrirmos, podemos ver todas as configurações padrão da tela, o chamado estado da tela. Você pode ver, por exemplo, que o estilo de preenchimento padrão
está definido como bloco aqui, a fonte
padrão é dez pixels, san serif, essa largura de
linha padrão é um pixel Podemos substituir qualquer uma dessas
configurações atribuindo-as a um valor diferente
com o script Java, e faremos isso Se eu clicar no protótipo
aqui e expandi-lo, podemos ver tudo
construído em dois métodos D. Podemos usar esses métodos para desenhar retângulos, círculos e linhas Podemos criar gradientes
e manipular imagens. Hoje, abordaremos
os básicos e nos
aprofundaremos no método de desenho de imagem
que está aqui. Também
mostrarei como analisar uma imagem pixel por
pixel e usá-la para uma
mágica de animação interessante com o método get image data,
que vem daqui. Vamos excluir o consoloc e
fechar o console do navegador. Eu pego a variável de tela da linha dois e acesso sua propriedade de
largura. Eu o configurei para a largura da janela
para fazer com que a tela cubra toda a janela
do navegador horizontalmente Eu também faço a mesma
coisa com
a altura para que ela cubra a
tela verticalmente
17. Aula 4: Hoje eu quero mostrar a vocês como
criar o chamado sistema de
partículas De um modo geral, o sistema de
partículas é uma coleção
de pequenos objetos Cada partícula é um pequeno elemento
gráfico. Pode ser uma imagem ou uma forma. Podemos programar essas partículas
para que pareçam e se comportem uma certa maneira para simular todos os tipos
diferentes de efeitos Pode ser fogo,
bolas quicando, enxames de inimigos em um
jogo ou muitas outras coisas Hoje, transformaremos cada
partícula em um pixel em nossa imagem e
as dividiremos em pedaços individuais Ao mesmo tempo, essas
partículas reagirão ao mouse de
uma forma dinâmica agradável, envolvendo
física e atrito. Para criar todas essas partículas, usaremos uma classe
Javascript personalizada. Eu a chamo, por exemplo, partícula como essa
com P maiúsculo. As classes
Javascript
são plantas para criar muitos objetos semelhantes Javascript é uma linguagem
baseada em protótipos. Cada objeto Javascript tem uma propriedade interna
chamada prototype que pode ser usada para estender
propriedades e métodos do objeto As classes em Javascript são
chamadas de açúcar sintático. É uma sintaxe mais limpa e
elegante construída sobre herança
nativa
baseada em protótipos de Javascript que imita classes Simplificando, a aula
é um modelo. Toda vez que chamamos
essa classe de partículas, ela cria um novo objeto de
partícula para Também teremos uma aula que
chamarei de Effect. Essa classe manipulará todo
o efeito, todas as partículas de uma só vez. A última peça
que precisaremos aqui é classe
Animation Loop Particle como um modelo para criar objetos de partículas
individuais, classe de
efeito para lidar com todas as
partículas ao mesmo tempo E loop de animação Para tornar
tudo animado e interativo, darei meu método construtor de
classes de partículas Esse é um
método especial quando eu chamo minha classe de partículas posteriormente com o novo
construtor de palavras-chave que executa todo o código dentro dela para
criar um novo objeto em branco e atribuir valores e
propriedades a ele com base
no blueprint Vamos definir esse plano. Vamos definir as propriedades
de nossas partículas. Cada partícula será um
pedaço de uma imagem, um pixel. Ele precisará se sentar em uma posição muito específica e todas as partículas combinadas
formarão a imagem inteira. Isso significa que ele precisará das
coordenadas x e y para que o script
Java saiba onde
desenhá-lo na tela HTML, mesma forma que no
desenvolvimento web em geral. Temos o
eixo x horizontal partindo de zero pixels à esquerda e
aumentando à medida que nos movemos para a direita. Também temos um eixo
Y vertical começando com zero
pixels no topo e
aumentando à medida que descemos. Por exemplo, a posição 5.100
na tela estará aqui a 50 pixels da esquerda
no eixo x e a 100 pixels da
parte superior no eixo y. Inicialmente, definirei duas coordenadas x
e y, 00 para o
canto superior esquerdo da tela. Quando definimos propriedades
na classe Java, dizemos isso x, que significa propriedade x. Nesta instância da classe de partículas que o
construtor está criando, agora nossas partículas serão retângulos porque o
Canvas é mais rápido
em desenhar retângulos
em vez em desenhar retângulos
em Na versão anterior
desse efeito, usei círculos. Desta vez, poderemos
extrair mais partículas de forma eficiente. O tamanho de cada retângulo de partícula será três vezes
três pixels
18. Aula 5: Para desenhar um retângulo na tela, tudo o que precisamos fazer é pegar variável
CTX da linha três
que contém uma instância da API de junção D da tela dois e
chamamos o método de
retângulo phil integrado Ele espera quatro argumentos x e y nas posições
onde desenhá-lo
e, com a altura
do retângulo, ele preencherá
esse retângulo com cores Se não definirmos o estilo de preenchimento, sabemos que o estilo padrão
no elemento de tela é preto. Aqui está nosso
retângulo preto desenhado 120 pixels da esquerda no eixo x e 150 pixels
da parte superior no eixo y, 100 pixels de largura e
200 pixels de altura Se este for seu primeiro projeto de
tela, talvez
você deva postar
o vídeo e alterar esses valores para
entender como os retângulos,
assim como as imagens na tela, são desenhados a partir das
coordenadas que fornecemos E eles vão para a direita
e para baixo a partir desse ponto, dependendo de sua
largura e altura. Também podemos desenhar círculos, curvas ou linhas e criar
diferentes formas e animações Com eles, você pode desenhar
praticamente qualquer coisa. Depois de saber como a tela funciona, se você estiver interessado em arte
que pode ser feita com linhas, confira minha aula sobre fractais Hoje vamos nos
aprofundar nas imagens. Vamos trazer nossa imagem angular de peixe para o projeto e
desenhá-la na tela.
19. Aula 6: Eu crio uma variável constante, eu chamo de imagem um. Eu apontei para
o elemento de imagem usando sua imagem de identificação, que eu dei aqui. Agora posso pegar a variável CTX da linha dois que,
como dissemos, contém todas as propriedades
e métodos
de tela chamo de método de desenho de
imagem incorporado, como este, método de
desenho de imagem espera pelo
menos três argumentos A imagem que queremos desenhar e as coordenadas x e y.
Onde desenhá-lo? Eu passo a imagem um da linha
sete e quero desenhar a imagem
do canto
superior esquerdo da tela a partir
das coordenadas 00. Eu dou a posição de x 100. Empurramos a imagem em 100
pixels para a direita. Se eu passar 100 pixels
como coordenada y vertical, empurro a imagem
100 pixels para baixo. Também posso passar argumentos opcionais
com e altura. Se não passarmos
com e altura, o Javascript apenas desenhará a
imagem em seu tamanho original. Se eu passar a largura de 100 pixels e a altura
de 100 pixels, comprimiremos a imagem
em uma área de 100 vezes 100 pixels
e a distorceremos Eu posso esticar e apertar
a imagem assim, o que pode ser útil
para certos efeitos Se esta é a primeira vez que você
usa o método de desenho de imagem, você pode postar o
vídeo e passar valores
diferentes
para x Y com e altura para que você
possa ver como isso afeta a posição
e o tamanho da imagem.
20. Aula 7: Agora sabemos como
montar um projeto Htimlcnvas. Sabemos como usar o método de preenchimento de
retângulo para desenhar um retângulo simples
e como usar um método de desenho de imagem para
desenhar uma imagem na tela Vamos usar nossa
classe de partículas para desenhar algo. Eu excluo esse código.
Digamos que eu queira que cada partícula seja um
quadrado preto de 30 vezes 30 pixels Eu dou à minha
classe de partículas um método personalizado. Eu chamo, por exemplo, de desenhar. Seu trabalho será
pegar propriedades do construtor de classes e desenhar partículas desse tamanho nessas
coordenadas Vamos começar de forma simples e
depois refatorá-la para empregar boas práticas de programação orientada a
objetos Novamente, para desenhar algo, eu pego a variável CTX
da linha três A partir disso, chamo o método
Phil Rectangle integrado. Já aprendemos que Phil Rectangle espera
quatro argumentos x, y, largura e altura Esse script Java
sabe onde desenhar esse retângulo e qual
tamanho ele deve ter Eu passo esse x da linha 11. Este ponto y da linha 12 tem
coordenadas x e y. Eu passo o
tamanho didot da linha 13. Assim como acontece com a mesma propriedade de tamanho de
disdote altura
, como esta Definimos nossa classe de partículas. Temos uma planta com
todas as propriedades. E temos um
método de desenho em que pegamos essas propriedades e
as usamos para desenhar um retângulo Como realmente
executamos esse código? Para desenhá-la, precisamos criar
uma instância dessa classe. Eu crio uma variável constante, eu chamo de partícula um Eu a defini igual a uma nova
partícula como essa. A nova palavra-chave é um
comando especial em Java script. Ele procurará uma
classe com esse nome. Ele encontrará essa
classe aqui na linha nove e
acionará automaticamente seu construtor O construtor de métodos criará um novo objeto em branco
e atribuirá propriedades a
ele com base
no blueprint interno Como esse objeto de partícula 1 foi criado usando
essa classe de partículas, ele tem acesso ao método de desenho
que definimos na linha 15 Podemos simplesmente chamá-lo
assim, desenho de partícula 1. Agradável. Estamos usando nossa classe para criar e desenhar uma partícula. Eu posso ajustar suas
posições X e Y aqui para movê-la. Também posso mudar seu tamanho.
21. Aula 8: Se eu quiser criar
mais de uma partícula, posso simplesmente repetir esse código e criar variáveis
para a partícula dois, partícula três e assim por diante, mas isso não
seria Nosso código deve estar seco, que é um acrônimo para
não se repita Também estamos tentando
manter tudo na estrutura de
código orientada a objetos. Podemos usar essa
classe de efeito que definimos na linha 20 para criar e lidar com
várias partículas. As partículas manipularão partículas
individuais. classe de efeito manipulará todo
o efeito, todas as partículas de uma só vez. Eu lhe dou um
construtor desta vez. O construtor
espera que dois argumentos para largura e altura
venham de fora Isso garantirá que
o efeito esteja ciente das
dimensões atuais
da tela. Dentro I, converto esses argumentos
em propriedades de classe. Estou dizendo pegar a
largura que foi passada como o primeiro argumento para o construtor
da classe e
convertê-la na propriedade de largura Nesta instância específica da classe
de efeito que você está criando
agora, o mesmo para a altura. Também teremos a propriedade de matriz de
partículas. Inicialmente, eu o
configurei como uma matriz vazia, que conterá todos os objetos de partículas atualmente
ativos criados pela classe de partículas A partir da linha nove,
darei à minha classe de efeito
um método personalizado que chamo, por exemplo, nele, seu trabalho será inicializar o efeito e preencher a
matriz de partículas da linha 24 com muitos objetos de partículas Vamos começar com
apenas uma partícula. Eu pego essa matriz de partículas e chamo o método
push embutido nela. O método push adiciona um ou mais elementos
ao final da matriz. Eu quero empurrar uma partícula para dentro, então eu passo uma nova
partícula como esta A nova palavra-chave
saltará para a linha nove e acionará o construtor da classe de
partículas criando um novo objeto de partícula com base nesse projeto.
Eu excluo esse código. Desenharemos formas de
dentro da nossa classe de efeitos. Agora, para desenhar essa
partícula que mantemos dentro da matriz de partículas,
eu crio o método de desenho Esse método pegará a matriz de
partículas da linha 24 e solicitará cada método de matriz
incorporado nela. O método for each executa uma função fornecida uma vez
para cada elemento da matriz Vou usar o
ES six moderno no imposto aqui. Isso é chamado de função de
seta. Agora, a matriz de partículas
contém apenas uma partícula, mas também pode conter muitas Estou dizendo que pegue essa matriz de
partículas e chame cada uma dela. Atribua a cada objeto na matriz uma partícula temporária de
nome de variável em cada uma delas, chame o método de desenho
associado A partir da linha 15, temos a classe de
efeito com método
init para preencher a matriz de
partículas com objetos de partículas e o
método draw para desenhar todos eles Esse método de desenho na linha 29 desenha todas as partículas, todo
o efeito. Esse outro método de desenho na linha 15 especifica a aparência de
cada partícula No nosso caso, decidimos
desenhá-los como simples retângulos pretos Por enquanto, para desenhar as partículas, agora eu crio uma variável
constante. Eu chamo o efeito e o defino uma instância da minha classe de
efeito como esta. Na linha 21, posso ver que construtor espera argumentos
para largura e altura Eu passo a largura da tela da linha quatro e a
altura da tela da linha cinco. Vamos consolar essa
variável de efeito para verificar se
tudo funciona até agora Agradável. Eu posso ver meu
objeto de efeito e ele tem propriedades de largura e
altura e também uma matriz de
partículas que
está vazia no momento. Eu pego minha variável de efeito e chamo de método da
linha 26 assim. Esse método deve empurrar
uma partícula para lá. Eu verifico no console, sim, temos um objeto de partícula dentro e posso ver que ele tem propriedades x, y e tamanho,
todas com valores corretos Se você ver indefinido
em alguns deles, significa
que há um erro em
algum lugar do seu código É bom verificar periodicamente
, ao escrever seu código,
se todas as suas propriedades
têm valores, especialmente se você encontrar
alguns problemas ou erros ao programar. O consoloc
está aqui para Agora eu posso tomar a
variável de efeito novamente e chamo o
método draw da linha 29. Eu também excluo o consoloc. Ótimo, estamos desenhando uma partícula usando nossa
nova estrutura de código Eu posso mover a partícula
alterando esses valores.
22. Aula 9: Estamos fazendo algo ruim. Aqui estamos puxando a variável CTX da linha três
diretamente para nossa classe Queremos que nossas classes e
objetos sejam modulares, independentes o
máximo possível e independentes do
código circundante, do ambiente léxico Em vez de puxar o
CTX diretamente, vou convertê-lo em uma
variável e transmiti-lo Vou me certificar de que o método de desenho na classe de
partículas espere o
contexto como argumento Em seguida, usarei essa variável de
contexto aqui para chamar o método do
retângulo phil a partir dela Vou passar a variável tx da linha três como
argumento para o método draw. Quando a chamamos na classe de
efeito na linha 36, damos a ela um contexto de
nome de variável aqui, assim. Passamos essa referência
para desenhar o método na classe de
partículas Essa referência
será passada aqui. A partir daí, chamamos
Phil Rectangle. Fazer isso dessa forma
garantirá que nosso código seja modular. É considerada uma boa prática e não a que tínhamos antes.
23. Aula 10: Também podemos randomizar as posições
das partículas. Em vez de codificar
as coordenadas, posso definir a posição
x horizontal como um número aleatório entre
zero e o peso da tela posição Y vertical pode ser um valor entre zero
e a altura da tela. Agora, toda vez que eu
atualizo minha página, partícula estará em uma posição aleatória
diferente algum lugar da tela Eu também poderia randomizar
o tamanho, se eu quiser. Dentro desse método, eu crio duas partículas
copiando essa linha. Bom, agora temos duas partículas à medida que as criamos
usando a nova palavra-chave. Toda vez que o construtor
for executado na linha dez, ele atribuirá
posições x e y
aleatórias diferentes a cada uma Também posso criar três
partículas como essa, mesma forma que fizemos
com a variável CTX Aqui, estamos inserindo
a largura e altura da
tela diretamente
em nossa classe, o que torna essa classe
dependente do código circundante Já estamos convertendo a largura e a altura da tela de
duas propriedades de classe na classe de
efeito aqui, passando-as para o
construtor da classe de efeito na linha 36 Vamos remover essas
duas partículas para garantir que cada partícula esteja ciente do tamanho atual da
tela Eu me certifico de que o construtor da
classe de partículas espere uma referência para toda
a classe de efeito, tudo como um
argumento interno Eu converto essa referência uma propriedade de classe chamada
efeito de ponto Lembre-se de que os objetos no script
Java são chamados de tipos de dados de
referência. que significa que, ao
passar uma referência todo
o objeto de efeito
para esse objeto de partícula, não
estou criando uma cópia da classe de efeito toda vez que
crio uma nova partícula Esse efeito de ponto não é uma cópia, é apenas uma referência
apontando para um espaço na memória onde a classe de
efeito principal está armazenada. Tem muitas vantagens. A principal delas é que, quando
atualizamos quaisquer valores
na classe de efeito, essas alterações serão
imediatamente visíveis a partir dessa propriedade de efeito de ponto
em objetos de partículas Agora, esse efeito de ponto aponta para
toda essa classe de efeito, e podemos acessar qualquer propriedade nela de dentro da classe de
partículas Por causa disso, posso substituir a largura da
tela pela largura do ponto com
efeito dist, referenciando o
valor da linha 23 Como sabemos, esse valor
representa a largura da tela. Também podemos fazer isso
aqui na linha 13 e usar a altura do ponto com efeito distal, um valor proveniente da linha 24 Se você é iniciante,
transmitir valores como
esses pode levar algum tempo para ser totalmente compreendido Não se preocupe demais. Se estiver com dificuldades,
você se tornará bom
nisso ao escrever mais códigos orientados a
objetos. Agora que sabemos que a classe de
partículas espera um argumento apontando para
a classe de efeito principal Aqui na linha 28, onde eu crio uma instância
da classe de partículas, eu passo o efeito como um argumento, uma referência a tudo
isso, a toda essa classe No entanto, como estamos
dentro dessa classe de efeito, preciso usar essa
palavra-chave em vez disso. Essa palavra-chave usada dentro dessa classe representa
a classe inteira em si. Quando eu atualizo a página, tenho uma partícula
sendo
gerada aleatoriamente e desenhada
em algum lugar Agradável. Estamos passando a largura da
tela para a classe de
efeito na linha 35, convertendo-a nessa propriedade de
largura pensada na linha 23 e usando esse valor na linha 12 para calcular a posição da
partícula Também estamos fazendo
o mesmo com a altura. Agora eu posso copiar essa linha novamente
para criar muitas partículas. Mas e se eu quiser
100 partículas? Copiar essa linha de código se
tornaria impraticável. Esse é um cenário perfeito
para usar quatro loops. Eu excluo todo esse código
e, em vez disso, vou
agrupá-lo em quatro loops. Assim.
O índice começará em zero, desde que o índice
seja menor que dez, aumente o índice em um
e crie uma partícula Esses quatro ciclos serão executados dez vezes e criarão dez partículas. Quatro loops são ótimos para
nos ajudar a reduzir a repetição de código.
24. Aula 11: Vamos também desenhar uma imagem. Mas porque eu não quero
puxar essa imagem uma variável de fora para minhas
classes Deixe-me transformá-lo em uma propriedade de classe na classe de
efeito como esta. Vou chamá-lo de imagem de Did. Podemos desenhá-lo pegando contexto e chamando
desenhar imagem nele. Eu passo a imagem de pontos da linha 24.00 para as coordenadas x e y. Estamos desenhando nossos
peixes na tela novamente. Mas desta vez
estamos fazendo isso a partir de uma base de código independente
orientada a objetos.
25. Aula 12: As imagens na tela são desenhadas
do canto superior esquerdo, indo para a direita e para baixo. Deixe-me mostrar como centralizar uma imagem exatamente
no meio da tela Vou criar uma
variável auxiliar chamada centro x. Será essa
largura de ponto da linha 21 Portanto, a largura da tela vezes 0,5 no meio da tela
na horizontal, centro do
ponto Y é a
altura do ponto da linha
22 vezes 0,5 do meio
da tela na Posso usar essas novas
propriedades como coordenadas x e y passadas
para o método de desenho de imagem. Agora, a imagem é desenhada
a partir do ponto na tela que
está exatamente no meio. No entanto, a imagem não
está centralizada. A imagem pontilhada é uma referência ao elemento
IMG que criamos
no índice HTML Deixe-me consologar
Este elemento de imagem gerou propriedades de
largura e altura automaticamente Se eu consolog a
largura da imagem com pontos, você pode vê-la. Diz que a altura do ponto da imagem com
pontos de 500 pixels é 369 pixels. Agora que sabemos disso,
podemos excluir o consoloc. E podemos usar a largura e a
altura da imagem para deslocar a posição pela metade da largura da imagem
e metade da altura da imagem Para centralizá-la, eu crio uma propriedade chamada ponto
x na classe de efeito. Nesse caso, distotex significa posição
horizontal
da imagem do peixe Será o centro do ponto
x da linha 25, então o meio da área da tela horizontalmente menos a
metade da largura da imagem Agora eu posso passar didot x para
desenhar o método de imagem na linha 37. E a imagem está
centralizada horizontalmente. Vamos fazer o mesmo para a posição
vertical Y ponto central, Y menos
Sdt, altura do ponto da imagem vezes 0,5. Eu a substituo aqui Para centralizar qualquer imagem na tela, basta encontrar o meio da tela vertical e horizontalmente
e deslocar esses
valores pela metade da largura da imagem e metade
da
altura da imagem
26. Aula 13: Então, estamos desenhando nosso peixe como uma imagem e
desenhando dez partículas. Vamos fazer com que sejam 100 partículas. Vamos transformar cada
partícula em um quadrado, cinco vezes cinco pixels Você pode jogar com o tamanho. Sempre que eu atualizo minha página, todas essas centenas de partículas ficam uma posição aleatória
em algum lugar na tela Também podemos tornar o
tamanho das partículas aleatório, assim. Também podemos fazer
essas partículas se moverem. Vamos lidar com essa lógica aqui. Dentro do
método de atualização, precisarei uma nova propriedade chamada
V x velocity x, que é basicamente
uma velocidade horizontal Vamos configurá-lo para 11 pixels
por quadro de animação. Por enquanto, eu também crio a velocidade y e a defino como
mais um Dentro do método de atualização para
cada quadro de animação, queremos aumentar a posição
horizontal da linha dez pelo valor de
Vx da linha 13 Também queremos aumentar a
posição Y pelo valor de V Y. Cada partícula terá seu próprio método de atualização que
definirá seu movimento Eu também crio o
método de atualização na classe de efeito. trabalho desse método
será chamar a atualização de
todos os objetos de
partículas atualmente ativos em seu interior Eu pego uma matriz de partículas. Para cada
objeto de partícula na matriz, chamo seu método de atualização, que é criado na
linha 19 desta forma Se eu chamar o método de atualização como
esse, não acontecerá muita coisa. Todas as partículas são desenhadas apenas uma vez e suas propriedades são
atualizadas uma vez. Não há nada chamando os métodos de
atualização e desenho repetidamente, precisamos de um loop de animação. Eu pego essas duas linhas
de código e as coloco dentro dessa
função personalizada que chamei de animate. Eu chamo o método embutido do
frame de animação de solicitação. Ele fica no objeto da janela, mas pode ser chamado diretamente. Assim, o método de
frame de animação de solicitação chamará uma função que
passamos para ele como argumento antes da próxima repintura do navegador Quando eu passo, ele animou o
nome de sua função principal. Ele desenhará constantemente todas as partículas e
as atualizará repetidamente, criando a animação com o quadro de animação
solicitado. O número de retornos de chamada
geralmente é de 60 quadros por segundo. Geralmente, ele tentará igualar a taxa de atualização
da tela
na maioria dos navegadores modernos Ele também
pausará automaticamente a animação
ao ser executado em guias em segundo plano para melhorar o desempenho e a
vida útil da bateria do computador Quando eu chamo o animate e
executo meu código, nós entendemos isso. Nossos retângulos pretos estão
se movendo e deixando trilhas. As trilhas são os quadros de animação
antigos. Se quisermos ver apenas o quadro de animação
atual, precisamos excluir a tela toda vez que atualizarmos as posições
das partículas Eu faço isso usando o método de retângulo transparente
embutido. Quero limpar a tela
de Corin às 00. Quero limpar
a tela inteira. Eu levo valores daqui de cima. A largura da
área limpa será a largura da tela. A altura será a altura da tela. Agora estamos animando. Parabéns,
você é um programador criativo. Você acabou de construir um sistema de
partículas funcional. As partículas estão se movendo porque
estamos adicionando velocidade x e velocidade y às suas coordenadas
x e y atuais Se quisermos que cada partícula se
mova em uma velocidade diferente, posso atribuir a elas uma
velocidade aleatória a partir de um intervalo predefinido quando elas são criadas pela primeira vez aqui dentro do construtor da
classe de partículas.
Posso, por exemplo, definir suas velocidades como
um número aleatório de
0 a 10 Se você quiser que as partículas se movam em todas as direções possíveis, não apenas para a direita e para baixo, podemos aumentar a faixa de velocidade para começar com números negativos. Essa linha significa um número aleatório entre menos um e mais um Partículas com
valor negativo se moverão para a esquerda. As partículas com um
valor positivo aqui se moverão para a direita na
coordenada y vertical. É o mesmo. Partículas com um
valor negativo aqui subirão. As partículas com um valor
positivo se moverão para baixo, pois cada partícula
receberá uma velocidade aleatória x e uma
velocidade y diferentes no ponto em que forem criadas pela
primeira vez pelo Aqui, a razão entre V, x e y dará cada partícula uma direção
e velocidade de movimento
diferentes e velocidade de movimento Cada partícula terá
um vetor diferente. Vamos remover o fundo
azul e deixar o fundo da tela
transparente. Como faço para que minhas partículas
assumam a forma e a cor
da imagem e como
fazemos com que elas se lembrem dessa forma
e a recriem Se o quebrarmos com o mouse, estamos prestes a aprender
isso agora. Isso conclui a primeira
parte do curso em que abordamos os fundamentos
da tela HTML Aprendemos como criar um sistema
básico de partículas simples e como manusear, desenhar e centralizar
imagens na tela A segunda parte
deste curso será mais avançada e
aprenderemos mais sobre manipulação de imagens e física de
partículas em profundidade Parabéns, se
você é iniciante e segue até o fim,
está indo muito bem Se o código das lições a
seguir parecer mais desafiador,
não se preocupe. Na próxima parte,
entraremos território
avançado de
codificação criativa Mas acho que você pode fazer isso.
Vamos fazer isso passo a passo e farei o meu melhor para
ajudá-lo a entender. Vamos.
27. Aula 14: Esta é nossa classe de
partículas personalizada. Seu trabalho é criar um novo objeto de partícula toda vez que o chamamos. Com
a nova palavra-chave. No momento, nossas partículas
parecem pequenos quadrados pretos. Na verdade, quero pixelizar
a imagem e fazer com que cada bloco de pixels seja uma partícula
de uma cor Essa partícula também precisa se
lembrar de onde está
na imagem geral, porque
queremos poder
empurrá-la na imagem geral, porque
queremos poder e fazer
outros truques com ela, e sempre queremos que ela encontre o caminho de volta à posição original
para recriar a Aqui na linha 36,
inicializamos o método
simplesmente empurra 100
partículas aleatórias para a matriz de partículas Eu comento isso,
precisamos encontrar outra maneira de transformar nossa
imagem em partículas. Lembre-se também de que distote x da linha 33 e distote y da linha 34 definem a posição horizontal
e vertical imagem
do peixe que
estamos Posso provar isso
aumentando diste
x em um para cada quadro de
animação aqui que fará com que o peixe se mova para a direita na direção
positiva. No eixo x horizontal. Eu excluo o código do método
init e coloco a imagem de
desenho dentro O trabalho desse método
inicializado é desenhar uma imagem no Canvas, analisá-la e
transformá-la em partículas Em seguida, excluímos completamente essa imagem
do Canvas, porque
teremos nossas partículas compondo e recriando
a própria imagem Vamos fazer isso passo a passo. Como estamos desenhando
algo de dentro dele, precisamos ter certeza de que ele espera um contexto de desenho
como argumento. Eu ligo para a linha 48 aqui embaixo. E eu preciso ter
certeza de passar essa variável CTX de
contexto
da linha três Ele é chamado apenas uma vez no carregamento
da primeira página. Aqui, Animate
limpará imediatamente a tela e excluirá a
imagem por um momento Vou comentar o animate
para impedir que ele seja executado, vamos nos concentrar no método
inicializado Aqui está nossa classe de
partículas personalizada que cria nossa partícula
com essas propriedades Em seguida, ele os desenha
como quadrados pretos e os faz se mover,
atualizando suas posições Usaremos essa
classe de partículas e faremos ela transforme cada pixel da
imagem em uma partícula Dentro desse método, eu crio uma
variável auxiliar temporária chamada pixels Essa será uma matriz contendo
todas as posições e valores de
cor sobre cada pixel
individual no Cannavas Não podemos analisar a imagem em si. Precisamos desenhar a imagem na tela, como estamos fazendo
aqui na linha 37. E então usamos get
image data para analisar nosso elemento de tela com
a imagem desenhada nele. método Get Image Data analisa uma
parte específica da tela e retorna seus dados de pixel
na forma de um objeto especial de dados de
imagem Ele precisa de quatro argumentos para especificar qual parte
da tela queremos analisar Quero analisar
todo o elemento da tela da coordenada 00
até a largura da canavasdizotwidth da linha 27
e a altura da tela da linha 28 e O importante a mencionar aqui é que,
ao executar o código localmente, obtenha dados de imagem algumas medidas de segurança integradas com
algumas medidas de segurança integradas, como estamos fazendo neste
projeto no momento. Se desenharmos um
arquivo de imagem e depois tentarmos analisar essa tela
com a imagem desenhada nela, obteremos um
erro no console que diz que tela foi contaminada por dados de origem
cruzada Mesmo se você colocar
o arquivo de imagem
na mesma pasta local do arquivo de script, ele ainda será
considerado de origem cruzada. É por isso que fizemos
tudo no começo,
onde converti o arquivo de imagem em uma string de base 64. Fazendo isso, a própria imagem se torna parte do arquivo HML de
índice Podemos evitar esse aviso de tela
contaminada. Vamos consolok pixels para ver o objeto de dados de
imagem no Eu posso ver que obter dados de imagem retornou
corretamente o objeto de dados de
imagem. Dentro dessa propriedade de dados, ela contém uma
matriz massiva representando os valores de
cor de cada pixel em todo
o elemento da tela. Esse é um tipo especial de matriz, chamada matriz de
oito fixações UI NT É uma matriz de números inteiros de
oito bits não atribuídos fixados para organizar de
0 a 255. Se você trabalhou
com cores da web antes,
sabe que todas as cores podem ser expressas por valores
RGB e alfa chamados de declaração de cores RGBA Nós o usamos em CSS o tempo todo. Nesse caso, vermelho, verde e azul podem ser qualquer
valor de 0 a 255. Em CSS, opacidade
alfa é um valor de
0 a 1 aqui nesta matriz,
alfa também é um intervalo de 0 a 255 em que zero é transparente e 255 é
totalmente Essa matriz é organizada de uma forma especial,
em que cada quatro
elementos representam vermelho, verde, azul e
alfa de um pixel. Quatro elementos nessa
matriz são um pixel. É importante lembrar isso. Acabei de abrir o início
da matriz e a tela é
analisada pelos dados
da imagem do kit no canto superior esquerdo. Isso significa que esse pixel do
canto superior esquerdo tem zero vermelho, zero verde, zero azul
e zero opacidade É um pixel preto transparente. segundo pixel também é zero vermelho, zero verde, zero azul
e zero opacidade Opacidade zero significa que esses pixels são
completamente transparentes. Os únicos
pixels visíveis na tela são aqueles que
compõem nosso desenho de peixe. Se você pesquisar na matriz, especialmente no meio,
começará a ver
valores de 0 a 255 aqui, onde cada valor
representa vermelho, verde, azul e alfa de
cada pixel individual Eu recebo todos os zeros aqui porque uma grande parte da
tela é transparente Não há nada aqui até
começarmos a desenhar o
peixe aqui embaixo. Obviamente, os pixels em si são
muito menores. Estou apenas usando essa escolha de
quadrado vermelho como uma ajuda visual. Imagine o quadrado vermelho uma vez um pixel de tamanho.
28. Aula 15: Eu excluo o console. Desenhamos imagens no Canavas e
analisamos seus dados de pixels Agora temos a cor de cada
pixel na loja Canavas. Nessa variável de pixels, quero que a variável pixels
aponte diretamente para a matriz, não para todo o objeto de dados da
imagem. Eu digo dados
apontando para essa matriz fixada de
oito bits não assinada Agora vou percorrer essa matriz linha por linha,
de cima para baixo. Se o valor alfa for
maior que zero, significa que esses são os pixels
que compõem o peixe, os não transparentes. Quando eu encontrar um pixel não
transparente, criarei um objeto de partícula para ele usando nossa classe de partículas Cada vez que encontramos um pixel
não transparente, criaremos uma partícula
que o representa Para percorrer algo linha
por linha, de cima para baixo, podemos usar os chamados quatro
loops aninhados Aninhado significa simplesmente que é um
loop dentro de outro loop. Os quatro loops externos
manipularão a coordenada y vertical. Ele pulará linha
por linha de cima para baixo até atingirmos a
altura da tela e depois pararmos. Na verdade, não quero que cada linha
tenha apenas um pixel de altura. Quero pular em
incrementos maiores, o que
pixelizará nossa imagem e tornará
o efeito Não podemos realmente criar 40.000 partículas e ainda assim
obter uma animação suave É possível fazer isso, mas isso exigiria otimizações
avançadas que eu não
abordarei nesta aula Queremos diminuir um pouco a
resolução. Em vez de pular um
pixel ao terminarmos uma linha, pularemos em um determinado valor Eu chamo, por exemplo, uma lacuna. Não é realmente uma lacuna,
mas sim o tamanho de um pixel de partícula
individual
que formará nossa imagem Seremos capazes de alterá-lo
dinamicamente. Realmente não importa
o valor que eu atribuo a ela. Agora basta lembrar que valor
mais alto em Gap significa
melhor desempenho, mas imagem mais pixelizada, eu disse lacuna de, por exemplo, cinco Toda vez que terminamos de
percorrer uma linha de pixels, pulamos cinco pixels para baixo e começamos a
analisar esses pixels. Toda vez que entramos em uma nova linha, vamos da esquerda para a direita até atingirmos a
largura da área da tela. Cada vez que saltamos de
uma posição para outra, saltamos pelo valor da lacuna. Esses quatro
loops aninhados podem ser um pouco difíceis de
entender no início O loop externo é uma posição y
vertical salta de uma linha para outra O loop interno
mapeia as posições x
horizontais da esquerda para a
direita em cada linha. Digamos que comecemos
aqui, y é zero. Entramos no
loop interno e vamos de x05 pixels por vez,
passo a passo, até atingirmos a largura e a extremidade horizontalmente Saímos do circuito interno. Entramos no loop externo, y aumenta em cinco e estamos em outra linha. Entramos no circuito interno. Novamente, vamos da esquerda para a direita, cinco pixels por vez. Quando chegarmos ao final, novamente, sairemos do loop interno, entraremos no loop externo,
y aumenta em cinco. Entramos no loop interno e
percorremos as posições x horizontais. Esses loops
continuarão até
chegarmos ao fundo da tela, altura da
tela aqui Nesse ponto, percorremos todos
os
pixels da imagem Essa técnica é útil para muitos outros efeitos criativos
de codificação Quando você precisa
percorrer uma grade, é bom saber e fica muito mais fácil
quando você a usa. Mais frequentemente, estamos
percorrendo toda a tela, linha por linha, saltos de cinco pixels Cada vez que pulamos para a próxima célula
nessa grade imaginária, queremos verificar se
há alguma cor lá ou se estamos
examinando a área transparente Se encontrarmos algumas cores, criaremos uma partícula
usando nossa classe de partículas Queremos fazer com que essa partícula se lembre de sua posição x e y, sua posição na
imagem e sua cor O desafio é que,
à medida que percorremos essa enorme
matriz de dados de pixels retornada pela variável get image e armazenada
na variável de pixels, os índices da matriz vão de zero a dezenas de milhares Precisamos encontrar uma maneira de pegar essa série linear de números e obter as coordenadas x e y
a partir dela, além da cor. Vamos começar
obtendo o índice, o índice atual do
pixel que estamos
examinando atualmente em nossa grade nessa
enorme matriz de dados de pixels. Essa fórmula é um pouco avançada, então não se preocupe se você
não a entender no início. O índice atual do pixel
é y a partir do loop externo, o número de linhas à medida que
percorremos a imagem,
linha por linha, de cima para baixo multiplicado pela largura
da tela que estamos analisando. Isso nos dará, por
exemplo, um bloco como esse. Em seguida, adicionamos os pixels
horizontais restantes, dependendo de quão longe
estamos na nova linha mais X. Por exemplo,
algo assim Estamos com cinco
pixels horizontais na nova linha. Tudo isso
precisa estar entre colchetes e multiplicado por
quatro, porque sabemos que na matriz fixada de
oito bits não assinada
retornada por get image data, cada pixel é representado por quatro posições Quatro valores para vermelho, verde, azul e alfa. Queremos esse índice de matriz real à medida que saltamos de pixel em pixel. Essa linha está aqui para
garantir que saibamos onde na matriz de pixels, em qual
índice estamos atualmente. À medida que percorremos os pixels
na imagem, linha por linha, mapeamos uma linha linear de números para as coordenadas X e Y. Se você ainda não entendeu
completamente, fique à
vontade para assistir novamente
esta última parte ou não se
preocupe muito com isso. Ser capaz de entender uma lógica como essa é para especialistas em matemática, somos programadores criativos e desenvolvedores de
Javascript. Você realmente não
precisa entender fórmulas
avançadas como essas, especialmente se
for iniciante Você só precisa saber
quando e como usá-los. Sabemos que cada pixel é representado por quatro
números inteiros na matriz Sabemos que o valor do pixel vermelho é a primeira matriz
de um pixel do índice atual da linha 39 na matriz em que estamos
atualmente, desta forma. Sabemos que o valor verde para o mesmo pixel é o
próximo índice mais um. Depois, há um inteiro representando o índice de
valor azul mais dois e temos o índice de
opacidade alfa Depois disso, temos novamente vermelho,
verde, azul e alfa
para o próximo pixel. Agora que tenho vermelho, verde, azul e alfa desse pixel, posso concatená-lo em uma boa e velha declaração de cores
RGB padrão Posso dizer
colchete de abertura RGB entre aspas como esta, mais vermelho da linha 43 mais verde mais vírgula mais azul
mais um colchete de fechamento O fato é que nós
realmente não nos importamos pixels
transparentes em toda
essa área. Não estamos criando
partículas para os pixels
transparentes nessa área. Nós nos preocupamos apenas com os pixels que compõem nossa imagem
angular de peixe. Os pixels ao redor
são brancos porque o corpo do site
por trás deles é branco. A tela em si é
transparente nessas áreas. É alfa, há zero. Posso dizer se o alfa da
linha 46 é maior que zero, o que significa que o pixel nessa
área não é transparente. Só então crie uma partícula
para essa posição. Criamos uma partícula pegando uma matriz de
partículas da linha 29 e chamando o método embutido
de envio de matriz Colocamos um novo
objeto de partícula criado por nossa classe de partículas personalizada da linha sete dentro da matriz No
momento, nossa classe de partículas só sabe como espalhar aleatoriamente
partículas quadradas pretas pela tela Precisamos
ensiná-lo a esperar esses novos dados de pixel e se organizar
corretamente
para formar uma imagem. Se você acha que estou indo um pouco rápido demais
agora, me avise. Vou recapitular essa
técnica de análise de pixels passo a passo. Quando tivermos toda a lógica estabelecida, estamos quase lá. Dentro do método inicializado,
percorremos a imagem linha por linha,
capturando
as posições X e Y e RGB de cada
partícula Preciso ter certeza de que o construtor da classe de
partículas espera esses valores como
esses por dentro, eu os
converto em propriedades de classe Em vez de definir esse X para o valor X passado
como argumento, criarei uma nova
propriedade chamada origem X. Essa propriedade
sempre lembrará onde a partícula está
na imagem geral Eu o configurei como X que foi
passado como argumento. Esse X foi calculado em
nossos loops aninhados. Depois de analisarmos a tela para origem dos dados em
pixels, Y será y. Isso foi passado como argumento. Vou agrupar esses valores em um piso
matemático para arredondá-los para baixo, apenas para garantir que não
obtenhamos nenhum valor de subpixel. E a tela não precisa usar antialiasing para
suavizar a imagem É bom combinar tudo o que
desenhamos na tela por motivos de
desempenho Essa cor será passada
como argumento a partir daqui. Ele virá
da cor RGB que concatenamos há algum tempo na linha 50, para que cada partícula retenha a cor original da imagem Ok, agora o construtor
da classe de partículas na linha oito espera os efeitos x, y e cor como argumentos Eu entro em nossa classe de efeito
principal novamente, sempre que crio
uma nova partícula, passo essa palavra-chave para representar todo esse objeto de
efeito Como primeiro argumento, passo o índice
do quatro loop interno como posição
horizontal, y do loop externo como posição y
vertical e cor. É assim que você analisa a imagem em busca dados de
pixels e a converte
em um sistema de partículas Se isso era um pouco
complicado demais para iniciantes, se você ainda está
acompanhando, muito bem, agora é hora de se
divertir com a animação.
29. Aula 16: Só para recapitular, o método
inicializado será executado apenas uma vez no carregamento da
primeira página Primeiro, desenhamos nossa
imagem na tela, depois usamos get image data para analisar todo o elemento da
tela. Para dados de pixels, esses dados de
pixels vêm em uma matriz especial em que cada quatro elementos
representam um pixel. São valores de vermelho, verde, azul
e alfa. Nós o colocamos em
quatro voltas aninhadas como esta. Para converter uma
série linear de números, índices na matriz em coordenadas
x e y. Usamos a largura e a altura
da imagem para saber onde cada linha e cada coluna
se quebra para mapeá-las corretamente. À medida que saltamos de célula em célula em nossa grade imaginária de cinco vezes cinco pixels em toda
a tela, extraímos valores de vermelho, verde, azul e alfa se
alfa for maior que zero se o pixel não for transparente, criamos uma partícula
nessa posição usando nossa classe de partículas
personalizada Agora vamos desenhar e
animar isso nele. O método será executado apenas uma vez
no carregamento da primeira página. Vamos fazer um efeito consoloc para ver se temos todas as
partículas de pixels Eu posso ver meu objeto de efeito aqui criado por nossa classe de efeito
personalizada. Da linha 28,
vejo a matriz de partículas que
definimos na linha 32. Ele contém 2.775 objetos de
partículas. Esse número dependerá
da imagem que você está usando, do
quanto da imagem
é transparente e também da resolução
na qual você digitalizou a imagem Em nosso caso, nós o
digitalizamos na resolução cinco vezes cinco pixels definida
nessa propriedade de lacuna Na linha 38, posso ver que cada partícula tem referência de
cor ao objeto de efeito principal, posições de
origem X e origem Y, velocidade
horizontal e vertical e às posições X
e Y atuais Se você ver indefinido em qualquer um
deles em seu projeto, significa
que há um erro de digitação em
algum lugar do seu código Precisamos garantir que
todas essas propriedades tenham valores para que o
efeito funcione. Animação incomum na linha 76, que excluirá imediatamente imagem
do peixe e criará
um conjunto de Quero que essas partículas comecem
a se mover para suas posições de origem x e origem y para
recriar a imagem Antes de fazermos isso,
vamos definir esse ponto x como x. Isso foi passado como argumento. Este brinquedo pontilhado é assim. Sim, a forma do peixe
está perfeita. Cada partícula também lembra
a cor da imagem. Só precisamos usá-lo. Vamos definir o estilo Phil com
essa cor de ponto como esta. Agradável. O peixe está se
partindo em pedaços por causa das propriedades VX e VY Eu defino V x zero e
VY como zero perfeito. Agora você sabe como recriar uma imagem como um sistema de partículas. Eu tenho essa
propriedade de lacuna de pontos na linha 39, que determina quantos
detalhes queremos na imagem. Quanto menor o número, maior será
o desempenho que
exigirá esse efeito. A lacuna é de cinco pixels
e eu estou desenhando blocos de
partículas de
dez vezes dez pixels Há muita sobreposição. Eu posso configurá-lo para cinco, ou quando eu fizer quatro,
haverá um pixel. Lacunas na nota podem torná-la dinâmica ao dizer
esse efeito Do gap. Dessa forma, o tamanho das
partículas mudará automaticamente à medida que alterarmos
essa propriedade de lacuna de pontos. Um valor grande significa
menor resolução. Não use nenhum ponto
decimal aqui. Não queremos valores de subpixels
por motivos de desempenho. Além disso, desenhar partículas como retângulos é mais eficiente em termos de
desempenho Eu fiz um tutorial para toda a versão
desse efeito antes, onde cada partícula
era um círculo Essa nova versão com retângulos
será muito mais rápida quando começarmos a animá-la e
fazê-la interagir com Desenhar retângulos é
mais rápido do que desenhar círculos na tela E quando você tem 3.000 formas, 3.000 partículas ou mais, você pode realmente sentir
a diferença Podemos fazer com que a lacuna seja de
dois ou três pixels, o que resultará
em uma imagem nítida. Eu não recomendo
fazer um pixel. Isso resultará em
muitas partículas dependendo do tamanho da imagem, e ficará lento
quando a animarmos Existem algumas técnicas e
algoritmos
de otimização de tela que podemos usar para fazer com que até mesmo partículas de um pixel
se movam suavemente. Mas eu não vou abordar
isso neste curso. Eu posso fazer com que o
tamanho da partícula seja sempre um pixel menor do que o
valor da lacuna atual para obter algum espaço Você pode brincar com os
valores para ver o que acontece. Até agora, parece que
acabamos de pixelizar a imagem. Mas lembre-se de que cada bloco de pixels é
um objeto de partícula, pode lhe dar física
e comportamento Para alguns efeitos muito legais, eu disse lacuna de 23 pixels. Por enquanto, vou consolidar a matriz de
partículas da linha
33 dizendo uma matriz de partículas de efeito como esta Como eu disse com uma diferença de
três pixels, obtemos 7.557 partículas que
compõem a imagem do peixe
30. Aula 17: Quero que as partículas sempre
tentem se mover para sua posição
original. Assim, quando
os empurramos com o mouse ou
separamos a imagem de alguma outra forma, as partículas estão sempre sendo puxadas para suas posições
originais. Quero que a imagem sempre se recrie
automaticamente
sempre que estiver quebrada Escreveremos essa lógica dentro do método de
atualização na
classe de partículas. Vamos começar de forma simples. Sem nenhuma física,
essa posição mais é igual à diferença
entre a posição de origem, que é a
posição das partículas na imagem, e sua posição
horizontal atual Y mais é igual a z
origem do ponto menos ty. Queremos que as partículas
estejam sempre cientes da diferença entre sua posição
atual e sua
posição original na imagem. Estamos chamando o
método de atualização na classe de efeito aqui dentro do
loop de animação na linha 74. Dentro desse método, estamos
acionando o método de atualização da linha 23 em cada objeto de
partícula individual Aqui na linha 63, vamos colocar esses
valores entre colchetes e vamos espalhar as
partículas pela tela No carregamento inicial da página, esse x será um método aleatório entre zero e a
largura da tela vezes o efeito de ponto. Para realmente
ver o movimento, preciso ter certeza de que a etapa
individual por quadro seja apenas uma pequena fração
da diferença entre a exposição atual e
a exposição original Assim. Eu faço o
mesmo para dist y. Eu defino a
posição vertical inicial para um valor aleatório entre zero e a altura do ponto do efeito
dist, que é a altura da área de tela
disponível Vamos fazer física muito simples. Vou ligar para ele, configuro para 0,2 e uso aqui e aqui. Ao alterar esse valor, alteramos a
rapidez ou a lentidão com que a imagem se
monta Pode ser interessante
randomizar esse valor e fazer com que cada partícula se mova em uma velocidade
diferente Talvez se você quiser câmera lenta, certifique-se de que seja um número
muito pequeno. Bem, isso é muito legal. Podemos nos divertir muito
com essa base de código. Agora, não é ótimo
o que você pode fazer com apenas um script do Elga Nem estamos
usando nenhuma biblioteca. Nós mesmos escrevemos toda essa
lógica. Podemos jogar com esse
efeito de várias maneiras. Até mesmo mudar
o início nas posições x e y nos dará
algo diferente. Como quando eu me sentei começando x a zero ou espalhei a partir de y
por uma área muito maior. Também podemos fazer um simples efeito de
encolhimento. Isso pareceria diferente se a velocidade ou a flexibilização de
cada partícula Há muitas maneiras de
jogar com essa base de código. Também posso espalhar
x e tornar Y zero. Só estou me divertindo com isso agora.
31. Aula 18: Vamos criar um botão no
qual clicamos. Vamos randomizar as posições X
e Y de cada partícula e obteremos uma boa animação da imagem remontando toda
vez que o botão Vou chamar isso,
por exemplo, de Warp, como um teletransporte de um filme de
ficção científica quando as pessoas são quebradas em
partículas Quando esse método Warp é executado, coordenada x
horizontal
de cada partícula será aleatória entre
zero Y será um valor aleatório
entre zero e a altura do efeito. Assim, também darei um valor diferente apenas
para experimentá-lo. Eu vou para a aula de efeitos principais. E da mesma forma que fizemos
com o draw and update, eu crio um método warp. Quando acionado, ele
percorrerá a matriz de partículas. Para cada
objeto de partícula na matriz, ele executará o
método warp a partir da linha 28 Vamos indexar o
HTML se você quiser que a longa string de dados de base 64 que contém nossa imagem
esteja em uma linha. No
editor de código do Visual Studio, você pode selecionar exibir quebra de palavras no painel de navegação
superior. Aqui temos um diff
com uma classe de controles e dentro
há um botão com ID do botão Warp no
script GS Eu vou até aqui e
gerenciaremos a funcionalidade do
botão Warp Eu crio uma variável constante, chamo o botão Warp
e a defino como igual ao elemento get
document pelo botão ID
Warp. Assim. Então eu pego e adiciono ouvinte de
eventos para
um evento de clique Na função de retorno de chamada, tomo uma instância do
efeito que definimos na linha 35 e instanciamos na E eu chamo seu método de
distorção pública associado da linha 71 Assim, esse método Warp principal chamará Warp em cada partícula
individual, randomizando as posições x e y
e definindo um valor diferente Agora seus usuários podem acionar essa animação escolar
clicando no botão Warp. Fantástico, vamos deixar o
botão um pouco mais bonito. Tenho certeza de que você sabe como
estilizar algo com CSS, e este não é um curso de CSS, mas vamos fazer isso de qualquer maneira. Eu pego todos os botões da página. Atualmente, temos apenas um, e eu defino o preenchimento para 20 pixels, tamanho
da fonte para 30 pixels, a
margem para dez pixels Preenchimento de dez pixels
e margem 20. Talvez eu abra outra janela
do navegador e vá para o site
do Google Fonts. Vou procurar uma fonte chamada
Bangers para o estilo de arte em
quadrinhos da escola Eu clico nesse botão de adição
para adicioná-lo à minha biblioteca. Em seguida, clico em Exibir bibliotecas
selecionadas e ele me dá essas
três tags de link. Posso simplesmente copiá-los e
colá-los aqui no índice HTML Certifique-se de colocá-los antes meu arquivo CSS de estilo personalizado para garantir que
estejam disponíveis lá. Então, tudo o que preciso
fazer é copiar essa regra CSS para a família de fontes e
aplicá-la aos controles. Não, tudo bem. Eu tenho que aplicá-lo
à própria etiqueta do botão. Vamos deletar isso.
40 pixels perfeitos, tamanho da
fonte, cor do texto branco, cor de
fundo preta. Só para torná-lo interessante, passar o mouse, troco a cor Cor do texto, preto,
fundo branco. Bom. Vamos fazer uma
transição de 0,2 segundos. Ok, eu gosto disso.
Transformamos a imagem em partículas e adicionamos um padrão de distorção que
reproduzirá uma transição Isso mostrará como nossa imagem remonta
automaticamente quando é quebrada Vamos adicionar mais física
e interatividade
fazendo com que partículas individuais
reajam ao mouse
32. Aula 19: Quero que a
classe de efeito principal esteja sempre ciente da posição atual do cursor
do mouse Eu crio uma propriedade personalizada
do mouse. Será um objeto com raio de
três propriedades. Inicialmente, definirei para
3.000. Isso definirá a área ao redor do cursor onde as partículas
reagem ao mouse Na verdade, não serão 3.000 pixels. Vou explicar por que o número é tão alto quando chegamos lá
, por motivos de desempenho. posições X e y
do cursor do mouse serão indefinidas no início construtor da classe é executado
uma vez no momento a classe é instanciada
chamando a Podemos tirar
proveito disso e na verdade, adicionar aqui qualquer
código que
desejamos que seja executado no momento em que
a
classe de efeito for criada. Posso até adicionar um
ouvinte de eventos aqui desta forma. Ouviremos o evento
mousemove. Preciso ter certeza de que
esse ouvinte de eventos está vinculado ao seu escopo léxico
atual Quero que seja um construtor de classes de
efeitos internos para que eu
possa substituir propriedades do
mouse e do mouse à
medida que o evento mousemove é acionado Para garantir que a
função de retorno de chamada nesse ouvinte de eventos
lembre em qual
objeto ela foi definida pela primeira vez, posso usar um método especial de vinculação de script
Java ou
transformar a função de retorno de chamada em uma função transformar a função de retorno de chamada em uma Às vezes, também a
chamamos de função de seta gorda. Uma das características especiais das funções
de seta é que elas vinculam automaticamente essa palavra-chave ao contexto dos
códigos circundantes Ele sempre poderá
ver essa propriedade domouse, que é exatamente
o que precisamos aqui Precisamos acessar o objeto de evento
gerado automaticamente, pois essa função de seta
terá apenas um argumento Eu posso até mesmo remover os
suportes assim. Sempre que o evento mousemove é acionado, eu pego esse ponto
ponto x do mouse da linha 47 e defino para a coordenada horizontal
atual do evento x do cursor
do Também vou definir esse ponto de
cúpula da linha 49 para o evento y.
Assim. Vamos testar se funciona com o consologin
mousex e mousey Porque eu coloquei aquele
ouvinte de eventos mousemove dentro do construtor
de classe da classe Ele será
aplicado automaticamente quando
instanciarmos a
classe de efeito aqui na linha 86 Salve minhas alterações, atualize a janela do
meu navegador. Agora, quando eu movo
o mouse sobre a tela, posso ver que a posição do mouse está atualizada e os valores atualizados estão sendo salvos corretamente em nossa
propriedade personalizada de mouse com pontos no vidro de efeito. Perfeito. Vamos excluir
o consolog na linha 88 Além disso, este na linha 54. É bom sempre excluir
consologs como esse. Por motivos de desempenho,
estamos capturando as coordenadas x
e y atuais do mouse Aqui, queremos que cada
partícula continue verificando a que distância
está do mouse Se o mouse estiver perto o suficiente, queremos que a partícula
seja empurrada para longe por ele Escreveremos essa lógica
dentro do método de atualização na classe de partículas x. A
distância no eixo
x horizontal entre o mouse e essa partícula é o efeito de
ponto mousettx
da linha 50 aqui menos
st x da linha 50 aqui menos dy A distância entre o
mouse e a partícula no eixo y vertical é esse efeito de
ponto dom y Para calcular a distância
entre dois pontos, podemos usar o teorema de Pitagoriano
. Funciona assim. Isso é mouse, isso
é uma partícula. Criamos um triângulo
retângulo imaginário entre esses dois pontos Essa é a distância
horizontal x. Já calculamos
isso na linha 25. Este local está a uma distância DY
no eixo y vertical. Calculamos isso na linha 26. Para obter esse local, que é a distância real
entre esses dois pontos, usamos o teorema de Ptagora
para calcular o
hipoteno, o lado mais longo de um triângulo oposto ao ângulo fórmula do teorema de Pitagora é que C é igual à raiz
quadrada a ao quadrado
mais b ao quadrado convertida em script Dizemos que a distância é a raiz quadrada da
boca de disto dx vezes stod x, que é um quadrado mais então
vezes Didi ao quadrado Isso nos dá a distância
entre dois pontos, entre a partícula e o mouse Eu removo a raiz quadrada
porque essa é uma
operação de alto desempenho e realmente não precisamos dela. Eu só preciso ajustar o raio
do mouse para um valor maior se você
não estiver usando a raiz quadrada aqui É por isso que eu configurei o raio do mouse
para 3.000 aqui na linha 51. Você pode ajustar o
intervalo ao ver o
tamanho da animação
em um minuto. Eu quero implementar um
pouco de física. Quero que as partículas
sejam empurradas mais força se estiverem
mais próximas do mouse. Eu faço isso criando uma
ajudante por propriedade chamada à força. Será um raio
do mouse, a área ao redor
do mouse onde as partículas reagem a ele, dividido pela
distância atual entre o mouse e
a partícula para fazer a partícula se afaste
do mouse na
direção Preciso colocar o sinal negativo aqui. Veremos como funciona
quando tivermos alguma animação. Você pode tentar colocar mais e menos aqui e ver o que acontece A força na qual as
partículas estão sendo empurradas é igual à
razão entre o raio da área interativa do
mouse e a distância atual
dessa partícula do percurso do mouse Eu verifico se a distância é
menor que o raio do mouse. Se for, afastamos a
partícula do mouse. Antes de fazermos isso, estou usando algumas novas propriedades de classe que não estão definidas
no construtor Vamos defini-los primeiro. Dx, distância do ponto dy
e força didot. Todas essas propriedades
serão zero no início. Também criarei
outra propriedade que chamo, por exemplo, ângulo do ponto. ângulo do ponto determinará a direção na qual as
partículas estão sendo
afastadas quando interagem com mouse. Aqui,
calcularemos esse ângulo usando matote, um método Javascript
integrado 102 método Matote 8102
retorna um valor numérico em brilho entre
menos Sabemos que o círculo tem
dois pi em brilho. Esse valor que matoteen
two retorna representa
o chamado ângulo teta entre um determinado ponto x e y e um eixo x
positivo É importante lembrar que esse método
Javascript embutido espera um valor
da coordenada y primeiro e a
coordenada x depois A diferença entre a posição
x Andy
da partícula e a
posição x Andy do cursor do mouse representada por
Diddy e dis dot x após o método 102 nos
dá um Aumentaremos a velocidade
horizontal, Vx velocidade x, pela
força a partir da linha 33 Isso depende da razão entre
o raio do
mouse e a
distância entre o mouse e a partícula, fazendo com que as partículas que
estão mais próximas sejam empurradas por uma força maior para especificar em qual direção
estão sendo Eu passo por esse ângulo. Estamos calculando na linha
3062, o método da maioria dos cossenos. Esse método mapeará o
ângulo que passamos para ele em radianos como um valor entre
menos um e mais um Esse valor representará o cosseno do
ângulo e fará com que as partículas flutuem
bem ao longo das bordas externas do círculo
à medida que o
mouse interage com Esses
métodos são dois e cosseno , e
tudo o que tem a ver com trigonometria, é muito difícil explicar se você os vê pela primeira
vez Não acho importante
entendê-lo completamente, desde que você saiba como usá-lo e como
obter o movimento desejado. Quando começarmos a animação,
vou reproduzir esses valores
para ver o que ela faz. O feedback visual que recebemos quando a animação está sendo pode facilitar
a compreensão. Isso é difícil, então
não se sinta mal se você não seguiu toda essa lógica
trigonométrica Isso não afeta
sua capacidade de ser um bom desenvolvedor de Javascript. Agora, atualizamos o VX
da linha 16 considerando a força
do impulso e a direção
desse impulso Faremos o mesmo com
a velocidade vertical, mas desta vez
usaremos o método seno Nós passamos no mesmo ângulo. O método cosseno e o
método seno trabalham juntos para mapear uma posição
ao longo do raio de Agora posso usar a velocidade
vertical e horizontal VX e VY, posições
x e y
calculadas aqui desta forma Vamos tentar primeiro ver o que ele faz enquanto as partículas
certamente reagem ao mouse. Mas algo está errado. Vou consertar isso em um segundo. Para melhorar a física, também
podemos aplicar atrito. Eu crio uma propriedade
chamada atrito. Eu o ajusto para 0,95 Eu
multiplico V x por ele aqui, fazendo com que ele diminua lentamente
em sua Para cada quadro de animação, o movimento está errado. Mesmo assim, acho interessante
verificar o que está acontecendo. Vejo que cometi um erro de
digitação aqui na linha 33. É suposto ser D x
vezes dx, dy vezes dy. Assim, o teorema de Pitagra. Agora, as partículas se comportam
conforme o esperado, perfeitas. Estamos pressionando-os para que
retornem à posição original Temos que fazer vezes iguais aqui. Se eu mudar para 0,2,
obteremos um movimento muito mais rápido. Quanto menor o valor do atrito, mais atrito
será aplicado Há muita matemática aqui. Não se concentre muito nisso. Este curso é principalmente sobre Java Script e
desenho em Canvas. Você pode usar esses
trechos de código matemático para outros projetos. Mesmo que você ainda não entenda
completamente como a matemática funciona, eu o encorajo a
brincar com a
mudança de valores menos o sinal de assinatura de troca, tentar quebrá-lo e ver como
isso afeta o movimento Espero que fique mais
claro
ver o que está acontecendo e o que
acontece quando eu aumento o
atrito e aumento o raio, obtemos esse limite mais
gradual Há uma versão estendida
deste curso vinculada
à descrição abaixo, na qual vamos ainda mais longe e criamos algumas transições
especiais Você pode
conferir se quiser. Espero que você tenha encontrado
algum valor hoje. Estou aqui para ajudá-lo
a aprender script
Java e descobrir todas as coisas incríveis que
você pode fazer com ele. Você acha que esse foi
um projeto difícil com todos os algoritmos? Foi difícil para você? Me dê um número
nos comentários. Um é extremamente fácil, dez é muito difícil, cinco é algo
intermediário, acho que mais tarde.
33. Aula 20: Vamos trocar a imagem
por outra coisa. Você pode usar seu próprio arquivo PNG com fundo transparente ou baixar a mesma imagem que estou usando na seção Ativos. Esta imagem é outro personagem do meu outro
curso de Javascript, onde
exploramos um planeta alienígena e estranhas formas de vida
mecânica. Podemos converter a imagem em uma string de
base 64 com Java Script. Mas é mais rápido
usar um
site externo se você quiser ver como eu
converto imagens desenhadas no
Canvas em dados como
esses em tempo real, parte
dinamicamente da base de código
Javascript. Confira meu outro curso de codificação
criativa sobre linhas, rotação
e fractais Lá, eu explico passo a passo como criar meu fractal
processual. Na verdade, o
mesmo que fizemos antes. Eu pesquisei PNG no Google para a base 64. Existem muitos sites
que podem fazer isso. Apenas certifique-se de que
o código convertido comece com a imagem de dois pontos de
dados Se não preencher
essa caixa de seleção, copio a longa linha de código Eu vou para o índice HTML e
quero substituí-lo
aqui na linha 15. É mais fácil se eu habilitar a
quebra de palavras. No código do Visual Studio, clico em Exibir Word Rap. Eu quero substituir todo esse
código no atributo fonte. Esse código é a imagem inteira. No código do Visual Studio, posso apenas destacar a
parte no início. Em seguida, rolo para baixo
onde o código termina e, para destacar
tudo o que está no meio, pressiono e mantenho a tecla
Shift e
clico com o botão esquerdo onde quero que a
seleção termine assim. Excluí e colo o novo código que copiamos
do site Vamos lá, trocamos a imagem e tudo funciona muito bem. É muito
divertido jogar com esse efeito. Acho que é muito relaxante. Por algum motivo, ajusto o
atrito na linha 19, disse o raio do mouse
para 3.000. Por exemplo, volta ao índice HTML, vou ver a quebra de linha
para desativá-la É melhor
ter a string de dados longa de base 64 em uma única linha,
caso contrário, teremos que rolar muito para
baixo Eu copio essa marcação para botão de
trabalho e dou uma
ideia do botão de bloqueio com texto que diz blocos no script GS Eu copio esse
bloco de código e o
ajusto para apontar para
o novo botão de bloqueio. No
código do Visual Studio, você pode fazer uma
seleção múltipla dessa forma
destacando um texto sempre que
pressionar o comando no Mac e o controle no PC e
pressionar a letra D, você selecionará outra
ocorrência desse Eu salvo uma referência
ao padrão de bloco, anexo um
ouvinte de eventos a ele e,
dentro dele, chamo o método público do
bloco de efeitos Precisamos
criá-lo. Eu me certifico de que estou classe de efeitos
internos
aqui onde criamos o Warp. Eu crio o método de blocos. Seu trabalho será simplesmente
percorrer a matriz de
partículas da linha 56. Para cada
objeto de partícula nessa matriz, ele acionará um método que também
é chamado de Blocos Precisamos garantir que
cada partícula individual tenha um método com esse nome Eu subo aqui para a classe de partículas e aqui
criamos o Método Warp. Antes de criar esse
novo método de blocos, posso fazer todos os
tipos de coisas diferentes para bagunçar as partículas,
porque sabemos que elas se reunirão novamente
em forma de imagem Novamente, devido à lógica
do método de atualização
que escrevemos anteriormente, posso, por exemplo, dividir
as partículas em dois grupos. Um grupo virá do topo
da tela,
coordenada zero A outra metade das partículas virá da parte inferior da tela a partir de uma coordenada
vertical igual à altura da tela Eu posso fazer isso usando o
chamado operador ternário. É o único
operador Java Script com três óperas. Neste caso, vamos usá-lo como uma simples declaração de uma linha
if L. A estrutura é uma
condição simples de avaliar, interrogação,
algo a ser feito se a verificação avaliar
o cólon verdadeiro Outra coisa a fazer se
ele avaliar o falso. A condição a ser
avaliada será
verificar se o método aleatório é
maior que 0,5 O método aleatório chamado
sozinho, assim, retornará um valor aleatório 0-1. Deve ser maior que 0,5 em aproximadamente 50% dos casos para essas partículas definirem sua posição
vertical como zero Na parte superior da outra
metade das partículas, defina sua
posição vertical em Y para afetar a altura. A condição do operador
ternário na parte inferior da tela para verificar se é verdadeira,
faça isso, caso contrário, faça isso Agora, quando clico no padrão de blocos, ele divide as partículas
em dois grupos, vindos de cima e de baixo Bom, posso alterar o valor em, na verdade, no Warp
para 0,2 em blocos Podemos tentar de forma diferente, pois quando clicamos em botões
diferentes, as partículas têm diferentes velocidades
de atenuação, podemos alterar quaisquer propriedades
das partículas que quisermos Aqui eu posso, por exemplo,
torná-los maiores. Vamos definir o tamanho do retângulo de
partículas individuais em dez
pixels Interessante. O problema
é que quando eu clico em Warp, agora o tamanho das partículas
fica em dez pixels Eu tenho que lembrar que quando eu manipulo um novo valor
no método de blocos, eu tenho que defini-lo para o método
Warp também, se eu não quiser que o tamanho
seja o mesmo Agora Warp tem partículas pequenas, blocos nos fornecem
grandes blocos de pixels vindos de cima e de baixo
34. Aula 21: Esse próximo efeito é muito legal. No índice HTML, eu crio um novo botão com o
ID do botão de montagem. E o texto diz montar
no script GS. Aqui, novamente, eu crio
uma seção onde eu crio uma variável para armazenar uma referência de Java Script
para esse novo botão, e eu dou a ele um
ouvinte de eventos dentro dele Chamamos de montagem de efeitos. Na classe Effect,
criarei uma versão de nível superior do método assembly que
gerenciará todas as partículas, mesma forma que fizemos com Warp and Blocks aqui dentro da classe de
partículas Preciso definir esse
novo método de montagem
e dar a ele um pouco Dentro, definimos x como um número aleatório entre
zero e a largura do efeito. Y será um número aleatório
entre zero e a altura do efeito. Quero que as partículas
sejam
espalhadas aleatoriamente pela área
disponível da tela Preciso definir facilidade e tamanho. Como também estamos alterando
esses valores nos botões abaixo, isso faz a mesma coisa que distorcer. Quero que ele se comporte de forma diferente ao remontar
a imagem Quero que as partículas voltem à
posição original na imagem, mas não todas de uma vez,
mas uma por uma. Em uma velocidade específica, teremos que criar uma
chave que habilitará e
desativará o comportamento de busca de
alvos de cada partícula No momento, as partículas
sempre querem retornar à sua
posição inicial na imagem. Eu preciso ter um interruptor que os impeça
de fazer isso. E crie um
sistema de semáforos que diga pare e vá. Vou escrever essa
lógica que atrasará as partículas de voltarem
à sua posição original. E então vou recapitular todo
o loop lógico. Não se preocupe muito
se você não
entender completamente tudo
na primeira rodada. Vamos escrevê-lo primeiro.
Aqui na classe de efeito principal, eu crio uma propriedade
chamada este contador. Inicialmente, eu o configurei para zero. Essa contravariável
aumentará lentamente. À medida que aumenta, permitirá que mais e mais partículas voltem à sua
posição original na imagem. Cada partícula aguardará
um certo número de milissegundos antes de começar a
se mover de volta para
montar a imagem Esse atraso em milissegundos
será igual a essa contravariável dentro
do método master assembly, eu defino o contador como zero Isso é importante
porque teremos outra transição que
usa o mesmo contador. Precisamos
garantir que o contador seja sempre zero quando clicamos
no botão de montagem ou quando
clicamos entre diferentes botões de
transição Teremos aqui,
fará mais sentido em um minuto. Cada vez
que o método de montagem for acionado em cada partícula
individual, eles aumentarão
cumulativamente acionado em cada partícula
individual,
eles aumentarão
cumulativamente a mesma variável
contadora única,
chamando a montagem em
cada objeto de partícula dentro da matriz de partículas, cada partícula aumentará o valor do
contador Vou criar um tempo limite
definido aqui. método set timeout do Java Script chama uma função após um certo número de melissegundos definido no
objeto da janela O mesmo que o quadro de animação de solicitação. Podemos chamá-lo
diretamente assim. Ela espera que a
função de dois argumentos chame e atrase quanto tempo esperar
até que a chamemos de atraso Usarei esse efeito de ponto
para contrariar o valor que aumenta em um toda vez cada
método de montagem de partículas é chamado. Dessa forma, cada partícula atrasará um pouco a próxima
que vier depois dela Quanto a cada método dentro
da classe de efeito principal chama o método de montagem em cada objeto de
partícula, um por um A função a ser chamada após
esse aumento no atraso será uma função de seta porque estamos dentro de uma classe,
dentro de um objeto. E preciso ter certeza de
que essa palavra-chave está vinculada ao contexto em que
o tempo limite definido é definido Como dissemos antes, a função ES
six arrow se
vincula automaticamente ao seu
escopo atual Dessa forma, posso usar esse ponto aqui
dentro e ele funcionará. Como alternativa,
teríamos que usar o método de
vinculação do Java Script aqui Usar a função de seta é sintaxe
mais simples e faz
a mesma coisa que eu disse Quero criar um sistema de
semáforos que as partículas sejam
instruídas a parar e ir embora Faremos isso criando mais
uma propriedade auxiliar
chamada ponto ativo Quando a partícula está ativa
definida como verdadeira, ela pode se mover. Se ativo for falso, partícula congelará em
sua posição atual Depois de definir o tempo limite, o
cronômetro é desligado. Definimos ativo como verdadeiro aqui no construtor da
classe de partículas, inicialmente
definimos
ativo também Dentro do método de atualização,
temos um código que reage ao código do mouse que retorna a
partícula à sua
posição original para montar a imagem Quero que todo esse código seja executado somente se o sinalizador ativo estiver definido como verdadeiro. Aqui embaixo, quando o
botão de montagem é pressionado, randomizamos as
posições x e y de cada partícula, espalhando-as
por toda Definimos a velocidade e o tamanho da flexibilização. Nesse ponto, à medida que as
partículas se espalham, colocamos esse ativo em quedas, congelando todas elas no lugar. Como o método for each é executado
dentro da classe de efeito principal, ele
percorre rapidamente toda a matriz
de
partículas, do índice inicial
ao índice final. Cada vez que esse código
é executado para uma nova partícula, o contador aumenta ligeiramente, aumentando esse valor de atraso Cada partícula
na matriz terá um valor de contador um pouco maior, fazendo com que esse tempo limite definido seja chamado com um
aumento no atraso Quando o tempo limite definido
finalmente for acionado, cada partícula será
definida como E a instrução if que
criamos dentro do
método update na linha 32 finalmente permitirá que ela volte à sua posição
original. Ao mesmo tempo,
também permitirá interações com o mouse. Isso foi divertido porque o valor do cronômetro é igual
ao atraso em milissegundos que cada partícula esperar antes
de
se tornar aumento no cronômetro em um valor maior aqui
fará com que
a montagem mais lenta das partículas tenha que esperar mais milissegundos
antes A velocidade da montagem
em si também dependerá da imagem e
da resolução que você tem nessa propriedade de lacuna Porque se sua
imagem for feita de menos partículas maiores, ela será montada mais rapidamente. Você também pode desacelerá-lo
multiplicando o
valor do contador por algo Dessa forma, você também está
aumentando os milissegundos. Portanto, você está
retardando o processo de montagem Multiplicá-lo por menos de um o acelerará Acho muito legal como as partículas esperam no lugar
até que estejam lá, viradas e depois se
posicionam para
recriar a imagem Também podemos brincar com as interações
do mouse enquanto a imagem está sendo montada
e ela ainda funcionará; elas simplesmente voltarão ao
lugar quando permitirmos Essa é uma base de
código bastante sólida, eu acho. Sinta-se à vontade para fazer seus próprios
experimentos com ele. Um problema que temos aqui é que, quando clicamos no botão
Montar, ele define instantaneamente a sequência de tempo limite
para todas as partículas E se trocarmos e voltarmos para essa transição de
montagem, se o tempo limite ainda não tiver sido
ativado, a animação começará em algum lugar no meio Também precisamos limpar todos os
tempos limite, todas as partículas. Toda vez
que ativamos o efeito de
montagem , a imagem sempre começa a ser montada
desde o início Uma forma de eliminar os tempos limite é capturá-los
em uma variável Eu crio uma nova variável
chamada tempo limite de pontos. Inicialmente, eu o configurei
como indefinido aqui na linha 68, onde criamos um novo tempo limite Nós o definimos igual ao tempo limite
desse ponto. Na verdade, ele será ativado
como antes. Defini-lo igual a uma
variável como essa
não terá efeito sobre como o
tempo limite é acionado sozinho No entanto, isso
nos fornece uma maneira fácil de
limpá-lo quando a
montagem é chamada. Primeiro, quero limpar
o tempo limite, se houver um método ativo de
tempo limite de limpeza em Java, cancela um tempo limite que foi estabelecido anteriormente Ao chamar set timeout, ele espera um
argumento que será um identificador do
tempo limite que queremos cancelar Set timeout retorna
um ID quando chamado, mas nós o temos em uma variável, então eu posso simplesmente passá-lo
dessa vez desta forma E funcionará aqui. Na verdade, não sei por
que ainda está
saindo do meio. Tem algo a
ver com esse número ser muito pequeno, porque
quando eu fizer isso, ele será reiniciado corretamente. Funciona com números maiores. Quando eu entro em
muitos pontos decimais, ele se reúne a partir do meio Acho que sim, porque
o número que estamos passando como
atraso de milissegundos é muito pequeno para índices iniciais em uma matriz como essa,
ele funciona muito bem Talvez seja melhor ajustar a velocidade de
montagem
controlando o
quanto o contador aumenta
aqui nos experimentos da linha 68.
35. Aula 22: Vamos criar mais um efeito de
transição. Eu chamo isso de
impressão de partículas porque me
lembra três impressoras D. Criando algo camada
por camada, linha por linha. Eu crio outro
botão com um ID do botão de impressão de partículas e um texto
que diz impressão de partículas Como sempre, trazemos o
botão para o projeto. Aqui nesta
área do script, fornecemos a ele um ouvinte de eventos para o evento clique e
chamaremos o método de impressão de partículas Criamos o método de
impressão de partículas
aqui embaixo , o mesmo que montar Também será necessário que
o contador seja redefinido para zero. Em seguida, ele percorrerá toda
a matriz
de partículas do início ao fim. Isso acionará o método de impressão de
partículas, que definiremos Agora eu o defino aqui e ele funcionará de
forma muito semelhante ao método de montagem. Desta vez, quero que a coordenada
x
inicial esteja exatamente no
meio da área da tela Este efeito com vezes 0,5 Agora, todas as partículas vêm dessa única
linha no meio. Se eu dissesse
a coordenada y
inicial no meio da
tela verticalmente, todas as partículas serão
comprimidas em um único Criamos uma singularidade de pixels. partir daí, a imagem
será montada como uma tela, um buraco negro
reverso, cuspindo
partículas e
diminuindo a entropia partículas e Eu acho que isso parece muito legal. Qual transição é sua
montagem
favorita de blocos Warp ou impressão de partículas. Deixe um comentário para me avisar. Espero que você tenha encontrado algum valor
e aprendido algo novo. Confira minhas outras
aulas se você quiser explorar uma codificação mais
criativa ou o desenvolvimento de dois jogos em D com vanilla Java sq, veja