Плавная прорисовка в canvas
Добрый вечер. Недавно начала изучать работу с canvas. Более и менее разобрался с простыми фигурами. Перешел вот к анимациями и получается скудновато.
Например, вот я нарисовал шестиугольник. Хочу что бы стороны рисовались плавно. То есть линия первой стороны выходит из начальной точки и движется к своей конечно точке, от туда начинает рисоваться следующая сторона и так все по кругу. Идея есть а с реализацией туго. Есть понимание как прямую линию или диагональ нарисовать плавно (начинать с x = 0, y = 0, и в цикле добавлять по одному), но с сложной фигурой это не особо выполнимо как по мне. Прошу помощи, советом или делом, кому как не жалко) |
Цитата:
|
анимация canvas
smart-create,
документация по анимации по ссылке выше более продвинутые варианты смотреть у Rise <!DOCTYPE HTML> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> </style> </head> <body> <input id="go" name="" type="button" value="go" > <canvas id="canvas" width="300" height="300" ></canvas> <script> function anim(a) { return function() { var d = performance.now(); requestAnimationFrame(function e(b) { b = (b - d) / a.duration; 1 <= b && (b = 1); var k = a.easing ? a.easing(b) : b; var y = a.from.y + (a.to.y - a.from.y) * k | 0; var x = a.from.x + (a.to.x - a.from.x) * k | 0; var ctx = a.elem.getContext("2d"); ctx.beginPath(); ctx.strokeStyle = a.color; ctx.lineWidth = a.width; ctx.moveTo(a.from.x, a.from.y); ctx.lineTo(x, y); ctx.stroke(); b == 1 && a.callback && a.callback() 1 > b && requestAnimationFrame(e) }) } } function makeEaseInOut(timing) { return function(timeFraction) { if (timeFraction < .5) return timing(2 * timeFraction) / 2; else return (2 - timing(2 * (1 - timeFraction))) / 2; } } function circ(timeFraction) { return 1 - Math.sin(Math.acos(timeFraction)) } var EaseInOut = makeEaseInOut(circ); var canvas = document.querySelector("#canvas"), but = document.querySelector("#go"), obj = { easing: circ, color: "#FF0000", width: 5, from: {x : 20,y : 20}, to: {x : 100,y : 200}, duration: 3 * 1000, elem: canvas, callback: function() { anim(obj2)() } }, obj2 = { easing: circ, color: "#FF0000", width: 5, from: {x : 100,y : 200}, to: {x : 200,y : 20}, duration: 3 * 1000, elem: canvas, callback: function() { anim(obj3)() } }, obj3 = { easing: circ, color: "#FF0000", width: 5, from: {x : 200,y : 20}, to: {x : 20,y : 20}, duration: 2 * 1000, elem: canvas, callback: function() { alert("test") } } ; but.addEventListener("mousedown", anim(obj)); </script> </body> </html> |
рони, большое спасибо. Я посидел по разбирался, в итоге решил учится не на canvas а на svg, его я больше пока понимаю.
Вот попытался сделать бесконечную простенькую анимацию, вот она (код прилагается) И все бы хорошо, но где то после 5-7 цикла она начинает лажить и в итоге выдает ошибку "Uncaught RangeError: Maximum call stack size exceeded" пытался менять requestAnimationFrame на setInterval с частотой 24. в этом случае лагов и ошибок нет но анимация не достаточно плавная, а если поменять 24 на 20 к примеру - анимация становится плавнее, но ошибки и лаги как и в случае с requestAnimationFrame. Подскажите пожалуйста что не так я делаю в этом случае? |
jquery animate svg
smart-create,
<!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> $(function() { function a() { $({offset:100}).delay(400).animate({offset:0}, {duration:2000, step:function(a, b) { $(".data_gradient").attr(b.prop, a + "%"); }, complete:a}); } a(); }); </script> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Слой_1" x="0px" y="0px" viewBox="0 0 1642 352" xml:space="preserve"> <path class="st0" d="M1011.8,345.1L955,288.4H458.8c-2-8.7-9.9-15.2-19.2-15.2c-10.9,0-19.7,8.8-19.7,19.7 c0,10.9,8.8,19.7,19.7,19.7c10.2,0,18.7-7.8,19.6-17.8h493.1l56.8,56.8H1641v-6.4H1011.8z M439.7,306.2c-7.3,0-13.3-6-13.3-13.3 c0-7.3,6-13.3,13.3-13.3c7.3,0,13.3,6,13.3,13.3C452.9,300.2,447,306.2,439.7,306.2z"/> <path class="st1" d="M979,279l-59.7-59.7H683.5c-1.5-6-6.8-10.4-13.3-10.4c-7.5,0-13.7,6.1-13.7,13.7c0,7.5,6.1,13.7,13.7,13.7 c6.4,0,11.8-4.5,13.3-10.4h233.2l59.7,59.7H1641V279H979z M670.2,229.8c-4,0-7.2-3.2-7.2-7.2c0-4,3.2-7.2,7.2-7.2 c4,0,7.2,3.2,7.2,7.2C677.4,226.5,674.2,229.8,670.2,229.8z"/> <path class="st2" d="M956,318.4l-54-54h-64.4v1.3c0-2.8-2.3-5.1-5.1-5.1c-2.8,0-5.1,2.3-5.1,5.1s2.3,5.1,5.1,5.1 c2.8,0,5.1-2.3,5.1-5.1v1.3H901l54,54h686v-2.6H956z"/> <path class="st3" d="M1641,251h-619.9c-0.6-2.2-2.6-3.8-4.9-3.8c-2.8,0-5.1,2.3-5.1,5.1c0,2.8,2.3,5.1,5.1,5.1c2.4,0,4.4-1.7,5-3.9 H1641V251z"/> <path class="st4" d="M1026.1,301.3l-52.8-52.8H761c-3.5,0-6.4-2.9-6.4-6.4l0,0H752v14h2.6v0c0-3.5,2.9-6.4,6.4-6.4h211.8l52.8,52.8 H1641v-1.3H1026.1z"/> <polygon class="st5" points="962.1,222.9 937.7,198.5 806.7,198.5 806.7,195.5 801.6,195.5 801.6,204.1 806.7,204.1 806.7,201.1 936.6,201.1 961.1,225.5 1641,225.5 1641,222.9 "/> <path class="test st6" fill="url(#linear-gradient)" d="M1009.1-0.1l-56.8,56.8H715.4c-1-10-9.4-17.8-19.6-17.8c-10.9,0-19.7,8.8-19.7,19.7c0,10.9,8.8,19.7,19.7,19.7 c9.3,0,17.1-6.5,19.2-15.2h240l56.8-56.8H1641v-6.4H1009.1z M695.8,71.8c-7.3,0-13.3-6-13.3-13.3s6-13.3,13.3-13.3 c7.3,0,13.3,6,13.3,13.3S703.1,71.8,695.8,71.8z"/> <path class="st7" d="M976.3,71.1l-59.7,59.7H763.3c-1.5-6-6.8-10.4-13.3-10.4c-7.5,0-13.7,6.1-13.7,13.7c0,7.5,6.1,13.7,13.7,13.7 c6.4,0,11.8-4.5,13.3-10.4h156L979,77.6h662v-6.4H976.3z M750.1,141.2c-4,0-7.2-3.2-7.2-7.2c0-4,3.2-7.2,7.2-7.2 c4,0,7.2,3.2,7.2,7.2C757.3,138,754.1,141.2,750.1,141.2z"/> <path class="st8" d="M905.4,35.6l-54,54h-80.8c-0.6-2.2-2.6-3.9-5-3.9c-2.8,0-5.1,2.3-5.1,5.1c0,2.8,2.3,5.1,5.1,5.1 c2.4,0,4.4-1.6,5-3.9h81.9l54-54H1641v-2.6H905.4z"/> <path class="st9" d="M1641,102.9h-551.1c-0.6-2.2-2.6-3.9-5-3.9c-2.8,0-5.1,2.3-5.1,5.1c0,2.8,2.3,5.1,5.1,5.1 c2.4,0,4.4-1.6,4.9-3.8H1641V102.9z"/> <polygon class="st10" points="1641,203.4 987.5,203.4 987.5,200 984.9,200 984.9,208.1 987.5,208.1 987.5,204.7 1641,204.7 "/> <polygon class="st11" points="1054.2,131 1029.8,155.5 870.4,155.5 870.4,152.5 865.2,152.5 865.2,161 870.4,161 870.4,158 1030.9,158 1055.3,133.6 1641,133.6 1641,131 "/> <polygon class="st12" points="1641,153.8 1090,153.8 1090,151.2 1084.8,151.2 1084.8,159.8 1090,159.8 1090,156.4 1641,156.4 "/> <path class="st13" d="M1641,174.3H19.9c-1.4-4.1-5.2-7-9.7-7c-5.7,0-10.3,4.6-10.3,10.3c0,5.7,4.6,10.3,10.3,10.3c4.5,0,8.3-3,9.7-7 H1641V174.3z"/> <linearGradient id="linear-gradient"> <stop class="data_gradient" offset="100%" stop-color="transparent"></stop> <stop class="data_gradient" offset="100%" stop-color="gold"></stop> </linearGradient> </svg> </body> </html> |
Цитата:
При следующем вызове снова создается замыкание которое имеем ссылку на текущее замыкание и так цепочка скопов растет пока не закончатся ресурсы системы. Работает почти как рекурсия. И блин кешируйте выборки в jQuere не обязательно каждые 5 милисек. производить полный поиск по всему дереву объектов. |
рони, то есть попытка применить requestAnimationFrame или setInterval для svg была ошибочная в корне?
|
MallSerg, большое спасибо за толкования. Но я видимо не корректно поставил вопрос. Корень возникновения проблемы мне приблизительно понятен. Но мне не известно решение. Так же я к сожалению не знаком с понятием "кешируйте выборки в jQuere". Буду очень признателен если поможете с этими моментами
|
Цитата:
кеширование это один раз создать переменную var a = $(".data_gradient"); и потом использовать только a |
smart-create,
вариант без кеширования $(function() { function a() { $({offset:100}).delay(400).animate({offset:0}, {duration:2000, step:function(a, b) { $(".data_gradient").attr(b.prop, a + "%"); //каждый раз идёт поиск элементов ".data_gradient" }, complete:a}); } a(); }); вариант с "кешем" $(function() { var el = $(".data_gradient"); //поиск всего 1 раз function a() { $({offset:100}).delay(400).animate({offset:0}, {duration:2000, step:function(a, b) { el.attr(b.prop, a + "%"); // поиска элементов нет }, complete:a}); } a(); }); |
Часовой пояс GMT +3, время: 15:51. |