javascript - 如何使用 CSS、JS 沿曲线对齐 HTML 元素(图标)
问题描述
美好的一天,伙计们,
无法找到一种方法来沿曲线对齐那些 png 图标。我正在为此寻找 CSS 或(和)Javascript 解决方案。关于如何做的任何想法?
HTML
<div class="container">
<div class="svg-curve">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 141">
<path class="layer-1"
d="M0,32c9.8,2.43,22.75,5.55,38,9,16,3.62,47.89,10.63,89,18,9,1.62,47.71,8.49,112,17,29.43,3.9,82.81,10.9,153,17,85.18,7.41,149.55,9.54,196,11,114.72,3.62,201,1.55,222,1,104.73-2.73,182.88-9.34,202-11,26-2.26,87.86-8,167-19,5.39-.75,32.57-5.1,66.52-10.53,22.55-3.61,45.94-7.39,52.48-8.47,27.81-4.59,72.7-13.43,142-32h0V0H0Z" />
<path class="layer-2"
d="M0,95c14.71,2.7,35.31,6.28,60,10,18.28,2.75,39.79,5.58,86.06,11,26.82,3.14,61.67,7.22,103.07,11,65.61,6,115.62,8.3,153.11,10,52.28,2.36,112.79,4,180.12,4,37.5,0,96.71-.13,175.12-4,28.61-1.4,91.33-4.87,172.12-13,65-6.54,130.95-13.26,217.15-29,55.91-10.19,98.43-20.15,123.09-26,67.74-16,125.3-32.33,170.12-46.07L1242.86,64.07h0c-59.38,10.1-139.89,21.83-236.16,30-13.44,1.13-52,4.4-106.08,7-129.63,6.2-240.37,5.09-326.22,2C295.06,93,113.9,56.09,71.05,47.09c-29.73-6.24-54.26-12-71-16Z" />
</svg>
</div>
</div>
CSS
.container {
margin:0;
padding:0;
position:relative;
}
.svg-curve {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow: hidden;
}
.svg-curve svg {
position: relative;
display: block;
height: 200px;
}
.svg-curve svg .layer-1 {
fill: red;
}
.svg-curve svg .layer-2 {
fill: blue;
}
并且根据屏幕大小,SVG 高度会像这样改变:
@media (min-width: 576px) {
.svg-curve svg {
height: 90px;
}
}
@media (min-width: 768px) {
.svg-curve svg {
height: 120px;
}
}
@media (min-width: 992px) {
.svg-curve svg {
height: 150px;
}
}
@media (min-width: 1400px) {
.svg-curve svg {
height: 200px;
}
}
解决方案
如果 svg 完整显示,则可以相对于该布局完成整个布局 - 在 CSS 中计算每个图标的 % 位置。
此代码段具有 svg 的纵横比和每个图标的位置。CSS calc 然后产生 % 距离。尺寸在宽度上逐渐减小,图标之间的距离是恒定的。
此片段中的测量值并非绝对准确,仅用于此演示。你可能想自己做。
* {
padding: 0;
margin: 0;
}
.container {
--svgAspectRatio: calc(1440 / 141);
margin:0;
padding:0;
position:relative;
width: 100vw;
height: calc(100vw / var(--svgAspectRatio) );
display: flex;
justify-content: center;
}
.svg-curve {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow: hidden;
line-height: 0;
background: transparent;
}
.svg-curve svg {
position: relative;
display: block;
width: 100%;
}
.svg-curve svg .layer-1 {
fill: red;
}
.svg-curve svg .layer-2 {
fill: blue;
}
.icons {
--measuredW: 60.96; /* the measured width of the icons picture */
--measuredH: 10.03;
--w: calc(100vw - 8vw);
width: var(--w);
height: auto;
position: relative;
top: 0;
left: 0;
display: inline-block;
}
.icon {
--iconW: calc(((14 - var(--n)) / 13) * 2vw);
width: var(--iconW);
height: var(--iconW);
background-color: #eeeeee;
display: inline-block;
position: absolute;
left: calc(100% * (var(--n) - 1) / 13);
z-index: 1;
background-size: contain;
background-position: center center;
background-repeat: no-repeat no-repeat;
background-image: var(--bg);
top: calc(var(--t) / var(--measuredH) * 100%);
}
.icon:nth-child(1) {
--n: 1;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 4.6;
}
.icon:nth-child(2) {
--n: 2;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 5.6;
}
.icon:nth-child(3) {
--n: 3;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 6.48;
}
.icon:nth-child(4) {
--n: 4;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 7.2;
}
.icon:nth-child(5) {
--n: 5;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 7.8;
}
.icon:nth-child(6) {
--n: 6;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 8.1;
}
.icon:nth-child(7) {
--n: 7;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 8.1;
}
.icon:nth-child(8) {
--n: 8;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 8.1;
}
.icon:nth-child(9) {
--n: 9;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 7.8;
}
.icon:nth-child(10) {
--n: 10;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 7.3;
}
.icon:nth-child(11) {
--n: 11;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 6.5;
}
.icon:nth-child(12) {
--n: 12;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 5.5;
}
.icon:nth-child(13) {
--n: 13;
--bg: url(https://i.stack.imgur.com/DWx67.png);
--t: 4.5;
}
<div class="container">
<div class="svg-curve">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 141">
<path class="layer-1"
d="M0,32c9.8,2.43,22.75,5.55,38,9,16,3.62,47.89,10.63,89,18,9,1.62,47.71,8.49,112,17,29.43,3.9,82.81,10.9,153,17,85.18,7.41,149.55,9.54,196,11,114.72,3.62,201,1.55,222,1,104.73-2.73,182.88-9.34,202-11,26-2.26,87.86-8,167-19,5.39-.75,32.57-5.1,66.52-10.53,22.55-3.61,45.94-7.39,52.48-8.47,27.81-4.59,72.7-13.43,142-32h0V0H0Z" />
<path class="layer-2"
d="M0,95c14.71,2.7,35.31,6.28,60,10,18.28,2.75,39.79,5.58,86.06,11,26.82,3.14,61.67,7.22,103.07,11,65.61,6,115.62,8.3,153.11,10,52.28,2.36,112.79,4,180.12,4,37.5,0,96.71-.13,175.12-4,28.61-1.4,91.33-4.87,172.12-13,65-6.54,130.95-13.26,217.15-29,55.91-10.19,98.43-20.15,123.09-26,67.74-16,125.3-32.33,170.12-46.07L1242.86,64.07h0c-59.38,10.1-139.89,21.83-236.16,30-13.44,1.13-52,4.4-106.08,7-129.63,6.2-240.37,5.09-326.22,2C295.06,93,113.9,56.09,71.05,47.09c-29.73-6.24-54.26-12-71-16Z" />
</svg>
</div>
<div class="icons">
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
</div>
</div>
推荐阅读
- java - 如何使用 Java 计算缓冲图像的 DPI
- office-js - 在 Officejs 中显示/隐藏功能区命令
- c++ - Win32 CopyFile 无法复制到外部驱动器
- c# - 带有接口的 Automapper 和自定义值解析器抱怨“类型必须可转换为 IValueResolver...”
- swift - 只有一个值时,函数生成器不起作用?
- java - OkHttp 没有发布到 mysql
- r - 如何在整个数据框中搜索精确的字符串匹配,同时忽略所有部分匹配?
- c# - 发布时如何将 Dlls 加载到自定义文件夹而不是 C# 中的 bin 文件夹中
- kubernetes - configmap 端口转发在 kubernetes 多容器 pod 中不起作用
- ruby-on-rails - 如何创建自定义路由