Mengapa transisi ini terjadi secara berbeda di Chrome dan Firefox?

Saya memiliki animasi SVG berikut (cuplikannya cukup besar, lihat 'Tampilkan cuplikan kode'):

.logo > .logo-compass-frame {
  fill: none;
  stroke: black;
  stroke-width: 15;
  stroke-linecap: round;
  stroke-miterlimit: 10;
}

.logo > .logo-compass-north, .logo > .logo-compass-south {
  stroke: black;
  stroke-width: 8;
  stroke-miterlimit: 10;
}

.logo > .logo-compass-south {
  fill: none;
}

.logo > .logo-compass-center {
  fill: black;
  stroke: black;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-miterlimit: 10;
}

.logo > .logo-compass-north, .logo > .logo-compass-south, .logo > .logo-compass-center {
  transition: 0.5s ease-in-out;
  opacity: 1;
}

.logo:hover > .logo-compass-north, .logo:hover > .logo-compass-south {
  transform-origin: center;
}

.logo:hover > .logo-compass-north {

  transform: rotate(90deg) scale(1.5) translate(10px);
}

.logo:hover > .logo-compass-south {
  transform: rotate(90deg) scale(1.5) translate(-10px);
}

.logo:hover > .logo-compass-center {
  opacity: 0;
}
<svg class="logo" x="0px" y="0px" viewBox="0 0 272.6 272.6">
  <circle class="logo-compass-frame" cx="136.3" cy="136.3" r="105.8" />
  <polygon class="logo-compass-north" points="138,63.6 123.8,110.5 138,134.5 152.2,110.5" />
  <polygon class="logo-compass-south" points="138,209 152.2,162.1 138,138.1 123.8,162.1" />
  <circle class="logo-compass-center" cx="138" cy="136.6" r="5.7" />
</svg>

Masalahnya adalah tindakannya berbeda hanya pada Firefox (belum diuji pada Edge atau IE karena saya menggunakan macOS). Untuk browser WebKit dan Opera, saya mendapatkan:

Chrome 60.0.3112.90:

Safari 10.1:

Opera 47.0.2631.39:

Firefox 54.0.1:

Sesuatu yang mencurigakan sedang terjadi. Saya belum mencoba Edge atau IE, jadi mungkin ini semacam masalah kepatuhan spesifikasi CSS? Saya pikir mungkin transform-origin tidak didukung karena ini merupakan teknologi eksperimental, tetapi menambahkan -moz-transform-origin tidak melakukan apa pun, dan MDN melaporkan bahwa transform-origin sekarang didukung.

Mengapa transisi memiliki efek yang berbeda pada browser yang berbeda, dan apakah mungkin untuk memperbaikinya?


person Andrew Li    schedule 12.08.2017    source sumber


Jawaban (1)


Anda tidak dapat menggunakan nilai persentase untuk transform-origin saat ini karena nilai persentase diperlakukan berbeda di Chrome dan Firefox. Hal ini juga berlaku untuk nilai semu seperti "pusat" yang didefinisikan setara dengan "50%".

Anda harus menggunakan nilai piksel absolut agar kompatibel lintas-browser.

.logo > .logo-compass-frame {
  fill: none;
  stroke: black;
  stroke-width: 15;
  stroke-linecap: round;
  stroke-miterlimit: 10;
}

.logo > .logo-compass-north, .logo > .logo-compass-south {
  stroke: black;
  stroke-width: 8;
  stroke-miterlimit: 10;
}

.logo > .logo-compass-south {
  fill: none;
}

.logo > .logo-compass-center {
  fill: black;
  stroke: black;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-miterlimit: 10;
}

.logo > .logo-compass-north, .logo > .logo-compass-south, .logo > .logo-compass-center {
  transition: 0.5s ease-in-out;
  opacity: 1;
}

.logo:hover > .logo-compass-north {
  transform-origin: 138px 99px;
}

.logo:hover > .logo-compass-south {
  transform-origin: 138px 173.5px;
}

.logo:hover > .logo-compass-north {

  transform: rotate(90deg) scale(1.5) translate(10px);
}

.logo:hover > .logo-compass-south {
  transform: rotate(90deg) scale(1.5) translate(-10px);
}

