Come posso animare il disegno di testo su una pagina Web?


229

Voglio avere una pagina web che abbia una parola centrata.

Voglio che questa parola sia disegnata con un'animazione, in modo tale che la pagina "scriva" la parola nello stesso modo in cui vorremmo, cioè inizia da un punto e disegna linee e curve nel tempo in modo che il risultato finale sia un glifo.

Non mi importa se questo è fatto con <canvas>o il DOM e non mi importa se è fatto con JavaScript o CSS. L'assenza di jQuery sarebbe piacevole, ma non necessaria.

Come posso fare questo? Ho cercato esaustivamente senza fortuna.


2
Ho messo qualche pensiero in come in realtà caratteri "scrivere a mano" e postato il mio pensiero qui: stackoverflow.com/questions/12700731/...
Marke

C'è qualcosa di molto simile in un articolo di codrops (con una demo in timpano )
Francisco Presencia,

1
Ai tempi, stavo facendo questa animazione in Flash usando maschere di sprite animate. Ciò di cui hai bisogno è animare una maschera, il che significa che rivela progressivamente il testo. L'animazione sarebbe composta da cornici di maschere.
Tiberiu-Ionuț Stan,

Ovviamente, avresti il ​​vantaggio di poter spezzare il testo in curve. Dovresti farlo usando prima di usare a mano SVG e alcuni editor SVG (Illustrator o qualsiasi altra cosa possa creare un SVG del tuo testo). Non so se gli SVG supportino le maschere, ma se lo facessero, questo sarebbe molto più facile da animare.
Tiberiu-Ionuț Stan,

Usa SVG e manipola il codice SVG con JavaScript per creare l'animazione.
Il Demz

Risposte:


264

Voglio che questa parola sia disegnata con un'animazione, in modo tale che la pagina "scriva" la parola nello stesso modo in cui vorremmo

Versione su tela

Questo attirerà singoli caratteri più come uno scriverà a mano. Utilizza un lungo trattino in cui l'ordine di attivazione / disattivazione viene scambiato nel tempo per carattere. Ha anche un parametro di velocità.

Istantanea
Esempio di animazione (vedere la demo seguente)

Per aumentare il realismo e l'atmosfera organica, ho aggiunto una spaziatura casuale delle lettere, un offset delta y, trasparenza, una rotazione molto sottile e infine usando un carattere già "scritto a mano". Questi possono essere raggruppati come parametri dinamici per fornire una vasta gamma di "stili di scrittura".

Per un aspetto ancora più realistico sarebbero necessari i dati del percorso che non sono predefiniti. Ma questo è un breve ed efficace pezzo di codice che si avvicina al comportamento scritto a mano e facile da implementare.

Come funziona

Definendo uno schema a tratteggio possiamo creare formiche in marcia, linee tratteggiate e così via. Approfittando di questo definendo un punto molto lungo per il punto "off" e aumentando gradualmente il punto "on", si darà l'illusione di tracciare la linea quando viene accarezzato mentre si anima la lunghezza del punto.

Poiché il punto spento è così lungo, il motivo ripetuto non sarà visibile (la lunghezza varierà con la dimensione e le caratteristiche del carattere tipografico in uso). Il percorso della lettera avrà una lunghezza, quindi dobbiamo assicurarci di avere almeno ogni punto ogni punto che copra questa lunghezza.

Per le lettere che consistono in più di un percorso (es. O, R, P ecc.) Come uno è per il contorno, uno è per la parte vuota, le linee appariranno disegnate simultaneamente. Non possiamo fare molto al riguardo con questa tecnica in quanto richiederebbe l'accesso a ciascun segmento di percorso da tracciare separatamente.

Compatibilità

Per i browser che non supportano l'elemento canvas è possibile posizionare un modo alternativo per mostrare il testo tra i tag, ad esempio un testo con stile:

<canvas ...>
    <div class="txtStyle">STROKE-ON CANVAS</div>
</canvas>

dimostrazione

Questo produce il tratto animato animato tratto-on ( nessuna dipendenza ) -

var ctx = document.querySelector("canvas").getContext("2d"),
    dashLen = 220, dashOffset = dashLen, speed = 5,
    txt = "STROKE-ON CANVAS", x = 30, i = 0;

ctx.font = "50px Comic Sans MS, cursive, TSCu_Comic, sans-serif"; 
ctx.lineWidth = 5; ctx.lineJoin = "round"; ctx.globalAlpha = 2/3;
ctx.strokeStyle = ctx.fillStyle = "#1f2f90";

(function loop() {
  ctx.clearRect(x, 0, 60, 150);
  ctx.setLineDash([dashLen - dashOffset, dashOffset - speed]); // create a long dash mask
  dashOffset -= speed;                                         // reduce dash length
  ctx.strokeText(txt[i], x, 90);                               // stroke letter

  if (dashOffset > 0) requestAnimationFrame(loop);             // animate
  else {
    ctx.fillText(txt[i], x, 90);                               // fill final letter
    dashOffset = dashLen;                                      // prep next char
    x += ctx.measureText(txt[i++]).width + ctx.lineWidth * Math.random();
    ctx.setTransform(1, 0, 0, 1, 0, 3 * Math.random());        // random y-delta
    ctx.rotate(Math.random() * 0.005);                         // random rotation
    if (i < txt.length) requestAnimationFrame(loop);
  }
})();
canvas {background:url(http://i.imgur.com/5RIXWIE.png)}
<canvas width=630></canvas>


21
Sono l'unico ad impazzire per questo? Sembra così reale, almeno, molto meglio della prima risposta e più vicino alla domanda dell'interrogatore.
KhoPhi,

5
Ho finito per usare l'altra risposta, perché ne avevo bisogno subito come hack rapido che ho usato il giorno successivo e poi non ho mai più toccato, ma sto accettando questo perché è molto più vicino a quello che stavo guardando per.
strugee,

Come possiamo farlo per più righe e un lungo blocco di testo?
Saad Farooq,

1
@ K3N Sì, in realtà è stato un bel tocco: p Ottimo lavoro.
keyser,

1
@ AliAl-arnous potresti impostare x sull'estremità opposta, sottrarre la larghezza del carattere invece di aggiungere, trasformare con spazio negativo negato e cambiare clearRect per cancellare dall'altro lato del carattere.

216

Modifica 2019


Ho creato una libreria javascript in grado di creare animazioni realistiche. È facile da usare e richiede uno speciale file JSON che funge da carattere.

var vara = new Vara("#container", "https://rawcdn.githack.com/akzhy/Vara/ed6ab92fdf196596266ae76867c415fa659eb348/fonts/Satisfy/SatisfySL.json", [{
  text: "Hello World!!",
  fontSize: 48,
  y:10
}, {
  text: "Realistic Animations",
  fontSize: 34,
  color:"#f44336"
}], {
  strokeWidth: 2,
  textAlign:"center"
});
#container {
  padding: 30px;
}
<script src="https://rawcdn.githack.com/akzhy/Vara/16e30acca2872212e28735cfdbaba696a355c780/src/vara.min.js"></script>
<div id="container"></div>

Checkout la pagina di Github per la documentazione e gli esempi. E Codepen


Risposta precedente

L'esempio seguente usa snap.js per creare dinamicamente tspanelementi e animare ciascuno di essi stroke-dashoffset.

Risposta precedente


Puoi fare qualcosa del genere usando svg's stroke-dasharray

Senza keyframesanimazione puoi fare qualcosa del genere

E per il supporto IE puoi usare jquery / javascript


4
Wow, è davvero interessante. Ho preso il tuo frammento di codice originale e l'ho migliorato un po 'rimuovendo le proprietà CSS duplicate, usando offset basati su percentuale e valori di dasharray e cambiando l'ampiezza del tratto per rendere più evidente il funzionamento del codice: jsfiddle.net/Ajedi32/gdc4azLn / 1 Sentiti libero di modificare uno di questi miglioramenti nella tua risposta, se lo desideri.
Ajedi32,

2
questa è una soluzione epica per questa domanda, SVG è meglio di canvas (+1) in quanto nel caso in cui il browser non lo supporti mostrerà invece il testo.
Jeffery ThaGintoki,

3
@JefferyThaGintoki puoi farlo anche con la tela, posiziona semplicemente il testo tra i tag della tela, se la tela non è supportata apparirà invece il testo (o gif animato come nell'altra risposta nel testo del corpo). Se il browser non supporta il canvas probabilmente non supporterà neanche svg.
torox,

1
Penso che l'uso del testo in formato SVG sia ottimo, comunque mi chiedo, è possibile aggiungere il riempimento a un certo punto? solo il contorno delle lettere non è bello in tutti i progetti, evviva! e ovviamente +1 a questa risposta
randomguy04

1
@ randomguy04 Controlla il primo frammento, l'ho modificato per aggiungere un effetto di riempimento. Viene fatto aggiungendo $(this).css('fill', 'red')come richiamo all'animazione
Akshay,

2

Solo CSS:

@keyframes fadein_left {
  from {
    left: 0;
  }
  to {
    left: 100%;
  }
}

#start:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0%;
  opacity: 0.7;
  height: 25px;
  background: #fff;
  animation: fadein_left 3s;
}
<div id="start">
  some text some text some text some text some text
</div>


0

A seguito di numerosi test, ecco alcune note. L'obiettivo è visualizzare dati di testo rapidi nel modo meno bloccante, su pagine pesanti di DOM che richiedono interazioni con gli utenti.

Esistono ovviamente molti modi per ottenere la stessa cosa. In questo esempio, le differenze potrebbero non essere ovvie, si applicano davvero a interfacce complesse.

Più lento : innerHTMLe styling in linea. Il DOM viene ricalcolato ad ogni iterazione. Il browser sta lavorando sodo per mantenere il treno. Fallirà rapidamente, causando perdite di memoria e blocchi:

setInterval(function(){
  out.innerHTML = `<span style="position:fixed;top:${~~(Math.random() * 220)}px">${Math.random() * 1000}<span>`
},1)
<h1 id="out"></h1>

Modo migliore : Utilizzando textContent, requestAnimationFramee l'API web di animazione. Questo diventa più fluido, è ovvio nelle pagine pesanti di DOM. Le interazioni dell'utente non bloccheranno le ridisegni. Alcuni ritocchi potrebbero essere saltati, per mantenere l'interfaccia ben reattiva.

let job
const paint = () => {
  job = requestAnimationFrame(paint)
  out.textContent = Math.random() * 1000
  out.animate([{top: ~~(Math.random() * 220)+"px"},{top:0}],{duration: 1,iterations: 1})
}

/* Start looping -----------------------------------------*/
requestAnimationFrame(paint)
#out{
position: fixed}
<h1 id="out"></h1>

Nell'esempio sopra, il DOM viene ancora ricalcolato per l'overflow del testo. Possiamo vedere il debugger lampeggiare forte. Questo conta davvero sugli elementi a cascata! Questo può ancora rallentare javascript e lo scorrimento degli utenti.

inserisci qui la descrizione dell'immagine

Piena potenza : è possibile utilizzare solo css per aggiornare i dati con la contentregola css e le variabili css. Il testo non sarà quindi selezionabile.

let job
const paint = () => {
  job = requestAnimationFrame(paint)
  out.setAttribute('data-before', Math.random() * 1000)
  out.animate([{top: ~~(Math.random() * 220)+"px"},{top:0}],{duration: 1,iterations: 1})
}

/* Start looping -----------------------------------------*/
requestAnimationFrame(paint)
#out{
  position: fixed
  
  }
#out:before {
   content: attr(data-before)
 }
<h1 id="out"></h1>

inserisci qui la descrizione dell'immagine

I miei test mostrano grandi miglioramenti, il motore javascript sta saltando rapidamente su altre attività. A volte può iniziare un po 'più lentamente dell'esempio sopra. Ma a parte questo, questo non blocca gli scroll degli utenti e anche il debugger sta gradendo, non più salti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.