如何在不使用SVG的情况下重新创建2020年Google Maps图标的形状?

huangapple go评论46阅读模式
英文:

How to recreate 2020 Google Maps icon's shape without SVG?

问题

我正在尝试重新创建Google地图的图标(2020年)。彩色背景和中间的洞看起来很容易:我只需要一些渐变和一个蒙版。

以下是显示我当前努力的代码片段(以及一个CodePen链接,如果你想尝试它):

:root {
  --1-3: calc(100% / 3);
  --2-3: calc(100% / 3 * 2);
  --sqrt-2: 1.4142135624;
  
  --hole-diameter: calc(100% / var(--sqrt-2) / 3);
  
  --red: #ea4335;
  --yellow: #fbbc04;
  --green: #34a853;
  --blue: #1a73e8;
  --azure: #4285f4;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

#wrapper {
  margin: 3em auto;
  width: 10em;
  background: linear-gradient(90deg, #c0392b, #8e44ad);
}

#icon {
  --mask: radial-gradient(
    circle at center,
    transparent calc(var(--hole-diameter) - 1px),
    #000 calc(var(--hole-diameter) + 1px)
  );
  
  border-radius: 50% 50% 50% 0;
  aspect-ratio: 1 / 1;
  background:
    linear-gradient(
      180deg,
      var(--red) var(--1-3),
      var(--yellow) var(--1-3) var(--2-3),
      var(--green) var(--2-3)
    ),
    linear-gradient(
      180deg,
      var(--blue) var(--1-3),
      var(--azure) var(--1-3) var(--2-3),
      var(--green) var(--2-3)
    ) calc(100% - 1px);
  background-size: 50% 100%;
  background-repeat: no-repeat;
  -webkit-mask: var(--mask);
  mask: var(--mask);
  rotate: -45deg;
}
<div id="wrapper">
  <div id="icon"></div>
</div>

然而,我无法理解其独特的形状。是否可能仅使用CSS创建这样的形状?

显然,我不寻求基于SVG的解决方案。我正在做这个作为一个个人项目,所以我只需要在至少一个浏览器中能够工作的东西。

英文:

I'm trying to recreate Google Maps's icon (2020). The colorful background and the donut hole are easy enough: I just need some gradients and a mask.

Here's a snippet that shows my current efforts (and a codepen, if you want to play with it):

<!-- begin snippet: js hide: true -->

<!-- language: lang-css -->

:root {
--1-3: calc(100% / 3);
--2-3: calc(100% / 3 * 2);
--sqrt-2: 1.4142135624;
--hole-diameter: calc(100% / var(--sqrt-2) / 3);
--red: #ea4335;
--yellow: #fbbc04;
--green: #34a853;
--blue: #1a73e8;
--azure: #4285f4;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
#wrapper {
margin: 3em auto;
width: 10em;
background: linear-gradient(90deg, #c0392b, #8e44ad);
}
#icon {
--mask: radial-gradient(
circle at center,
transparent calc(var(--hole-diameter) - 1px),
#000 calc(var(--hole-diameter) + 1px)
);
border-radius: 50% 50% 50% 0;
aspect-ratio: 1 / 1;
background:
linear-gradient(
180deg,
var(--red) var(--1-3),
var(--yellow) var(--1-3) var(--2-3),
var(--green) var(--2-3)
),
linear-gradient(
180deg,
var(--blue) var(--1-3),
var(--azure) var(--1-3) var(--2-3),
var(--green) var(--2-3)
) calc(100% - 1px);
background-size: 50% 100%;
background-repeat: no-repeat;
-webkit-mask: var(--mask);
mask: var(--mask);
rotate: -45deg;
}

<!-- language: lang-html -->

&lt;div id=&quot;wrapper&quot;&gt;
&lt;div id=&quot;icon&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

However, I can't wrap my head around its peculiar shape. Is it possible to create such a shape with CSS only?

It should be obvious that I'm not looking for an SVG-based solution. I'm doing this as a pet project, so I just need something that works in at least one browser.

答案1

得分: 2

这是我尽力想出的最佳方法,通过滥用多个radial-gradient-webkit-mask-image-webkit-mask-image-composite,不幸的是,为了实现“尖尖部分”,我使用了一个兄弟元素,而不是能够扩展原始的#icon,也不能使用::after元素(因为::after元素会被其父元素的蒙版剪裁)。

(我想这可以重新组织,使顶部的圆形部分使用::before,尖尖部分使用::after,否则#icon仅作为其两个伪元素子元素的容器和边界,但这是留给读者的练习)。

这是在Chrome中的效果。我还没有在其他浏览器中进行测试:

如何在不使用SVG的情况下重新创建2020年Google Maps图标的形状?


:root {
    --1-3: calc(30%);
    --2-3: calc(70%);
    --sqrt-2: 1.41421356237;
    --inner-radius: calc(18.4%);

    --red: #ea4335;
    --yellow: #fbbc04;
    --green: #34a853;
    --blue: #1a73e8;
    --azure: #4285f4;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
}

#wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2em;
    margin: 1em;
}

