我正在使用以下动画创建一个Reaction按钮组件:

enter image description here

我在网上找到了一些有用的代码,并从try 纯html/css开始,只是为了体验一下,并得到了以下代码:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}


body {
  font-family: sans-serif;
  background-color: black;
  height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.button {
  position: relative;
  width: 200px;
  height: 40px;
  background-color: #083a65;
  border: 0;
  color: white;
  font-size: 18px;
  border-radius: 10px;
  cursor: pointer;
  max-width: 100%;
}

button svg {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

button rect {
  animation: button-border 2s linear both;
}

button path {
  animation: button-border 1s linear both;
}

@keyframes button-border {
  to {
    stroke-dashoffset: 0;
  }
}
<button
  type="button"
  class="button"
>
  My button
  <svg
    viewBox="0 0 200 40"
    fill="none"
    preserveAspectRatio="none"
  >
  
    <path
    d="M100,1
       h90
       q9.5,0 9.5,9.5
       v19
       q0,9.5 -9.5,9.5
       h-90
    "
      stroke="red"
      stroke-dasharray="460"
      stroke-dashoffset="460"
      stroke-width="1"
      vectorEffect="non-scaling-stroke"
  />
       <path
    d="M100,1
       h-90
       q-9.5,0 -9.5,9.5
       v19
       q0,9.5 9.5,9.5
       h90
    "
      stroke="red"
      stroke-dasharray="460"
      stroke-dashoffset="460"
      stroke-width="1"
      vectorEffect="non-scaling-stroke"
 / > 
  </svg>
</button>

总体而言,这达到了我的目标,但我发现我有以下问题.如果按钮宽度为200px,高度为40px(与视区大小相同),则此代码可以工作.当我有一个不同的按钮大小时,边框有效地按需要zoom ,但边框半径也是如此(即整个边框只是拉伸).我希望边框半径保持相同的像素量,即使当SVG被zoom 到不同的按钮大小时.我怎样才能做到这一点呢?

推荐答案

如果让SVG填充按钮,它将zoom 整个SVG,从而拉伸边框.相反,您可以修改SVG视图框和路径以适合您需要的大小.这里有几个例子.

因为你使用的是Reaction,如果你知道高度和宽度,你就可以使用props 在这个基础上建造它.(如果它需要处理未知的高度和宽度,您可以使用JavaScript来计算文本的宽度,并在运行时根据该宽度设置属性.)

[Note:我还将背景 colored颜色 移到了SVG中,使按钮背景透明,并将SVG设置为-1 z-index以显示在文本后面.]

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}


body {
  font-family: sans-serif;
  background-color: black;
  height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

section {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1em;
}

.button {
  position: relative;
  background-color: transparent;
  border: 0;
  color: white;
  font-size: 18px;
  border-radius: 10px;
  cursor: pointer;
  max-width: 100%;
}

button svg {
  position: absolute;
  left: 0;
  top: 0;
  z-index: -1;
}

button rect {
  animation: button-border 2s linear both;
}

button path {
  animation: button-border 1s linear both;
}

@keyframes button-border {
  to {
    stroke-dashoffset: 0;
  }
}
<section>

<button
  type="button"
  class="button"
  style="width: 200px; height: 40px"
>
  My Button
<svg viewBox="0 0 200 40" fill="none" preserveAspectRatio="none">
  <rect x="1" y="1" width="198" height="38" fill="#083a65" rx="9.5" ry="9.5" />

  <path
    d="M100,1
       h90
       q9.5,0 9.5,9.5
       v19
       q0,9.5 -9.5,9.5
       h-90
    "
    stroke="red"
    stroke-dasharray="460"
    stroke-dashoffset="460"
    stroke-width="1"
    vectorEffect="non-scaling-stroke"
  />

  <path
    d="M100,1
       h-90
       q-9.5,0 -9.5,9.5
       v19
       q0,9.5 9.5,9.5
       h90
    "
    stroke="red"
    stroke-dasharray="460"
    stroke-dashoffset="460"
    stroke-width="1"
    vectorEffect="non-scaling-stroke"
  />
</svg>
</button>

&nbsp;&nbsp;

<button
  type="button"
  class="button"
  style="width: 400px; height: 40px"
>
  My Button with Longer Text
<svg viewBox="0 0 400 40" fill="none" preserveAspectRatio="none">
  <rect x="1" y="1" width="398" height="38" fill="#083a65" rx="9.5" ry="9.5" />

  <path
    d="M200,1
       h190
       q9.5,0 9.5,9.5
       v19
       q0,9.5 -9.5,9.5
       h-190
    "
    stroke="red"
    stroke-dasharray="860"
    stroke-dashoffset="860"
    stroke-width="1"
    vectorEffect="non-scaling-stroke"
  />

  <path
    d="M200,1
       h-190
       q-9.5,0 -9.5,9.5
       v19
       q0,9.5 9.5,9.5
       h190
    "
    stroke="red"
    stroke-dasharray="860"
    stroke-dashoffset="860"
    stroke-width="1"
    vectorEffect="non-scaling-stroke"
  />
</svg>
</button>

&nbsp;&nbsp;

<button
  type="button"
  class="button"
  style="width: 400px; height: 120px"
>
  My Button with Longer Text
<svg viewBox="0 0 400 120" fill="none" preserveAspectRatio="none">
  <rect x="1" y="1" width="398" height="118" fill="#083a65" rx="9.5" ry="9.5" />

  <path
    d="M200,1
       h190
       q9.5,0 9.5,9.5
       v99
       q0,9.5 -9.5,9.5
       h-190
    "
    stroke="red"
    stroke-dasharray="1020"
    stroke-dashoffset="1020"
    stroke-width="1"
    vectorEffect="non-scaling-stroke"
  />

  <path
    d="M200,1
       h-190
       q-9.5,0 -9.5,9.5
       v99
       q0,9.5 9.5,9.5
       h190
    "
    stroke="red"
    stroke-dasharray="1020"
    stroke-dashoffset="1020"
    stroke-width="1"
    vectorEffect="non-scaling-stroke"
  />
</svg>
</button>

</section>

总而言之:

<button
  type="button"
  class="button"
  style="width: {{width}}px; height: {{height}}px"
>
  My Button with Longer Text
<svg viewBox="0 0 {{width}} {{height}}" fill="none" preserveAspectRatio="none">
  <rect x="1" y="1" width="{{width - 2}}" height="{{height - 2}}" fill="#083a65" rx="9.5" ry="9.5" />

  <path
    d="M{{width / 2}},1
       h{{width / 2 - 10}}
       q9.5,0 9.5,9.5
       v{{height - 9.5*2 - 2}}
       q0,9.5 -9.5,9.5
       h-{{width / 2 - 10}}
    "
    stroke="red"
    stroke-dasharray="{{height * 2 + width * 2 - 20}}"
    stroke-dashoffset="{{height * 2 + width * 2 - 20}}"
    stroke-width="1"
    vectorEffect="non-scaling-stroke"
  />

  <path
    d="M{{width / 2}},1
       h-{{width / 2 - 10}}
       q-9.5,0 -9.5,9.5
       v{{height - 9.5*2 - 2}}
       q0,9.5 9.5,9.5
       h{{width / 2 - 10}}
    "
    stroke="red"
    stroke-dasharray="{{height * 2 + width * 2 - 20}}"
    stroke-dashoffset="{{height * 2 + width * 2 - 20}}"
    stroke-width="1"
    vectorEffect="non-scaling-stroke"
  />
</svg>
</button>

Html相关问答推荐

如何在angular 17.2中使用routerLink解决此错误

为什么这个高度为100%的页面会出现滚动条?

<;img>;和具有负边距的元素的堆叠顺序

获得一个css框,以便在页面太小时不再粘在页面的角落.

带有MathJax SVG的HTML代码在XHTML中不起作用

天使17:令人惊叹的动画

穿过整个屏幕的旋转线

不呈现孙子元素,使用R htmlTools::Taglist为分页的pdf生成HTML

为什么当我按第三个按钮时,前两个按钮会跳动?

使用简单的 HTML 设计公司徽标和文本

无法在 CSS 中将 h1 标签居中

如何用js和CSS在两点之间画一条线

获取链接到功能的网页表单

这两个CSS中的网格居中对齐内部盒子有什么区别?

CSS 随着内容宽度的增加而减少填充

子 div 在父 div 中溢出

发光效果html动画

CSS 变量不适用于自定义属性回退值

CSS:如何在模糊的背景上剪切文本?

下拉菜单项在页面加载时显示,需要隐藏直到悬停