如何使用 svg 或 css 建立混合直線/曲線截面邊界?
P粉920835423
2023-09-02 11:35:13
<p>對於我的應用程序,我正在創建一個具有非標準部分邊界的註冊頁面。您可以在這裡看到我試圖實現的效果:
這不是一個簡單的圓弧——它有兩條直線,中間還有一個圓弧。 </p>
<p>據我所知,實現此類目標的最佳方法是使用 SVG。問題是,白色區域將有一個影像覆蓋整個區域。出於演示目的,我將使用淺藍色。如果您使用帶有 <code>background-image</code> 屬性的標準 <code>div</code>,則 SVG 的白色不透明,因此您會得到以下結果:
</p>
<p>提示稍後閱讀<code>shape-outside</code> 和<code>clip-path</code> 屬性,這是我嘗試過的最新方法(注意我正在使用與樣式組件反應):</p>
<pre class="brush:php;toolbar:false;">const LeftContainer = styled(FlexContainer)`
width: 55%;
height: 100%;
background-color: lightblue;
z-index: 1;
/* background: linear-gradient(360deg, #FFFFFF 24.95%, rgba(255, 255, 255, 0) 50.95%), url(${process.env.PUBLIC_URL}/TestImage.png);
`;
const RightContainer = styled(FlexContainer)`
width: 45%;
height: 100%;
/* background-color: ${colors.secondary600}; */
float: left;
/* background-image: url(${process.env.PUBLIC_URL}/SignUpBackground.svg); */
background-repeat: no-repeat;
background-size: cover;
background-position: center;
position: relative;
z-index: 5;
clip-path: url(${process.env.PUBLIC_URL}/SignUpBackground.svg#sidebar);
`;</pre>
<p>仍然存在間隙,但不僅如此,SVG 形狀的底部三分之一被切掉了:
</p>
<p>我能夠使左側容器填充額外空間的唯一方法是使右側容器<code>位置:絕對</code>,但這會導致我計劃的登錄表單出現問題添加到右側(它似乎沒有解決切斷svg 底部三分之一的問題)。</p>
<p>有沒有辦法讓右側容器保持在頁面流中,顯示 100% 的 svg,並確保左側容器與右側容器齊平? </p>
<p>編輯:
這是 SVG 程式碼:</p>
<pre class="brush:php;toolbar:false;"><svg width="708" height="1056"svg width="708" height="1056" viewBox="0 0 708 1056" ;http://www.w3.org/2000/svg">
<clipPath id="sidebar">
<path d="M144.5 0H799.5V1056H144.5L23.4254 775.169C0.402533 721.768 -5.09917 662.442 7.710896850989&t 4042 7.71089&Ft. 79A"/>
</clipPath>
</svg></pre>
<p>這是到目前為止的 React 元件(如您所見,構建的早期階段):</p>
<pre class="brush:php;toolbar:false;">const SignUpPage = (props) => {
return (
<Container>
<LeftContainer>
{/* Site logo and marketing copy, promo bubbles to go here. This side should be the one to shrink */}
</LeftContainer>
<RightContainer flexDirection="column" justify="center">
{/* Signup/Login form to go here */}
</RightContainer>
</Container>
);
}</pre>
<p>編輯2:
我已嘗試實施以下答案中的解決方案,但到目前為止,每個解決方案都至少存在一個問題。從 ccprog 的建議開始,我有點不確定,因為程式碼似乎與方法的描述不匹配,但我嘗試實現它並得到了這個結果:(首先是程式碼,然後是結果圖像)</ p>
<pre class="brush:php;toolbar:false;">const Container = styled(FlexContainer)`
height: 523px;
background-image: linear-gradient(360deg, #FFFFFF 24.95%, rgba(255, 255, 255, 0) 50.95%), url(${process.env.PUBLIC_URL}/SignUpImage.jpg);
background-position: top right 282px;
background-size: cover;
background-repeat: no-repeat;
`;
const LeftContainer = styled(FlexContainer)`
flex-grow: 1;
`
const RightContainer = styled(FlexContainer)`
width: 354px;
background-image: url('data:image/svg xml,<svg viewBox="0 0 708 1056" fill="none" xmlns="http://www.w3.org/2000/svg" ><path d="M144.5 0H799.5V1056H144.5L23.4254 775.169C0.402533 721.768 -5.09917 662.442 7.721.768 -5.09917 662.442 7.721089.71003000300030003000303030303030303000203; 16979A"/></svg>' );
background-size: 100% 100%;
`</pre>
<p>正如您所看到的,這實際上並沒有填充螢幕的整個高度,即使在右側也是如此,並且左側圖像確實被切斷了(左側圖像是所有解決方案中的一個問題,因為你會看到的)。 </p>
<p>接下來,我嘗試實施 Chrwahl 的第二個解決方案。這個有點接近(右側看起來很棒),但左側圖像有一些問題:</p>
<pre class="brush:php;toolbar:false;">const Container = styled(FlexContainer)`
width: 100%;
height: 100vh;
background-image: url(${process.env.PUBLIC_URL}/SignUpBackground.svg),
linear-gradient(360deg, #FFFFFF 24.95%, rgba(255, 255, 255, 0) 50.95%), url(${process.env.PUBLIC_URL}/SignUpImage.jpg);
background-repeat: no-repeat;
background-position: right, left;
background-size: contain, cover;
margin-bottom: 5px;
`;</pre>
<p>我不確定它是否出現在該圖像中,但螢幕的整個左側都是空白的,因此即使位置指定為左側,圖像似乎也不是從左邊緣開始。 <code>background-size: 40%, 70%</code> 的問題更嚴重:
</p>
首先介紹一些術語:我們將 SVG 形狀頂部和底部覆蓋的區域的寬度稱為“右側最小值”,將中間覆蓋的寬度稱為“右側最大值”。
我理解你的問題的方式是,右側區域 a) 具有恆定的寬度,b) 應始終顯示完整的 SVG 形狀。由此可見,它必須具有恆定的高度和 708 : 1056 的縱橫比。這樣可以輕鬆計算所需的尺寸,最重要的是右邊最小值與右邊最小值之間的比率右最大值為 564 : 708。
現在,我建議透過將左側圖像作為背景圖像移動到外部容器元素來解決您的問題,其寬度確保它位於彎曲部分下方,即。 e. 100% 減 564px(或固定分數)。包含促銷內容的左側容器元素的寬度為 100% 減去 708px,右側容器的寬度為 708px(或固定分數)。 (為簡單起見,容器透過與其元件名稱相符的類別名稱來識別)
您可以使用其他 px 大小值,只要保持它們之間的比例即可。
如果您不想想要顯示完整的SVG,而只想確保左側的曲線保持完全可見,請將以下屬性新增至根
當改變右側容器的縱橫比時,這將具有與 CSS
cover
相同的效果,而且viewBox
的區域始終與左邊。只有當縱橫比相對於寬度移動到更高的高度時,這才有效。如果縱橫比寬度增加,曲線的相同部分將在頂部和底部被切除 - 但另一種選擇是它的寬度不足以覆蓋右側。如果你走這條路,請記住,如果你提前設定了固定的高度,你只能知道最大和最小右側之間區域的寬度。 CSS 無法使用元素的高度來計算寬度值。