Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

160
Visualizações
Sine wave that does not lose its original structure when shortened or lengthened

I would like to replicate a sine wave function as a spring that expand and contracts without losing its original wave structure, like the spring animation of a bouncing black box (not the red wave), found here. Í am able to draw a sine wave and edit its length but cannot keep the same structure of the sine wave.

Take a look at the animation at https://react-spring.io/#why-springs-and-not-durations

You can see that the spring expands and contracts without losing its wave form.

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var i;
for(i=0; i<360; i+= 20){
 ctx.moveTo(i+5,180);
    ctx.lineTo(i,180);

}
ctx.stroke();

var counter = 0, x=0,y=180;


//100 iterations
var increase = ((110/180)*(Math.PI / 3));
for(i=0; i<=270; i+=10){
     ctx.moveTo(x,y);
    x = i;
    y =  180 - Math.sin(counter) * 113;
        counter += increase;
     
    ctx.lineTo(x,y);
    ctx.stroke();
    //alert( " x : " + x + " y : " + y + " increase : " + counter ) ;
}
<canvas id="myCanvas" width="360" height="360" style="border:1px solid #d3d3d3;">

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

To keep the wave form in your canvas you need a smaller iteration increment. You can see below that I used a 0.1 increment.

I also modified the function in order to use scale parameters so that you can modify the period and amplitude:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var i;
for (i = 0; i < 360; i += 20) {
  ctx.moveTo(i + 5, 180);
  ctx.lineTo(i, 180);

}
ctx.stroke();


const increase = 0.1;
const scale = { 
    x: 18,
    y: 90
};

for (let x = 0; x <= 360 / scale.x;) {

  ctx.moveTo(x * scale.x, Math.sin(x) * scale.y + 180);
  x += increase;
  ctx.lineTo(x * scale.x, Math.sin(x) * scale.y + 180);
  ctx.stroke();

}
<canvas id="myCanvas" width="360" height="360" style="border:1px solid #d3d3d3;">

about 4 years ago · Juan Pablo Isaza Relatório

0

In canvas, the simplest way to imitate a sine could be done by ctx.quadraticCurveTo(). Here is one period;

ctx.beginPath();
ctx.moveTo(150,50);                   // starting point of the curve
ctx.quadraticCurveTo(160,60,150,70);  // control point and final point
ctx.quadraticCurveTo(140,80,150,90);  // control point and final point

Just to give you an idea i prepared a makeshift implementation of the example that you linked. The vertical oscillation is also sinusoidal like shown in the example. As always all modifications and updates of the DOM and canvas shall be done behind requestAnimationFrame and inside a document fragment.

var cont   = document.getElementById("container"),
    frag   = new DocumentFragment(),
    canvas,
    ctx;

function drawSpring(startX, startY, spins = 10, radius = 20, period = 15){
  ctx.beginPath();
  ctx.moveTo(startX, startY);
  ctx.lineTo(startX,startY += 10); // increment startY by 10 and draw a line to startX startY
  while (spins--){
    ctx.quadraticCurveTo(startX+radius, startY+period*0.25, startX, startY+period*0.5);
    ctx.quadraticCurveTo(startX-radius, startY+period*0.75, startX, startY+period);
    startY += period;
  }
  ctx.lineTo(startX, startY += 10);
  ctx.stroke();
  ctx.fillRect(startX -= radius, startY,radius*2 , radius*2);
}

function oscillator(freq, amp, step = 0, spins = 10){
  var delta  = Math.sin(Math.PI*step)*amp/spins,
      period = 15 + delta;

  canvas = cont.children[0].cloneNode("true");
  ctx = canvas.getContext('2d');
  step = (step + Math.PI * freq / 60) % 120; 
  requestAnimationFrame(_ => ( drawSpring(150,25,spins,20,period)
                             , frag.appendChild(canvas)
                             , cont.children[0].replaceWith(frag)
                             , oscillator(freq,amp,step,spins)
                             )
                       );
}

oscillator(1,60);
<div id="container">
  <canvas width="300" height="300"></canvas>
</div>

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda