Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Canvas. Как сделать или вообще нельзя? Вращение рандомизированно изменяемого объекта. (https://javascript.ru/forum/misc/43614-canvas-kak-sdelat-ili-voobshhe-nelzya-vrashhenie-randomizirovanno-izmenyaemogo-obekta.html)

Zemsky 13.12.2013 17:42

Canvas. Как сделать или вообще нельзя? Вращение рандомизированно изменяемого объекта.
 
Как это сделать в canvas? Или вообще не получится?

Пример:
- отрисованный объект (не подгружаемый). Например, стрелка заданного размера, цвета (именно нарисованная как пятиугольник).
- ориентация "вверх-вниз-влево-вправо". 90 град. Random.
- изменение положения объекта (центра) в пределах квадрата со стороной в 2 раза больше длины объекта. Random. Шаг 10 пикселей.
- изменение размера объекта. Увеличение/уменьшение с шагом 0,1 от начального размера до в 2-е увеличенного. Random.
- таймер 1 секунда, счетчик до 10.

Т.е. стрелка каждую секунду меняет свое положение, размер и ориентацию.

Не получаются совместные вращения с перемещением центра вращения в центр рандомизированно построенного смещенного объекта. Учусь... Находил примеры для подгружаемых рисунков. Аналогия не получается.. А может и нельзя сделать? М.б. нужны библиотеки или по-другому как-то?

Faab 13.12.2013 18:32

Я тоже только учусь, но если каждую секунду воздействовать на свойства в CSS (размер, угол вращения), то может получится.. а canvas вроде для цвета, но я точно не утвеждаю.

Zemsky 13.12.2013 18:57

Вот пытаюсь:

<!DOCTYPE HTML>
<html>                                                
<head>                                                      
<script>

        setInterval(function() {

        var canvas=document.getElementById("myCanvas");
	var context=canvas.getContext("2d");
// Очистка холста        
    context.clearRect(0, 0, canvas.width, canvas.height);    
// Размеры квадрата.        
        var rectWidth = 40;
	var rectHeight = 40;          
// Расчет угла поворота по часовой стрелке
        var q1 = Math.floor((Math.round(Math.random()*10))/4);
        var q2 = Math.floor((Math.round(Math.random()*10))/4);
// Расчет смещения стимула по X и Y 	   
        var x1 = 20+Math.round((Math.random()*10));
        var y1 = 20+Math.round((Math.random()*10));
//        var x2 = 100+Math.round(Math.random()*100)/10);
//        var y2 = 100+Math.round(Math.random()*100)/10);                 

 
 
  
// Смещение начала осей координат в центр фигуры
	context.translate(canvas.width/2,canvas.height/2); 		
// Смещение фигуры
        context.translate(x1,y1);
        //context.translate(-x2,-y2);
// Поворот фигуры
        context.rotate(Math.PI/q1);
        context.rotate(Math.PI/q2);
 
// Рисование квадрата

        context.fillStyle="#ff0000";
	context.fillRect(-rectWidth/2,-rectHeight/2,rectWidth,rectHeight);
// Вставка символа
	context.font="30pt Calibri";
	context.textAlign="center";
	context.fillStyle="#0000ff";
	context.fillText("Ю",0,15); }, 200);
 
</script>
</head>
<body>
	<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>

Zemsky 13.12.2013 19:33

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 286518)
Пожалуйста, отформатируйте свой код!

Так сделал?

Faab 13.12.2013 20:02

Наверное он просил это (чистый JS):
setInterval(function() {

        var canvas=document.getElementById("myCanvas");
	var context=canvas.getContext("2d");
// Очистка холста        
    context.clearRect(0, 0, canvas.width, canvas.height);    
// Размеры квадрата.        
        var rectWidth = 40;
	var rectHeight = 40;          
// Расчет угла поворота по часовой стрелке
        var q1 = Math.floor((Math.round(Math.random()*10))/4);
        var q2 = Math.floor((Math.round(Math.random()*10))/4);
// Расчет смещения стимула по X и Y 	   
        var x1 = 20+Math.round((Math.random()*10));
        var y1 = 20+Math.round((Math.random()*10));
//        var x2 = 100+Math.round(Math.random()*100)/10);
//        var y2 = 100+Math.round(Math.random()*100)/10);                 

  
// Смещение начала осей координат в центр фигуры
	context.translate(canvas.width/2,canvas.height/2); 		
// Смещение фигуры
        context.translate(x1,y1);
        //context.translate(-x2,-y2);
// Поворот фигуры
        context.rotate(Math.PI/q1);
        context.rotate(Math.PI/q2);
 
// Рисование квадрата

        context.fillStyle="#ff0000";
	context.fillRect(-rectWidth/2,-rectHeight/2,rectWidth,rectHeight);
// Вставка символа
	context.font="30pt Calibri";
	context.textAlign="center";
	context.fillStyle="#0000ff";
	context.fillText("Ю",0,15); }, 200);

