Rumah > hujung hadapan web > tutorial css > % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi

% CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi

Linda Hamilton
Lepaskan: 2025-01-18 06:10:09
asal
428 orang telah melayarinya

Ini adalah susulan terus untuk Mendapatkan Data Respons API 32 bit dalam CSS

Dalam CSS, 16 bit data tindak balas, diletakkan dalam kedua-dua lebar intrinsik dan dalam ketinggian intrinsik, merupakan peningkatan yang besar daripada tidak boleh mendapatkan data respons API sama sekali (tanpa JavaScript)...

Namun, beberapa hari selepas saya memikirkannya, fikiran saya condong ke satu arah:
Ia akan menjadi lebih menyeronokkan jika ia adalah 16 bit 32 kali dan bukannya hanya dua kali.

Gif recording of a harsh terminal app setting several integer values to an array of variables one at a time

Membungkus 512 bit ke dalam SVG untuk Exfiltration

Saya sedang bermeditasi sebelum tidur dan dikejutkan dengan pemikiran inspirasi lain -

"Bagaimana jika mungkin dokumen imej sendiri menghidupkan saiz intrinsiknyasendiri

?"

Rantai kesedaran biasa selepas pemikiran yang diilhamkan masing-masing muncul dengan pemahaman tentang cara ia boleh dicapai... Saya hanya perlu memikirkan sama ada jenis imej sedemikian wujud.

Saya mengambil telefon saya dan mencari semua format imej animasi yang saya ketahui, melihat sama ada mana-mana daripada mereka yang mampu melakukannya. svg, webp, apng, gif, mungkin format video yang pelik

? Saya tidak menemui apa-apa.

Pada waktu pagi, sesuatu dalam diri saya berkata kepada teruskan menggali SVG

.

Saya mencuba CSS terbenam, pertanyaan media, use'd defs, lebih use'd defs, menyelami banyak dokumen animasi SVG, cuba menipu mereka dan membaca idea lain serta sifat berkaitan animasi - tiada apa yang boleh membenarkan saya tetapkan ketinggian atau lebar.

Tetapi pautan terakhir itu membuatkan saya terfikir...

...bagaimana dengan viewBox? Saya ada beberapa halangan lain untuk diatasi tetapi... Adakah itu

mungkin untuk dianimasikan?


vvv
IALAH!!

^^ Menyusun ruang penyelesaian

Sekarang masalahnya ialah, jika anda tidak menetapkan atribut lebar dan ketinggian pada elemen root svg kemudian cuba gunakan svg sebagai kandungan pada pseudo, ia menjadikan 0px x 0px kerana ia adalah dokumen vektor dan tidak lagi mempunyai saiz intrinsik.

Jadi saya mencari dan menambah preserveAspectRatio padanya... Masih 0x0... tetapi kemudian dalam CSS saya, saya menyematkan lebar kepada 10px dan biarkan nisbah aspek yang dipelihara bagi Kotak paparan menentukan ketinggian (yang boleh saya ubah dengan animasi dibenamkan dalam SVG) aaand... elemen html yang mengandunginya berkembang ke ketinggian yang dijangkakan.

:3

Jika terdapat hanya satu bingkai, ini mengambil 32 bit asal saya dan memotongnya separuh; kerana hanya satu dimensi boleh dieksfiltrasi manakala satu lagi adalah statik.

TAPI! Kini, dimensi ke-2 saya ialah masa dan yang pertama adalah mengikut kehendak masa, jadi terdapat lebih daripada cukup data untuk dimiliki.

Alangkah mengujakan!

Saya belajar semua yang saya boleh tentang cara mengawal animasi dalam SVG dan menyiapkan skrip sisi pelayan untuk menjana SVG animasi pertama saya:

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

(kenapa php?! - kerana saya sudah mempunyai pelayan yang telah saya bayar selama bertahun-tahun, sediakan untuk menjalankan php keluar dari pintu gerbang.... Dan walaupun saya telah memperoleh kehidupan yang hebat dengan mengetahui JavaScript dan nod sangat baik, kadangkala seronok untuk mencari setiap fungsi, pengendali dan sintaks untuk maju melalui sesuatu yang anda tahu boleh lakukan tanpa mengetahui secara spesifik. lol)

Sekarang mari kita ganti % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi pertama saya dari artikel sebelumnya untuk melihat CSS bertindak balas dan menukar saiz --vars apabila SVG berdetik bersama:

