关于CSS:SVG图标动画留有像素间隙

SVG icon animation leaves a pixel gap

我正在使用CSS制作SVG动画,并且已经注意到,在使用线条绘制动画时,任何SVG矩形(#clipboard-border和#clipboard-clip-border)笔划始终不包含左上角的部分, 使其成为不完整的矩形。

我试过在CSS中调整stroke-dasharray和stroke-dashoffset量,并调整SVG代码中协调的大小和像素,但看起来都不是问题。 救命?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
html,
body {
  width: 100%;
  height: 100%;
  background-color: #CECECE;
}
div {
  text-align: center;
}
svg {
  display: inline-block;
  width: 120px;
  margin: 3% auto;
  padding: 0px 100px;
}
/* ---------------------
SVG RULES
--------------------- */


/* All grey strokes */

#clipboard-border,
.clipboard-content,
.clipboard-borders,
.mech-pencil-borders {
  fill: none;
  stroke: #4D5152;
  stroke-width: 6;
  stroke-miterlimit: 10;
}
/* All things white */

#clipboard-paper-fill,
#mech-pencil-eraser-fill {
  fill: #F3F7F6;
}
/* All things green */

#mech-pencil-point-fill,
#mech-pencil-top-fill {
  fill: #25B686;
}
/* All things blue */

#clipboard-fill {
  fill: #85D0D3;
}
/* All things yellow */

#clipboard-clip-fill,
#mech-pencil-grip {
  fill: #FBFBCE;
}
#clipboard-knob-1,
#clipboard-knob-2,
#clipboard-knob-3,
#mech-pencil-bottom-btn,
#mech-pencil-top-btn {
  stroke-dasharray: 8px;
  stroke-dashoffset: 8px;
  animation: trace .5s ease-out forwards;
}
/* ---------------------
ANIMATION KEYFRAMES
--------------------- */


@keyframes trace {
  100% {
    stroke-dashoffset: 0px;
  }
}
@keyframes fill-it {
  100% {
    opacity: 1;
  }
}
@keyframes grow {
  0% {
    transform: scale(0);
  }
  30% {
    transform: scale(1.1);
  }
  60% {
    transform: scale(.9);
  }
}
/* ---------------------
SVG ANIMATION: INSIGHT & PLANNING ICON
--------------------- */


#clipboard-clip-border {
  stroke-dasharray: 180px;
  stroke-dashoffset: 180px;
  animation: trace .2s ease-out forwards;
}
#clipboard-clip-fill {
  opacity: 0;
  animation: fill-it .2s .2s ease-in-out forwards;
}
#clipboard-border {
  stroke-dasharray: 640px;
  stroke-dashoffset: 640px;
  animation: trace 1.25s ease-in-out forwards;
}
#clipboard-fill,
#mech-pencil-point-fill,
#mech-pencil-top-fill {
  opacity: 0;
  animation: fill-it .25s 1.25s ease-in-out forwards;
}
#clipboard-paper-border {
  stroke-dasharray: 400px;
  stroke-dashoffset: 400px;
  animation: trace 1s ease-out forwards;
}
#clipboard-paper-fill,
#mech-pencil-eraser-fill,
#mech-pencil-grip {
  opacity: 0;
  animation: fill-it .75s 1s ease-in-out forwards;
}
#clipboard-content-line-1 {
  stroke-dasharray: 30px;
  stroke-dashoffset: 30px;
  animation: trace .5s ease-out forwards;
}
#clipboard-content-line-7,
#clipboard-clip-detail {
  stroke-dasharray: 52px;
  stroke-dashoffset: 52px;
  animation: trace .5s ease-out forwards;
}
#clipboard-content-line,
#clipboard-content-line-even,
#mech-pencil-eraser-border {
  stroke-dasharray: 80px;
  stroke-dashoffset: 80px;
  animation: trace .75s ease-out forwards;
}
#mech-pencil-border-left,
#mech-pencil-border-right {
  stroke-dasharray: 115px;
  stroke-dashoffset: 115px;
  animation: trace .75s ease-out forwards;
}
#mech-pencil-point-border {
  stroke-dasharray: 60px;
  stroke-dashoffset: 60px;
  animation: trace .5s ease-out forwards;
}
#mech-pencil-tip,
#mech-pencil-top {
  stroke-dasharray: 10px;
  stroke-dashoffset: 10px;
  animation: trace .4s ease-out forwards;
}
/* ---------------------
ANIMATION DELAYS
--------------------- */