Zemsky 13.12.2013 21:34

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 286534)
Zemsky,

Кстати, у вас эффект всех context.translate и context.rotate будет складываться, и получится, что вся картинка через несколько кадров уедет куда-то за экран.
Перед изменениями трансформаций желательно сохранить контекст, а после рендеринга восстановить.

Спасибо. Понял. Буду пробовать.

Zemsky 18.12.2013 19:23

Попробовал сделать цикл. Чтобы значение угла поворота квадрата не повторялось подряд. В чем я ошибся?

a=0;
		
		// Первое объявление переменных для проверки неповторения значения q
		var q=0;  
		var qold=0;


	
        b=setInterval (function() {
        var canvas=document.getElementById("myCanvas");
	    var context=canvas.getContext("2d");
// Размеры квадрата.        
        var rectWidth = 40;
	    var rectHeight = 40;          
// Сохранение 
        context.save();
// Очистка холста 
        context.clearRect(0, 0, canvas.width, canvas.height);      
// Смещение начала осей координат в центр фигуры
        context.translate(canvas.width/2+Math.round((Math.random()*100)-50),canvas.height/2+Math.round((Math.random()*100)-50)); 		

		
		// Алгоритм поворота квадрата с проверкой неповторения значения q 
		
		// Расчет угла поворота по часовой стрелке
        if (q==qold) {
		q = Math.floor((Math.random()*10)/3)*0.5;}
		// Поворот  	
		context.rotate(Math.PI*q);
		qold=q;
		
		
		
// Рисование квадрата
        context.fillStyle="#ff0000";
	    context.fillRect(0,0,rectWidth,rectHeight);
// Вставка символа
	    context.font="30pt Calibri";
	    context.textAlign="center";
	    context.fillStyle="#0000ff";
	    context.fillText("W",20,33);
        a++;
        if(a==50){clearInterval(b)};
		// Восстановление
        context.restore(); 
        }, 1000);

рони 18.12.2013 19:57

Zemsky,
Вариант...
Цитата:

Сообщение от Zemsky
Чтобы значение угла поворота квадрата не повторялось подряд

<!DOCTYPE html>

<html>
<head>
  <title></title>
  <meta charset="utf-8">
</head>

<body>
  <canvas id="myCanvas" width="400" height="400"></canvas> <script>
  var a = 0;

  // Первое объявление переменных для проверки неповторения значения q
  var q = 0;
  var qold = 0;
  var b = setInterval(function () {
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
    // Размеры квадрата.
    var rectWidth = 40;
    var rectHeight = 40;
    // Сохранение
    context.save();
    // Очистка холста
    context.clearRect(0, 0, canvas.width, canvas.height);
    // Смещение начала осей координат в центр фигуры
    context.translate(canvas.width / 2 + Math.round((Math.random() * 100) - 50), canvas.height / 2 + Math.round((Math.random() * 100) - 50));


    // Алгоритм поворота квадрата с проверкой неповторения значения q

    // Расчет угла поворота по часовой стрелке

    do {
        q = Math.floor((Math.random() * 10) / 3) * 0.5
    } while (q == qold)

    // Поворот
    context.rotate(Math.PI * q);
    qold = q;

    // Рисование квадрата
    context.fillStyle = "#ff0000";
    context.fillRect(0, 0, rectWidth, rectHeight);
    // Вставка символа
    context.font = "30pt Calibri";
    context.textAlign = "center";
    context.fillStyle = "#0000ff";
    context.fillText("\u2603", 20, 33);
    a++;
    if (a == 50) {
        clearInterval(b)
    };
    // Восстановление
    context.restore();
  }, 1000);
  </script>
</body>
</html>

Zemsky 18.12.2013 20:09

Правильно ли я понял, что надо было применить другой цикл? Сейчас еще раз осмыслю. Спасибо! Продолжаю изучать. :)

рони 18.12.2013 20:40

для вашего варианта сколько раз прежнее значение может повторится за 50 шагов
for (var i = 0, k = 0, q = 0, qold; i < 50; i++) {
      if (q == qold) {
          q = Math.floor((Math.random() * 10) / 3) * 0.5;
      };
      if (q == qold) k++;
      qold = q;
  }
  alert('50 -> ' + k)


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