Disahkan! Kami boleh membaca perubahan saiz. Seperti dalam artikel sebelum ini, pada akhirnya, ia akan menggunakan teknik pengukuran garis masa lihat dan bukannya teknik tan(atan2()) ini.

Ia memasak cpu saya jadi kami akan mahu mengalih keluarnya daripada kandungan apabila penapisan selesai.

Dari segi konsep, cara mengeluarkan masa 1D secara prosedur

Demo di atas tidak begitu berguna dengan sendirinya. Ia melaporkan salinan ketinggian pada bila-bila masa ia ada tetapi kita perlu menyimpannya... dan apa gunanya sekumpulan nilai 16 bit jika anda tidak tahu dan tidak boleh mempercayai pesanan itu?

Saya tahu saya boleh mengumpul nilai dalam CSS dengan Hack CPU dan secara matematik menentukan yang mana --var mendapat kemas kini nilai masuk dan bukannya hanya menyimpan nilai sebelumnya, jadi saya tidak akan risau tentang CSS secara khusus. Secara amnya, bagaimanakah kita boleh mengeluarkan 1D dari semasa ke semasa?

Nilai sentinel untuk menyelamatkan!

Saiz kawasan pengukur yang kami gunakan tidak PERLU dihadkan kepada 16 bit walaupun saya ingin mengehadkan paket data itu sendiri kepada 16 bit. Jadi kita boleh mengemas beberapa pengawal di sana juga. css-api-fetch kapal dengan keupayaan untuk mengendalikan nilai sehingga 99999, yang jauh melebihi 65535 (siling 16 bit).

Jadi apa yang kita perlu tahu?

Apakah masalah yang mungkin kita hadapi?

Jika dua nilai dalam data kami adalah sama berturut-turut, kami memerlukan gangguan untuk mengetahui bahawa ia adalah dua paket yang berbeza. Saya sudah memutuskan bahawa kami akan menyasarkan 512 bit, jadi kami memerlukan animasi SVG untuk mempunyai maksimum 32 bingkai data 16-bit, dengan bingkai sentinel di antaranya...

Jika CPU berasa berat, animasi SVG mungkin kelihatan melangkau langkah diskret sepenuhnya. Ini bermakna kita memerlukan beberapa cara untuk sentiasa mengetahui langkah yang sedang kita lakukan. Oleh itu, daripada satu sentinel "antara bingkai data", mari gunakan indeks data (berasaskan 1 seperti CSS nth-* pemilih) sebagai nilai sentinel, menjadikannya langkah diskretnya sendiri sebelum langkah diskret yang menunjukkan data untuk indeks tersebut.

Indeks sentinel -> data -> indeks sentinel -> data ...

Itu memberitahu kami apabila gelung itu juga, berkemungkinan apabila kami memukul sentinel 1.

Tetapi bagaimana kita tahu bahawa ia tidak melangkau ke bingkai data yang berbeza dan secara tidak sengaja menyebabkan kami merekodkannya dalam slot yang salah?

Kita perlu membiarkannya berpusing dan teruskan sehingga ia betul, dan cara terbaik untuk mengetahui sama ada data adalah betul ialah checksum! Jadi kami memerlukan satu lagi bingkai data dan pengawal untuk nilai itu.

Mencipta Algoritma Checksum

Saya boleh menggunakan css-bin-bits untuk XOR semua data, tetapi ia agak berat dan tidak diperlukan di tempat lain - mari kita selesaikan alternatif yang mudah dilakukan dalam CSS.

Secara matematik, jika anda mengambil nilai 16 bit, bahagikannya dengan 256 (tingkat kepada integer), dan ambil nilai 16 bit sekali lagi modulo sebanyak 256, anda mendapat bait tinggi dan rendah. Tambahkan nilai 8 bit tersebut bersama-sama dan anda berada pada 9 bit. Ini terasa seperti pendekatan checksum yang munasabah, mari kita kembali kepada perkara ini.

Kita tidak perlu kekal dalam julat 16 bit untuk mengira jumlah semak selagi jumlah semak akhir ialah 16 bit, jadi mari kita jumlahkan kesemuanya (sehingga) 32 nilai.

Kita perlu berhati-hati tentang penulisan storan yang salah kerana bingkai yang dilangkau, jadi mari kita tambahkan nilai indeks genap dua kali supaya terdapat sedikit kemiripan tertib.

