css3 daripada imej segi empat sama kepada trapezoid tanpa putaran x
P粉604669414
P粉604669414 2024-03-28 15:26:58
0
1
335

Saya cuba menukar div segi empat sama dengan imej latar belakang kepada trapezoid.

Saya mahu membuatnya dalam 2D, sama seperti alat "herotkan" Photoshop.

Pada asasnya, apa yang saya mahukan ialah mengecilkan tepi atas segi empat sama dan mengubah bentuk imej dengan sewajarnya.

Penukaran 3D "nampaknya" melakukan silap mata:

transform: rotateX(30deg);

Ia berfungsi untuk kebanyakan kes penggunaan, tetapi bukan semua. Malah, ia adalah segi empat sama berpusing 30 darjah yang "kelihatan" seperti trapezium apabila dilihat dari hadapan/belakang, tetapi masih merupakan segi empat sama berpusing 30 darjah apabila dilihat dari mana-mana sisi lain.

Apa yang saya mahu ialah mendapatkan trapezoid sebenar. Saya mahu imej segi empat sama diherotkan dalam cara 2D supaya bentuk dan imej benar-benar berubah tanpa melibatkan putaran.

Saya mencuba ini dan ia berfungsi dari segi bentuk (trapezoid):

border-style: solid;
height: 0;
border-color: transparent transparent red transparent;
border-width: 0 100px 100px 100px;

Tetapi saya tidak boleh menggantikan kawasan merah dengan imej latar belakang yang herot. Ini mengalahkan tujuan saya. Semua yang saya cuba memastikan imej tidak terganggu.

Adakah terdapat sebarang helah css/html5/javascript untuk mencapai apa yang saya mahukan?

Terima kasih.

P粉604669414
P粉604669414

membalas semua(1)
P粉131455722

Anda boleh mendapatkan kesannya dengan menggunakan transformasi 3D pada unsur pseudo (anda juga boleh menetapkan background-image padanya) dan memastikan ia diratakan pada satah asalnya (satah unsur induknya). Ini bermakna jika anda ingin memutarkan sesuatu dalam 3D, anda perlu memutarkan objek induk.

Langkah #1: Buat div segi empat sama, tambah pembolehubah tiruan (atau sub-pembolehubah) dengan dimensi yang sama dan tetapkan div,添加一个具有完全相同尺寸的伪变量(或子变量),并在该伪变量上设置 background-image pada pembolehubah tiruan itu.

div {
    display: grid; /* makes pseudo stretch all across */
    width: 28em; /* whatever edge value we want */
    aspect-ratio: 1; /* make it square */
    /* just to highlight div boundaries */
    box-shadow: 0 0 0 3px;
    
    &::after {
        background: url(image.jpg) 50%/ cover;
        content: ''
    }
}

Langkah #2: Letakkan nilai tiruan pada transform-origin 设置为底部边缘的中间 (100% 50%) - ini memastikan bahagian tepi bawah kekal pada tempatnya selepas menggunakan transformasi 3D.

Langkah #3: Panjangkan tepi di sepanjang paksi z 轴应用 3D 倾斜,沿 y.

Ya, kami tidak mempunyai fungsi kecondongan 3D dalam CSS. Tetapi kami mempunyai matrix3d(), yang boleh digunakan untuk menyatakan sebarang putaran, penskalaan, kecondongan dan terjemahan!

Jadi mari kita fahami dahulu cara kecondongan berfungsi.

Kecondongan berlaku di sepanjang paksi.

Ini ialah demo interaktif yang menggambarkan cara fungsi kecondongan 2D berfungsi.

Pertimbangkan contoh ini di mana kita mencondongkan sepanjang paksi x, apabila paksi y berputar dari kedudukan asalnya, tepi sepanjang paksi y memanjang - sudut ini ialah sudut kecondongan. Paksi z berserenjang dengan satah yang kita condongkan (dalam kes ini xOy) dan tidak terjejas:

Nah, dalam kes kami, kami melakukan sesuatu yang serupa, tetapi kecondongan berlaku pada satah yOz, bukan satah xOy, kerana kami condong di sepanjang satah yOz >z sebaliknya Di sepanjang paksi x.

