OpenLayers: могу ли я получить цвет, накладывая слои с некоторой непрозрачностью?

У меня есть 2 слоя с некоторой непрозрачностью:

var vectorLayer = new ol.layer.Vector({
    source: vectorSource,
    style: function (feature) {
        return new ol.style.Style({
            fill: new ol.style.Fill({
                color: *some function to get color from data*
            }),
            stroke: new ol.style.Stroke({
                color: 'rgb(23, 23, 23)',
                width: 0.5
            }),
        });
    }
});

vectorLayer.setOpacity(0.7)

и 1 «финальный» слой без непрозрачности:

var finalLayer = new ol.layer.Vector({
source: vectorSource,
    style: function (feature) {
        return new ol.style.Style({
            fill: new ol.style.Fill({
                color: 'rbg(255, 255, 255)'
            }),
            stroke: new ol.style.Stroke({
                color: 'rgb(23, 23, 23)',
                width: 0.5
            }),
        });
    }
});

Итак, цвет, который я получаю в результате, — это результат наложения 3 слоев.

Я пытался получить цвет, используя

R = R1 + (R2 - R1) * Alfa / 255; 
G = G1 + (G2 - G1) * Alfa / 255; 
B = B1 + (B2 - B1) * Alfa / 255;

но цвет, который я получил, был не тот, который я вижу на карте

Цвета двух слоев с непрозрачностью я сохраняю как свойство объекта:

var color1 = feature.get('color1').match(/\d+(\.\d+)?/g).map(Number)

var color2 = feature.get('color2').match(/\d+(\.\d+)?/g).map(Number)

const selectStyle = new ol.style.Style({
    fill: new ol.style.Fill({
        color: function (feature) {
            var color1 = feature.get('color1').match(/\d+(\.\d+)?/g).map(Number)
            var color2 = feature.get('color2').match(/\d+(\.\d+)?/g).map(Number)
            return rbg(???);
        },
    }),
    stroke: new ol.style.Stroke({
        color: 'rgba(30, 210, 255)',
        width: 1,
    }),
});

Я думаю, вы не получаете ожидаемых результатов, потому что OpenLayers по умолчанию отображает слои, используя source-over. Был пример использования других режимов openlayers.org/en/v5.3.0/examples/blend-modes.html который был удален, так как не мог работать в версии 6. В последней версии 9 он снова будет работать jsfiddle.net/k3fy042a, заменив события precompose и postcompose на prerender и postrender. screen может быть это то, чего вы ожидаете?

Mike 26.05.2024 17:10

@Mike screen кажется, это то, что я ожидал, но, глядя на это в сравнении, я вполне доволен текущим режимом наложения, я думал, смогу ли я получить текущий цвет сразу или за этим стоит гораздо больше? Можно ли получить цвет по пикселям с помощью рендеринга canvas?

baeko 26.05.2024 17:54

Вообще-то мне нужно, чтобы он выделял feature при наведении, я просто не знаю, как получить смешанный цвет. Возможно, есть более подходящее решение…

baeko 26.05.2024 17:55
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Любое смешивание с контекстами Canvas 2d немного нестандартно, поскольку оно применяет предварительное альфа-умножение.

Если вы нарисуете rgba(r1, g1, b1, a1) на чистом холсте

затем с помощью source-over нарисуй rgba(r2, g2, b2, a2)

итак результат rgba(r3, g3, b3, a3)

финальная альфа а3 будет

a3 = a1 * (1 - a2) + a2

в то время как значения r3, g3 и b3 можно предсказать с помощью

c3 = (c1 * a1 * (1 - a2) + c2 * a2) / a3

Действуя в обратном порядке, если у вас уже есть R1, G1 и B1 для вашего color1 и вы хотите создать R2, G2 и B2 для вашего color2, значения R, G и B, которые вам нужно будет использовать с непрозрачностью alpha, будут такими:

R = R1 + (R2 - R1) / alpha
G = G1 + (G2 - G1) / alpha
B = B1 + (B2 - B1) / alpha

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

В OpenLayers, возможно, лучше использовать взаимодействие «Выбрать», которое заменяет заливку color1 на заливку color2 при наведении курсора, вместо наложения и попытки смешать другой слой.

Другие вопросы по теме