Bagaimana saya bisa menghidupkan gambar teks di halaman web?

229

Saya ingin memiliki halaman web yang memiliki satu kata terpusat.

Saya ingin kata ini digambar dengan animasi, sehingga halaman "menulis" kata dengan cara yang sama seperti yang kita inginkan, yaitu mulai pada satu titik dan menggambar garis dan kurva dari waktu ke waktu sehingga hasil akhirnya adalah mesin terbang.

Saya tidak peduli apakah ini dilakukan dengan <canvas>atau DOM, dan saya tidak peduli apakah itu dilakukan dengan JavaScript atau CSS. Tidak adanya jQuery akan menyenangkan, tetapi tidak diperlukan.

Bagaimana saya bisa melakukan ini? Saya telah mencari secara mendalam tanpa hasil.

strugee
sumber
2
Saya menaruh beberapa pemikiran tentang bagaimana sebenarnya "tulisan tangan" karakter dan memposting pemikiran saya di sini: stackoverflow.com/questions/12700731/…
markE
Ada sesuatu yang sangat mirip dalam artikel codrops (dengan demo di tympanus )
Francisco Presencia
1
Kembali pada hari-hari, saya melakukan animasi ini di Flash menggunakan topeng sprite animasi. Yang Anda butuhkan adalah untuk menghidupkan topeng, yang berarti memiliki itu semakin mengungkapkan teks. Animasi akan dibuat dari bingkai topeng.
Tiberiu-Ionuț Stan
Tentu saja, Anda akan mendapat manfaat karena dapat memecah teks menjadi kurva. Anda harus melakukan ini menggunakan sebelum menjalankan SVG dan editor SVG (Illustrator, atau apa pun yang dapat membuat SVG teks Anda). Saya tidak tahu apakah SVG mendukung topeng, tetapi jika mereka melakukannya, ini akan menjadi lebih mudah untuk digerakkan.
Tiberiu-Ionuț Stan
Gunakan SVG dan memanipulasi kode SVG dengan JavaScript untuk membuat animasi.
The Demz

Jawaban:

264

Saya ingin kata ini dibuat dengan animasi, sehingga halaman "menulis" kata dengan cara yang sama seperti yang kita inginkan

Versi kanvas

Ini akan menarik karakter tunggal lebih seperti yang akan ditulis dengan tangan. Ini menggunakan pola dash panjang di mana pesanan on / off ditukar dari waktu ke waktu per karakter. Ini juga memiliki parameter kecepatan.

Foto
Contoh animasi (lihat demo di bawah)

Untuk meningkatkan realisme dan nuansa organik, saya menambahkan spasi huruf acak, offset y delta, transparansi, rotasi yang sangat halus dan akhirnya menggunakan font yang sudah "tulisan tangan". Ini dapat dibungkus sebagai parameter dinamis untuk menyediakan berbagai "gaya penulisan".

Untuk tampilan yang lebih realistis, data jalur akan diperlukan yang tidak secara default. Tetapi ini adalah potongan kode yang pendek dan efisien yang mendekati perilaku tulisan tangan, dan mudah diimplementasikan.

Bagaimana itu bekerja

Dengan mendefinisikan pola tanda hubung, kita dapat membuat semut berbaris, garis putus-putus, dan sebagainya. Mengambil keuntungan dari ini dengan mendefinisikan titik yang sangat panjang untuk titik "off" dan secara bertahap meningkatkan titik "on", itu akan memberikan ilusi menggambar garis ketika dibelai sambil menggerakkan panjang titik.

Karena titik mati begitu panjang, pola berulang tidak akan terlihat (panjangnya akan bervariasi dengan ukuran dan karakteristik jenis huruf yang digunakan). Jalur surat akan memiliki panjang sehingga kita perlu memastikan bahwa kita memiliki setiap titik setidaknya mencakup panjang ini.

Untuk huruf yang terdiri dari lebih dari satu jalur (mis. O, R, P dll.) Karena satu untuk garis besar, satu untuk bagian berongga, garis-garis akan tampak digambar secara bersamaan. Kami tidak bisa berbuat banyak tentang itu dengan teknik ini karena akan membutuhkan akses ke setiap segmen jalur untuk dibelai secara terpisah.

Kesesuaian

Untuk browser yang tidak mendukung elemen kanvas cara alternatif untuk menampilkan teks dapat ditempatkan di antara tag, misalnya teks gaya:

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

Demo

Ini menghasilkan animasi stroke-on langsung ( tidak ada ketergantungan ) -

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>


sumber
21
Apakah saya satu-satunya yang gila karena ini? Terlihat sangat nyata, setidaknya, jauh lebih baik daripada jawaban pertama, dan paling dekat dengan pertanyaan si penanya.
KhoPhi
5
Saya akhirnya menggunakan jawaban yang lain, karena saya membutuhkannya segera sebagai hack cepat-n-kotor yang saya gunakan pada hari berikutnya dan kemudian tidak pernah menyentuh lagi, tapi saya menerima yang ini karena itu jauh lebih dekat dengan apa yang saya cari untuk.
strugee
Bagaimana kita membuatnya untuk beberapa baris, dan blok teks yang panjang?
Saad Farooq
1
@ K3N Ya, itu sebenarnya sentuhan yang bagus: p Kerja bagus.
keyser
1
@ AliAl-arnous Anda dapat mengatur x ke ujung yang berlawanan, kurangi lebar char alih-alih menambahkan, mengubah dengan ruang negatif yang dinegasikan dan mengubah clearRect untuk menghapus di sisi lain dari char.
216

Edit 2019


Saya membuat perpustakaan javascript yang dapat membuat animasi realistis. Mudah digunakan dan memerlukan file JSON khusus yang bertindak sebagai font.

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>

Lihat halaman Github untuk dokumentasi dan contoh. Dan Codepen


Jawaban Sebelumnya

Contoh di bawah ini menggunakan snap.js untuk secara dinamis membuat tspanelemen dan kemudian menghidupkan masing-masing stroke-dashoffset.

Jawaban Sebelumnya


Anda dapat melakukan sesuatu seperti ini menggunakan svg stroke-dasharray

Tanpa keyframesanimasi Anda dapat melakukan hal seperti ini

Dan untuk dukungan IE Anda dapat menggunakan jquery / javascript

Akshay
sumber
4
Wow, itu sangat menarik. Saya telah mengambil cuplikan kode asli Anda dan memperbaikinya dengan menghapus properti duplikat CSS, menggunakan nilai persentase dan tanda hubung berbasis persentase, dan mengubah lebar goresan untuk membuatnya lebih jelas bagaimana kodenya bekerja: jsfiddle.net/Ajedi32/gdc4azLn / 1 Jangan ragu untuk mengedit perbaikan apa pun ke dalam jawaban Anda jika Anda mau.
Ajedi32
2
ini adalah satu solusi epik untuk pertanyaan ini, SVG lebih baik daripada kanvas (+1) sejauh dalam hal browser tidak mendukungnya maka ia akan menampilkan teks sebagai gantinya.
Jeffery ThaGintoki
3
@JefferyThaGintoki Anda dapat melakukannya dengan kanvas juga, cukup tempatkan teks di antara tag kanvas, jika kanvas tidak didukung teks (atau animasi gif seperti pada jawaban lain yang ditampilkan dalam teks tubuh) akan muncul sebagai gantinya. Jika browser tidak mendukung kanvas itu mungkin tidak akan mendukung svg juga.
torox
1
Saya pikir penggunaan teks SVG bagus, namun saya bertanya-tanya, apakah mungkin menambahkan isian di beberapa titik? garis besar huruf-hurufnya tidak terlihat bagus di semua proyek, tepuk tangan! dan tentu saja +1 untuk jawaban ini
randomguy04
1
@ randomguy04 Periksa cuplikan pertama, saya telah mengeditnya untuk menambahkan efek isi. Hal ini dilakukan dengan menambahkan $(this).css('fill', 'red')panggilan balik ke animasi
Akshay
2

Hanya 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>

zloctb
sumber
0

Setelah banyak tes, berikut adalah beberapa catatan. Tujuannya adalah untuk menampilkan data teks cepat dengan cara yang paling tidak menghalangi, pada halaman berat DOM yang membutuhkan interaksi pengguna.

Tentu saja ada banyak cara untuk mencapai hal yang sama. Pada contoh ini, perbedaannya mungkin tidak jelas, itu benar-benar berlaku untuk antarmuka yang kompleks.

Paling lambat : innerHTMLdan gaya inline. DOM dihitung ulang di setiap iterasi. Browser bekerja keras untuk menjaga kereta. Ini akan gagal dengan cepat, menyebabkan kebocoran memori dan membeku:

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

Cara yang lebih baik : Menggunakan textContent, requestAnimationFramedan api animasi web. Ini berjalan lebih lancar, sudah jelas di halaman berat DOM. Interaksi pengguna tidak akan memblokir repaints. Beberapa pengecatan mungkin dilewati, agar antarmuka tetap responsif.

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>

Pada contoh di atas, DOM masih dihitung ulang untuk limpahan teks .. Kita bisa melihat debugger berkedip keras. Ini sangat penting pada elemen cascading! Ini masih bisa memperlambat javascript dan pengguliran pengguna.

masukkan deskripsi gambar di sini

Kekuatan penuh : Adalah mungkin untuk menggunakan css sendiri untuk menyegarkan data dengan contentaturan css dan variabel css. Teks tidak akan dipilih.

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>

masukkan deskripsi gambar di sini

Tes saya menunjukkan peningkatan besar, mesin javascript melompati tugas-tugas lain dengan cepat. Kadang-kadang itu bisa mulai sedikit lebih lambat daripada contoh di atas. Tapi di samping itu, ini tidak memblokir gulungan pengguna, dan debugger juga menyukai, tidak ada lagi lompatan.

NVRM
sumber