Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

164
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda