是否有可能获得表情符号的多数颜色?

时间:2018-04-24 23:36:46

标签: javascript css css3 shadow emoji

我想要实现的是将text-shadow添加到表情符号中,text-shadow颜色是表情符号中最突出的颜色。

我知道有一些JavaScript库可以识别图像中最突出的颜色,但由于表情符号在技术上是文字的,我不知道我是怎么做的,或者即使它完全可能。

我会提供一些我已经尝试过的代码,但老实说,我甚至不知道从哪里开始。

.emoji {
  text-shadow: 0px 0px 20px rgba(54, 169, 230, 0.65);
  padding: 3px 6px;
  font-size: 24px;
}
<span class="emoji"></span>

3 个答案:

答案 0 :(得分:9)

不使用text-shadow的替代方法是复制表情符号,将其直接放在原始图像后面并将其模糊。

您可以直接在HTML中创建副本,或者如果更容易使用js,则如下例所示。

var emoji = document.querySelector("#blur-me");
var copy = emoji.cloneNode(true);
copy.classList.remove("emoji");
emoji.appendChild(copy);
.emoji {
  padding: 3px 6px;
  font-size: 24px;
  position: relative;
  display: inline-block;
}

.emoji span {
  position: absolute;
  left: 6px;
  z-index: -1;
  filter: blur(10px);
}
<span class="emoji" id="blur-me"></span>

答案 1 :(得分:7)

@Sol提议的另一个答案是使用属性来复制图标而不需要JS。您还可以应用缩放转换以使效果更加明显:

&#13;
&#13;
.emoji {
  padding: 3px 6px;
  margin:0 5px;
  font-size: 24px;
  position: relative;
  display: inline-block;
  z-index: 0;
}

.emoji:before {
  content: attr(data-icon);
  position: absolute;
  z-index: -1;
  filter: blur(3px);
  transform: scale(1.5);
}
&#13;
<span class="emoji" data-icon=""></span>
<span class="emoji" data-icon=""></span>
<span class="emoji" data-icon=""></span>
<span class="emoji" data-icon=""></span>
&#13;
&#13;
&#13;

答案 2 :(得分:2)

模糊表情符号副本的方法(由sol提出)是一种有效且相当轻量级的方法。稍微调整一下你可以获得更像阴影的东西:

var emoji = document.querySelector("#blur-me");
var copy = emoji.cloneNode(true);
copy.classList.remove("emoji");
emoji.appendChild(copy);
.emoji {
  padding: 3px 6px;
  font-size: 24px;
  position: relative;
  display: inline-block;
}

.emoji span {
  position: absolute;
  left: 6px;
  z-index: -1;
  filter: blur(5px);
  transform: scale(.95) translate(5px, 5px);
}
<span class="emoji" id="blur-me"></span>

scale(.95)是为了弥补增长它的模糊,然后translate()只是将它转移到更像文字阴影而不像模糊。

另一种让你获得更准确颜色的方法是将它绘制到画布上。一旦你有一个画布,它基本上是一个图像,所以你提到的那些库可以工作。

const canvas = document.querySelector('canvas');
canvas.width = 30;
canvas.height = 30;
const ctx = canvas.getContext('2d');
ctx.font = "20px Arial";
ctx.fillText("", 0, 20);
canvas {
  border: 1px solid #000;
}

.emoji {
  text-shadow: rgba(0, 0, 0, .5) 2px 2px 2px;
}
<div class="emoji"></div>
<canvas></canvas>

一旦你有了这个,你可以通过几种不同的方式获得平均值。一种是获取原始像素,排除背景颜色,然后在数学上平均余数。由于帆布是不透明的,你可以使用旧式的技巧来填充一种非常难看的颜色:

const canvas = document.querySelector('canvas');
canvas.width = 30;
canvas.height = 30;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#121212'; // 12 => 17 in decimal
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font = "20px Arial";
ctx.fillText("", 0, 20);

const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// an array in the format [r, g, b, count] decimal
const sums = imageData.data.reduce((r, v, i) => {
   if (v === 18) return r; // our fill color, skip
   if (i % 4 !== 3) { // i % 4 === 3 is transparent, ignoring
     r[i % 4] += v;
     r[3]++;
   }
   
   return r;
}, [0, 0, 0, 0]);

sums[3] = sums[3] / 3; // divide by 3 since we counted each pixel 3 times
const averages = [Math.floor(sums[0] / sums[3]), Math.floor(sums[1] / sums[3]), Math.floor(sums[2] / sums[3])];

// just to see the color
ctx.fillStyle = `rgb(${averages.join(',')})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
canvas {
  border: 1px solid #000;
}

.emoji {
  text-shadow: rgba(0, 0, 0, .5) 2px 2px 2px;
}
<div class="emoji"></div>
<canvas></canvas>

显然,这种特殊算法非常基本且不完美(主要用于演示目的)。还有其他算法或库。如果您致电canvas.toDataUrl(),您甚至可以获得一个值,您可以像大多数图书馆中的图像一样使用。

从那里,只需获取计算出的颜色,然后使用JavaScript将其设置为element.style.textShadow属性。

document.querySelector('.emoji').style.textShadow = 'rgb(255, 0, 0) 2px 2px';
<span class="emoji"></span>