Jumlah itu, nilai 16 bit, 32 kali, ditambah tambahan 16 kali, ialah kira-kira 22 bit. Bahagikan dan modulkan 11 bit pada setiap sisi berputar kembali ke pemikiran awal, kemudian tambahkan bersama-sama, memberikan 12 bit sebagai respons checksum kami.

Nampak munasabah... Ia bukan bukti ralat sepenuhnya tetapi SVG perlu melangkau beberapa langkah untuk mengacaukannya dengan cara MUNGKIN menjana checksum yang sama sekarang... Walau apa pun, mari kita hantar semula data panjang dan masukkan itu dalam checksum juga, hanya dengan menambahkannya sebagai langkah terakhir checksum kami. Panjang data maksimum (bilangan nilai 16 bit yang ingin kami kendalikan) hanya 32, jadi menambah nilai panjang pada 12 bit tidak akan menyebabkan kami melebihi 16 bit. Yay!

spoiler: ini ialah yang saya lakukan tetapi CSS menjadi lossy di suatu tempat sekitar 21 bit jadi saya membahagikannya dan dengan berkesan melakukan algoritma yang sama tetapi dalam ketulan yang lebih kecil pada satu masa. Bahagian pelayan menggunakan alg betul-betul seperti yang diterangkan.

Secara teknikal dengan persediaan yang telah kami terangkan, tidak kira apa susunan dalam animasi asalkan setiap sentinel memberitahu anda indeks apa yang sepatutnya ada pada bingkai seterusnya dalam data.

Seperkara lagi, mari letakkan nilai panjang data dahulu dalam respons dan tambahkan sentinel untuk itu juga (sentinel dalam animasi SVG sebelum nilai, seperti data yang lain).

Itulah 34 pengawal. Ketinggian SVG viewBox tidak boleh 0 dan CSS akan mendapat manfaat daripada membenarkan 0 mewakili tiada data secara dalaman, jadi katakan kami mempunyai 35 pengawal dengan 0 yang tidak digunakan secara sengaja.

Semua bingkai data kini dibenamkan dalam SVG dengan 35 ditambah pada nilainya. Nilai data panjang dan jumlah semak JUGA mendapat 35 ditambahkan pada nilai kotak pandangan. ketinggian kotak pandangan dalam Animasi SVG yang mewakili sentinel akan mempunyai nilai 0 hingga 34 (melangkau 0) dan setiap satu memberitahu kami dengan tepat apa yang diwakili oleh bingkai seterusnya dalam Animasi SVG.

Sebelah CSS, kami hanya menyemak sama ada ukuran mentah lebih besar daripada 34, itu data jadi tolak 35 daripadanya, jika kurang daripada 35, itu sentinel.

A meme picture of Charlie Day from It's Always Sunny in Philadelphia with a crazed look standing in front of a board covered in paper with red lines connecting them hectically

Bermula untuk mengeksfiltrasi 512 bit dengan CSS

Selepas saya menyelesaikan bahagian PHP untuk menjana animasi SVG seperti yang terperinci, saya memikirkan cara khusus untuk memulakan CSS untuk proses exfiltrasi ini.

Ini kod PHP!
<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Terdapat beberapa cara untuk mencapai ini dalam CSS dan kemungkinan lebih banyak lagi akan datang dengan penambahan spesifikasi terkini.

Pendekatan pertama saya adalah yang paling mudah dari segi konsep - menggunakan garis masa paparan untuk setiap data dan melakukan perkara yang sama berulang kali. Ia berkesan tetapi saya mengeluh melalui kemajuan saya kerana tidak berpuas hati dengan betapa teruknya ia. Itu akan menjadi hampir 40 animasi pada :root jika saya meneruskan.

Jadi saya pergi tidur.

Apabila saya tersedar, saya berbaring di sana beberapa saat sambil memandang ke luar tingkap sambil tersenyum dengan perasaan yang baru bangun tidur atau direnungkan, kemudian fikiran melayang ke kepala saya. Saya berguling, meraih buku nota dan pen terdekat saya, duduk di atas katil, dan mula menulis algoritma untuk mengeluarkannya dengan hanya 6 animasi CSS.

my chicken scratch handwriting on a single piece of lined notebook paper with arrows pointing to a couple of nested boxes detailing the method described below

