Функция для создания [закрытых] цветовых дисков

Элемент, который вы пытались найти, не был в DOM , когда ваш скрипт работал.

Позиция вашего DOM-зависимого скрипта может оказать глубокое влияние на его поведение. Браузеры анализируют HTML-документы сверху донизу. Элементы добавляются в DOM, и сценарии выполняются (как правило), когда они встречаются. Это означает, что порядок имеет значение. Как правило, скрипты не могут найти элементы, которые появляются позже в разметке, потому что эти элементы еще не добавлены в DOM.

Рассмотрим следующую разметку; сценарий # 1 не находит

, а сценарий # 2 преуспевает:


test div

Итак, что вы должны делать? У вас есть несколько вариантов:


Вариант 1: Переместите свой скрипт

Переместите свой скрипт дальше по странице, перед закрывающим тегом тела. Организованный таким образом остальная часть документа анализируется до того, как будет выполнен ваш скрипт:


  
  

Примечание: размещение скриптов внизу как правило, считается лучшей практикой .


Вариант 2: jQuery's ready()

Отмените свой сценарий до тех пор, пока DOM не будет полностью проанализирован, используя ready() :



Примечание. Вы можете просто привязать к DOMContentLoaded или window.onload, но у каждого есть свои оговорки. jQuery ready() предоставляет гибридное решение.


Вариант 3: Делегирование событий

Делегированные события имеют преимущество в том, что они могут обрабатывать события из элементов-потомков, которые будут добавлены в документ позже.

blockquote>

Когда элемент вызывает событие (при условии, что это bubbling g6], и ничто не останавливает его распространение), каждый родитель в родословной этого элемента также получает событие. Это позволяет нам привязать обработчик к существующему элементу и примерным событиям, когда они пузырятся от его потомков ... даже те, которые добавлены после присоединения обработчика. Все, что нам нужно сделать, это проверить событие, чтобы узнать, был ли он поднят нужным элементом и, если да, запустите наш код.

jQuery on() выполняет эту логику для нас. Мы просто предоставляем имя события, селектор для желаемого потомка и обработчик событий:



Примечание: Обычно этот шаблон зарезервированы для элементов, которые не существовали во время загрузки или , чтобы избежать прикрепления большого количества обработчиков. Также стоит отметить, что, пока я прикреплял обработчик к document (для демонстрационных целей), вы должны выбрать ближайшего надежного предка.


Вариант 4: Атрибут defer

Используйте атрибут defer в

Для справки, вот код из этого внешнего скрипта :

document.getElementById("test").addEventListener("click", function(e){
   console.log("clicked: %o", this); 
});

Примечание: атрибут defer, безусловно, кажется , как волшебная пуля , но важно знать об оговорках ... 1. defer может использоваться только для внешних скриптов, т. е. для тех, у кого есть атрибут src. 2. знать о поддержке браузера , то есть: ошибка реализации в IE & lt; 10

67
задан Rann Lifshitz 30 May 2018 в 13:53
поделиться

6 ответов

Моя первая мысль об этом, "как генерировать векторы N в пространстве, которые максимизируют расстояние друг от друга".

Вы видите, что RGB (или любой другой масштаб, который Вы используете, который формирует основание в цветовом пространстве) является просто векторами. Смотрите на Случайная точка, Выбирающая . Как только у Вас есть ряд векторов, которые максимизируются независимо, можно сохранить их в хэш-таблице или чем-то на потом, и просто выполнить случайные вращения на них для получения всех цветов, Вы требуете, чтобы были максимально друг кроме друга!

Взгляды об этой проблеме больше, было бы лучше отобразить цвета линейным способом, возможно (0,0,0) в †’ (255,255,255) лексикографически, и затем распределить их равномерно.

я действительно не знаю, как хорошо это будет работать, но это должно с тех пор, позволять нам сказать:

n = 10

мы знаем, что у нас есть 16 777 216 цветов (256^3).

Мы можем использовать Алгоритм Застежек 515 для нахождения лексикографически индексированного цвета. \frac {\binom {256^3} {3}} {n} * i . Необходимо будет, вероятно, отредактировать алгоритм, чтобы избежать переполнения и вероятно добавить некоторые незначительные улучшения скорости.

24
ответ дан Rann Lifshitz 24 November 2019 в 14:44
поделиться

Было бы лучше найти цвета максимально удаленными в "перцепционно универсальном" цветовом пространстве, например, CIELAB (использующий Евклидово расстояние между L**, b* координаты как Ваша метрика расстояния) и затем преобразовывающий в цветовое пространство по Вашему выбору. Перцепционная однородность достигается путем тонкой настройки цветового пространства для приближения нелинейности в зрительной системе человека.

18
ответ дан Jeff Holt 24 November 2019 в 14:44
поделиться

Некоторые связанные ресурсы:

ColorBrewer - Наборы цветов, разработанных, чтобы быть максимально различимым для использования на картах.

Выход RGBland: Выбор Цветов для Статистической Графики - технический отчет, описывающий ряд алгоритмов для генерации хорошего (т.е. максимально различимый) наборы цветов в hcl цветовом пространстве.

8
ответ дан hadley 24 November 2019 в 14:44
поделиться

