Рисование спирографа с единственной линией - PullRequest
0 голосов
/ 23 сентября 2019

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

PS.это для класса, хотя анимация не требуется, я просто хотел бы посмотреть, как я буду делать это

HTML

<head>

</head>
<body>

<canvas id="canvas" width="500" height="500"
style="border:1px solid black;">

<script src="test.js"></script>

Your browser does not support the canvas element.
</canvas>
<br>
<button onclick="draw(context)">Draw</button>
<button onclick="randoSpiro(context)">Random</button>
<button onlick="drawSpiro()">Draw Spiro</button>
<b>High = .01 </b> <input id="resolution" type="range" min="1" max="100" value="1" onchange="draw(context)"><b> 1 = Low</b>
<br>
R<input id="R" value="86" type="number" onchange="draw(context)"></td>
<br>
r<input id="r" value="75" type="number" onchange="draw(context)"></td>
<br>
O<input id="O" value="30" type="number" onchange="draw(context)"></td>
<br>
T-Ratio<input id="t" value="9" type="number" step="0.1" onchange="draw(context)">
<br>



</body>
</html>


var canvas = document.getElementById("canvas");
 var context = canvas.getContext("2d");



function draw(position){
  let R = parseInt(document.getElementById("R").value);
  let r = parseInt(document.getElementById("r").value);
  let O = parseInt(document.getElementById("O").value);
  let t = parseFloat(document.getElementById("t").value);
  let i = parseFloat(document.getElementById("resolution").value / 100);

  spiro(R,r,O,t,i,position);
}
/////////Randomly creates variables for spirograph//////////
function randoSpiro(position){

  let R = Math.floor(Math.random() * Math.floor(200))
  let r = Math.floor(Math.random() * Math.floor(140))
  let O = Math.floor(Math.random() * Math.floor(200))
  let t = (Math.floor(Math.random() * 100) / 10) + 0.1
  let i = parseFloat(document.getElementById("resolution").value / 100);

  spiro(R,r,O,t,i,position);
}
//////////////////////////////////////////////////////////////

//////////////////Creates Spirograph//////////////////////////
function spiro(R,r,O,tRatio,resolution,position){

var cx = canvas.width / 2 ;
var cy = canvas.height / 2 ;
position.clearRect(0, 0, canvas.width, canvas.height);


position.moveTo(cx, cy); 
position.beginPath();

    for (var i = 0; i < 500; i+= resolution) {

        let t  = tRatio * i;
        let x = cx + ((R+r)*Math.cos(t) - (r+O)*Math.cos(((R+r)/r)*t));
                let y = cy - ((R+r)*Math.sin(t) - (r+O)*Math.sin(((R+r)/r)*t));

     position.lineTo(x, y);
    }
    position.strokeStyle = "#000";
    position.stroke();

}
///////////////////////////////////////////////////////////

//Draw spirograph
function drawSpiro(R,r,O,tRatio,i,position){

  var cx = canvas.width / 2 ;
  var cy = canvas.height / 2 ;
  position.clearRect(0, 0, canvas.width, canvas.height);
  position.moveTo(cx, cy); 
  position.beginPath();

  for (var i = 1; i < 100; i++) {

          let t  = tRatio * i;
          let x = cx + ((R+r)*Math.cos(t) - (r+O)*Math.cos(((R+r)/r)*t));
          let y = cy - ((R+r)*Math.sin(t) - (r+O)*Math.sin(((R+r)/r)*t));

       position.lineTo(x, y);
      position.strokeStyle = "#000";
      position.stroke();
    }
  }```

1 Ответ

1 голос
/ 23 сентября 2019

Чтобы добавить анимацию в ваш код, вам нужно немного реорганизовать код:

  • Создать функцию, которая рисует только один отрезок вашей петли.Это означает, что начинайте новый путь и обводите каждый сегмент
  • несколько раз вызовом requestAnimationFrame вместо вашего цикла, остановитесь на счетчике итераций
  • Будьте осторожны, если началось рисование другой линии!Если это так, прекратите вызывать requestAnimationFrame

Здесь простое расширение.Поиграйте немного с параметрами и, возможно, добавьте цвета.Веселитесь!

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var ident = 0;


function draw(position) {
  let R = parseInt(document.getElementById("R").value);
  let r = parseInt(document.getElementById("r").value);
  let O = parseInt(document.getElementById("O").value);
  let t = parseFloat(document.getElementById("t").value);
  let i = parseFloat(document.getElementById("resolution").value / 100);

  spiro(R, r, O, t, i, position);
}
/////////Randomly creates variables for spirograph//////////
function randoSpiro(position) {

  let R = Math.floor(Math.random() * Math.floor(200))
  let r = Math.floor(Math.random() * Math.floor(140))
  let O = Math.floor(Math.random() * Math.floor(200))
  let t = (Math.floor(Math.random() * 100) / 10) + 0.1
  let i = parseFloat(document.getElementById("resolution").value / 100);

  spiro(R, r, O, t, i, position);
}
//////////////////////////////////////////////////////////////

//////////////////Creates Spirograph//////////////////////////
function spiro(R, r, O, tRatio, resolution, position) {

  var cx = canvas.width / 2;
  var cy = canvas.height / 2;
  position.clearRect(0, 0, canvas.width, canvas.height);

  var ox = cx;
  var oy = cy;

  var i = 0;
  var myIdent = ++ident;
  position.strokeStyle = "#000";

  function step() {
    if (ident != myIdent) return;

    position.beginPath();
    position.moveTo(ox, oy);


    let t = tRatio * i;
    let x = cx + ((R + r) * Math.cos(t) - (r + O) * Math.cos(((R + r) / r) * t));
    let y = cy - ((R + r) * Math.sin(t) - (r + O) * Math.sin(((R + r) / r) * t));

    ox = x;
    oy = y;
    position.lineTo(x, y);
    position.stroke();
    i++;
    if (i < 500) window.requestAnimationFrame(step);
  }

  step();

}
///////////////////////////////////////////////////////////

//Draw spirograph
function drawSpiro(R, r, O, tRatio, i, position) {

  var cx = canvas.width / 2;
  var cy = canvas.height / 2;
  position.clearRect(0, 0, canvas.width, canvas.height);
  position.moveTo(cx, cy);
  position.beginPath();

  for (var i = 1; i < 100; i++) {

    let t = tRatio * i;
    let x = cx + ((R + r) * Math.cos(t) - (r + O) * Math.cos(((R + r) / r) * t));
    let y = cy - ((R + r) * Math.sin(t) - (r + O) * Math.sin(((R + r) / r) * t));

    position.lineTo(x, y);
    position.strokeStyle = "#000";
    position.stroke();
  }
}
<canvas id="canvas" width="500" height="500" style="border:1px solid black;">

<script src="test.js"></script>

Your browser does not support the canvas element.
</canvas>
<br>
<button onclick="draw(context)">Draw</button>
<button onclick="randoSpiro(context)">Random</button>
<button onlick="drawSpiro()">Draw Spiro</button>
<b>High = .01 </b> <input id="resolution" type="range" min="1" max="100" value="1" onchange="draw(context)"><b> 1 = Low</b>
<br> R
<input id="R" value="50" type="number" onchange="draw(context)"></td>
<br> r
<input id="r" value="75" type="number" onchange="draw(context)"></td>
<br> O
<input id="O" value="30" type="number" onchange="draw(context)"></td>
<br> T-Ratio
<input id="t" value="0.1" type="number" step="0.1" onchange="draw(context)">
<br>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...