Secara literal diselesaikan di atas kertas; Ini adalah TEPAT bagaimana ia dilaksanakan.

Saya bangun, membuka komputer saya, mengabaikan kerja terdahulu saya dan membuka % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi baharu.

Saya menyediakan 4 elemen html yang ditunjukkan di antara calar ayam di sana, kemudian membanjiri panel CSS dengan nota sekitar 4 pemilih kelas kosong yang sepadan dengannya. Ia tidak akan berada pada :root sekarang tetapi kita boleh meletakkan apa sahaja yang bergantung padanya di dalam.

Tiada satu pun fungsi ditambahkan sehingga nota disalin daripada kertas dan ditulis dengan lebih terperinci dalam % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi.

Apabila saya selesai, saya hanya membaca nota dan mula melaksanakan apa yang mereka katakan, sehingga ke hasil kerja akhir.

(Saya menulis "20" bukannya "35" kerana saya akan menguji dengan 256 bit)

Saya akan mendalami cara ia berfungsi. Disebabkan oleh garis masa paparan dan skop garis masa, anda boleh menetapkan data untuk mengalir masuk dalam bentuk Botol Klein jika anda dapat membayangkan permukaan yang menganimasikan dan disedut ke dalam "lubang", sandarkan ke bahagian atas yang sempit kepada yang lemah. ke atas permukaan sekali lagi, memperoleh saiz dan kerumitan melalui lapisan dom, dan kemudian gelung kembali melalui lubang hitam ke dalam kesedaran yang lebih tinggi (:root).

Kebanyakannya kitaran menegak (bukan kitaran mendatar atau kitaran statik)

Mengeluarkan 512 bit dengan CSS

Nota yang kami tweak sedikit dan lebih jelas:

256 ujian -> 512 akhir

dan saya menambah nod pembentangan di dalamnya yang bagus kerana saya boleh menunjukkan dalaman juga semasa algoritma dilaksanakan.

tetapi inilah nota akhir tanpa semua bunyi pelaksanaan dan pembentangan. Ini betul-betul menerangkan cara semuanya berfungsi.

Mungkin tidak dalam bentuk yang baik untuk artikel mempunyai butiran sebanyak ini tertanam secara luaran tetapi saya akan memecahkan setiap bahagian untuk menunjukkan bagaimana ia dilaksanakan.

Pengawal Utama

Di bahagian atas struktur ini terdapat 4 nilai garis masa dan animasinya. Jadi, mari kita masukkan mereka.

Sekeping utama aliran data yang didayakan ini, adalah ia memberi kita keupayaan untuk mengangkat data yang bersarang jauh dalam DOM kembali ke hos (skop garis masa). Ia tidak cekap, jadi kami mahu mengehadkan kekerapan kami melakukan ini. Setiap harta berdaftar dan animasinya boleh mengehoskan sekeping data secara menegak. Nilai data ditentukan oleh kedudukan paparan sebaris atau blok bagi elemen di suatu tempat dalam struktur - kita akan sampai ke bahagian itu kemudian.

(lihat contoh gelung yang dibenamkan di atas sebelum ini untuk mendapatkan gambaran aliran data yang lebih jelas)

Empat keping data yang kami angkat di sini ialah:

--xfl-cpu-phase - ini ialah nilai berangka 0 hingga 4 yang menandakan fasa Hack CPU yang sedang dilaksanakan. (satu 'bingkai' CPU Hack ialah 4 hingga 5 bingkai pemaparan CSS, satu gelung fasa 'mendetik' Hack CPU) Saya akan menunjukkan ini dengan lebih khusus kemudian dalam artikel ini.

--xfl-raw-data - ini mengehoskan ketinggian SVG di mana sahaja SVG berada dalam kitaran animasinya. Data mentah kami. Seperti yang dinyatakan sebelum ini, jika nilai ini kurang daripada 35, langkah diskret animasi SVG ini ialah nilai sentinel. Jika lebih besar daripada 34, langkah diskret animasi SVG ini ialah nilai 16 bit kami 35, yang sepadan dengan apa yang ditunjukkan oleh sentinel sebelumnya.

--xfl-data-type - ini ialah nilai sentinel terkini. Nilai ini tidak berubah sehingga sentinel seterusnya ditemui. Terdapat 1 kelewatan bingkai CSS daripada menetapkan --xfl-raw-data kepada menetapkan nilai ini.

--xfl-data-value - ini ialah nilai data semasa selepas 35 ditolak daripada nilai mentah, atau 0 jika kita belum mencapai langkah jujukan ini lagi. Terdapat 1 kelewatan bingkai CSS daripada menetapkan --xfl-data-type kepada menetapkan nilai ini.

Saya juga telah membungkus svg-animation-current-state-reporter dalam keadaan yang hanya mempunyai fungsi dan hanya memuatkan SVG animasi semasa prosesnya tidak lengkap. (jadi semua dalaman dikeluarkan daripada memori dan svg animasi berat dikeluarkan daripada rendering apabila kami selesai)

Nilai bingkai utama bertukar daripada nilai maksimum untuk sekeping data itu kepada 0. Saya akan menerangkan kemudian mengapa ini adalah ke belakang - cari imej kad Uno Reverse.

Penyaring CPU

Seterusnya kami menyediakan plat dandang asas untuk Hack CPU

Boilerplate CPU Hack hanya mengikut corak nama berubah untuk menyediakan animasi tangkapan dan angkat.

Jika kami mempunyai 1 integer --xfl\1 yang kami mahu kitar secara mendatar (dari semasa ke semasa), kami mendaftarkannya dan kami menyediakan animasi tangkap dan angkat seperti:

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Kemudian selesaikan tugasan kitaran pada elemen .cpu-exfiltrator tempat kedua-dua animasi CPU dihoskan. Saya akan melakukannya untuk hanya satu daripada nilai buat masa ini:

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  // add 35 to all the values so we can use 0 to 34 for sentinels. 0 = CSS-side sentinel, 1-32 = data frames, 33 = length, 34 = checksum
  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return ($viewBoxXYWidth . ((string) $index) . '; ' . $viewBoxXYWidth . ((string) ($val + 35)));
  }, $data, range(1, $datalen)); // 1 up to 32 = indicator that next frame is the value(+35) for that index(1-based)

  // no matter how many are in the array, '33' indicates the next frame is data length, which is used in the checksum too
  array_unshift($frames, $viewBoxXYWidth . '33; ' . $viewBoxXYWidth . ((string) ($datalen + 35))); // + 35 b/c data
  // unshift so the length is (hopefully) the first value read and a sense of progress can be reported

  $fullsum = 0;

  for ($x = 0; $x <= ($datalen - 1); $x++) {
    // double the odd ones so there's some semblance of order accounted for
    // the odd ones with 0 based index is the even ones on the CSS side
    $fullsum += ($data[$x] + (($x & 1) * $data[$x]));
  }

  $checksum = floor($fullsum / 2048) + ($fullsum % 2048) + $datalen + 35; // + 35 because it's data

  // no matter how many are in the array, '34' indicates the next frame is checksum
  array_push($frames, $viewBoxXYWidth . '34; ' . $viewBoxXYWidth . $checksum);

  $actualNumItems = count($frames) * 2;

  $dur = $actualNumItems * 0.33; // total seconds

  $keytimeStep = 1 / ($actualNumItems); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $actualNumItems - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam Chrome, ia tidak akan berkitar secara statik (menjadi nilai awal) melainkan kedua-dua animasi berjalan pada masa yang sama. Ia merupakan kesan sampingan yang HEBAT dari kemungkinan pengoptimuman animasi yang dijeda yang menetapkan sifat berangka.

Akhir sekali, memandangkan kami menggunakan versi automatik CPU Hack yang baharu (anda tidak perlu :tuding untuk mengitar fasa seperti dalam hack asal), kami menyambungkan var --xfl-cpu-phase daripada sebelumnya (dihoskan pada elemen induk di sini, jadi kami boleh menggunakan pertanyaan gaya untuk membalasnya) dan mengawal keadaan mainan animasi kami.

Kami juga mengeluarkan --cpu-next-phase yang kemudiannya akan diangkat kembali ke atas dan menetapkan nilai seterusnya untuk --xfl-cpu-phase menggunakan kedudukan paparan dan skop garis masanya.

Saya telah menambah fasa tambahan untuk memastikan CPU Hack dijeda sehingga pengukuran Animasi SVG berjaya dikunci dalam --xfl-data-type seterusnya

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

