Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

159
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!