#javascript #css3 #анимация #canvas #css_animation
В каждом фрейме отрисовки (requestAnimationFrame) в центре канваса рисуется круг. Размер канваса анимируется. В Хроме и FF круг немного дрожит, а в IE он заметно толстеет перед перерисовкой - т. е. браузер сначала растягивает имеющуюся картинку, а потом заменяет её новой. Почему так происходит и как исправить? Насколько я представляю, если я делаю что-то в requestAnimationFrame, то содержимое страницы вообще не должно перерисовываться, пока я не закончу. Соответственно, на момент отрисовки должна отрисоваться сразу новая версия. Но в IE сценарий не такой? https://jsfiddle.net/3wLroppt/ function draw() { var canvas = document.querySelector('canvas'); var width = canvas.clientWidth, height = canvas.clientHeight; canvas.width = width * 2; canvas.height = height * 2; var ctx = canvas.getContext('2d'); var cx = width, cy = height, r = height; ctx.beginPath(); ctx.arc(cx, cy, r, 0, 2 * Math.PI, false); ctx.fill(); } requestAnimationFrame(function frame() { draw(); requestAnimationFrame(frame); }); canvas { outline: 1px dotted red; height: 200px; width: 200px; display: block; margin: auto; animation: w-100-200 .5s linear infinite; } @keyframes w-100-200 { 0% { width: 200px; } 50% { width: 400px; } 100% { width: 200px; } }
Ответы
Ответ 1
Нашел ответ, правда на IE пока не тестировал, у меня linux))) Как я и подозревал дело было в том что анимация с высотой и шириной по умолчанию происходит так: Например у вас ширина должна с 200px расшириться до 400px в определенном промежутке времени ($t), и расчет происходит так - к ширине добавляется один пиксель в (400-200) / $t времени.И кода размер ширины контейнера нечетное количество пикселей то центр круга рисуется на один пиксель вправо (по оси x) (201/2 пиксель шириной для него будет 101px), и это приводит к непредусмотренной анимации (дрожанию) круга внутри контейнера. Эту проблему я решил свойством animation-timing-function, у него есть значение steps. там можно задать шаг анимации и у нас поскольку от 200 - 400 будет 100 2-пиксельных шагов прописываем в нем 100 animation-timing-function: steps(100); И вот что у меня получилось: А это пример от автора но время я поставил 5s что бы наглядно было видно непредусмотренная анимация черного круга.Ответ 2
Вы же сами написали - браузер сначала рисует кружок с помощью js,а css его тем временем растягивает. let start = Date.now(); const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); const height = canvas.clientHeight; function draw() { let dt = Date.now() - start; var side = Math.pow(-1, ~~(dt/500)); var delta_width = 200 * (dt%500)/500; width = canvas.width = ((side>0)?200:400) + side * delta_width; prev = Date.now(); var cx = width/2, cy = height, r = height; ctx.beginPath(); ctx.arc(cx, 100, 100, 0, 2 * Math.PI, false); ctx.fill(); } setInterval(draw, 54); canvas { outline: 1px dotted red; height: 200px; display: block; margin: auto; }
Комментариев нет:
Отправить комментарий