向SVG元素(例如线条)添加阴影

时间:2019-09-23 14:53:01

标签: html css svg

所以我对SVG还是很陌生,但是我开始玩图。该图来自here。我一直在寻找几个小时,却只找到一半解决方案来解决我的问题。从代码片段中可以看到,如果将鼠标悬停在图形上,它将“发光”。但是我希望当我将鼠标悬停在圆圈和“关节”上时,它们会发光。

我尝试过的:

  1. 使用常规CSS阴影
  2. 使用使图表“发光”的代码,但仅限于g个元素。
  3. 同时创建单独的SVG:a)在主SVG中b)分别创建,以及 将它们与position: absolute混合。 (此后的定位 工作异常)

我应该怎么做才能使圆和关节“发光”?

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

  html, body{
    height: 100%;
    width: 100%;  
  }

  @import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400,500&display=swap');
  body {
    font-family: 'Roboto Mono', monospace;
  }

  .graph .labels.x-labels {
    text-anchor: middle;
  }

  .graph .labels.y-labels {
    text-anchor: end;
  }

  .graph {
    height: 500px;
    width: 800px;
  }

  .graph .grid {
    stroke: #ccc;
    stroke-dasharray: 0;
    stroke-width: 3;
  }

  .labels {
    font-size: 17px;
    font-weight: 400;
  }

  .label-title {
    font-weight: 500;
    text-transform: uppercase;
    font-size: 15px;
    fill: black;
  }

  .data {
    fill: #f86d36;
    stroke-width: 1;
  }

  .graph .dot-joints {
    stroke: #f86d36;
    stroke-dasharray: 0;
    stroke-width: 3;
  }

  svg:hover  {
    -webkit-filter: drop-shadow(0px 0px 4px #f86d36e8);
    filter: drop-shadow(0px 0px 4px #f86d36e8);
  }
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="graph"
    aria-labelledby="title" role="img">
    <g class="grid x-grid" id="xGrid">
        <line x1="90" x2="90" y1="5" y2="371"></line>
    </g>
    <g class="grid x-grid" id="xGrid">
        <line x1="90" x2="705" y1="370" y2="370"></line>
    </g>
    <g class="labels x-labels"><text x="100" y="400">2008</text><text x="246" y="400">2009</text><text x="392"
            y="400">2010</text><text x="538" y="400">2011</text><text x="694" y="400">2012</text><text x="400" y="440"
            class="label-title">Year</text></g>
    <g class="labels x-labels"><text x="70" y="15">15</text><text x="70" y="131">10</text><text x="70"
            y="248">5</text><text x="70" y="373">0</text><text x="35" y="200" class="label-title">Price</text></g>
    <g class="data" data-setname="Our first data set">
        <circle cx="95" cy="192" data-value="7.2" r="5"></circle>
        <circle cx="240" cy="141" data-value="8.1" r="5"></circle>
        <circle cx="388" cy="179" data-value="7.7" r="5"></circle>
        <circle cx="531" cy="200" data-value="6.8" r="5"></circle>
        <circle cx="677" cy="104" data-value="6.7" r="5"></circle>
    </g>
    <g class="dot-joints x-grid">
        <line x1="95" x2="240" y1="192" y2="141"></line>
        <line x1="240" x2="388" y1="141" y2="179"></line>
        <line x1="388" x2="531" y1="179" y2="200"></line>
        <line x1="531" x2="677" y1="200" y2="104"></line>
    </g>
</svg>

1 个答案:

答案 0 :(得分:3)

我希望这是您所需要的:我正在为阴影使用svg过滤器。 在您的代码中,我为各个圆圈添加了.data circle:hover{filter:url(#f)},为这组线添加了.dot-joints.x-grid:hover{filter:url(#f)}

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

  html, body{
    height: 100%;
    width: 100%;  
  }

  @import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400,500&display=swap');
  body {
    font-family: 'Roboto Mono', monospace;
  }

  .graph .labels.x-labels {
    text-anchor: middle;
  }

  .graph .labels.y-labels {
    text-anchor: end;
  }

  .graph {
    height: 500px;
    width: 800px;
  }

  .graph .grid {
    stroke: #ccc;
    stroke-dasharray: 0;
    stroke-width: 3;
  }

  .labels {
    font-size: 17px;
    font-weight: 400;
  }

  .label-title {
    font-weight: 500;
    text-transform: uppercase;
    font-size: 15px;
    fill: black;
  }

  .data {
    fill: #f86d36;
    stroke-width: 1;
  }
  .data circle:hover{filter:url(#f)}

  .graph .dot-joints {
    stroke: #f86d36;
    stroke-dasharray: 0;
    stroke-width: 3;
  }
  
  .dot-joints.x-grid:hover{filter:url(#f)}
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="graph"
    aria-labelledby="title" role="img">
    <defs>
    <filter id="f" filterUnits="userSpaceOnUse" id="shadow" x="-10" y="-150" width="120%" height="120%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"></feGaussianBlur>
      <feOffset in="blur" dx="3" dy="1" result="shadow"></feOffset>
      <feFlood flood-color="rgba(0,0,0,.52)" result="color" />
      <feComposite in ="color" in2="shadow" operator="in" />
      <feComposite in="SourceGraphic"/>
    </filter>
  </defs>
    <g class="grid x-grid" id="xGrid">
        <line x1="90" x2="90" y1="5" y2="371"></line>
    </g>
    <g class="grid x-grid" id="xGrid">
        <line x1="90" x2="705" y1="370" y2="370"></line>
    </g>
    <g class="labels x-labels"><text x="100" y="400">2008</text><text x="246" y="400">2009</text><text x="392"
            y="400">2010</text><text x="538" y="400">2011</text><text x="694" y="400">2012</text><text x="400" y="440"
            class="label-title">Year</text></g>
    <g class="labels x-labels"><text x="70" y="15">15</text><text x="70" y="131">10</text><text x="70"
            y="248">5</text><text x="70" y="373">0</text><text x="35" y="200" class="label-title">Price</text></g>
    <g class="data" data-setname="Our first data set">
        <circle cx="95" cy="192" data-value="7.2" r="5"></circle>
        <circle cx="240" cy="141" data-value="8.1" r="5"></circle>
        <circle cx="388" cy="179" data-value="7.7" r="5"></circle>
        <circle cx="531" cy="200" data-value="6.8" r="5"></circle>
        <circle cx="677" cy="104" data-value="6.7" r="5"></circle>
    </g>
    <g class="dot-joints x-grid" >
        <line x1="95" x2="240" y1="192" y2="141"></line>
        <line x1="240" x2="388" y1="141" y2="179"></line>
        <line x1="388" x2="531" y1="179" y2="200"></line>
        <line x1="531" x2="677" y1="200" y2="104"></line>
    </g>
</svg>

或者,您可能想要这样:

svg:hover .data,
svg:hover .dot-joints.x-grid{filter:url(#f)} 

将svg元素悬停时,将阴影应用于直线和圆。

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

  html, body{
    height: 100%;
    width: 100%;  
  }

  @import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400,500&display=swap');
  body {
    font-family: 'Roboto Mono', monospace;
  }

  .graph .labels.x-labels {
    text-anchor: middle;
  }

  .graph .labels.y-labels {
    text-anchor: end;
  }

  .graph {
    height: 500px;
    width: 800px;
  }

  .graph .grid {
    stroke: #ccc;
    stroke-dasharray: 0;
    stroke-width: 3;
  }

  .labels {
    font-size: 17px;
    font-weight: 400;
  }

  .label-title {
    font-weight: 500;
    text-transform: uppercase;
    font-size: 15px;
    fill: black;
  }

  .data {
    fill: #f86d36;
    stroke-width: 1;
  }


  .graph .dot-joints {
    stroke: #f86d36;
    stroke-dasharray: 0;
    stroke-width: 3;
  }
  
    svg:hover .data,
    svg:hover .dot-joints.x-grid{filter:url(#f)}
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="graph"
    aria-labelledby="title" role="img">
    <defs>
    <filter id="f" filterUnits="userSpaceOnUse" id="shadow" x="-10" y="-150" width="120%" height="120%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"></feGaussianBlur>
      <feOffset in="blur" dx="3" dy="1" result="shadow"></feOffset>
      <feFlood flood-color="rgba(0,0,0,.52)" result="color" />
      <feComposite in ="color" in2="shadow" operator="in" />
      <feComposite in="SourceGraphic"/>
    </filter>
  </defs>
    <g class="grid x-grid" id="xGrid">
        <line x1="90" x2="90" y1="5" y2="371"></line>
    </g>
    <g class="grid x-grid" id="xGrid">
        <line x1="90" x2="705" y1="370" y2="370"></line>
    </g>
    <g class="labels x-labels"><text x="100" y="400">2008</text><text x="246" y="400">2009</text><text x="392"
            y="400">2010</text><text x="538" y="400">2011</text><text x="694" y="400">2012</text><text x="400" y="440"
            class="label-title">Year</text></g>
    <g class="labels x-labels"><text x="70" y="15">15</text><text x="70" y="131">10</text><text x="70"
            y="248">5</text><text x="70" y="373">0</text><text x="35" y="200" class="label-title">Price</text></g>
    <g class="data" data-setname="Our first data set">
        <circle cx="95" cy="192" data-value="7.2" r="5"></circle>
        <circle cx="240" cy="141" data-value="8.1" r="5"></circle>
        <circle cx="388" cy="179" data-value="7.7" r="5"></circle>
        <circle cx="531" cy="200" data-value="6.8" r="5"></circle>
        <circle cx="677" cy="104" data-value="6.7" r="5"></circle>
    </g>
    <g class="dot-joints x-grid" >
        <line x1="95" x2="240" y1="192" y2="141"></line>
        <line x1="240" x2="388" y1="141" y2="179"></line>
        <line x1="388" x2="531" y1="179" y2="200"></line>
        <line x1="531" x2="677" y1="200" y2="104"></line>
    </g>
</svg>

更新

OP正在评论:

  

您能详细解释一下吗

<defs>中,我添加了一个svg过滤器。该过滤器首先创建模糊feGaussianBlur。您可能需要更改stdDeviation才能更改阴影的外观。

下一步是抵消先前创建的模糊feOffset:您可能需要更改dx="3"dy="1"属性才能移动阴影。

然后使用feFloodfeComposite为阴影添加颜色。在这种情况下,我使用的是半透明的黑色,但是您可以使用所需的颜色。

我正在使用此过滤器将阴影仅应用于所需的那些元素:filter:url(#f)-其中f是过滤器的ID