Suponha que exista um requisito de função de animação: altere a largura de uma div de 100px para 200px. O código escrito pode ser assim:
A cópia do código é a seguinte:
<div id = "test1"> </div>
função Animate1 (elemento, endValue, duração) {
var startTime = new Date (),
startValue = parseint (element.style.width),
passo = 1;
var timerId = setInterval (function () {
var nextValue = parseint (element.style.width) + etapa;
element.style.width = nextValue + 'px';
if (nextValue> = endValue) {
ClearInterval (timerid);
// consumo de tempo para exibir animação
element.innerhtml = nova data - starttime;
}
}, duração / (endValue - startValue) * etapa);
}
Animate1 (document.getElementById ('test1'), 200, 1000);
O princípio é aumentar 1px a cada determinado tempo até 200px. No entanto, o tempo de exibição após o término da animação é superior a 1s (geralmente em torno de 1,5s). O motivo é que o SetInterval não pode garantir estritamente o intervalo de execução.
Existe alguma maneira melhor de fazer isso? Vamos primeiro olhar para um problema de matemática da escola primária:
A cópia do código é a seguinte:
O edifício A e o edifício B estavam a 100 metros de distância. Um homem caminhou do edifício A para o edifício B a uma velocidade constante. Depois de caminhar por 5 minutos, ele chegou ao seu destino. A que distância ele estava da construção de A no terceiro minuto?
A fórmula de cálculo para calcular uma distância de um determinado tempo durante a velocidade constante é: distância * tempo atual. Portanto, a resposta deve ser 100 * 3/5 = 60.
A inspiração dessa questão é que a jornada de um determinado momento pode ser calculada através de uma fórmula específica. Da mesma forma, o valor de um certo momento durante o processo de animação também pode ser calculado através de fórmulas em vez de ser acumulado:
A cópia do código é a seguinte:
<div id = "test2"> </div>
função Animate2 (elemento, endValue, duração) {
var startTime = new Date (),
startValue = parseint (element.style.width);
var timerId = setInterval (function () {
VAR porcentagem = (nova data - starttime) / duração;
var stepvalue = startValue + (endValue - startValue) * porcentagem;
element.style.width = StepValue + 'PX';
if (porcentagem> = 1) {
ClearInterval (timerid);
element.innerhtml = nova data - starttime;
}
}, 13);
}
Animate2 (document.getElementById ('test2'), 200, 1000);
Após essa melhoria, você pode ver que o tempo de execução da animação levará apenas 10 ms. No entanto, o problema não foi completamente resolvido. Se você verificar o elemento Test2 na ferramenta de desenvolvimento do navegador, descobrirá que a largura final do Test2 pode ser superior a 200px. Se você verificar cuidadosamente o código da função Animate2, encontrará:
1. O valor da porcentagem pode ser maior que 1, que pode ser resolvido limitando o valor máximo por matemática.
2. Mesmo que o valor da porcentagem seja garantido não mais que 1, desde que o EndValue ou o StartValue seja um decimal, o valor de (endValue - StartValue) * porcentagem pode causar erros, porque a operação decimal JavaScript não é precisa o suficiente. De fato, o que precisamos garantir é a precisão do valor final; portanto, quando a porcentagem é 1, basta usar o endValue diretamente.
Portanto, o código da função Animate2 é modificado para:
A cópia do código é a seguinte:
função Animate2 (elemento, endValue, duração) {
var startTime = new Date (),
startValue = parseint (element.style.width);
var timerId = setInterval (function () {
// garante que a porcentagem não seja maior que 1
var porcentagem = math.min (1, (nova data - starttime) / duração);
var stepvalue;
if (porcentagem> = 1) {
// garantir a precisão do valor final
StepValue = endValue;
} outro {
StepValue = StartValue + (EndValue - StartValue) * Porcentagem;
}
element.style.width = StepValue + 'PX';
if (porcentagem> = 1) {
ClearInterval (timerid);
element.innerhtml = nova data - starttime;
}
}, 13);
}
Há outra última pergunta: por que o intervalo do setInterval está definido para 13ms? A razão é que a taxa de atualização do monitor atualmente geralmente não excede 75Hz (ou seja, é atualizada 75 vezes por segundo, o que significa que é atualizado a cada 13ms) e sincronizando o intervalo com a taxa de atualização é melhor.