#clipboard-knob-1,
#clipboard-knob-2 {
  animation-delay: .25s;
}
#clipboard-clip-detail,
#clipboard-content-line,
#clipboard-content-line-7,
#clipboard-knob-2 {
  animation-delay: .5s;
}
#mech-pencil-bottom-btn,
#mech-pencil-top-btn {
  animation-delay: 1.25s;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  <!-- INSIGHT & PLANNING ICON -->

  <svg id="insight-planning" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="200px" height="200px" viewBox="0 0 200 200">
    <g class="clipboard">
      <rect id="clipboard-fill" x="15.015" y="11.44" width="132" height="182" />
      <rect id="clipboard-paper-fill" x="30.753" y="11.44" width="100" height="151" />
      <g class="clipboard-content">
        <line id="clipboard-content-line-even" x1="46.491" y1="68.096" x2="115.738" y2="68.096" />
        <line id="clipboard-content-line" x1="46.491" y1="80.687" x2="115.738" y2="80.687" />
        <line id="clipboard-content-line-even" x1="46.491" y1="93.277" x2="115.738" y2="93.277" />
        <line id="clipboard-content-line" x1="46.491" y1="105.867" x2="115.738" y2="105.867" />
        <line id="clipboard-content-line-even" x1="46.491" y1="118.458" x2="115.738" y2="118.458" />
        <line id="clipboard-content-line-7" x1="46.491" y1="131.048" x2="96.852" y2="131.048" />
        <line id="clipboard-content-line-1" x1="115.738" y1="49.211" x2="90.557" y2="49.211" />
      </g>
      <rect id="clipboard-border" x="15.015" y="11.44" width="132" height="182" />
    </g>
    <g class="mech-pencil-fills">
      <rect id="mech-pencil-grip" x="166.099" y="96.425" width="18" height="47" />
      <rect id="mech-pencil-top-fill" x="166.099" y="30.325" width="18" height="66" />
      <rect id="mech-pencil-eraser-fill" x="166.099" y="11.44" width="18" height="18" />
      <polygon id="mech-pencil-point-fill" points="184.985,143.639 184.985,159.376 175.542,168.819 166.099,159.376 166.099,143.639" />
    </g>
    <g class="mech-pencil-borders">
      <line id="mech-pencil-border-left" x1="166.099" y1="143.639" x2="166.099" y2="30.325" />
      <line id="mech-pencil-border-right" x1="184.985" y1="30.325" x2="184.985" y2="145" />
      <rect id="mech-pencil-eraser-border" x="166.099" y="11.44" width="18" height="18" />
      <polygon id="mech-pencil-point-border" points="184.985,143.639 184.985,159.376 175.542,168.819 166.099,159.376 166.099,143.639" />
      <line id="mech-pencil-top" x1="175.542" y1="11.44" x2="175.542" y2="1.997" />
      <line id="mech-pencil-tip" x1="175.542" y1="168.819" x2="175.542" y2="175.114" />
      <line id="mech-pencil-bottom-btn" x1="175.542" y1="127.901" x2="175.542" y2="121.605" />
      <line id="mech-pencil-top-btn" x1="175.542" y1="115.31" x2="175.542" y2="109.015" />
    </g>
    <g class="clipboard-clip">
      <rect id="clipboard-clip-fill" x="49.639" y="5.144" width="62" height="25" />
    </g>
    <g class="clipboard-borders">
      <polyline id="clipboard-paper-border" points="131.476,11.44 131.476,162.524 30.753,162.524 30.753,11.44" />
      <rect id="clipboard-clip-border" x="49.639" y="5.144" width="62" height="25" />
      <line id="clipboard-clip-detail" x1="59.081" y1="17.735" x2="103.148" y2="17.735" />
      <line id="clipboard-knob-1" x1="65.376" y1="178.262" x2="71.672" y2="178.262" />
      <line id="clipboard-knob-2" x1="77.967" y1="178.262" x2="84.262" y2="178.262" />
      <line id="clipboard-knob-3" x1="90.557" y1="178.262" x2="96.852" y2="178.262" />
    </g>
  </svg>

也张贴在Codepen中。


只需将stroke-linecap: square;添加到SVG对象的CSS声明中即可。

1
2
3
4
5
6
7
svg {
  display: inline-block;
  width: 120px;
  margin: 3% auto;
  padding: 0px 100px;
  stroke-linecap: square;  /* <-- Add this */
}

例:

这是具有两条路径(打开,未关闭)的SVG。 用"对接"线末端绘制的路径在上角缺少一些,但是其他路径(用"方"线末端绘制)没有此问题。

1
2
3
4
5
6
<svg width="250" height="100" viewBox="0 0 250 100">
  <path d="M10 10h80v80h-80v-80" style="stroke:#000; stroke-width:10px; fill:none; stroke-linecap: square;"/>
  <text x="50" y="70" text-anchor="middle">Square</text>
  <path d="M160 10h80v80h-80v-80" style="stroke:#000; stroke-width:10px; fill:none; stroke-linecap: butt;"/>
  <text x="200" y="70" text-anchor="middle">Butt</text>
 </svg>

P.S。 我喜欢您的工作,但下一次请考虑制作一个最小,完整且可验证的示例来说明问题。 这样一来,人们就不必遍历大量代码来查找出了什么问题:-)