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

Posted

技术标签:

【中文标题】如何将剪辑路径的文本相对于视口居中并显示所有剪辑路径的文本?【英文标题】:How can I center my clip-path's text relatively to the viewport and display all the clip-path's text? 【发布时间】:2020-03-10 18:46:59 【问题描述】:

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

注意:您会在沙箱中看到一些 cmet 提供信息或我以前的试验的部分内容。 我的代码有什么作用?具体来说,我显示了一个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"   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"   x="-25px">
          </rect>
        </g>
        <g class="color_panel_group" clip-path="url(#clipPath_text)">
          <rect class="shape_animation" fill="#F2385A"  ></rect>
          <rect class="shape_animation" fill="#F5A503"  ></rect>
          <rect class="shape_animation" fill="#E9F1DF"  ></rect>
          <rect class="shape_animation" fill="#56D9CD"  ></rect>
          <rect id="shape_animation_ref" class="shape_animation" fill="#3AA1BF"   x="-25px">
          </rect>
        </g>
      </symbol>
    </defs>
    <rect   filter="url(#background_light)"></rect>
    <use   x="50%" xlink:href="#panel_animation" class="brandtype_use"></use>
  </svg>
</div>

感谢任何提示。

【问题讨论】:

您的 svg 需要以用户单位而不是百分比设置的 viewBox 属性。还要在用户单位中设置其他所有内容 感谢您的回答,您介意解释一下您的建议背后的理由吗?此外,如果我在用户单元中设置所有内容,我会假设我会失去可能响应的好处? viewBox 中不允许使用百分比值。它们必须是无单位的数字。 感谢您的回答,现在我的剪辑路径和居中问题仍然存在,也许您知道为什么会出现这种情况? 所以基本上你的主要问题是水平居中两行 SVG 文本,对吧?剪辑、动画、过滤器和 React 部分现在不重要吗? 【参考方案1】:

SVG 中的文本对齐方式不像我们习惯的 html 和 CSS 那样工作,在 HTML 和 CSS 中,所有内容都是具有某些尺寸的盒子,我们可以应用例如text-align: center.

&lt;svg:text&gt; 中,起始坐标定义了文本行将从该点展开。 text-anchor 属性控制此扩展将发生的方向:center 值表示它将双向扩展,因此初始锚点将位于边界框宽度的中间(对于水平书写系统)。请参阅出色的答案,说明 text-anchor 是在 SVG 中居中文本的最佳方法:https://***.com/a/23272367/540955。此外,SVG 内部没有 CSS 位置属性(左/上),只有 x/y 坐标,也没有您在 HTML 中所知道的框模型的边距和其余部分。

因此,在您的代码中添加text-anchor="middle" 并将x 坐标向右移动会产生居中的文本。我建议使用裸&lt;text&gt; 元素而不是&lt;tspan&gt;s,因为用dx/dy 移动它们是相对于前面的最后一个字符,这个字符可能是来自父&lt;text&gt; 的一些空格(取决于代码格式)什么会产生不平衡的居中。对于更容易计算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- 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>

(不完全相关:只能在 CSS 中使用 background-clip: text 进行剪辑;这是您的设计在 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,bodymargin: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>

【讨论】:

SVG 内部没有 CSS 位置属性(左/上),只有 x/y 坐标 ... => 非常感谢,充分了解这一事实非常重要。 ... 并且这个字符可能是父 的一些空格,(取决于代码格式)什么会产生不平衡的居中 => 你什么时候建议相对使用 tspan 例如关于居中元素或 svg 格式? ...dominant-baseline="central"(或者对于水平书写系统来说只是中间)很有用 ... => 我编辑了一个 codepen:codepen.io/joondoe/pen/oNNOppp,感谢 MDN。 感谢您的回答,它提供了有关如何处理这种情况的深刻见解,最后一个问题,据您所知,社区是否会知道其他任何元素?

以上是关于如何将剪辑路径的文本相对于视口居中并显示所有剪辑路径的文本?的主要内容,如果未能解决你的问题,请参考以下文章

可以将 SVG 剪辑路径相对于其容器居中吗?

Safari 不允许隐藏溢出的 svg 剪辑路径溢出容器

如何在 SVG 剪辑路径中居中对齐图像?

如何使用 CSS 剪辑路径剪辑画布?

具有剪辑路径的元素中的水平(子)像素间隙

当引用为 css 剪辑路径属性时,SVG 剪辑路径的位置不正确