Вот некоторый код для выделения цветов RGB равномерно вокруг цветового диска HSL указанной яркости.

class cColorPicker
{
public:
    void Pick( vector<DWORD>&v_picked_cols, int count, int bright = 50 );
private:
    DWORD HSL2RGB( int h, int s, int v );
    unsigned char ToRGB1(float rm1, float rm2, float rh);
};
/**

  Evenly allocate RGB colors around HSL color wheel

  @param[out] v_picked_cols  a vector of colors in RGB format
  @param[in]  count   number of colors required
  @param[in]  bright  0 is all black, 100 is all white, defaults to 50

  based on Fig 3 of http://epub.wu-wien.ac.at/dyn/virlib/wp/eng/mediate/epub-wu-01_c87.pdf?ID=epub-wu-01_c87

*/

void cColorPicker::Pick( vector<DWORD>&v_picked_cols, int count, int bright )
{
    v_picked_cols.clear();
    for( int k_hue = 0; k_hue < 360; k_hue += 360/count )
        v_picked_cols.push_back( HSL2RGB( k_hue, 100, bright ) );
}
/**

  Convert HSL to RGB

  based on http://www.codeguru.com/code/legacy/gdi/colorapp_src.zip

*/

DWORD cColorPicker::HSL2RGB( int h, int s, int l )
{
    DWORD ret = 0;
    unsigned char r,g,b;

    float saturation = s / 100.0f;
    float luminance = l / 100.f;
    float hue = (float)h;

    if (saturation == 0.0) 
    {
      r = g = b = unsigned char(luminance * 255.0);
    }
    else
    {
      float rm1, rm2;

      if (luminance <= 0.5f) rm2 = luminance + luminance * saturation;  
      else                     rm2 = luminance + saturation - luminance * saturation;
      rm1 = 2.0f * luminance - rm2;   
      r   = ToRGB1(rm1, rm2, hue + 120.0f);   
      g = ToRGB1(rm1, rm2, hue);
      b  = ToRGB1(rm1, rm2, hue - 120.0f);
    }

    ret = ((DWORD)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)));

    return ret;
}


unsigned char cColorPicker::ToRGB1(float rm1, float rm2, float rh)
{
  if      (rh > 360.0f) rh -= 360.0f;
  else if (rh <   0.0f) rh += 360.0f;

  if      (rh <  60.0f) rm1 = rm1 + (rm2 - rm1) * rh / 60.0f;   
  else if (rh < 180.0f) rm1 = rm2;
  else if (rh < 240.0f) rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f;      

  return static_cast<unsigned char>(rm1 * 255);
}

int _tmain(int argc, _TCHAR* argv[])
{
    vector<DWORD> myCols;
    cColorPicker colpick;
    colpick.Pick( myCols, 20 );
    for( int k = 0; k < (int)myCols.size(); k++ )
        printf("%d: %d %d %d\n", k+1,
        ( myCols[k] & 0xFF0000 ) >>16,
        ( myCols[k] & 0xFF00 ) >>8,
        ( myCols[k] & 0xFF ) );

    return 0;
}
7
ответ дан ravenspoint 24 November 2019 в 14:44
поделиться

Разве это не также фактор, которые приказывают, чтобы Вы настроили цвета?

Как то, если Вы используете идею Dillie-Os, необходимо смешать цвета как можно больше. 0 64 128 256 от одного до следующего. но 0 256 64 128 в колесе был бы больше "независимо"

, это имеет смысл?

3
ответ дан svrist 24 November 2019 в 14:44
поделиться

Я читал где-нибудь, человеческий глаз не может различать меньше чем 4 значения независимо. таким образом, Это - что-то для учета. Следующий алгоритм не компенсирует это.

я не уверен, что это точно, что Вы хотите, но это - один способ случайным образом генерировать неповторяющиеся значения цвета:

(остерегаются, непоследовательный псевдокод вперед)

//colors entered as 0-255 [R, G, B]
colors = []; //holds final colors to be used
rand = new Random();

//assumes n is less than 16,777,216
randomGen(int n){
   while (len(colors) < n){
      //generate a random number between 0,255 for each color
      newRed = rand.next(256);
      newGreen = rand.next(256);
      newBlue = rand.next(256);
      temp = [newRed, newGreen, newBlue];
      //only adds new colors to the array
      if temp not in colors {
         colors.append(temp);
      }
   }
}

Один способ, которым Вы могли оптимизировать, это для лучшей видимости должно будет сравнить расстояние между каждым новым цветом и всеми цветами в массиве:

for item in color{
   itemSq = (item[0]^2 + item[1]^2 + item[2]^2])^(.5);
   tempSq = (temp[0]^2 + temp[1]^2 + temp[2]^2])^(.5);
   dist = itemSq - tempSq;
   dist = abs(dist);
}
//NUMBER can be your chosen distance apart.
if dist < NUMBER and temp not in colors {
   colors.append(temp);
}

, Но этот подход значительно замедлил бы Ваш алгоритм.

Иначе должен был бы фрагментировать случайность и систематически проходить каждые 4 значения и добавлять цвет к массиву в вышеупомянутом примере.

1
ответ дан helloandre 24 November 2019 в 14:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: