css和svg多边形按钮实现

2021-10-11  本文已影响0人  橙子只过今天

1. css实现

1.1 强行实现

页面效果

image.png

代码

<template>
  <div class="angle-button">
    <div class="angle top-right"></div>
    <div class="angle top-left"></div>
    <div class="angle bottom-right"></div>
    <div class="angle bottom-left"></div>
    <span class="name"><slot></slot></span>
  </div>
</template>

<script>
export default {}
</script>
<style lang="scss" scoped>
.angle-button {
  width: 100px;
  height: 35px;
  cursor: pointer;
  background: rgba(237, 112, 83, 0);
  border: 1px solid #1983c2;
  position: relative;
  box-shadow: 0px 0px 30px rgb(9, 83, 143) inset;
  text-align: center;
  line-height: 35px;
  font-size: 16px;
  color: #80d2fa;
  margin: 0 10px;

  .angle {
    position: absolute;
    border-left: 8px solid rgb(1, 14, 41, 0.9);
    border-right: 8px solid transparent;
    border-top: 8px solid transparent;
    border-bottom: 8px solid transparent;

    &::before {
      content: '';
      position: absolute;
      right: 1px;
      width: 15px;
      height: 1px;
      background-color: #1983c2;
      z-index: 9999;
      transform: rotate(90deg);
    }
  }

  .top-right {
    top: -9px;
    right: -9px;
    transform: rotate(-45deg);
  }

  .top-left {
    top: -9px;
    left: -9px;
    transform: rotate(225deg);
  }

  .bottom-right {
    bottom: -9px;
    right: -9px;
    transform: rotate(45deg);
  }

  .bottom-left {
    bottom: -9px;
    left: -9px;
    transform: rotate(135deg);
  }
}
</style>

总结
不适用背景颜色变化较多时。

1.2 clip-path实现

页面效果

image.png

代码

<template>
   <div class="box">
     <div class="box-border">
       <div class="ono"></div>
     </div>
   </div>
</template>

<style scoped>
.box {
  width: 300px;
  height: 300px;
  background-color: green;
  overflow: hidden;
}

.box-border {
  margin: 20px;
  width: 122px;
  height: 62px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgb(18, 192, 195);
  /** filter: drop-shadow(0 0 10px #ff0000); */
  clip-path: polygon(
    10% 0,
    0 20%,
    0 80%,
    10% 100%,
    90% 100%,
    100% 80%,
    100% 20%,
    90% 0
  );
}

.ono {
  width: 120px;
  height: 60px;
  background-color: rgb(0, 30, 166);
  box-shadow: 0 0 20px #dddddd inset;
  /** filter: drop-shadow(0 0 10px #ff0000); */
  clip-path: polygon(
    10% 0,
    0 20%,
    0 80%,
    10% 100%,
    90% 100%,
    100% 80%,
    100% 20%,
    90% 0
  );
}
</style>

总结
使用css的clip-path属性截取按钮形状,通过div叠加的方式实现边框。clip-path属性暂未发现更好添加border的方式。
参考:CSS3剪贴路径(Clip-path)在线生成器工具

2. SVG实现

2.1 多边形SVG

2.1.1 填充背景

页面效果

image.png

代码实现

<div style="width: 20%; height: 10%; background-color: pink; padding: 20px">
    <svg height="100%" width="100%" viewBox="0,0,200,100">
        <polygon
          points="15 0, 0 15, 0 45, 15 60, 115 60, 130 45, 130 15, 115 0, 15 0 "
          style="fill: rgb(7, 74, 129); stroke: purple; stroke-width: 1"
        />
        <text x="25" y="35" fill="red">I love SVG</text>
    </svg>
</div>

2.2.1 渐变背景

页面效果

image.png

代码实现

<div style="width: 20%; height: 10%; background-color: pink; padding: 20px">
      <svg height="100%" width="100%" viewBox="0,0,200,100">
        <defs>
          <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
            <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
          </linearGradient>
        </defs>
        <polygon
          fill="url(#grad1)"
          points="15 0, 0 15, 0 45, 15 60, 115 60, 130 45, 130 15, 115 0, 15 0 "
          style="stroke: purple; stroke-width: 1"
        />
        <text x="25" y="35" fill="blue">I love SVG</text>
    </svg>
</div>

2.2.3 内渐变边框 (最接近CSS效果)

效果

image.png

代码实现

<div style="width: 20%; height: 10%; background-color: #000e35; padding: 20px;">
      <svg height="100%" width="100%" viewBox="0,0,200,100">
        <filter id="inset-shadow" x="-80%" y="-80%" width="200%" height="200%">
          <feComponentTransfer in=SourceAlpha>
            <feFuncA type="table" tableValues="1 0" />
          </feComponentTransfer>
          <feGaussianBlur stdDeviation="16"/>
          <feOffset dx="0" dy="1" result="offsetblur"/>
          <feFlood flood-color="#1283c2" result="color"/>
          <feComposite in2="offsetblur" operator="in"/>
          <feComposite in2="SourceAlpha" operator="in" />
          <feMerge>
            <feMergeNode in="SourceGraphic" />
            <feMergeNode />
          </feMerge>
        </filter>
        <polygon
          filter="url(#inset-shadow)"
          points="15 0, 0 15, 0 45, 15 60, 115 60, 130 45, 130 15, 115 0, 15 0 "
          style="stroke: #1283c2; stroke-width: 1"
        />
        <text x="25" y="35" fill="#81d3fa">I love SVG</text>
    </svg>
 </div>

通过feGaussianBlur的stdDeviation调节模糊半径, filter的id为唯一标识,filter的url用于绑定标识

参考自:SVG内发光实现(CSDN)

2.2 线条SVG

页面效果

image.png

代码实现

<div style="width: 20%; height: 10%; background-color: pink; padding: 20px">
      <svg height="100%" width="100%" viewBox="0,0,200,100">
        <polyline
          points="15 0,0 15,0 45,15 60, 115 60,130 45,130 15, 115 0, 15 0 "
          style="fill: none; stroke: black; stroke-width: 1"
        />
        <text x="25" y="35" fill="red">I love SVG</text>
     </svg>
</div>

(背景颜色设置同2.1)


svg: viewbox大小用于设置图标自适应
polyline\polygon: fill设置填充背景, stroke设置边框颜色, stroke-width设置边框宽度

上一篇下一篇

猜你喜欢

热点阅读