Unicode 表情符号的颜色
Color for Unicode Emoji
在现代浏览器中可以包含 Emoji 字符,但如何使其成为单一颜色并选择该颜色?
例如,这里有一些表情符号和一些常规(平面 0)Unicode 符号。都应该是红色的,但只有符号呈现为红色。
关联HTML + CSS:
<p>
</p>
<p>
♥★ℹ
</div>
p {
font-size: 3em;
color: red
}
由于表情符号非常新,因此尚不支持其样式。
解决方法是使用表情符号字体,例如 Twitter's Twemoji。然后它的样式可以与 Font Awesome 或本机 Unicode 的样式大致相同。
是的,你可以给它们上色!
div {
color: transparent;
text-shadow: 0 0 0 red;
}
<div></div>
您可以用纯色填充它们:
p {
font-size: 20px;
color: transparent;
text-shadow: 0 0 0 blue;
}
<p></p>
<p></p>
<p></p>
或者您可以概述它们:
body {
background: #fff;
}
p {
margin: 0;
color: transparent;
text-shadow: 0 0 3px blue;
font-size: 20px;
position: relative;
}
p::before {
content: attr(title);
position: absolute;
text-shadow: 0 0 0 #fff;
}
<p title=""></p>
<p title=""></p>
<p title=""></p>
并非每个表情符号的作用都相同。有些是旧的文本符号,现在具有(可选或默认)彩色表示,其他的则明确(仅)作为表情符号。这意味着,一些 Unicode 代码点应该有两种可能的表示形式,text
和 emoji
。作者和用户应该能够表达他们对其中一个或另一个的偏好。这是目前完成的,否则不可见 variation selectors U+FE0E (text
, VS-15) and U+FE0F (emoji
, VS-16), but higher-level solutions (e.g. for CSS) 已被提议。
文本样式的表情符号是单色的,应该以前景色显示,即 CSS 中的 currentcolor
,就像任何其他字形一样。 Unicode 联盟提供 overview of emojis by style (beta version)。您应该能够将 HTML 中的 ︎
附加到 select 文本变体,其中包含标有“默认文本样式”的列中的任何内容; 有 VSs”和“默认表情符号样式; 有VS”。不过,这不包括示例表情符号和许多其他表情符号。
p {
color: red; font-size: 3em; margin: 0;
text-transform: text; /* proposed */
font-variant-emoji: text; /* proposed */
font-variant-color: monochrome; /* proposed */
font-color: monochrome; /* proposed */
font-palette: dark; /* drafted for CSS Fonts Level 4 */
}
p.hack {
color: rgba(100%, 0%, 0%, 0);
text-shadow: 0 0 0 red;
}
p.font {
font-family: Emojione, Noto, Twemoji, Symbola;
}
@font-face { /* http://emojione.com/developers/ */
font-family: Emojione;
src: local("EmojiOne BW"), local("EmojiOne"), local("Emoji One"),
/* https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-bw.otf – monochrome only, deprecated, removed
https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-android.ttf – with hack
https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-apple.ttf – with hack */
url("https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-svg.woff2") format("woff2"),
url("https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-svg.woff") format("woff"),
url("https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-svg.otf") format("truetype");
}
@font-face { /* https://www.google.com/get/noto/#noto-emoji-zsye */
font-family: Noto;
src: local("Noto Emoji"), local("Noto Color Emoji"), local("Noto"),
url("https://cdn.rawgit.com/googlei18n/noto-emoji/master/fonts/NotoEmoji-Regular.ttf");
}
@font-face { /* https://github.com/eosrei/twemoji-color-font/releases */
font-family: Twemoji;
src: local("Twemoji");
}
@font-face { /* http://users.teilar.gr/~g1951d/ */
font-family: Symbola;
src: local("Symbola");
}
<p title="♥★ℹ without variation selectors">🐘 🐧 🐼 ♥ ★ ℹ 💀 👌</p>
<p title="♥★ℹ with text variation selector 15">🐘︎ 🐧︎ 🐼︎ ♥︎ ★︎ ℹ︎ 💀︎ 👌︎</p>
<p title="♥★ℹ with emoji variation selector 16">🐘️ 🐧️ 🐼️ ♥️ ★️ ℹ️ 💀️ 👌️</p>
<p title="♥★ℹ with `text-shadow` hack" class="hack">🐘 🐧 🐼 ♥ ★ ℹ 💀 👌</p>
<p title="♥★ℹ with custom font" class="font">🐘 🐧 🐼 ♥ ★ ℹ 💀 👌</p>
我添加了 U+1F480 Skull 和 U+1F44C OK Hand Sign,因为背景应该通过他们的“眼睛”显示出来,我使用数字字符引用只是为了让代码更明显,更健壮,防止复制- 并粘贴错误。
然而,有人提议,两种变体 selector 都可以应用于任何字符,这在大多数情况下都没有效果。请注意,一些供应商,尤其是三星,已经发货(默认)emoji glyphs for several other characters(goo.gl/a4yK6p
或 goo.gl/DqtHcc
)。
一些(但不是全部)代码点可以文本形式(非基于图片的字形)或表情符号形式(基于图片的字形)绘制。 Unicode 描述可以使用两个变体选择器之一来选择这两种形式:U+FE0E (VARIATION SELECTOR-15) 或 U+FE0F (VARIATION SELECTOR-16)。当以非图片形式绘制时,color
CSS 属性 应适用。
示例:
U+2603(雪人)是这样画的:☃
码点序列U+2603 U+FE0E这样画:☃︎
码点序列U+2603 U+FE0F是这样画的:☃️
可以在 http://unicode.org/emoji/charts/emoji-variants.html
中找到更多信息以及参与这些变体序列的代码点的完整列表
(请注意,不同的操作系统在使用裸代码点时可能会选择不同的默认值。例如,尝试在 macOS 中查看此 post 和 iOS - 上面的裸代码点看起来不同!)
如果您需要使用 CSS 之后,您可以像这样处理之前的伪元素
<span class="react-thumb-fly" title="Aimé">
<button class="react-toggle-icon-thumb"></button>
</span>
然后为 CSS
写这个
.react-toggle-icon-thumb {
width: 20pt;
height: 20pt;
font-size: 30pt;
position: relative;
color: gray;
cursor: pointer;
border: none;
background: transparent;
margin-left: 0px;
margin-right: 8px;
top: -0px;
}
.react-toggle-icon-thumb:before, .react-toggle-icon-thumb:after {
position: absolute;
top: 0;
left: 0;
transition: all .3s ease-out;
content: "";
font-family: fontawesome;
color: transparent;
text-shadow: 0 0 0 #3498db;
}
.react-toggle-icon-thumb:hover:before {
transform: scale(1.2);
animation: thumbs-up 2s linear infinite;
}
@keyframes thumbs-up {
25% {
transform: rotate(20deg);
}
50%, 100% {
transform: rotate(5deg);
}
}
我想自己做这个,所以我最近想出了一个解决方案,使用更新的 CSS 效果,也适用于 Firefox 和 Edge。
使用滤镜,首先使用深褐色 (1) 对颜色进行标准化,然后将其浸透以获得纯红色。如果你想去掉黑线,在使用 contrast(0) 应用其他滤镜之前从表情符号中吸取对比度。之后,您只需使用 hue-rotate() 将色轮从红色旋转到您想要的任何颜色。请注意,因为我使用的是十进制值而不是 %,所以值 100 表示 10000%。
色调偏移定义为从红色开始。我们很幸运,棕褐色大部分是红色的,所以轮子完美地从 0 度开始。您可以使用 RGB 到 HSL 转换器计算您想要的偏移量。我在这里找到了一篇用 Javascript 写的不错的文章:https://web.archive.org/web/20180808220922/http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
您必须将色调值乘以 360 才能从该函数获得所需的结果。一个例子是 rgbToHsl(0,100,100)[0]*360
。这将 return 180。由于没有红色,这将是预期的结果,您将旋转 180 度远离红色。
正如 Litherium an Crissov 指出的那样,也有文字表情符号。这些在转换时效果更好,而且通常看起来更好。但是,您不能应用我上面描述的方法,除非您首先在文本表情符号上应用 invert(.5)
,这是因为函数需要某种阴影才能运行。因此,只需将 invert(.5)
添加到每个公式的开头,就可以让它们在所有浏览器上对两个代码点进行操作。
.a { /* Normalize colour to a primary red */
filter: sepia(1) saturate(100);
}
.b { /* Less saturation so more features, shifted colour 90-degrees */
filter: sepia(1) saturate(5) hue-rotate(90deg);
}
.c { /* Remove black outlines if desired by removing contrast */
filter: contrast(0) sepia(1) saturate(100) hue-rotate(180deg);
}
.d { /* Other shades possible by lowering brightness */
filter: contrast(0) sepia(1) saturate(100) brightness(.05) hue-rotate(180deg);
}
.e { /* Weird possibilities with no colour normalization */
filter: contrast(100) hue-rotate(180deg);
}
.ma { /* Invert to provide a gray shade to apply sepia*/
filter: invert(.5) sepia(1) saturate(100);
}
div {
font-size: 25px;
}
.emo > div::after {
content: "⛄";
}
.mono > div::after {
content: "F30D\FE0EC4\FE0EF60D\FE0EF431\FE0E";
}
<div class="emo">
<div>-:</div>
<div class="a">a:</div>
<div class="b">b:</div>
<div class="c">c:</div>
<div class="d">d:</div>
<div class="e">e:</div>
</div>
<span>Change the code point to text mode:</span>
<div class="mono">
<div class="a">a:</div>
<div class="ma">ma:</div>
</div>
更新:
现在 npm 上有更新的软件包可以计算色调等。您不需要在我之前链接的网站上使用该片段。这是一个示例:
如果您想在表情符号中保留详细信息,可以使用 filter: url(svg)
where url()
will take an svg filter
svg {
display: none;
}
div {
-webkit-filter: url(#red);
filter: url(#red);
}
<svg>
<filter id="red">
<feColorMatrix type="matrix" values="
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0" />
</filter>
</svg>
<div></div>
虽然 feColorMatrix
的使用乍一看可能令人望而生畏,但实际上定义您自己的颜色非常简单。以下面的例子代表红色:
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0
如果你从上面获取 粗体 值,我们可以看到它们与 RGBA 颜色模式的关系:
1 - red (r)
0 - green (g)
0 - blue (b)
1 - alpha (a)
此处每种颜色都与 0 到 255 除以 255 之间的值相关。因此,如果您有绿色,其 RGBA 为:
R G B A
(0, 255, 0, 1)
那么您的值将是:
0/255 -> 0 (r)
255/255 -> 1 (g)
0/255 -> 0 (b)
1 -> 1 (a) - don't divide
因此,在我们的矩阵中使用这些值,我们得到:
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0
您现在可以将其添加为附加过滤器(或删除旧过滤器)并给它一个 id
以便它可以在 css filter: url(#filterID)
[=31 中被引用=]
查看下面的实施版本:
svg {
display: none;
}
.red {
-webkit-filter: url(#red);
filter: url(#red);
}
.green {
-webkit-filter: url(#green);
filter: url(#green);
}
<svg>
<filter id="red">
<feColorMatrix type="matrix" values="
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0" />
</filter>
<!-- \/ --- change id to be referenced within css -->
<filter id="green">
<feColorMatrix type="matrix" values="
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0" />
</filter>
</svg>
<div class="red"></div>
<div class="green"></div>
<feColorMatrix />
颜色矩阵生成器:
为方便起见,我制作了一个 feColorMatrix
生成器,它允许您选择或输入颜色以及不透明度,并从该颜色生成 feColorMatrix:
const colorPicker = document.getElementById("color-picker");
const alphaPicker = document.getElementById("alpha-picker");
const codeOutput = document.getElementById("code-output");
const alphaValue = document.getElementById("alpha-value");
const pickedFilter = document.getElementById("picked-filter");
let r=0, g=0, b=0, a=1;
const generateFeColorMatrix = () => `<feColorMatrix type="matrix" values="
${r} 0 0 0 0
0 ${g} 0 0 0
0 0 0 ${b} 0
0 0 0 ${a} 0"
/>
`;
const update = () => {
const feColorMatrixStr = generateFeColorMatrix();
codeOutput.textContent = feColorMatrixStr;
pickedFilter.innerHTML = feColorMatrixStr;
}
colorPicker.addEventListener("input", (e) => {
const hexparts = e.target.value.match(/(\w{1,2})/g);
([r,g,b] = hexparts.map(hex => (parseInt(hex, 16) / 255).toFixed(2)));
update();
});
alphaPicker.addEventListener("input", e => {
a = e.target.value;
alphaValue.textContent = a;
update();
});
alphaValue.textContent = a;
svg {
display: none;
}
#color-picker {
float: right;
}
#code-output {
background-color: #f6f6f6;
}
#emojis {
-webkit-filter: url(#picked-filter);
filter: url(#picked-filter);
font-size: 30px;
}
<input type="color" id="color-picker" />
<input type="range" id="alpha-picker" value="1" min="0" max="1" step="0.01"/><span id="alpha-value">1</span>
<pre id="code-output">
</pre>
<svg>
<filter id="picked-filter"></filter>
</svg>
<p id="emojis"></p>
请注意目前,此解决方案的浏览器支持非常有限。要查看此功能支持的浏览器的完整列表,请参阅 here。
Nick Parsons 的 SVG 矩阵解决方案也可以使用 data:
方案转换为 in-line 解决方案:
filter: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0'/></filter></svg>#f");
color-interpolation-filters='sRGB'
是因为一些浏览器使用不同的默认颜色 space.
我还建议添加灰度滤镜,否则如果使用纯色,某些表情符号会失去对比度:
filter: grayscale(100%) url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0'/></filter></svg>#f");
灰度滤镜也可以用矩阵来表示并合并到SVG数据中。这是一个应该比 CSS 提供的更符合人类感知的:
filter: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='linearRGB' type='matrix' values='0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0'/><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0'/></filter></svg>#f");
最后,这里是一些 PHP 代码,它根据给定的颜色生成矩阵(输入为 CSS hex-based 颜色代码):
function matrixcolor($hex)
{
list($r, $g, $b) = array_map(function($c) {return $c / 255 / 3;}, sscanf($hex, "#%02x%02x%02x"));
return "$r $r $r 0 0 $g $g $g 0 0 $b $b $b 0 0";
}
function colormatrix($col)
{
return "url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='linearRGB' type='matrix' values='0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0'/><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='".matrixcolor($col)." 0 0 0 1 0'/></filter></svg>#f\")";
}
在现代浏览器中可以包含 Emoji 字符,但如何使其成为单一颜色并选择该颜色?
例如,这里有一些表情符号和一些常规(平面 0)Unicode 符号。都应该是红色的,但只有符号呈现为红色。
关联HTML + CSS:
<p>
</p>
<p>
♥★ℹ
</div>
p {
font-size: 3em;
color: red
}
由于表情符号非常新,因此尚不支持其样式。
解决方法是使用表情符号字体,例如 Twitter's Twemoji。然后它的样式可以与 Font Awesome 或本机 Unicode 的样式大致相同。
是的,你可以给它们上色!
div {
color: transparent;
text-shadow: 0 0 0 red;
}
<div></div>
您可以用纯色填充它们:
p {
font-size: 20px;
color: transparent;
text-shadow: 0 0 0 blue;
}
<p></p>
<p></p>
<p></p>
或者您可以概述它们:
body {
background: #fff;
}
p {
margin: 0;
color: transparent;
text-shadow: 0 0 3px blue;
font-size: 20px;
position: relative;
}
p::before {
content: attr(title);
position: absolute;
text-shadow: 0 0 0 #fff;
}
<p title=""></p>
<p title=""></p>
<p title=""></p>
并非每个表情符号的作用都相同。有些是旧的文本符号,现在具有(可选或默认)彩色表示,其他的则明确(仅)作为表情符号。这意味着,一些 Unicode 代码点应该有两种可能的表示形式,text
和 emoji
。作者和用户应该能够表达他们对其中一个或另一个的偏好。这是目前完成的,否则不可见 variation selectors U+FE0E (text
, VS-15) and U+FE0F (emoji
, VS-16), but higher-level solutions (e.g. for CSS) 已被提议。
文本样式的表情符号是单色的,应该以前景色显示,即 CSS 中的 currentcolor
,就像任何其他字形一样。 Unicode 联盟提供 overview of emojis by style (beta version)。您应该能够将 HTML 中的 ︎
附加到 select 文本变体,其中包含标有“默认文本样式”的列中的任何内容; 有 VSs”和“默认表情符号样式; 有VS”。不过,这不包括示例表情符号和许多其他表情符号。
p {
color: red; font-size: 3em; margin: 0;
text-transform: text; /* proposed */
font-variant-emoji: text; /* proposed */
font-variant-color: monochrome; /* proposed */
font-color: monochrome; /* proposed */
font-palette: dark; /* drafted for CSS Fonts Level 4 */
}
p.hack {
color: rgba(100%, 0%, 0%, 0);
text-shadow: 0 0 0 red;
}
p.font {
font-family: Emojione, Noto, Twemoji, Symbola;
}
@font-face { /* http://emojione.com/developers/ */
font-family: Emojione;
src: local("EmojiOne BW"), local("EmojiOne"), local("Emoji One"),
/* https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-bw.otf – monochrome only, deprecated, removed
https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-android.ttf – with hack
https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-apple.ttf – with hack */
url("https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-svg.woff2") format("woff2"),
url("https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-svg.woff") format("woff"),
url("https://cdn.rawgit.com/Ranks/emojione/master/assets/fonts/emojione-svg.otf") format("truetype");
}
@font-face { /* https://www.google.com/get/noto/#noto-emoji-zsye */
font-family: Noto;
src: local("Noto Emoji"), local("Noto Color Emoji"), local("Noto"),
url("https://cdn.rawgit.com/googlei18n/noto-emoji/master/fonts/NotoEmoji-Regular.ttf");
}
@font-face { /* https://github.com/eosrei/twemoji-color-font/releases */
font-family: Twemoji;
src: local("Twemoji");
}
@font-face { /* http://users.teilar.gr/~g1951d/ */
font-family: Symbola;
src: local("Symbola");
}
<p title="♥★ℹ without variation selectors">🐘 🐧 🐼 ♥ ★ ℹ 💀 👌</p>
<p title="♥★ℹ with text variation selector 15">🐘︎ 🐧︎ 🐼︎ ♥︎ ★︎ ℹ︎ 💀︎ 👌︎</p>
<p title="♥★ℹ with emoji variation selector 16">🐘️ 🐧️ 🐼️ ♥️ ★️ ℹ️ 💀️ 👌️</p>
<p title="♥★ℹ with `text-shadow` hack" class="hack">🐘 🐧 🐼 ♥ ★ ℹ 💀 👌</p>
<p title="♥★ℹ with custom font" class="font">🐘 🐧 🐼 ♥ ★ ℹ 💀 👌</p>
我添加了 U+1F480 Skull 和 U+1F44C OK Hand Sign,因为背景应该通过他们的“眼睛”显示出来,我使用数字字符引用只是为了让代码更明显,更健壮,防止复制- 并粘贴错误。
然而,有人提议,两种变体 selector 都可以应用于任何字符,这在大多数情况下都没有效果。请注意,一些供应商,尤其是三星,已经发货(默认)emoji glyphs for several other characters(goo.gl/a4yK6p
或 goo.gl/DqtHcc
)。
一些(但不是全部)代码点可以文本形式(非基于图片的字形)或表情符号形式(基于图片的字形)绘制。 Unicode 描述可以使用两个变体选择器之一来选择这两种形式:U+FE0E (VARIATION SELECTOR-15) 或 U+FE0F (VARIATION SELECTOR-16)。当以非图片形式绘制时,color
CSS 属性 应适用。
示例:
U+2603(雪人)是这样画的:☃
码点序列U+2603 U+FE0E这样画:☃︎
码点序列U+2603 U+FE0F是这样画的:☃️
可以在 http://unicode.org/emoji/charts/emoji-variants.html
中找到更多信息以及参与这些变体序列的代码点的完整列表(请注意,不同的操作系统在使用裸代码点时可能会选择不同的默认值。例如,尝试在 macOS 中查看此 post 和 iOS - 上面的裸代码点看起来不同!)
如果您需要使用 CSS 之后,您可以像这样处理之前的伪元素
<span class="react-thumb-fly" title="Aimé">
<button class="react-toggle-icon-thumb"></button>
</span>
然后为 CSS
写这个.react-toggle-icon-thumb {
width: 20pt;
height: 20pt;
font-size: 30pt;
position: relative;
color: gray;
cursor: pointer;
border: none;
background: transparent;
margin-left: 0px;
margin-right: 8px;
top: -0px;
}
.react-toggle-icon-thumb:before, .react-toggle-icon-thumb:after {
position: absolute;
top: 0;
left: 0;
transition: all .3s ease-out;
content: "";
font-family: fontawesome;
color: transparent;
text-shadow: 0 0 0 #3498db;
}
.react-toggle-icon-thumb:hover:before {
transform: scale(1.2);
animation: thumbs-up 2s linear infinite;
}
@keyframes thumbs-up {
25% {
transform: rotate(20deg);
}
50%, 100% {
transform: rotate(5deg);
}
}
我想自己做这个,所以我最近想出了一个解决方案,使用更新的 CSS 效果,也适用于 Firefox 和 Edge。
使用滤镜,首先使用深褐色 (1) 对颜色进行标准化,然后将其浸透以获得纯红色。如果你想去掉黑线,在使用 contrast(0) 应用其他滤镜之前从表情符号中吸取对比度。之后,您只需使用 hue-rotate() 将色轮从红色旋转到您想要的任何颜色。请注意,因为我使用的是十进制值而不是 %,所以值 100 表示 10000%。
色调偏移定义为从红色开始。我们很幸运,棕褐色大部分是红色的,所以轮子完美地从 0 度开始。您可以使用 RGB 到 HSL 转换器计算您想要的偏移量。我在这里找到了一篇用 Javascript 写的不错的文章:https://web.archive.org/web/20180808220922/http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
您必须将色调值乘以 360 才能从该函数获得所需的结果。一个例子是 rgbToHsl(0,100,100)[0]*360
。这将 return 180。由于没有红色,这将是预期的结果,您将旋转 180 度远离红色。
正如 Litherium an Crissov 指出的那样,也有文字表情符号。这些在转换时效果更好,而且通常看起来更好。但是,您不能应用我上面描述的方法,除非您首先在文本表情符号上应用 invert(.5)
,这是因为函数需要某种阴影才能运行。因此,只需将 invert(.5)
添加到每个公式的开头,就可以让它们在所有浏览器上对两个代码点进行操作。
.a { /* Normalize colour to a primary red */
filter: sepia(1) saturate(100);
}
.b { /* Less saturation so more features, shifted colour 90-degrees */
filter: sepia(1) saturate(5) hue-rotate(90deg);
}
.c { /* Remove black outlines if desired by removing contrast */
filter: contrast(0) sepia(1) saturate(100) hue-rotate(180deg);
}
.d { /* Other shades possible by lowering brightness */
filter: contrast(0) sepia(1) saturate(100) brightness(.05) hue-rotate(180deg);
}
.e { /* Weird possibilities with no colour normalization */
filter: contrast(100) hue-rotate(180deg);
}
.ma { /* Invert to provide a gray shade to apply sepia*/
filter: invert(.5) sepia(1) saturate(100);
}
div {
font-size: 25px;
}
.emo > div::after {
content: "⛄";
}
.mono > div::after {
content: "F30D\FE0EC4\FE0EF60D\FE0EF431\FE0E";
}
<div class="emo">
<div>-:</div>
<div class="a">a:</div>
<div class="b">b:</div>
<div class="c">c:</div>
<div class="d">d:</div>
<div class="e">e:</div>
</div>
<span>Change the code point to text mode:</span>
<div class="mono">
<div class="a">a:</div>
<div class="ma">ma:</div>
</div>
更新: 现在 npm 上有更新的软件包可以计算色调等。您不需要在我之前链接的网站上使用该片段。这是一个示例:
如果您想在表情符号中保留详细信息,可以使用 filter: url(svg)
where url()
will take an svg filter
svg {
display: none;
}
div {
-webkit-filter: url(#red);
filter: url(#red);
}
<svg>
<filter id="red">
<feColorMatrix type="matrix" values="
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0" />
</filter>
</svg>
<div></div>
虽然 feColorMatrix
的使用乍一看可能令人望而生畏,但实际上定义您自己的颜色非常简单。以下面的例子代表红色:
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
如果你从上面获取 粗体 值,我们可以看到它们与 RGBA 颜色模式的关系:
1 - red (r) 0 - green (g) 0 - blue (b) 1 - alpha (a)
此处每种颜色都与 0 到 255 除以 255 之间的值相关。因此,如果您有绿色,其 RGBA 为:
R G B A (0, 255, 0, 1)
那么您的值将是:
0/255 -> 0 (r) 255/255 -> 1 (g) 0/255 -> 0 (b) 1 -> 1 (a) - don't divide
因此,在我们的矩阵中使用这些值,我们得到:
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0
您现在可以将其添加为附加过滤器(或删除旧过滤器)并给它一个 id
以便它可以在 css filter: url(#filterID)
[=31 中被引用=]
查看下面的实施版本:
svg {
display: none;
}
.red {
-webkit-filter: url(#red);
filter: url(#red);
}
.green {
-webkit-filter: url(#green);
filter: url(#green);
}
<svg>
<filter id="red">
<feColorMatrix type="matrix" values="
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0" />
</filter>
<!-- \/ --- change id to be referenced within css -->
<filter id="green">
<feColorMatrix type="matrix" values="
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0" />
</filter>
</svg>
<div class="red"></div>
<div class="green"></div>
<feColorMatrix />
颜色矩阵生成器:
为方便起见,我制作了一个 feColorMatrix
生成器,它允许您选择或输入颜色以及不透明度,并从该颜色生成 feColorMatrix:
const colorPicker = document.getElementById("color-picker");
const alphaPicker = document.getElementById("alpha-picker");
const codeOutput = document.getElementById("code-output");
const alphaValue = document.getElementById("alpha-value");
const pickedFilter = document.getElementById("picked-filter");
let r=0, g=0, b=0, a=1;
const generateFeColorMatrix = () => `<feColorMatrix type="matrix" values="
${r} 0 0 0 0
0 ${g} 0 0 0
0 0 0 ${b} 0
0 0 0 ${a} 0"
/>
`;
const update = () => {
const feColorMatrixStr = generateFeColorMatrix();
codeOutput.textContent = feColorMatrixStr;
pickedFilter.innerHTML = feColorMatrixStr;
}
colorPicker.addEventListener("input", (e) => {
const hexparts = e.target.value.match(/(\w{1,2})/g);
([r,g,b] = hexparts.map(hex => (parseInt(hex, 16) / 255).toFixed(2)));
update();
});
alphaPicker.addEventListener("input", e => {
a = e.target.value;
alphaValue.textContent = a;
update();
});
alphaValue.textContent = a;
svg {
display: none;
}
#color-picker {
float: right;
}
#code-output {
background-color: #f6f6f6;
}
#emojis {
-webkit-filter: url(#picked-filter);
filter: url(#picked-filter);
font-size: 30px;
}
<input type="color" id="color-picker" />
<input type="range" id="alpha-picker" value="1" min="0" max="1" step="0.01"/><span id="alpha-value">1</span>
<pre id="code-output">
</pre>
<svg>
<filter id="picked-filter"></filter>
</svg>
<p id="emojis"></p>
请注意目前,此解决方案的浏览器支持非常有限。要查看此功能支持的浏览器的完整列表,请参阅 here。
Nick Parsons 的 SVG 矩阵解决方案也可以使用 data:
方案转换为 in-line 解决方案:
filter: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0'/></filter></svg>#f");
color-interpolation-filters='sRGB'
是因为一些浏览器使用不同的默认颜色 space.
我还建议添加灰度滤镜,否则如果使用纯色,某些表情符号会失去对比度:
filter: grayscale(100%) url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0'/></filter></svg>#f");
灰度滤镜也可以用矩阵来表示并合并到SVG数据中。这是一个应该比 CSS 提供的更符合人类感知的:
filter: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='linearRGB' type='matrix' values='0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0'/><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0'/></filter></svg>#f");
最后,这里是一些 PHP 代码,它根据给定的颜色生成矩阵(输入为 CSS hex-based 颜色代码):
function matrixcolor($hex)
{
list($r, $g, $b) = array_map(function($c) {return $c / 255 / 3;}, sscanf($hex, "#%02x%02x%02x"));
return "$r $r $r 0 0 $g $g $g 0 0 $b $b $b 0 0";
}
function colormatrix($col)
{
return "url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix color-interpolation-filters='linearRGB' type='matrix' values='0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0'/><feColorMatrix color-interpolation-filters='sRGB' type='matrix' values='".matrixcolor($col)." 0 0 0 1 0'/></filter></svg>#f\")";
}