Memandangkan kami telah menggunakan transform-origin untuk melabuhkan bahagian tengah tepi bawah nilai pseudo pada tempatnya, dan kecondongan ini berlaku di sepanjang paksi z (berserenjang dengan skrin), pada dasarnya kami menarik pseudo-belakang ke arah belakang skrin, mengekalkan setiap koordinat x dan y sesuatu titik, tetapi tukar koordinat z.

Pada asasnya, jika kita melihatnya dalam 3D tanpa mendatar ke satah induk (induk dihadkan oleh garis besar), ia akan kelihatan seperti ini.

Anda boleh melihat cara garis panduan mendatar di bahagian atas menunjukkan cara bahagian atas nilai pseudo senget mengekalkan koordinat x dan ynya, ia hanya di sepanjang paksi z.

Baiklah, bagaimana kita melakukan ini menggunakan CSS?

Seperti yang dinyatakan di atas, tiada kecondongan 3D, tetapi kita boleh membina matriks transformasi sendiri. Memandangkan ini ialah kecondongan di sepanjang paksi z (paksi ketiga) dan tepi diregangkan di sepanjang paksi y (paksi kedua), satu-satunya perkara dalam matriks yang sama dengan matriks identiti ( 1,其他地方的 0)将位于第 3 行第 2 行柱子。我们将在那里得到倾斜角的正切。在 MDN 上,您也可以在 skewX()skewY() sepanjang pepenjuru utama) ke titik ini

Ini kerana setiap titik di sepanjang paksi kecondongan disesarkan oleh koordinatnya di sepanjang paksi memanjang dikali tangen sudut kecondongan - anda boleh melihat ini dalam ilustrasi pertama jika anda melukis garisan selari dengan paksi (Paksi x , paksi y (dicondongkan ke hadapan dan ke belakang) melepasi kedudukan asal (kelabu) dan kedudukan akhir (hitam) titik contoh Melukis garis selari ini menghasilkan segi tiga tepat dengan koordinat y pada Anjakan x . ialah tangen bagi sudut kecondongan

.

Baiklah, kembali kepada matriks, ia kelihatan seperti ini.

1   0    0
0   1    0
0 tan(a) 1

Untuk mendapatkan matrix3d() 值,我们再添加一行和一列,与 4x4 nilai yang sama dalam matriks identiti, kemudian senaraikan nilai lajur demi lajur ( bukan ) > baris demi baris!). Setakat ini kami ada:

@use 'sass:math'; // allows us to use trigonometric functions
$a: 60deg; // the skew angle

div {
    display: grid;
    width: 28em;
    aspect-ratio: 1;
    perspective: 25em;
    box-shadow: 0 0 0 3px;
    
    &::after {
        transform-origin: 50% 100%;
        transform: matrix3d(1, 0, 0, 0, /* 1st column */
                            0, 1, math.tan($a), 0, /* 2nd column */
                            0, 0, 1, 0, /* 3rd column */
                            0, 0, 0, 1);
        background: url(image.jpg) 50%/ cover;
        content: ''
    }
}

Perhatikan bahawa kami juga menambah perspective untuk mendapatkan pandangan yang herot (lebih kecil di bahagian atas/lebih jauh ke belakang).

Kod setakat ini memberikan kita versi rata yang dilihat dalam gif di atas. Saya katakan versi diratakan kerana, sejauh yang kita ada di sini, objek pseudo sentiasa diratakan pada satah induknya.

Apabila ibu bapa divtidak mempunyai transformasi 3D, dan kami melihatnya dari hadapan, rupa pseudo-obvious adalah rata.

Apabila ibu bapa div 确实具有 3D 变换时,其 3D 变换伪值会展平到其平面中,因为默认 transform-style 值为 flat。这意味着 3D 变换父级的任何 3D 变换子级/伪对象都会在父级平面中展平。如果我们将div的transform-style设置为preserve-3d memang mempunyai penjelmaan 3D, nilai pseudo penjelmaan 3Dnya diratakan ke dalam satahnya, kerana nilai lalai gaya perubahan ialah rata. Ini bermakna bahawa mana-mana kanak-kanak/objek pseudo-transformasi 3D induk transformasi 3D akan diratakan dalam satah induk. Tetapan ini boleh ditukar jika kami menetapkan transform-style div kepada preserve-3d. Tetapi kami tidak mahu itu.

Langkah 4: Selamatkan bahagian tepi atas!

Seperkara lagi yang masih nampak tidak betul: transform Tepi atas kini berada di bawah tepi asal.

Ini kerana cara kami menyediakannya perspective 以及它的工作原理。默认情况下,perspective-origin 死在我们设置它的元素的中间(在本例中是我们的 div),水平方向为 50%,垂直方向为 50% dan cara ia berfungsi. Secara lalai, perspective-origin mati di tengah-tengah elemen yang kami tetapkan (dalam kes ini

kami), pada 50% secara mendatar dan menegak 50% .

Mari kita pertimbangkan titik di belakang satah skrin, kerana di situlah keseluruhan nilai pseudo kecondongan 3D kita.

perspective-origin (50% 50%),只有 div 正中间垂直于屏幕平面的线上的点才会被投影到屏幕平面上的某个点:考虑视角后,与自己的 x,y 坐标相同的 x,y 坐标。考虑透视后,只有垂直于屏幕并沿 divMenggunakan perspektif-asal lalai (50% 50%), hanya

titik pada garis yang berserenjang dengan satah skrin akan ditayangkan pada satah skrin Titik tertentu : koordinat x, y yang sama dengan koordinat x, y anda sendiri selepas mengambil kira perspektif. Dengan mengambil kira perspektif, hanya titik dalam satah yang berserenjang dengan skrin dan bersilang dengan skrin di sepanjang garis tengah mendatar

akan ditayangkan ke garis tengah mendatar itu. perspective-origin 使其位于 div 顶部边缘的中间 (50% 0

Adakah anda tahu apa yang berlaku? Jika kita bergerak

), maka mata dalam satah berserenjang dengan skrin di sepanjang tepi atas itu akan ditayangkan di sepanjang tepi atas itu - iaitu, tepi atas objek pseudo condong 3D akan berada di sepanjang garis yang sama dengan tepi atas induknya.

🎜Jadi kod terakhir kami ialah: 🎜
@use 'sass:math'; // allows us to use trigonometric functions
$a: 60deg; // the skew angle

div {
    display: grid;
    width: 28em;
    aspect-ratio: 1;
    perspective-origin: 50% 0;
    perspective: 25em;
    box-shadow: 0 0 0 3px;
    
    &::after {
        transform-origin: 50% 100%;
        transform: matrix3d(1, 0, 0, 0, /* 1st column */
                            0, 1, math.tan($a), 0, /* 2nd column */
                            0, 0, 1, 0, /* 3rd column */
                            0, 0, 0, 1);
        background: url(image.jpg) 50%/ cover;
        content: ''
    }
}

Berikut ialah pandangan perbandingan langsung antara keputusan kami dan versi prapenukarannya kerana kedua-dua div diputar dalam 3D untuk menunjukkan bahawa ia rata pada satah xOy.


Tidak mahu menggunakan prapemproses untuk mengendalikan nilai tangen? Firefox dan Safari sudah pun menyokong fungsi trigonometri secara lalai, dan Chrome 111+ menyokong fungsi trigonometri dengan mendayakan bendera chrome://flagsCiri Platform Web Eksperimen dalam .

Tidak mahu menunggu sokongan Chromium? Anda tidak perlu menggunakan pengiraan tangen di sana, anda boleh menggunakan mana-mana nombor positif - semakin besar nombor itu, semakin kecil tepi atasnya. Saya menggunakan nilai tangen untuk menggambarkan dari mana asalnya, tetapi anda tidak perlu melakukannya. Tangen kami adalah untuk tangen dari 90° 的角度计算的。这为我们提供了从 0+Infinity. Jadi ya, sebarang nombor positif boleh muncul dalam matriks.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan