Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Часы Безье. Начало (https://javascript.ru/forum/dom-window/52894-chasy-beze-nachalo.html)

JSN 12.01.2015 01:31

Часы Безье. Начало
 
Здравствуйте,
Я тут наткнулся на такие веселые часы, которые были анимированы при помощи кривых Безье на Processing.js. Вот я и решил попробовать сотворить если не точную копию, то хотя бы что-то похожее.
Вот что на данный момент написано
<html>
<head>
	<style>
	* {
		padding: 0px;
		margin: 0px;
	}
	.point {
		position: absolute;
		margin-left: -5px;
		margin-top: -5px;
		background: red;
		width: 10px;
		height: 10px;
		-webkit-border-radius: 10px;
		-moz-border-radius: 10px;
		-ms-border-radius: 10px;
		-o-border-radius: 10px;
		border-radius: 10px;
	}
	#bezier {
		outline: 1px solid black;
	}
	</style>
</head>
<body>
    <canvas id='bezier' width='1000' height='800'></canvas>
    <div onclick='makeNULL()'>clear line</div>
	<script>
		var f = [1, 1], p = [], path = [], create = true;
		function getBase(i, n, t) {
		    while (n > f.length - 1) {
		        f[f.length] = f[f.length - 1] * f.length;
		    }
		    return (f[n] / (f[i] * f[n - i])) * Math.pow(t, i) * Math.pow(1 - t, n - i);
		}
		function Point(x, y) {
			var self = this;
			self.x = x;
			self.y = y;
			self.move = function (xx, yy, pos) {
				var el = document.createElement('div');
				el.className = 'point';
				document.getElementsByTagName('body')[0].appendChild(el);
				switch (arguments.length) {
					case 0:
						console.log(self.x + ' ' + self.y);
					break;
					default:
						var steps = 20,
							stepX = (xx - self.x) / steps,
							stepY = (yy - self.y) / steps;
						//console.log(stepX + ' ' + stepY);
						self.x = self.x + stepX * pos;
						self.y = self.y + stepY * pos;
					}
			}
			return self;
		}
		function getCurve(pnt, step) {
			var line = [];
		    step = step ? step : 0.01;
		    for (var i = 0; i < 1 + step; i += step) {
		        i = ((i > 1) ? 1 : i);
		        var ind = line.length;
		        line[ind] = {x:0,y:0};   
		        var len = pnt.length;
		        for (var j = 0; j < pnt.length; j++) {
		            var b = getBase(j, pnt.length - 1, i);
		            line[ind].x += pnt[j].x * b;
		            line[ind].y += pnt[j].y * b;
		        }
		    }
		    return line;
		}
		function drawS(c, line) {
		    var i = 0;
		    c.moveTo(line[0].x, line[0].y);
		    c.clearRect(0, 0, 1000, 800);
		    c.beginPath();
		    var it = setInterval(function() {
		        if (i >= line.length - 2)
		            clearInterval(it);
		        c.moveTo(line[i].x, line[i].y);
		        c.lineTo(line[i + 1].x, line[i + 1].y);
        		c.stroke();
		        i++;
		    }, 10);
		    c.closePath();
		}
		function draw(c, line) {
		    c.beginPath();
		    for (var i = 0; i < line.length - 1; ++i) {
		        c.moveTo(line[i].x, line[i].y);
		        c.lineTo(line[i + 1].x, line[i + 1].y);
        		c.stroke();
        	}
		    c.closePath();
		}
		function init() {
		    line = [];
		    var canvas = document.getElementById('bezier');
		    var c = canvas.getContext('2d');
		    canvas.width = screen.width;
		    canvas.height = screen.height;
		    c.clearRect(0, 0, canvas.width, canvas.height);
		    c.fillStyle = '#000';
		    c.lineWidth = 1;
		    return c;
		}
		init();
		p[1] = [
				new Point(21, 54),
				new Point(34, 22),
				new Point(83, 3),
				new Point(49, -3),
				new Point(58, 80),
				new Point(56, 112),
				new Point(57, 136),
				new Point(26, 137),
				new Point(78, 130),
				new Point(-1, 133),
				new Point(-2, 133),
				new Point(70, 132),
				new Point(61, 132),
		];
		p[2] = [
				new Point(47, 38),
				new Point(57, 15),
				new Point(101, 16),
				new Point(124, 54),
				new Point(116, 112),
				new Point(67, 213),
				new Point(-2, 170),
				new Point(-1, 98),
				new Point(56, 83),
				new Point(83, 94),
				new Point(21, 93),
				new Point(97, 163),
				new Point(121, 119)
		];
		p[3] = [
				new Point(21, 32),
				new Point(37, 9),
				new Point(71, 16),
				new Point(110, 32),
				new Point(89, 66),
				new Point(53, 157),
				new Point(16, 91),
				new Point(21, 50),
				new Point(58, 3),
				new Point(146, 110),
				new Point(131, 83),
				new Point(90, 183),
				new Point(18, 147)
		];
		var c = init();
		path = p[1];
		draw(c, getCurve(path));
		function move (pd) {	
			var pos = 0, steps = 20;
			var it = setInterval(function () {
				if (pos++ >= steps) {
					path = pd;
					clearInterval(it);
				}
				for (var i = 0; i < path.length; i++) {
					path[i].move(pd[i].x, pd[i].y, pos);
				};	
				var c = init();
				draw(c, getCurve(path));
			}, 10);
		}
		var sec = 1;
		setInterval(function() {
			if (sec > 3)
				sec = 1;
			move(p[sec]);
			sec++;
		}, 1000);
	</script>
</body>
</html>

Тут я столкнулся с проблемой: браузер запускает скрипт и 1 плавно cменяет 2, затем два cменяет 3, но потом 2 вместо одного cменяет 3. Но это полбеды. Со временем на исполнение функции move занимает все больше и больше времени. Я догадываюсь, что я компьютерный насильник, но поясните, пожалуйста, почему она замедляется?
Заранее благодарен
P.S. Есть смысл записать в массивы готовые точки, а не опорные?

MallSerg 12.01.2015 03:43

var el = document.createElement('div');
Дивы множатся когда их больше мильена браузер начинает подтормаживать

JSN 12.01.2015 08:01

Цитата:

Сообщение от MallSerg (Сообщение 350952)
var el = document.createElement('div');
Дивы множатся когда их больше мильена браузер начинает подтормаживать

Ох, спасибо, я и не заметил, что не убрал эту часть кода :thanks:


Часовой пояс GMT +3, время: 11:05.