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

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

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

问题

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

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

  1. :root {
  2. --1-3: calc(100% / 3);
  3. --2-3: calc(100% / 3 * 2);
  4. --sqrt-2: 1.4142135624;
  5. --hole-diameter: calc(100% / var(--sqrt-2) / 3);
  6. --red: #ea4335;
  7. --yellow: #fbbc04;
  8. --green: #34a853;
  9. --blue: #1a73e8;
  10. --azure: #4285f4;
  11. }
  12. * {
  13. box-sizing: border-box;
  14. }
  15. body {
  16. margin: 0;
  17. }
  18. #wrapper {
  19. margin: 3em auto;
  20. width: 10em;
  21. background: linear-gradient(90deg, #c0392b, #8e44ad);
  22. }
  23. #icon {
  24. --mask: radial-gradient(
  25. circle at center,
  26. transparent calc(var(--hole-diameter) - 1px),
  27. #000 calc(var(--hole-diameter) + 1px)
  28. );
  29. border-radius: 50% 50% 50% 0;
  30. aspect-ratio: 1 / 1;
  31. background:
  32. linear-gradient(
  33. 180deg,
  34. var(--red) var(--1-3),
  35. var(--yellow) var(--1-3) var(--2-3),
  36. var(--green) var(--2-3)
  37. ),
  38. linear-gradient(
  39. 180deg,
  40. var(--blue) var(--1-3),
  41. var(--azure) var(--1-3) var(--2-3),
  42. var(--green) var(--2-3)
  43. ) calc(100% - 1px);
  44. background-size: 50% 100%;
  45. background-repeat: no-repeat;
  46. -webkit-mask: var(--mask);
  47. mask: var(--mask);
  48. rotate: -45deg;
  49. }
  1. <div id="wrapper">
  2. <div id="icon"></div>
  3. </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 -->

  1. :root {
  2. --1-3: calc(100% / 3);
  3. --2-3: calc(100% / 3 * 2);
  4. --sqrt-2: 1.4142135624;
  5. --hole-diameter: calc(100% / var(--sqrt-2) / 3);
  6. --red: #ea4335;
  7. --yellow: #fbbc04;
  8. --green: #34a853;
  9. --blue: #1a73e8;
  10. --azure: #4285f4;
  11. }
  12. * {
  13. box-sizing: border-box;
  14. }
  15. body {
  16. margin: 0;
  17. }
  18. #wrapper {
  19. margin: 3em auto;
  20. width: 10em;
  21. background: linear-gradient(90deg, #c0392b, #8e44ad);
  22. }
  23. #icon {
  24. --mask: radial-gradient(
  25. circle at center,
  26. transparent calc(var(--hole-diameter) - 1px),
  27. #000 calc(var(--hole-diameter) + 1px)
  28. );
  29. border-radius: 50% 50% 50% 0;
  30. aspect-ratio: 1 / 1;
  31. background:
  32. linear-gradient(
  33. 180deg,
  34. var(--red) var(--1-3),
  35. var(--yellow) var(--1-3) var(--2-3),
  36. var(--green) var(--2-3)
  37. ),
  38. linear-gradient(
  39. 180deg,
  40. var(--blue) var(--1-3),
  41. var(--azure) var(--1-3) var(--2-3),
  42. var(--green) var(--2-3)
  43. ) calc(100% - 1px);
  44. background-size: 50% 100%;
  45. background-repeat: no-repeat;
  46. -webkit-mask: var(--mask);
  47. mask: var(--mask);
  48. rotate: -45deg;
  49. }

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

  1. &lt;div id=&quot;wrapper&quot;&gt;
  2. &lt;div id=&quot;icon&quot;&gt;&lt;/div&gt;
  3. &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图标的形状?


  1. :root {
  2. --1-3: calc(30%);
  3. --2-3: calc(70%);
  4. --sqrt-2: 1.41421356237;
  5. --inner-radius: calc(18.4%);
  6. --red: #ea4335;
  7. --yellow: #fbbc04;
  8. --green: #34a853;
  9. --blue: #1a73e8;
  10. --azure: #4285f4;
  11. }
  12. * {
  13. box-sizing: border-box;
  14. }
  15. body {
  16. margin: 0;
  17. }
  18. #wrapper {
  19. display: grid;
  20. grid-template-columns: 1fr 1fr;
  21. gap: 2em;
  22. margin: 1em;
  23. }
  24. #wrapper > div {
  25. border-radius: 1em;
  26. background: linear-gradient(90deg, #c0392b, #8e44ad);
  27. overflow: hidden;
  28. }
  29. #wrapper > div > h2 {
  30. font-family: sans-serif;
  31. text-align: center;
  32. background-color: white;
  33. border-radius: 0.25em;
  34. width: 90%;
  35. margin-left: auto;
  36. margin-right: auto;
  37. }
  38. #image > img {
  39. transform-origin: 50% 35%;
  40. /*transform: rotate(50deg);*/
  41. }
  42. #icon {
  43. aspect-ratio: 1 / 1;
  44. background-image:
  45. linear-gradient(
  46. 180deg,
  47. var(--red) var(--1-3),
  48. var(--yellow) var(--1-3) var(--2-3),
  49. var(--green) var(--2-3)
  50. ),
  51. linear-gradient(
  52. 180deg,
  53. var(--blue) var(--1-3),
  54. var(--azure) var(--1-3) var(--2-3),
  55. var(--green) var(--2-3)
  56. );
  57. background-position-x: 0, calc(100% - 1px);
  58. background-position-y: 0, 0;
  59. background-size: 50% 100%;
  60. background-repeat: no-repeat;
  61. -webkit-mask-image:
  62. /* 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. */
  63. radial-gradient(
  64. circle at center,
  65. transparent 28.2%,
  66. black calc(28.2% + 1px),
  67. black 70%,
  68. transparent calc(70.0% + 1px)
  69. );
  70. rotate: -50deg;
  71. z-index: 10;
  72. }
  73. #tip {
  74. aspect-ratio: 26 / 25;
  75. width: 100%;
  76. background-color: #47A756;
  77. margin-top: -14.2%; /* this is relative to the #tip element's *width* btw. */
  78. z-index: 5;
  79. background-image:
  80. linear-gradient(
  81. 130deg,
  82. var(--yellow) 0% 25.5%,
  83. var(--green) 25.5%
  84. );
  85. background-size: cover;
  86. background-repeat: no-repeat;
  87. -webkit-mask-repeat: no-repeat;
  88. -webkit-mask-image:
  89. radial-gradient(ellipse 127.3% 100% at -85.62% 60.5%, transparent 0%, transparent 100%, black 100%),
  90. radial-gradient(ellipse 127.3% 100% at 185.62% 60.5%, transparent 0%, transparent 100%, black 100%),
  91. linear-gradient(to bottom, black 55%, transparent 50%),
  92. radial-gradient(ellipse 8.4% 8.8% at 50% 55%, black 100%, transparent 100%);
  93. /* https://tympanus.net/codrops/css_reference/mask_composite/ */
  94. -webkit-mask-composite:
  95. source-in,
  96. source-in,
  97. source-over;
  98. }
  1. <div id="wrapper">
  2. <div id="image">
  3. <h2>Google Maps Logo SVG</h2>
  4. <img src="https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_(2020).svg" alt="Google Maps icon"/>
  5. </div>
  6. <div id="attempt">
  7. <h2>Image-Mask Abuse</h2>
  8. <div id="icon"></div>
  9. <div id="tip"></div>
  10. </div>
  11. </div>
  1. <details>
  2. <summary>英文:</summary>
  3. 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).
  4. (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).
  5. This is how it looks in Chrome. I haven&#39;t tested in any other browsers:
  6. [![enter image description here][1]][1]
  7. ---------------
  8. &lt;!-- begin snippet: js hide: false console: true babel: false --&gt;
  9. &lt;!-- language: lang-css --&gt;
  10. :root {
  11. --1-3: calc(30%);
  12. --2-3: calc(70%);
  13. --sqrt-2: 1.41421356237;
  14. --inner-radius: calc(18.4%);
  15. --red: #ea4335;
  16. --yellow: #fbbc04;
  17. --green: #34a853;
  18. --blue: #1a73e8;
  19. --azure: #4285f4;
  20. }
  21. * {
  22. box-sizing: border-box;
  23. }
  24. body {
  25. margin: 0;
  26. }
  27. #wrapper {
  28. display: grid;
  29. grid-template-columns: 1fr 1fr;
  30. gap: 2em;
  31. margin: 1em;
  32. }
  33. #wrapper &gt; div {
  34. border-radius: 1em;
  35. background: linear-gradient(90deg, #c0392b, #8e44ad);
  36. overflow: hidden;
  37. }
  38. #wrapper &gt; div &gt; h2 {
  39. font-family: sans-serif;
  40. text-align: center;
  41. background-color: white;
  42. border-radius: 0.25em;
  43. width: 90%;
  44. margin-left: auto;
  45. margin-right: auto;
  46. }
  47. #image &gt; img {
  48. transform-origin: 50% 35%;
  49. /*transform: rotate(50deg);*/
  50. }
  51. #icon {
  52. aspect-ratio: 1 / 1;
  53. background-image:
  54. linear-gradient(
  55. 180deg,
  56. var(--red) var(--1-3),
  57. var(--yellow) var(--1-3) var(--2-3),
  58. var(--green) var(--2-3)
  59. ),
  60. linear-gradient(
  61. 180deg,
  62. var(--blue) var(--1-3),
  63. var(--azure) var(--1-3) var(--2-3),
  64. var(--green) var(--2-3)
  65. );
  66. background-position-x: 0, calc(100% - 1px);
  67. background-position-y: 0, 0;
  68. background-size: 50% 100%;
  69. background-repeat: no-repeat;
  70. -webkit-mask-image:
  71. /* 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. */
  72. radial-gradient(
  73. circle at center,
  74. transparent 28.2%,
  75. black calc(28.2% + 1px),
  76. black 70%,
  77. transparent calc(70.0% + 1px)
  78. );
  79. rotate: -50deg;
  80. z-index: 10;
  81. }
  82. #tip {
  83. aspect-ratio: 26 / 25;
  84. width: 100%;
  85. background-color: #47A756;
  86. margin-top: -14.2%; /* this is relative to the #tip element&#39;s *width* btw. */
  87. z-index: 5;
  88. background-image:
  89. linear-gradient(
  90. 130deg,
  91. var(--yellow) 0% 25.5%,
  92. var(--green) 25.5%
  93. );
  94. background-size: cover;
  95. background-repeat: no-repeat;
  96. -webkit-mask-repeat: no-repeat;
  97. -webkit-mask-image:
  98. radial-gradient( ellipse 127.3% 100% at -85.62% 60.5%, transparent 0%, transparent 100%, black 100% ),
  99. radial-gradient( ellipse 127.3% 100% at 185.62% 60.5%, transparent 0%, transparent 100%, black 100% ),
  100. linear-gradient( to bottom, black 55%, transparent 50% ),
  101. radial-gradient( ellipse 8.4% 8.8% at 50% 55%, black 100%, transparent 100% );
  102. /* https://tympanus.net/codrops/css_reference/mask-composite/ */
  103. -webkit-mask-composite:
  104. source-in,
  105. source-in,
  106. source-over;
  107. }
  108. &lt;!-- language: lang-html --&gt;
  109. &lt;div id=&quot;wrapper&quot;&gt;
  110. &lt;div id=&quot;image&quot;&gt;
  111. &lt;h2&gt;Google Maps Logo SVG&lt;/h2&gt;
  112. &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;
  113. &lt;/div&gt;
  114. &lt;div id=&quot;attempt&quot;&gt;
  115. &lt;h2&gt;Image-Mask Abuse&lt;/h2&gt;
  116. &lt;div id=&quot;icon&quot;&gt;&lt;/div&gt;
  117. &lt;div id=&quot;tip&quot;&gt;&lt;/div&gt;
  118. &lt;/div&gt;
  119. &lt;/div&gt;
  120. &lt;!-- end snippet --&gt;
  121. [1]: https://i.stack.imgur.com/eujIk.png
  122. </details>
  123. # 答案2
  124. **得分**: 2
  125. 以下是您要翻译的内容:
  126. ```html
  127. 一个在所有浏览器中应该有效的具有一个元素的近似方法:
  128. &lt;!-- 开始代码片段:js 隐藏:false 控制台:true babel:false --&gt;
  129. &lt;!-- 语言:lang-css --&gt;
  130. .logo {
  131. width: 200px; /* 控制大小 */
  132. aspect-ratio: .7;
  133. background:
  134. linear-gradient(130deg,#0000 53%,#34a853 53.5%),
  135. conic-gradient(from 40deg at 36% 26%, #4285f4 25%,#fbbc04 0 50%,#ea4335 0 75%, #1a73e8 0);
  136. -webkit-mask:
  137. radial-gradient(#000 69%,#0000 71%)
  138. bottom/10% 9% no-repeat,
  139. radial-gradient(92% 173% at 100% 116%,#0000 98%,#000)
  140. 100% 97%/50% 18% no-repeat,
  141. radial-gradient(92% 173% at 0% 116%,#0000 98%,#000)
  142. 0% 97%/50% 18% no-repeat,
  143. conic-gradient(from -35deg at 50% 90%,#000 70deg,#0000 0)
  144. bottom/100% 43% no-repeat,
  145. radial-gradient(#0000 27%,#000 28% 70%,#0000 71%)
  146. top /100% 70% no-repeat;
  147. display: inline-block;
  148. }
  149. html {
  150. min-height: 100%;
  151. background: repeating-linear-gradient(-45deg, #fff 0 20px, #f9f9f9 0 40px);
  152. text-align: center;
  153. }
  154. &lt;!-- 语言:lang-html --&gt;
  155. &lt;div class=&quot;logo&quot;&gt;&lt;/div&gt;
  156. &lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_(2020).svg&quot; width=&quot;200&quot;&gt;
  157. &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 -->

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

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

  1. &lt;div class=&quot;logo&quot;&gt;&lt;/div&gt;
  2. &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:

确定