.logo:hover > .logo-compass-center {
  opacity: 0;
}
<svg class="logo" x="0px" y="0px" viewBox="0 0 272.6 272.6">
  <circle class="logo-compass-frame" cx="136.3" cy="136.3" r="105.8" />
  <polygon class="logo-compass-north" points="138,63.6 123.8,110.5 138,134.5 152.2,110.5" />
  <polygon class="logo-compass-south" points="138,209 152.2,162.1 138,138.1 123.8,162.1" />
  <circle class="logo-compass-center" cx="138" cy="136.6" r="5.7" />
</svg>

Perbarui

Saya telah mengetahui mengapa Firefox berperilaku berbeda. Ini bukan bug. Firefox sebenarnya benar. Itu karena Firefox menafsirkan spesifikasi dengan benar dan browser lain tidak.

Penyebab langsungnya adalah karena kami menentukan transform-origin dalam aturan :hover. Jadi asal usulnya juga diinterpolasi (yaitu bergerak). Cara mengatasinya adalah dengan:

  1. Tentukan bahwa kita hanya ingin mentransisikan properti transform.

    transition: transform 0.5s ease-in-out;
    
  2. Atau pindahkan transform-origin dari aturan hover.

Di bawah ini adalah versi terbaru yang menggunakan pendekatan #2.

.logo > .logo-compass-frame {
  fill: none;
  stroke: black;
  stroke-width: 15;
  stroke-linecap: round;
  stroke-miterlimit: 10;
}

.logo > .logo-compass-north {
  stroke: black;
  stroke-width: 8;
  transform-origin: 138px 99px;
}

.logo > .logo-compass-south {
  stroke: black;
  stroke-width: 8;
  fill: none;
  transform-origin: 138px 173.5px;
}

.logo > .logo-compass-center {
  fill: black;
  stroke: black;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-miterlimit: 10;
}

.logo > .logo-compass-north, .logo > .logo-compass-south, .logo > .logo-compass-center {
  transition: 0.5s ease-in-out;
  opacity: 1;
}

.logo:hover > .logo-compass-north {
  transform: rotate(90deg) scale(1.5) translate(10px);
}

.logo:hover > .logo-compass-south {
  transform: rotate(90deg) scale(1.5) translate(-10px);
}

.logo:hover > .logo-compass-center {
  opacity: 0;
}
<svg class="logo" width="300px" viewBox="0 0 272.6 272.6">
  <circle class="logo-compass-frame" cx="136.3" cy="136.3" r="105.8" />
  <polygon class="logo-compass-north" points="138,63.6 123.8,110.5 138,134.5 152.2,110.5" />
  <polygon class="logo-compass-south" points="138,209 152.2,162.1 138,138.1 123.8,162.1" />
  <circle class="logo-compass-center" cx="138" cy="136.6" r="5.7" />
</svg>

person Paul LeBeau    schedule 12.08.2017
comment
Ah ya. Saya curiga transform-origin tapi saya lupa bahwa center hanyalah alias untuk nilai persentase, dan FF belum mendukung sepenuhnya. Terima kasih! - person Andrew Li; 12.08.2017
comment
Juga -- bagaimana tepatnya Anda menghitung nilai piksel? Sebenarnya, logo saya ada di navbar. - person Andrew Li; 12.08.2017
comment
Saya menemukan pusatnya dengan membuka alat dev dan memilih elemen yang diinginkan dengan alat pemilih elemen. Kemudian di konsol saya mengetik: var b=$0.getBBox();. Kemudian b.x+b.width/2 dan b.y+b.height/2. - person Paul LeBeau; 12.08.2017
comment
@AndrewLi FF mendukung sepenuhnya hal itu. Itu Chrome yang salah. Perilaku Chrome/Opera dijadwalkan untuk selaras dengan Firefox dan spesifikasi w3c, bukan sebaliknya. - person Robert Longson; 12.08.2017
comment
Apakah ada cara yang masuk akal untuk mempertahankan animasi saya saat ini atau menulis ulang sehingga sesuai spesifikasi tetapi terlihat sama? - person Andrew Li; 13.08.2017
comment
@AndrewLi Saya tidak bisa menjelaskan perilaku aneh yang tersisa di Firefox. Tampaknya ada kesalahan dalam cara transformasi diinterpolasi dalam animasi. Saya akan menyelidikinya. - person Paul LeBeau; 13.08.2017
comment
@PaulLeBeau Terima kasih banyak! - person Andrew Li; 13.08.2017