(seperti sekarang, jenis data masih sentiasa 0 jadi sebaik sahaja fasa seterusnya disambungkan, ini sudah pun menggelungkan Hack CPU. Sebaik sahaja kita mempunyai sentinel jenis data ia tidak akan gelung sehingga kita telah membersihkannya dengan sengaja dengan 0 sentinel)

Kemudian, kami juga akan menambah syarat yang dinyatakan untuk menghalang CPU fasa 1 daripada bermula sehingga data tersedia. Itu akan memastikan bahawa antara jenis data (sentinel) dikunci masuk dan nilai data (mentah - 35) dikunci masuk, kami mahu meninggalkan Hack CPU dalam fasa tangkapannya. Jadi ia "bersedia untuk bersedia" seperti yang mungkin dikatakan oleh Abraham Hicks.

Saya akan teruskan dan mendaftarkan semua 32 nilai serta jumlah semak dan panjang yang kami jangkakan oleh Animasi SVG untuk melaporkan.

Memandangkan pendaftaran --xfl\1 hingga --xfl\32 adalah satu blok besar dan animasi CPU hanyalah boilerplate juga, saya akan mengalihkan kesemuanya ke bahagian bawah persediaan hack untuk diabaikan bergerak ke hadapan.

Hack CPU automatik

Ini menyambungkan fasa cpu seterusnya kepada nilai fasa --xfl-cpu

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  // add 35 to all the values so we can use 0 to 34 for sentinels. 0 = CSS-side sentinel, 1-32 = data frames, 33 = length, 34 = checksum
  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return ($viewBoxXYWidth . ((string) $index) . '; ' . $viewBoxXYWidth . ((string) ($val + 35)));
  }, $data, range(1, $datalen)); // 1 up to 32 = indicator that next frame is the value(+35) for that index(1-based)

  // no matter how many are in the array, '33' indicates the next frame is data length, which is used in the checksum too
  array_unshift($frames, $viewBoxXYWidth . '33; ' . $viewBoxXYWidth . ((string) ($datalen + 35))); // + 35 b/c data
  // unshift so the length is (hopefully) the first value read and a sense of progress can be reported

  $fullsum = 0;

  for ($x = 0; $x <= ($datalen - 1); $x++) {
    // double the odd ones so there's some semblance of order accounted for
    // the odd ones with 0 based index is the even ones on the CSS side
    $fullsum += ($data[$x] + (($x & 1) * $data[$x]));
  }

  $checksum = floor($fullsum / 2048) + ($fullsum % 2048) + $datalen + 35; // + 35 because it's data

  // no matter how many are in the array, '34' indicates the next frame is checksum
  array_push($frames, $viewBoxXYWidth . '34; ' . $viewBoxXYWidth . $checksum);

  $actualNumItems = count($frames) * 2;

  $dur = $actualNumItems * 0.33; // total seconds

  $keytimeStep = 1 / ($actualNumItems); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $actualNumItems - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Terdapat beberapa plat dandang CSS di sini untuk menjadikan elemen itu sebagai bekas tatal dan meletakkannya dari skrin. Bahagian yang penting ialah:

lihat garis masa: --xfl-cpu-phase inline;

yang mengatakan di mana tepi kanan elemen pseudo ini berada dalam induk lebarnya 100px, pasangkannya sebagai "kemajuan" dari kiri ke animasi kami yang bergerak dari 0 ke 4... Jadi 25px adalah 25% lengkap, yang memetakan kepada 1 apabila 25% adalah antara 0 dan 4.

picture of two 'reverse' cards from Uno imej bersumber daripada carian google yang menuju ke twitter

SECARA TEKNIKAL animasi adalah 4 hingga 0 dan SECARA TEKNIKAL ia mengukur dari tepi kanan pseudo sambil melihat kemajuan ke arah kanan. Jadi pseudo lebar 25px ialah 75% dari sebelah kanan induk tatal lebar 100pxnya dan memetakan kepada nilai 1 apabila 75% adalah antara 4 dan 0.

Lebih mudah difahami jika anda tidak memproses matematik songsang secara kognitif dan hanya menerima keputusan akhir ialah kemajuan mudah 0 hingga 4 kerana nilai maksimum dalam animasi ialah 4 (sekali lagi mengabaikan bahawa animasi bermula pukul 4).

Mari kita juga menulis keadaan sedia yang memegang CPU dalam fasa 0 sehingga data siap. Nota itu ada pada baris 64 demo kami:

