如何将剪辑路径的文本相对于视口居中并显示剪辑路径的所有文本?



这里是我的React组件演示:https://codesandbox.io/s/epic-brown-osiq1,我现在使用viewBox的值getBBoxgetBoundingClientRect()来实现一些计算,以便定位我的元素。目前,我已经根据控制台从getBoundingClientRect()的日志中提供的返回值输入了原始值。您可以在我实现了getBoundingClientRect()的元素上看到它,即<svg>的根元素和clip-pathtext的元素。更好的是,text更像是在屏幕中心,真正对准text盒子的中心,你可以看到"所以"的字在"食物"的字的开头,而不是对准box的中心。所以我现在正处于这个阶段。感谢您的反馈。*

注意:你会在沙盒中看到一些评论,提供我以前的审判的信息或部分内容。我的代码做什么?具体来说,我展示了一个clip-path的文本,一些动画面板沿着clip-path移动——这就是color_panel_group's element——给构图带来了一些动态。text后面也有一个阴影,为构图提供了一些深度

  • 期望:显示clip-pathtext,其响应性定位在视口的垂直和水平中心
  • 问题:我的clip-path隐藏了text的一部分,并且我将元素相对于视口居中的尝试未能取得成果
  • 我试过的:我尝试过处理元素的宽度和元素的x的位置,主要是textclip-pathsymbol,以及两种情况。甚至试图通过在use元素中实现一些类来处理它,但最终得到了非常近似的结果。此外,在tspansymbol中,我试图利用x的属性,再次获得非常近似的结果。我尝试过使用position absoluterelative container——主要是直接在SVG的CSS选择器上——仍然有近似的结果

我想知道我错过了什么。也许有人能对我的代码行为做出一些解释?

