Disegnare una linea curva in CSS o canvas e muoverla su di essa

Oggi mi è stato dato un disegno che è un cerchio che si muove lungo una linea curva. Ho creato un JSBin con i progressi che ho compiuto finora con puro css ma sento di essere sulla direzione sbagliata. Penso che forse sarebbe meglio farlo con la canvas ma non sono sicuro da dove cominciare. Questo non è solo disegnare lungo una linea e riempire anche le barre.

Violino

Ecco il design:

inserisci la descrizione dell'immagine qui

Ecco quanto mi sono avvicinato al CSS:

inserisci la descrizione dell'immagine qui

Ecco come animare il tuo cerchio lungo la tua linea curva (che è una curva Bezier cubica).

  • Disegna la curva usando il metodo context.bezierCurveTo della canvas.

  • Chiudi il percorso arcobaleno utilizzando una serie di metodi context.lineTo della canvas.

  • Per riempire solo il percorso curvo con i colors dell’arcobaleno, puoi usare context.clip per limitare i disegni da visualizzare solo all’interno del percorso. Quindi puoi usare context.fillRect per riempire con le tue bande multicolors.

  • Usa requestAnimationFrame per creare un ciclo di animazione che disegna la tua palla a punti di passaggio crescenti lungo la curva.

  • Calcola i waypoint lungo la curva usando De Casteljau's Algorithm

Ecco il codice di esempio e una demo:

 var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; var colors=[[229,133,50],[251,183,50],[133,206,63],[22,155,116],[26,160,219]]; var points=[35,120,317,511,709,792]; var p0={x:37,y:144}; var p1={x:267,y:143}; var p2={x:651,y:129}; var p3={x:794,y:96}; var waypoints=cubicBezierPoints(p0,p1,p2,p3); var currentIndex=0; var radius=10; // requestAnimationFrame(animate); // draw the rainbow curve thing function drawCurve(){ ctx.save(); ctx.moveTo(37,144); ctx.bezierCurveTo(267,143,651,129,794,96); ctx.lineTo(794,158); ctx.lineTo(37,158); ctx.closePath(); ctx.fill(); ctx.globalCompositeOperation='source-atop'; for(var i=0;i 
 body{ background-color: ivory; } #canvas{border:1px solid red; margin:0 auto; } 
  

Ottima risposta di MarkE (e merita la ricompensa) ma quando ho visto l’algoritmo di De Casteljau e ho avuto uno sguardo ravvicinato mi ha colpito come un software di scrittura matematico, non un programmatore che fa matematica.

Usando gli argomenti passati come intermedi nel calcolo ci sono alcune operazioni che possono essere abbandonate migliorando così l’algoritmo. È la stessa funzione matematica divergente di non più di +/- 1e-14 (che nel punto di virgola mobile di Javascript è il più vicino ansible)

Per mancanza di un nome migliore cubicQ

 function cubicQ(t, a, b, c, d) { a += (b - a) * t; b += (c - b) * t; c += (d - c) * t; a += (b - a) * t; b += (c - b) * t; return a + (b - a) * t; } 

E nel caso in cui vi sia la necessità del polinomio di secondo ordine richiesto da ctx.quadraticCurveTo

 function quadQ(t, a, b, c){ a += (b - a) * t; b += (c - b) * t; return a + (b - a) * t; } 

Dove a, b, c sono i punti x o y sulla curva con b il punto di controllo. t è la posizione 0 <= t <= 1

E solo per l’interesse la versione lineare

 function linearQ(t, a, b){ return a + (b - a) * t; } 

Come puoi vedere è solo una linea. Il quadratico composto da interpolazioni lineari 3 (linee), e il cubo è 6.

Per questa domanda l’aumento del 15% delle prestazioni è banale e irrilevante, ma per il bisogno più intensivo il 15% vale le poche righe di codice aggiuntive, per non parlare del fatto che sembra solo meglio .. LOL