Data sedia = jenis data > 0 && raw-frame-data - 35 === data-value

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Tunggu, === dalam CSS?

Ini agak lapuk sekarang dan saya akan melakukannya secara berbeza hari ini, ditulis sebelum clamp() adalah garis dasar, tetapi saya sentiasa membuka pen kod lama ini untuk menyalin tampal pembanding angka secara tidak sengaja apabila saya memerlukannya. Artikel yang bagus untuk mengemas kini dan menerangkannya tetapi di sini anda pergi sementara itu: https://codepen.io/propjockey/pen/YzZMNaz

Membaca Animasi SVG

Ini pada mulanya SANGAT serupa dengan bahagian CPU Exfiltrator kerana ia adalah teknik yang sama, mengukur dan mengalihkan data dari sini ke atas DOM ke tempat ia dihoskan (skop).

Kami akan mengukur dan melaporkan 3 nilai terakhir untuk elemen asas yang kami sediakan pada mulanya.

Hidup ::sebelum kami akan memaparkan SVG dan menetapkan --xfl-raw-data menggunakan kedudukan paparan blok yang merupakan ukuran ketinggian SVG animasi. (ingat, kami akan menyematkan lebar kepada 10px)

Hidup ::selepas kami akan menetapkan --xfl-data-type inline (nilai sentinel 0 hingga 34) dan --xfl-data-value block (nilai 16 bit).

Ibu bapa perlu cukup lebar untuk memaparkan SVG (sekurang-kurangnya 10px) dan memberikan ukuran dengan tepat untuk nilai sentinel (0 hingga 34).

Ibu bapa juga perlu cukup tinggi untuk mengukur nilai 16 bit ( 35). Memandangkan kami menetapkan nilai maks dalam langkah pertama sebanyak 100k, kami hanya akan menggunakannya walaupun kira-kira 30% lebih besar daripada yang kami perlukan.

Dan alihkannya dari skrin ke bahagian atas dan kiri supaya ia tidak menyebabkan bar skrol.

Oleh itu,

.svg-animation-current-state-reporter

mendapat

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  // add 35 to all the values so we can use 0 to 34 for sentinels. 0 = CSS-side sentinel, 1-32 = data frames, 33 = length, 34 = checksum
  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return ($viewBoxXYWidth . ((string) $index) . '; ' . $viewBoxXYWidth . ((string) ($val + 35)));
  }, $data, range(1, $datalen)); // 1 up to 32 = indicator that next frame is the value(+35) for that index(1-based)

  // no matter how many are in the array, '33' indicates the next frame is data length, which is used in the checksum too
  array_unshift($frames, $viewBoxXYWidth . '33; ' . $viewBoxXYWidth . ((string) ($datalen + 35))); // + 35 b/c data
  // unshift so the length is (hopefully) the first value read and a sense of progress can be reported

  $fullsum = 0;

  for ($x = 0; $x <= ($datalen - 1); $x++) {
    // double the odd ones so there's some semblance of order accounted for
    // the odd ones with 0 based index is the even ones on the CSS side
    $fullsum += ($data[$x] + (($x & 1) * $data[$x]));
  }

  $checksum = floor($fullsum / 2048) + ($fullsum % 2048) + $datalen + 35; // + 35 because it's data

  // no matter how many are in the array, '34' indicates the next frame is checksum
  array_push($frames, $viewBoxXYWidth . '34; ' . $viewBoxXYWidth . $checksum);

  $actualNumItems = count($frames) * 2;

  $dur = $actualNumItems * 0.33; // total seconds

  $keytimeStep = 1 / ($actualNumItems); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $actualNumItems - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

dan sebelum menjadi

@keyframes capture {
  0%, 100% {
    --xfl\1-captured: var(--xfl\1);
  }
}

@keyframes hoist {
  0%, 100% {
    --xfl\1-hoist: var(--xfl\1-captured, 0);
  }
}
Salin selepas log masuk

dan ::selepas mendapat

  --xfl\1: calc(
    var(--xfl\1-hoist, 0) + 1
  );
Salin selepas log masuk

Pada asasnya, medium storan di sini untuk nilai selepas ini ialah kedudukan paparan pseudo segi empat sama 1px terhadap bekas skrol induknya. Kami menolak 1px dalam kal kiri dan atas kerana pseudo itu sendiri ialah 1x1 dan kami mahu ia melaporkan 0 apabila nilai yang sepadan ialah 0.