#wrapper > div {
    border-radius: 1em;
    background: linear-gradient(90deg, #c0392b, #8e44ad);
    overflow: hidden;
}
#wrapper > div > h2 {
    font-family: sans-serif;
    text-align: center;
    background-color: white;
    border-radius: 0.25em;
    width: 90%;
    margin-left: auto;
    margin-right: auto;
}

#image > img {
    transform-origin: 50% 35%;
    /*transform: rotate(50deg);*/
}

#icon {
    aspect-ratio: 1 / 1;
    background-image:
        linear-gradient(
            180deg,
            var(--red) var(--1-3),
            var(--yellow) var(--1-3) var(--2-3),
            var(--green) var(--2-3)
        ),
        linear-gradient(
            180deg,
            var(--blue) var(--1-3),
            var(--azure) var(--1-3) var(--2-3),
            var(--green) var(--2-3)
        );

    background-position-x: 0, calc(100% - 1px);
    background-position-y: 0, 0;

    background-size: 50% 100%;
    background-repeat: no-repeat;

    -webkit-mask-image:
    /* The radius of the circle at 100% is actually the corners of the bounding rect, not the perpendicular top+bottom/side edges, hence the weird numbers. */
    radial-gradient(
        circle at center,
        transparent 28.2%,
        black       calc(28.2% + 1px),
        black       70%,
        transparent calc(70.0% + 1px)
    );

    rotate: -50deg;

    z-index: 10;
}

#tip {
    aspect-ratio: 26 / 25;
    width: 100%;
    background-color: #47A756;
    margin-top: -14.2%; /* this is relative to the #tip element's *width* btw. */
    z-index: 5;
    background-image:
        linear-gradient(
            130deg,
            var(--yellow) 0% 25.5%,
            var(--green) 25.5%
        );

    background-size: cover;
    background-repeat: no-repeat;

    -webkit-mask-repeat: no-repeat;
    -webkit-mask-image:
        radial-gradient(ellipse 127.3% 100% at -85.62% 60.5%, transparent 0%, transparent 100%, black 100%),
        radial-gradient(ellipse 127.3% 100% at 185.62% 60.5%, transparent 0%, transparent 100%, black 100%),
        linear-gradient(to bottom, black 55%, transparent 50%),
        radial-gradient(ellipse 8.4% 8.8% at 50% 55%, black 100%, transparent 100%);

    /* https://tympanus.net/codrops/css_reference/mask_composite/ */
    -webkit-mask-composite:
        source-in,
        source-in,
        source-over;
}
<div id="wrapper">

  <div id="image">
    <h2>Google Maps Logo SVG</h2>
    <img src="https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_(2020).svg" alt="Google Maps icon"/>
  </div>

  <div id="attempt">
    <h2>Image-Mask Abuse</h2>
    <div id="icon"></div>
    <div id="tip"></div>

  </div>
</div>

