【发布时间】:2022-08-22 21:58:00
【问题描述】:
(这解决方案W3 验证器的 clean 可以在这篇文章的底部找到)
我的任务目标很简单:
-
有一个“心脏”图标,用户可以点击并填充红色(需要心脏慢慢填充);
-
理想情况下,用户可以再次点击“填满的心”来清空它(喜欢和不喜欢的机制);
-
哦,最后一个要求:船上只允许使用 html 和 css/scss。
我第一次制作心形图标时遇到了麻烦。我在网上查看了各种解决方案,从自己在代码行中设计到导入图像。最后,我决定[从这个站点][1] 导入一个 .svg 文件,并使用以下代码:
<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"
viewBox=\"0 0 40.508 40.508\" style=\"enable-background:new 0 0 40.508 40.508;\" xml:space=\"preserve\">
<g>
<path style=\"fill:#010002;\" d=\"M3.023,20.822c0.019,0.031,0.042,0.059,0.066,0.083l15.918,16.914
c0.115,0.122,0.271,0.192,0.444,0.197h0.012c0.163,0,0.317-0.062,0.435-0.176L37.28,21.032c0.008-0.006,0.076-0.068,0.117-0.108
c0.034-0.032,0.062-0.065,0.068-0.081c1.962-2.032,3.043-4.702,3.043-7.517c0-5.974-4.86-10.834-10.835-10.834
c-3.91,0-7.498,2.094-9.419,5.48c-1.92-3.387-5.508-5.48-9.419-5.48C4.86,2.492,0,7.352,0,13.326
C-0.001,16.14,1.078,18.808,3.023,20.822z M10.834,3.743c3.875,0,7.346,2.312,8.842,5.891c0.098,0.233,0.324,0.383,0.577,0.383
c0.252,0,0.479-0.15,0.577-0.384c1.497-3.578,4.968-5.89,8.843-5.89c5.285,0,9.585,4.3,9.585,9.584
c0,2.521-0.978,4.904-2.754,6.712c-0.017,0.018-0.032,0.035-0.045,0.053L19.483,36.5l-15.4-16.358
c-0.023-0.037-0.05-0.072-0.082-0.104c-1.775-1.805-2.752-4.188-2.752-6.711C1.249,8.042,5.549,3.743,10.834,3.743z\"/>
</g>
</svg>
在不知道如何正确使用 SVG 的情况下,我搜索了网络,查找了一些文章和 YouTube 视频,我现在正在学习的课程并没有以直观的方式告诉我太多或没有,但我终于把我的抓住两个有趣的机会:
1] [在 Codepen 上找到的这个心脏动画][2]
它的专业: 已经做好了。老实说,在我自己的情况下,不需要用于“脉冲”效果的少数 Js 代码,因此我将其删除。
这是缺点:
- 我不知道如何拥有一颗饱满的心来保持饱满。我知道动画,你必须插入类似的东西:
animation:forwards;
但是在这种情况下,如果有人有解决方案似乎不起作用,我认为这对于他们要求我提供的项目来说是一个不错的选择;
它不使用 \'@keyframes\',看起来像一个简单的过渡,但是,再次,我缺乏知识使其难以解释;
- “填充”动画如果模拟一个从底部开始的“加载条”会更好。但老实说,这更像是一个装饰元素,而不是一个真正的问题;
2] [这里][3]找到的“补水效果”问题
链接的 Q/A 与应用于圆圈的注水动画有关。
它的专业: 效果不错,另外一个贡献者提出的附加动画也很棒!我更喜欢这种“自下而上”的填充效果,而不是第一个选项中的填充效果。
它的骗局: 嗯,这不是一个适当的骗局,是我无法适应我自己的需要。在本示例中,我不能将其应用于我的 .svg 图像,而不是像他们对圆圈所做的那样的“本地制作形式”。
我曾希望将帖子中描述的动画应用到我的心形图标上。好吧,不用说,在该领域没有适当的技能,我只是复制/粘贴似乎有效的东西,令人惊讶的是,它有一些效果,但不是我正在寻找的,这是我当前的代码。
[编辑:我在这里使用 \":hover\" 而不是 \":active\" 因为我找不到如何简单地单击心脏以使其自动填充,而使用 \":active\" 我有像在按钮粉碎迷你游戏中一样多次单击它来填充它。]
HTML第一:
<svg class=\'bigHeart\' height=\"0\" width=\"0\">
<defs>
<clipPath id=svgClip clipPathUnits=\"objectBoundingBox\" transform=\"scale(0.01 0.01)\">
<path d=\'M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z\'></path>
</clipPath>
</defs>
</svg>
<div class=\"heart-container\">
<svg viewBox=\"0 0 100 100\" class=\'heart-stroke\'>
<path class=bigHeart d=\"M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z\" />
</svg>
<input type=\'checkbox\' class=\'heart-clip\'>
<div class=\"fill\">
<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 400 400\" xml:space=\"preserve\">
<path d=\"M0,6c100,10,100,-10,200,0c100,10,100,-10,200,0v394h-400Z\" class=\"waveShape\"></path>
</svg>
</div>
</div>
然后是 CSS:
.heart{
width:40px;
position:relative;
overflow:hidden;
}
.heart:hover:before{
content:\'\';
position:absolute;
background: #04ACFF;
z-index: -1;
width:100%;
bottom:0;
animation: wipe 5s forwards;
}
@keyframes wipe {
0% {
height: 0;
}
100% {
height: 100%;
}
}
如果我们参考[我找到的原始代码][3],我决定删除 \"background:#000\" 并添加一个 \"z-index:-1\" 以便有填充动画不重叠图标的边框。但后来我被卡住了,在试图搞砸并重新阅读我手头的东西之后,我决定输入这个(长)帖子。
如果您到目前为止,我要感谢您,感谢您今天阅读我的请求,并提前感谢您提供任何建议和解决方案,您将很乐意与我分享,
3] 解决方案(感谢@thehujib)
解决方案由@thehujib 在下面提供,我只在这里再次发布他的代码,因为它清除了 W3 验证器发现的所有小元素(主要是开放式和重复出现的 ID):
<svg class=\'bigHeart\' height=\"0\" width=\"0\">
<defs>
<clipPath id=svgClip clipPathUnits=\"objectBoundingBox\" transform=\"scale(0.01 0.01)\">
<path d=\'M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z\'></path>
</clipPath>
</defs>
<linearGradient id=\"my-cool-gradient\" x2=\"1\" y2=\"1\">
<stop offset=\"0%\" stop-color=\"#FF79DA\" />
<stop offset=\"100%\" stop-color=\"#9356DC\" />
</linearGradient>
</svg>
<div class=\"heart-container\">
<svg viewBox=\"0 0 100 100\" class=\'heart-stroke\'>
<path class=bigHeart d=\"M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z\" />
</svg>
<input type=\'checkbox\' class=\'heart-clip\'>
<div class=\"fill\">
<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 400 400\" xml:space=\"preserve\">
<path d=\"M0,6c100,10,100,-10,200,0c100,10,100,-10,200,0v394h-400Z\" class=\"waveShape\"></path>
</svg>
</div>
</div>
和 CSS(唯一的变化是将一些重复的 ID 转换为 CLASSES :
:root {
--stroke-width: 2px;
--heart-width: 100%;
--transition-length: 1.2s;
--heart-color:#d32f2f;
}
.heart-container {
position: relative;
width:10%;
aspect-ratio: 1/1;
overflow: hidden;
clip-path: url(#svgClip);
}
.heart-clip {
appearance: none;
margin: 0px;
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
overflow: hidden;
z-index: 2;
}
.heart-clip + .fill {
top:0;
left:0;
transform: translateY(50%);
width: calc(2 * var(--heart-width, 100px));
aspect-ratio: 1/1;
transition: transform var(--transition-length, 0s) cubic-bezier(.2, .6, .8, .4);
}
.heart-clip:checked + .fill {
transform: translateY(0);
}
.heart-stroke {
width: calc(100% - (2 * var(--stroke-width, 2px)));
aspect-ratio: 1/1;
position: absolute;
top: var(--stroke-width, 0);
left: var(--stroke-width, 0);
fill: transparent;
stroke: var(--heart-color);
stroke-width: var(--stroke-width, 1px);
}
.waveShape {
animation-name: waveAction;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-duration: 1s;
fill: var(--heart-color);
}
@keyframes waveAction {
0% {
transform: translate(-175px, 0px);
}
100% {
transform: translate(0px, 0px);
}
}
``
Regards,
Elrad.
[1]: https://www.svgrepo.com/svg/5233/heart
[2]: https://codepen.io/GeorgeWL/pen/yLeGGMw
[3]: https://stackoverflow.com/questions/29738787/filling-water-animation/29739227#29739227