这里是我的第二个演示的结果代码(大约是React组件产生的代码(:

body {
background: orange;
}
svg {
background: green;
display: block;
margin: auto;
position: relative;
z-index: 2;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
.component {
min-width: 100vw;
min-height: 100vh;
font-size: 100%;
}
.fade_in_background {
opacity: 1;
visibility: visible;
transition: all 1.5s ease-out 0s;
}
.brandtype {
margin: auto;
text-align: center;
}
.brandtype_use {
position: absolute;
transform: translate(-112.65px, 0)
}
.clipPath_text {
text-align: center;
}
.color_panel_group {
padding: 25px;
}
.shape_animation {
transform-origin: 0;
transform: scale(0, 1) translate(0, 0);
animation: moving-panel 3s 1.5s 1 alternate forwards;
}
.shadow {
transform: translate(10px, 10px)
}
.shape_animation_shadow {
fill: black;
fill-opacity: .505;
transition: all 1.3s ease-out 0.3s;
}
.brandtype {
font-size: 6.8em;
}
@keyframes moving-panel {
to {
transform: scale(1, 1) translate(20px, 0);
}
}
<div class="component">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 965 657">
<defs>
<symbol id="panel_animation" y="0">
<clipPath class="clipPath_text" id="clipPath_text"><text class="brandtype" word-spacing="-.45em">
<tspan x="0%" y="50%" dy="1.6em">So</tspan>
<tspan x="0%" y="50%" dy="3em">Food</tspan>
</text></clipPath>
<g class="shadow" clip-path="url(#clipPath_text)">
<rect class="shape_animation shape_animation_shadow" width="100%" height="100%" x="-25px">
</rect>
</g>
<g class="color_panel_group" clip-path="url(#clipPath_text)">
<rect class="shape_animation" fill="#F2385A" width="100%" height="100%"></rect>
<rect class="shape_animation" fill="#F5A503" width="80%" height="100%"></rect>
<rect class="shape_animation" fill="#E9F1DF" width="60%" height="100%"></rect>
<rect class="shape_animation" fill="#56D9CD" width="40%" height="100%"></rect>
<rect id="shape_animation_ref" class="shape_animation" fill="#3AA1BF" width="20%" height="100%" x="-25px">
</rect>
</g>
</symbol>
</defs>
<rect width="100%" height="100%" filter="url(#background_light)"></rect>
<use width="500px" height="100%" x="50%" xlink:href="#panel_animation" class="brandtype_use"></use>
</svg>
</div>

谢谢你的提示。

SVG中的文本对齐方式与我们习惯的HTML和CSS不同,在HTML和CSS中,所有内容都是带一些维度的框,我们可以应用例如text-align: center

<svg:text>中,起始坐标定义了文本线展开的点。text-anchor属性控制扩展的方向:center值表示它将双向扩展,因此初始定位点将位于边界框宽度的中间(对于水平书写系统(。请参阅优秀的答案,将此text-anchor说明为SVG中文本居中的最佳方法:https://stackoverflow.com/a/23272367/540955.此外,SVG中没有CSS位置属性(左/上(,只有x/y坐标,也没有HTML中的边距和框外模型。

因此,在您的代码中,添加text-anchor="middle"并将x坐标向右移动会产生居中的文本。我建议使用裸露的<text>元素,而不是<tspan>元素,因为用dx/dy移动它们是相对于前一个字符的,并且这个字符可能是父<text>的一些空白(取决于代码格式(,这会产生不平衡的居中。此外,为了便于计算,dominant-baseline="central"(或仅用于水平书写系统的middle(也很有用,因为它将锚点从基线移动到"中心线"。因此,使用dy属性(正如您已经做的那样(将第一行向上移动行高的"一半",另一行向下移动应该可以做到这一点:

<svg viewBox="0 0 800 200" text-anchor="middle" dominant-baseline="central" font-size="100">
<!-- Outline and diagonals with center point for illustration: -->
<path d="M0,0h800v200h-800zl800,200m0 -200L0,200" fill="#FC9" stroke-width="1" stroke="rgba(0,0,0,0.3)"></path>
<circle cx="50%" cy="50%" r="10" fill="red"></circle>
<!-- Centered text: -->
<text x="50%" y="50%" fill="rgba(0,0,0,0.3)">So</text>
<!-- Shifted up and down: -->
<text x="50%" y="50%" dy="-0.5em">So</text>
<text x="50%" y="50%" dy="+0.5em">Food</text>
</svg>


(不完全相关:剪辑只能用background-clip: text在CSS中完成;这是你的设计在Chrome浏览器中的粗略变化,有动画文本背景,但没有阴影。不幸的是,我认为添加阴影需要更多的元素或属性。这应该适用于任何支持背景剪辑的浏览器。(

div {
	display: flex;
	flex-direction: column;
	align-items: center;
	font-size: 30vh;
	line-height: 30vh;
	font-weight: bold;
	font-family: Impact;
}
span {
	color: #fff;
	background-color: #000;
	width: 100%;
	text-align: center;
}
@supports (-webkit-text-fill-color: transparent) and (-webkit-background-clip: text) {
	span {
		-webkit-text-fill-color: transparent;
		-webkit-background-clip: text;
		animation: 2s wohoo infinite alternate cubic-bezier(1,0,1,1);
		background-position: 0 0;
		background-size: 100% 100%;
		background-color: transparent;
		background-image: linear-gradient(
			to right,
			#f2385a 0,
			#f2385a 20%,
			#f5a503 0,
			#f5a503 40%,
			#e9f1df 0,
			#e9f1df 60%,
			#56d9cd 0,
			#56d9cd 80%,
			#3aa1bf 0,
			#3aa1bf 100%
		);
		background-repeat: no-repeat;
		transform-origin: center center;
	}
}
@keyframes wohoo {
	from {
		background-size: 0 100%;
		background-position: -5vh 0;
		transform: scale(0.7);
	}
	50% {
		transform: scale(0.7);
	}
	90% {
		transform: scale(0.9);
	}
	to {
		background-size: 500% 100%;
		background-position: 0vh 0;
		transform: scale(0.9) 
	}
}
html,body{margin:0;overflow:hidden;}
body {
	background-color: #1d1f20;
	color: snow;
	display: flex;
	flex-direction: row;
	justify-content: center;
	width: 100%;
}
<div>
	<span>Baz</span>
	<span>Gazonk</span>
	<span>Qux</span>
</div>

最新更新