Ini semua sangat serupa dengan apa yang dilakukan sebelum ini.

Terdapat beberapa kerumitan cara kita mengira nilai ini sepatutnya, seperti yang ditunjukkan oleh nota:

  @container style(--xfl-cpu-phase: 4) {
    animation-play-state: paused, paused;
    --cpu-next-phase: calc(
      min(1, var(--xfl-data-type)) * 4
    );
  }
Salin selepas log masuk

Kunci untuk memahami cara menyelesaikan perkara ini ialah mana-mana nilai pembanding ditetapkan kepada sama ada 0 atau 1. 1 jika ia benar, 0 jika ia palsu. Kemudian darabkannya dengan beberapa nilai. Jika ia palsu, hasilnya kekal 0, jika tidak, ia akan menjadi apa sahaja nilainya.

Ana Tudor mendalami cara idea ini berfungsi di sini

Kemudian, jika kita melakukan perbandingan itu dua kali, dengan perbandingan yang berbeza atau bertentangan untuk nilai kedua, dan menambahnya bersama-sama (Memastikan paling banyak satu daripada pembanding ialah 1) maka penambahan dua daripadanya hanya mengatakan "lain jika".

jika belum bersedia * gunakan nilai lama yang lain
jika sudah bersedia * gunakan nilai baru ini

Beginilah cara kami memegang nilai sentinel melalui tempoh langkah diskret Animasi SVG untuk nilai selepas jenis telah dilaporkan.

Kod CSS yang melaksanakannya bermula pada baris 191 di sini, tepat di atas blok besar --xfl\... pendaftaran hartanah yang kami letakkan di bahagian bawah
@property --xfl\1 { sintaks: ""; nilai awal: 0; mewarisi: benar; }
...
dan ia mengandungi nota tambahan:

Menetapkan nilai CSS --var khusus (tugasan beralamat)

Logik yang baru kita sentuh adalah konsep yang sama yang kita gunakan untuk semua nilai --xfl\1, 2, 32.

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Anda membaca --xfl-set\1 seolah-olah --xfl-data-type sama dengan 1 penggunaan --xfl-data-is-ready dengan 0 tersirat lain

--xfl-data-is-ready telah ditubuhkan lebih awal sebagai bendera yang menahan kita dalam fasa 0 sehingga tiba masanya untuk beralih ke fasa 1.

Maksudnya keadaan kita adalah && logik. Kedua-dua bendera mestilah 1 untuk lulus.

Kemudian anda terus membaca --xfl\1 seolah-olah --xfl-set\1 gunakan --xfl-data-value (nilai Animasi SVG semasa) jika TIDAK --xfl-set\1 gunakan -- xfl\1-hoist (nilai sebelumnya yang disimpan oleh penggodaman CPU --xfl1)

Ini sangat berulang dan menerangkan hampir keseluruhan penyusutan yang lain.

Langkah akhir menjalankan matematik asas calc() dan mod() untuk membina checksum seperti yang diterangkan sebelum ini, kemudian menambah jika checksum yang dikira === checksum yang dibenamkan dalam Animasi SVG ke Hack CPU supaya kita tahu bila ianya lengkap. Semuanya lebih sama.

Jadi sekarang tiba masanya. :)

Mempersembahkan: Hack Penyusutan SVG Animasi CSS

Oleh kerana saya ingin menunjukkan setiap bahagian penggodaman ini satu nilai bagi setiap elemen, pembentangan untuk ini sangat berat. Lebih 2000 baris HTML dan lebih 400 baris CSS. Selain itu, saya menggunakan css-bin-bits untuk menukar setiap daftar kepada binari, dsb.

(Klik jalankan semula di bahagian bawah sebelah kanan bingkai codepen untuk melihatnya berlaku dalam masa nyata!)

Tiada JavaScript!


Buka Kenalan ?

Sila hubungi jika anda rasa ini kemas dan ingin mengetahui lebih lanjut! Sentiasa gembira menjawab soalan.

% CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi DEV Blog % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi
% CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi DEV Blog % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi

?@JaneOri.% CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi

?@Jane0ri

Atas ialah kandungan terperinci % CSS: Ambil dan Keluarkan bit Data Dijana Pelayan yang Dibenamkan dalam SVG Animasi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan