需要SVG解决方法

时间:2017-02-12 22:13:48

标签: javascript html xml animation svg

我正在将蓝图重新创建为SVG,如此Pen中所示。我显然没有完成,所以代码现在有点草率,因为我一直在尝试不同的变通办法。

我实施的其中一项效果是,如果悬停,则fill会有opacity: 0.5个房间。

最初,门只包含两个元素(一个path或旋转的线,以及一个path动画的stroke-dashoffset,以实现门关闭然后打开的效果所以,如果一个房间有向外突出并且悬停的门,那么就会有空的"那个(或那些)门框内的空间。

因此,为了fill门内空的空间"框架"我只是创建了一个封闭的路径,将其覆盖在最初的两个元素之上,摆脱了它的stroke,并给它一个fill。但是,这种解决方法的问题在于,当门完全关闭时,如果您将门fill(也设置为opacity: 0.5)与关门同时旋转那个房间的fill部分当然会变成更暗的颜色(即opacity: 0.5 + opacity: 0.5)。

所以我的下一个想法是创建一个"面具"元件。 "面具"元素是另一个四分之一圆(代码笔中的蓝色),它反映了门的区域"框架",并且还与门一起旋转以最终遮挡门"框架" S"填。如果某些房间的门不靠近其他墙壁,这将是一个充分的解决方案,但我设计了SVG,使其在移动scale(1)处显得非常清晰。

我设计的下一个解决方法与上一个类似,但我没有使用镜像的四分之一圆,而是尝试使用rect角度(在codepen中为GREEN),我会在增加然后减少宽度。我使用此解决方法遇到的问题是,无论出于何种原因,rect角度似乎从其中心向两个方向向外增加width,并transition s尽管其x设置为transform-origin,但其100% 100%位置。值得注意的是,我已经玩过相当多的价值观,并且已经让它几乎充分发挥作用,因此它掩盖了大部分四分之一圆门#34;框架&#34 ;;尽管如此,我相当肯定在蓝图scale d时,我必须不断调整这些值,并且似乎没有任何押韵或理由对于特定的值&& #34;工作"

我的另一个想法是缩小门的尺寸,但我担心这样做会使scale(1)处的门变得难以辨认。

以前有人遇到过这个问题吗?

有人知道有任何变通方法吗?

1 个答案:

答案 0 :(得分:1)

只是对您尝试的第一个策略的建议。你说你有一个较暗的颜色,因为不透明度重叠,门填充旋转到地板填充顶部和顶部。将不透明度分别应用于每个元素时会发生这种情况。但是,如果您可以将两个元素组合在一起,然后将不透明度应用于组,则两个形状实际上重叠的颜色没有深色。下面的代码演示了这一点。左侧的形状分组具有应用于两个元素中的每一个的不透明度。除了将不透明度应用于整个组之外,对形状的右侧分组绘制相同。您能否以这种方式对元素进行分组,以便能够将不透明度应用于组元素?



<svg width='400'>
  <g transform='translate(0,0)'>
    <path d='M100,90 L100,40 A50,50 0 0 0 50,90 Z' transform='rotate(45, 100, 90)' opacity='0.5'/>
    <path d='M100,10 H200 V110 H100 Z' opacity='0.5'/>
  </g>
  <g transform='translate(200,0)' opacity='0.5'>
    <path d='M100,90 L100,40 A50,50 0 0 0 50,90 Z' transform='rotate(45, 100, 90)'/>
    <path d='M100,10 H200 V110 H100 Z'/>
  </g>
</svg>
&#13;
&#13;
&#13;

当一扇门属于两个不同的房间时,情况会有点复杂。在这种情况下,对于门打开 out 的房间,您可以将门填充添加到地板填充,如上所示。但是,对于门打开进入的房间,您需要从地板填充中减去门填充的形状。要做到这一点,首先要创建一个门填充的反转,即:

&#13;
&#13;
<svg width="200">
    <path id="doorFillPath"
          transform="translate(120,100)"
          d="                                       M0,0 h-50 a50,50 0 0 1 50,-50 Z"
          />
</svg>

<svg width="200">
    <path id="doorFillInvPath"
          transform="translate(120,100)"
          d="M-1000,-1000 v2000 h2000 v-2000 h-2000 M0,0 h-50 a50,50 0 0 1 50,-50 Z"
          />
</svg>
&#13;
&#13;
&#13;

这需要将门填充形状的代码加倍,因为门形状部分地放置在反转形状的d属性中,因此无法使用{动态复制{1}}和<defs>,但至少门填充形状的<use>路径组件(即以d开头的部分)在两个地方都是相同的,这使得手动相对容易通过一些属性检索和字符串操作来复制甚至是一些自动复制。

然后,对于房间的每个门打开 out ,将门填充路径添加到地板填充路径,如上所示,但是对于每个门打开进入房间,使用"M0,0..."元素和<clipPath>属性剪切门填充反向路径,如下所示。

请注意,使用此策略,clip-path部分中可以有一个门填充形状,每个<defs>副本在图像主体中进行转换,但您必须制作每个人在<use>部分中的门填充形状的副本,在那里转换每个副本,并为每个副本提供适当的ID。不过,对我来说,它似乎仍然是一个可行的解决方案。

&#13;
&#13;
<defs>
&#13;
.floor {
  fill: red;
  opacity: 0;
}
.floor:hover {
  opacity: 0.3;
}
#walls, #door {
  fill: none;
  stroke: black;
  stroke-width: 4;
}
&#13;
&#13;
&#13;