Почему подтормаживает анимация?
В чём дело, в коде или в железе? (а может и в том и том, ведь я беден и криворук одновременно).
Вот html файл: https://drive.google.com/open?id=1UE...MjIexOXMGQj-nG Может действительно в железе, поскольку программа вращает против часовой стрелки фигуру, имеющую 12 высот, а для каждой она вычисляет sin и cos... |
MrRiseYT,
setInterval(rotateFigure,1) картинка тут код вентилятора ниже :) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Any title</title> </head> <body> <canvas id="canvas" width="5000" height="5000"></canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); function defineWay (x,y) { if ((y>0)||(y === 0)) { return Math.acos(x); } else return (2*Math.PI-Math.acos(x)); }; function radiansToDegrees (rad) { return rad/(Math.PI/180); }; var square = { 'name' : 'Square #1', 'demension' : '2D', 'coordinates' : [[200,0],[0,0],[0,200],[200,200]], 'connecting' : [[0,1],[1,2],[2,3],[3,0]], 'vertexes' : 4 }; var strange = { 'name' : 'strange', 'demension' : '2D', 'coordinates' : [[600,100],[400,100],[400,0],[0,0],[0,200],[100,200],[100,600],[300,600],[300,500],[400,500],[400,400],[600,400]], 'connecting' : [[0,1],[1,2],[2,3],[3,0]], 'vertexes' : 12 }; var triangle = { 'name' : 'triangle', 'demension' : '2D', 'coordinates' : [[200,200],[100,0],[0,200]], 'connecting' : [[0,1],[1,2],[2,3],[3,0]], 'vertexes' : 3 }; var house = { 'name' : 'house', 'demension' : '2D', 'coordinates' : [[300,200],[200,0],[100,200],[100,400],[300,400]], 'connecting' : [[0,1],[1,2],[2,3],[3,0]], 'vertexes' : 5 }; function center (figure) { if (figure.demension === '2D') { var x_center = 0; var y_center = 0; var center = []; for (var i = 0; i<figure.vertexes; i++) { x_center+=figure.coordinates[i][0]; y_center+=figure.coordinates[i][1]; }; x_center = x_center / figure.vertexes; y_center = y_center / figure.vertexes; center[0] = x_center; center[1] = y_center; return center; }; }; var circle = function (x, y, radius, fillCircle) { ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.PI * 2, false); if (fillCircle) { ctx.fill(); } else { ctx.stroke(); } }; function distance2D (x1,y1,x2,y2) { return Math.sqrt((x1-x2)*(x1-x2)+ (y1-y2)*(y1-y2)); }; function drawFigure (figure,x,y) { ctx.beginPath(); ctx.moveTo(figure.coordinates[0][0]+x,figure.coordinates[0][1]+y); for (var i = 1; i<figure.vertexes; i++) { ctx.lineTo(figure.coordinates[i][0]+x,figure.coordinates[i][1]+y); }; ctx.lineTo(figure.coordinates[0][0]+x,figure.coordinates[0][1]+y); ctx.strokeStyle = 'red'; ctx.stroke(); ctx.strokeStyle = 'black'; }; function drawCircles (figure,x,y) { for (var i = 0; i<figure.vertexes; i++) { ctx.beginPath(); ctx.arc(center(figure)[0]+x,center(figure)[1]+y,distance2D(center(figure)[0]+x,center(figure)[1]+y,figure.coordinates[i][0]+x,figure.coordinates[i][1]+y),0,2*Math.PI,false); ctx.stroke(); }; }; function reCenter (x0,y0,r,x1,y1) { var localCenter = []; localCenter[0] = (x1-x0)/r; localCenter[1] = -1*(y1-y0)/r; return localCenter; }; function reCenterBack (x0,y0,r,local1,local2) { var globalCenter = []; globalCenter[0] = local1*r+x0; globalCenter[1] = -1*local2*r+y0; return globalCenter; }; function powerfulDefineStrange (x,y) { return radiansToDegrees(defineWay(reCenter(300,300,distance2D(x,y,300,300),x,y)[0],reCenter(300,300,distance2D(x,y,300,300),x,y)[1])); }; function powerfulDefine (figure,x,y) { return radiansToDegrees(defineWay(reCenter(center(figure)[0],center(figure)[1],distance2D(x,y,center(figure)[0],center(figure)[1]),x,y)[0],reCenter(center(figure)[0],center(figure)[1],distance2D(x,y,center(figure)[0],center(figure)[1]),x,y)[1])); }; var x1 = x2 = x3 = x4 = y1 = y2 = y3 = y4 = 0; var n = 0; function drawRotatingSquare () { x1 = Math.cos(Math.PI/4+n*Math.PI/10); //Верхняя левая y1 = Math.sin(Math.PI/4+n*Math.PI/10); x2 = Math.cos((3*Math.PI)/4+n*Math.PI/10); //Верхняя правая y2 = Math.sin((3*Math.PI)/4+n*Math.PI/10); x3 = Math.cos((5*Math.PI)/4+n*Math.PI/10); //Нижняя правая y3 = Math.sin((5*Math.PI)/4+n*Math.PI/10); x4 = Math.cos((7*Math.PI)/4+n*Math.PI/10); //Нижняя левая y4 = Math.sin((7*Math.PI)/4+n*Math.PI/10); x1 = reCenterBack(100,100,distance,x1,y1)[0]; y1 = reCenterBack(100,100,distance,x1,y1)[1]; x2 = reCenterBack(100,100,distance,x2,y2)[0]; y2 = reCenterBack(100,100,distance,x2,y2)[1]; x3 = reCenterBack(100,100,distance,x3,y3)[0]; y3 = reCenterBack(100,100,distance,x3,y3)[1]; x4 = reCenterBack(100,100,distance,x4,y4)[0]; y4 = reCenterBack(100,100,distance,x4,y4)[1]; ctx.clearRect(0,0,1000,1000); ctx.beginPath(); ctx.moveTo(x1+200,y1+200); ctx.lineTo(x2+200,y2+200); ctx.lineTo(x3+200,y3+200); ctx.lineTo(x4+200,y4+200); ctx.lineTo(x1+200,y1+200); ctx.stroke(); n = n + 0.01 drawCircles(square,200,200); }; //drawFigure(strange); //drawCircles(strange); //setInterval(drawRotatingSquare,1); function rotateFigure(figure) { figure = strange; var figureCenterX = center(figure)[0]; var figureCenterY = center(figure)[1]; var degreesArray = []; if (degreesArray.length === 0) { for (var i = 0; i<figure.vertexes; i++) { degreesArray[i] = (Math.PI/180)*powerfulDefine(figure,figure.coordinates[i][0],figure.coordinates[i][1]); }; }; for (var i = 0; i<figure.vertexes; i++) { var distance = distance2D(figureCenterX,figureCenterY,figure.coordinates[i][0],figure.coordinates[i][1]); figure.coordinates[i][0] = Math.cos(degreesArray[i] + n*Math.PI/10); figure.coordinates[i][1] = Math.sin(degreesArray[i] + n*Math.PI/10); figure.coordinates[i][0] = reCenterBack(figureCenterX,figureCenterY,distance,figure.coordinates[i][0],figure.coordinates[i][1])[0]; figure.coordinates[i][1] = reCenterBack(figureCenterX,figureCenterY,distance,figure.coordinates[i][0],figure.coordinates[i][1])[1]; }; ctx.clearRect(0,0,1000,1000); drawFigure(figure,200,200); //drawCircles(figure,200,200); n = 1; }; function figureDegrees (figure) { var degreesArray = []; for (var i = 0; i<figure.vertexes; i++) { degreesArray[i] = (Math.PI/180)*powerfulDefine(figure,figure.coordinates[i][0],figure.coordinates[i][1]); }; return degreesArray; }; setInterval(rotateFigure,1000/60) </script> </body> </html> |
На такие вопросы отвечает профилирование приложений загугли посмотри на ютубе.
но setInterval(rotateFigure,1) - не лучшее решение для анимации. и ужасно много ненужных и часто повторяющихся вычислений. К примеру функция центр в которой много вычислений цикл по вершинам вызывается много раз за одну анимацию в этом нет никакой необходимости т.к. фигура не двигается и ее центр не изменяется. Еще любопытный факт что если сдвинуть фигуру на 100 пикселей вправо то и ее центр также сдвинется вправо на 100 пикселей и совсем не обязательно пересчитывать все вершины и искать их центр. Такие вычисления происходят на каждой отрисовке кадра и для каждой фигуры. Тригонометрические функции так же не лучший подход для вычислений вращения фигуры. Обычно в анимации используют комплексные числа матрицу поворота для простых вращений ну или же матрицу трансформации для более сложных фращений перемещений или масштабирования. Просто работа с комплексными числами сводится к простым арифметическим операциям над матрицами что для компьютера гораздо проще чем расчеты тригонометрических функций. Приведенный код простой и не должен притормаживать даже на слабых устройствах вроде телефонов. Проблема в том что анимации не выглядит плавной =). а это уже отдельная тема |
Часовой пояс GMT +3, время: 01:59. |