<details>
<summary>英文:</summary>
Here&#39;s the best I could come up with, by abusing multiple `radial-gradient`, `-webkit-mask-image`, `-webkit-mask-image-composite` and, unfortunately: a sibling-element for the &quot;_pointy-bit_&quot; instead of being able to extend the original `#icon`, nor use an `::after` element (as the `::after` element will be clipped by the mask of its parent).
(I suppose this could be re-organized to make the circular part at the top use `::before` and the pointy-bit use `::after` and otherwise have `#icon` serve only as a container and bounds for its two psedoelement children, but that&#39;s an exercise left for the reader).
This is how it looks in Chrome. I haven&#39;t tested in any other browsers:
[![enter image description here][1]][1]
---------------
&lt;!-- begin snippet: js hide: false console: true babel: false --&gt;
&lt;!-- language: lang-css --&gt;
:root {
--1-3: calc(30%);
--2-3: calc(70%);
--sqrt-2: 1.41421356237;
--inner-radius: calc(18.4%);
--red: #ea4335;
--yellow: #fbbc04;
--green: #34a853;
--blue: #1a73e8;
--azure: #4285f4;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
#wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2em;
margin: 1em;
}
#wrapper &gt; div {
border-radius: 1em;
background: linear-gradient(90deg, #c0392b, #8e44ad);
overflow: hidden;
}
#wrapper &gt; div &gt; h2 {
font-family: sans-serif;
text-align: center;
background-color: white;
border-radius: 0.25em;
width: 90%;
margin-left: auto;
margin-right: auto;
}
#image &gt; img {
transform-origin: 50% 35%;
/*transform: rotate(50deg);*/
}
#icon {
aspect-ratio: 1 / 1;
background-image:
linear-gradient(
180deg,
var(--red) var(--1-3),
var(--yellow) var(--1-3) var(--2-3),
var(--green) var(--2-3)
),
linear-gradient(
180deg,
var(--blue) var(--1-3),
var(--azure) var(--1-3) var(--2-3),
var(--green) var(--2-3)
);
background-position-x: 0, calc(100% - 1px);
background-position-y: 0, 0;
background-size: 50% 100%;
background-repeat: no-repeat;
-webkit-mask-image:
/* The radius of the circle at 100% is actually the corners of the bounding rect, not the perpendicular top+bottom/side edges, hence the weird numbers. */
radial-gradient(
circle at center,
transparent 28.2%,
black       calc(28.2% + 1px),
black       70%,
transparent calc(70.0% + 1px)
);
rotate: -50deg;
z-index: 10;
}
#tip {
aspect-ratio: 26 / 25;
width: 100%;
background-color: #47A756;
margin-top: -14.2%; /* this is relative to the #tip element&#39;s *width* btw. */
z-index: 5;
background-image:
linear-gradient(
130deg,
var(--yellow) 0% 25.5%,
var(--green) 25.5%
);
background-size: cover;
background-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
-webkit-mask-image:
radial-gradient( ellipse 127.3% 100% at -85.62% 60.5%, transparent 0%, transparent 100%, black 100% ),
radial-gradient( ellipse 127.3% 100% at 185.62% 60.5%, transparent 0%, transparent 100%, black 100% ),
linear-gradient( to bottom, black 55%, transparent 50% ),
radial-gradient( ellipse 8.4% 8.8% at 50% 55%, black 100%, transparent 100% );
/* https://tympanus.net/codrops/css_reference/mask-composite/ */
-webkit-mask-composite:
source-in,
source-in,
source-over;
}
&lt;!-- language: lang-html --&gt;
&lt;div id=&quot;wrapper&quot;&gt;
&lt;div id=&quot;image&quot;&gt;
&lt;h2&gt;Google Maps Logo SVG&lt;/h2&gt;
&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_(2020).svg&quot; alt=&quot;Google Maps icon&quot;/&gt;
&lt;/div&gt;
&lt;div id=&quot;attempt&quot;&gt;
&lt;h2&gt;Image-Mask Abuse&lt;/h2&gt;
&lt;div id=&quot;icon&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;tip&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;!-- end snippet --&gt;
[1]: https://i.stack.imgur.com/eujIk.png
</details>
# 答案2
**得分**: 2
以下是您要翻译的内容:
```html
一个在所有浏览器中应该有效的具有一个元素的近似方法:
&lt;!-- 开始代码片段:js 隐藏:false 控制台:true babel:false --&gt;
&lt;!-- 语言:lang-css --&gt;
.logo {
width: 200px; /* 控制大小 */
aspect-ratio: .7;
background:
linear-gradient(130deg,#0000 53%,#34a853 53.5%),
conic-gradient(from 40deg at 36% 26%, #4285f4 25%,#fbbc04 0 50%,#ea4335 0 75%, #1a73e8 0);
-webkit-mask:
radial-gradient(#000 69%,#0000 71%) 
bottom/10% 9% no-repeat,
radial-gradient(92% 173% at 100% 116%,#0000 98%,#000) 
100% 97%/50% 18% no-repeat,
radial-gradient(92% 173% at 0%   116%,#0000 98%,#000) 
0%   97%/50% 18% no-repeat,
conic-gradient(from -35deg at 50% 90%,#000 70deg,#0000 0)
bottom/100% 43% no-repeat,
radial-gradient(#0000 27%,#000 28% 70%,#0000 71%)
top   /100% 70% no-repeat;
display: inline-block;
}
html {
min-height: 100%;
background: repeating-linear-gradient(-45deg, #fff 0 20px, #f9f9f9 0 40px);
text-align: center;
}
&lt;!-- 语言:lang-html --&gt;
&lt;div class=&quot;logo&quot;&gt;&lt;/div&gt;
&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_(2020).svg&quot; width=&quot;200&quot;&gt;
&lt;!-- 结束代码片段 --&gt;

请注意,这里只包括了代码部分,没有翻译代码部分之外的内容。

英文:

An approximation with one element that should work in all the browsers:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

.logo {
width: 200px; /* control the size */
aspect-ratio: .7;
background:
linear-gradient(130deg,#0000 53%,#34a853 53.5%),
conic-gradient(from 40deg at 36% 26%, #4285f4 25%,#fbbc04 0 50%,#ea4335 0 75%, #1a73e8 0);
-webkit-mask:
radial-gradient(#000 69%,#0000 71%) 
bottom/10% 9% no-repeat,
radial-gradient(92% 173% at 100% 116%,#0000 98%,#000) 
100% 97%/50% 18% no-repeat,
radial-gradient(92% 173% at 0%   116%,#0000 98%,#000) 
0%   97%/50% 18% no-repeat,
conic-gradient(from -35deg at 50% 90%,#000 70deg,#0000 0)
bottom/100% 43% no-repeat,
radial-gradient(#0000 27%,#000 28% 70%,#0000 71%)
top   /100% 70% no-repeat;
display: inline-block;
}
html {
min-height: 100%;
background: repeating-linear-gradient(-45deg, #fff 0 20px, #f9f9f9 0 40px);
text-align: center;
}

<!-- language: lang-html -->

&lt;div class=&quot;logo&quot;&gt;&lt;/div&gt;
&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_(2020).svg&quot; width=&quot;200&quot;&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月22日 19:23:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76531374.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定