Возможно ли получить цвет большинства эмодзи? - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь добиться добавления 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 голосов
/ 25 апреля 2018

Альтернативным ответом на предложенный @ Sol является использование атрибута для дублирования значка без необходимости использования JS.Вы также можете применить масштабное преобразование, чтобы сделать эффект более заметным:

.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);
}
<span class="emoji" data-icon="?">?</span>
<span class="emoji" data-icon="?">?</span>
<span class="emoji" data-icon="?">?</span>
<span class="emoji" data-icon="?">?</span>
0 голосов
/ 25 апреля 2018

Подход размытия копии смайликов (предложенный 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>
0 голосов
/ 25 апреля 2018

Альтернативный подход без использования 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>
...