{"id":153,"date":"2024-08-14T06:34:30","date_gmt":"2024-08-14T06:34:30","guid":{"rendered":"https:\/\/research.binus.ac.id\/geoecoai\/?p=153"},"modified":"2024-08-14T06:49:28","modified_gmt":"2024-08-14T06:49:28","slug":"adding-color-palette-and-opacity-slider-to-map","status":"publish","type":"post","link":"https:\/\/research.binus.ac.id\/geoecoai\/2024\/08\/14\/adding-color-palette-and-opacity-slider-to-map\/","title":{"rendered":"6. Adding Color Palette and Opacity Slider to Map"},"content":{"rendered":"<p>In this tutorial, we&#8217;ll enhance your Leaflet map on the geospatial dashboard by adding two interactive features: a color palette for selecting colors and an opacity slider for adjusting transparency. These features allow users to dynamically customize the appearance of map layers in real-time, improving the interactivity and flexibility of your map.<\/p>\n<h2>Prerequisites<\/h2>\n<p>Before you begin, ensure you have:<\/p>\n<ul>\n<li>A Leaflet map set up<\/li>\n<li>Basic React.js setup<\/li>\n<li><code>nouislider<\/code> and <code>leaflet<\/code> installed<\/li>\n<\/ul>\n<p>If <code>nouislider<\/code> is not installed, you can add it using npm:<\/p>\n<div class=\"dark bg-gray-950 rounded-md border-[0.5px] border-token-border-medium\">\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"!whitespace-pre hljs language-bash\">npm install nouislider<br \/>\n<\/code><\/div>\n<div dir=\"ltr\"><\/div>\n<\/div>\n<h2>1. Setting Up the Color Picker and Opacity Slider<\/h2>\n<p>We will create a custom Leaflet control that integrates both a color picker and an opacity slider. Here\u2019s the code to define this control:<\/p>\n<div class=\"dark bg-gray-950 rounded-md border-[0.5px] border-token-border-medium\">\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"!whitespace-pre hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> L <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'leaflet'<\/span>;<br \/>\n<span class=\"hljs-keyword\">import<\/span> noUiSlider <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'nouislider'<\/span>;<br \/>\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">'nouislider\/dist\/nouislider.css'<\/span>;<br \/>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-title class_\">ColorPickerControl<\/span> = L.<span class=\"hljs-property\">Control<\/span>.<span class=\"hljs-title function_\">extend<\/span>({<br \/>\n    <span class=\"hljs-attr\">slider<\/span>: <span class=\"hljs-literal\">null<\/span>,<br \/>\n    <span class=\"hljs-attr\">onAdd<\/span>: <span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">map<\/span>) {<br \/>\n        <span class=\"hljs-comment\">\/\/ Create container element for color picker and slider<\/span><br \/>\n        <span class=\"hljs-keyword\">var<\/span> container = L.<span class=\"hljs-property\">DomUtil<\/span>.<span class=\"hljs-title function_\">create<\/span>(<span class=\"hljs-string\">'div'<\/span>, <span class=\"hljs-string\">'leaflet-bar leaflet-control'<\/span>);<br \/>\n        container.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">display<\/span> = <span class=\"hljs-string\">'flex'<\/span>; <span class=\"hljs-comment\">\/\/ Set display to flex for layout<\/span><\/p>\n<p>        <span class=\"hljs-comment\">\/\/ Create color picker input element<\/span><br \/>\n        <span class=\"hljs-keyword\">var<\/span> colorPicker = <span class=\"hljs-variable language_\">document<\/span>.<span class=\"hljs-title function_\">createElement<\/span>(<span class=\"hljs-string\">'input'<\/span>);<br \/>\n        colorPicker.<span class=\"hljs-property\">type<\/span> = <span class=\"hljs-string\">'color'<\/span>;<br \/>\n        colorPicker.<span class=\"hljs-property\">id<\/span> = <span class=\"hljs-string\">'color-picker'<\/span>; <span class=\"hljs-comment\">\/\/ ID for styling or event handling<\/span><br \/>\n        colorPicker.<span class=\"hljs-property\">title<\/span> = <span class=\"hljs-string\">'Choose Color'<\/span>;<br \/>\n        colorPicker.<span class=\"hljs-property\">value<\/span> = <span class=\"hljs-string\">'#0000ff'<\/span>;<\/p>\n<p>        <span class=\"hljs-comment\">\/\/ Create opacity slider container<\/span><br \/>\n        <span class=\"hljs-keyword\">var<\/span> opacitySliderContainer = <span class=\"hljs-variable language_\">document<\/span>.<span class=\"hljs-title function_\">createElement<\/span>(<span class=\"hljs-string\">'div'<\/span>);<br \/>\n        opacitySliderContainer.<span class=\"hljs-property\">id<\/span> = <span class=\"hljs-string\">'opacity-pick'<\/span>;<br \/>\n        opacitySliderContainer.<span class=\"hljs-property\">title<\/span> = <span class=\"hljs-string\">'Choose Opacity'<\/span>;<br \/>\n        opacitySliderContainer.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">marginLeft<\/span> = <span class=\"hljs-string\">'10px'<\/span>; <span class=\"hljs-comment\">\/\/ Margin to separate from color picker<\/span><br \/>\n        opacitySliderContainer.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">width<\/span> = <span class=\"hljs-string\">'150px'<\/span>;<br \/>\n        opacitySliderContainer.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">height<\/span> = <span class=\"hljs-string\">'15px'<\/span>;<br \/>\n        opacitySliderContainer.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">marginTop<\/span> = <span class=\"hljs-string\">'8px'<\/span>;<br \/>\n        opacitySliderContainer.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">marginRight<\/span> = <span class=\"hljs-string\">'5px'<\/span>;<\/p>\n<p>        <span class=\"hljs-comment\">\/\/ Append color picker and opacity slider container to container<\/span><br \/>\n        container.<span class=\"hljs-title function_\">appendChild<\/span>(colorPicker);<br \/>\n        container.<span class=\"hljs-title function_\">appendChild<\/span>(opacitySliderContainer);<br \/>\n        <span class=\"hljs-comment\">\/\/ Initialize noUiSlider<\/span><br \/>\n        <span class=\"hljs-variable language_\">this<\/span>.<span class=\"hljs-property\">slider<\/span> = noUiSlider.<span class=\"hljs-title function_\">create<\/span>(opacitySliderContainer, {<br \/>\n            <span class=\"hljs-attr\">start<\/span>: <span class=\"hljs-number\">0.2<\/span>, <span class=\"hljs-comment\">\/\/ Initial value<\/span><br \/>\n            <span class=\"hljs-attr\">range<\/span>: {<br \/>\n                <span class=\"hljs-string\">'min'<\/span>: <span class=\"hljs-number\">0<\/span>,<br \/>\n                <span class=\"hljs-string\">'max'<\/span>: <span class=\"hljs-number\">1<\/span><br \/>\n            },<br \/>\n            <span class=\"hljs-attr\">step<\/span>: <span class=\"hljs-number\">0.1<\/span>, <span class=\"hljs-comment\">\/\/ Step size<\/span><br \/>\n            <span class=\"hljs-attr\">connect<\/span>: [<span class=\"hljs-literal\">true<\/span>, <span class=\"hljs-literal\">false<\/span>], <span class=\"hljs-comment\">\/\/ Connect the slider handle<\/span><br \/>\n        });<\/p>\n<p>        <span class=\"hljs-comment\">\/\/ Set CSS rules for slider handle<\/span><br \/>\n        <span class=\"hljs-variable language_\">this<\/span>.<span class=\"hljs-property\">slider<\/span>.<span class=\"hljs-title function_\">on<\/span>(<span class=\"hljs-string\">'update'<\/span>, <span class=\"hljs-keyword\">function<\/span>() {<br \/>\n            <span class=\"hljs-keyword\">var<\/span> handle = opacitySliderContainer.<span class=\"hljs-title function_\">querySelector<\/span>(<span class=\"hljs-string\">'.noUi-handle'<\/span>);<br \/>\n            <span class=\"hljs-keyword\">if<\/span> (handle) {<br \/>\n                handle.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">width<\/span> = <span class=\"hljs-string\">'25px'<\/span>;<br \/>\n                handle.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">height<\/span> = <span class=\"hljs-string\">'25px'<\/span>;<br \/>\n            }<br \/>\n        });<br \/>\n        <span class=\"hljs-comment\">\/\/ Function to update thumb color<\/span><br \/>\n        <span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title function_\">updateThumbColor<\/span>(<span class=\"hljs-params\">color<\/span>) {<br \/>\n            <span class=\"hljs-comment\">\/\/ Set the background color of the slider handle<\/span><br \/>\n            <span class=\"hljs-keyword\">const<\/span> handle = opacitySliderContainer.<span class=\"hljs-title function_\">querySelector<\/span>(<span class=\"hljs-string\">'.noUi-connect'<\/span>);<br \/>\n            <span class=\"hljs-keyword\">if<\/span> (handle) {<br \/>\n                handle.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">backgroundColor<\/span> = color || <span class=\"hljs-string\">'#0040FF'<\/span>;<br \/>\n                handle.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-title function_\">setProperty<\/span>(<span class=\"hljs-string\">'background-color'<\/span>, color || <span class=\"hljs-string\">'#0040FF'<\/span>, <span class=\"hljs-string\">'important'<\/span>);<br \/>\n            }<br \/>\n        }<\/p>\n<p>        <span class=\"hljs-comment\">\/\/ Add event listener to color picker<\/span><br \/>\n        colorPicker.<span class=\"hljs-title function_\">addEventListener<\/span>(<span class=\"hljs-string\">'input'<\/span>, <span class=\"hljs-keyword\">function<\/span>() {<br \/>\n            <span class=\"hljs-keyword\">var<\/span> color = colorPicker.<span class=\"hljs-property\">value<\/span>;<br \/>\n            <span class=\"hljs-title function_\">updateThumbColor<\/span>(color);<br \/>\n        });<\/p>\n<p>        <span class=\"hljs-comment\">\/\/ Function to update opacity value<\/span><br \/>\n        <span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title function_\">updateOpacity<\/span>(<span class=\"hljs-params\">value<\/span>) {<br \/>\n            <span class=\"hljs-keyword\">var<\/span> opacitySlider = <span class=\"hljs-variable language_\">document<\/span>.<span class=\"hljs-title function_\">getElementById<\/span>(<span class=\"hljs-string\">'opacity-pick'<\/span>);<br \/>\n            <span class=\"hljs-keyword\">if<\/span> (opacitySlider) {<br \/>\n                <span class=\"hljs-comment\">\/\/ Change slider color based on opacity value<\/span><br \/>\n                opacitySlider.<span class=\"hljs-property\">style<\/span>.<span class=\"hljs-property\">backgroundColor<\/span> = <span class=\"hljs-string\">'rgba(0, 0, 0, '<\/span> + value + <span class=\"hljs-string\">')'<\/span>;<br \/>\n            }<br \/>\n        }<\/p>\n<p>        <span class=\"hljs-comment\">\/\/ Add event listener to slider<\/span><br \/>\n        <span class=\"hljs-variable language_\">this<\/span>.<span class=\"hljs-property\">slider<\/span>.<span class=\"hljs-title function_\">on<\/span>(<span class=\"hljs-string\">'update'<\/span>, <span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">values<\/span>) {<br \/>\n            <span class=\"hljs-keyword\">var<\/span> opacity = <span class=\"hljs-built_in\">parseFloat<\/span>(values[<span class=\"hljs-number\">0<\/span>]);<br \/>\n            <span class=\"hljs-title function_\">updateOpacity<\/span>(opacity);<br \/>\n        });<br \/>\n        <span class=\"hljs-keyword\">return<\/span> container;<br \/>\n    },<\/p>\n<p>    <span class=\"hljs-attr\">getSliderValue<\/span>: <span class=\"hljs-keyword\">function<\/span>() {<br \/>\n        <span class=\"hljs-keyword\">if<\/span> (<span class=\"hljs-variable language_\">this<\/span>.<span class=\"hljs-property\">slider<\/span>) {<br \/>\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">parseFloat<\/span>(<span class=\"hljs-variable language_\">this<\/span>.<span class=\"hljs-property\">slider<\/span>.<span class=\"hljs-title function_\">get<\/span>());<br \/>\n        }<br \/>\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">null<\/span>;<br \/>\n    },<br \/>\n    <span class=\"hljs-attr\">onRemove<\/span>: <span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">map<\/span>) {<br \/>\n    }<br \/>\n});<br \/>\n<\/code><\/div>\n<div dir=\"ltr\"><\/div>\n<\/div>\n<h2>2. Integrating the Control into Your Leaflet Map<\/h2>\n<p>Once we&#8217;ve created the custom control, the next step is to integrate it into your Leaflet map in your React.js application. Here\u2019s an example of how to do that:<\/p>\n<div class=\"dark bg-gray-950 rounded-md border-[0.5px] border-token-border-medium\">\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"!whitespace-pre hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-title class_\">React<\/span>, { useEffect } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;<br \/>\n<span class=\"hljs-keyword\">import<\/span> L <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'leaflet'<\/span>;<br \/>\n<span class=\"hljs-keyword\">import<\/span> { <span class=\"hljs-title class_\">ColorPickerControl<\/span> } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/ColorPickerControl'<\/span>; <span class=\"hljs-comment\">\/\/ Adjust path as needed<\/span><br \/>\n<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-title function_\">MapComponent<\/span> = () =&gt; {<br \/>\n    <span class=\"hljs-title function_\">useEffect<\/span>(<span class=\"hljs-function\">() =&gt;<\/span> {<br \/>\n        <span class=\"hljs-comment\">\/\/ Initialize the Leaflet map<\/span><br \/>\n        <span class=\"hljs-keyword\">const<\/span> map = L.<span class=\"hljs-title function_\">map<\/span>(<span class=\"hljs-string\">'map'<\/span>).<span class=\"hljs-title function_\">setView<\/span>([<span class=\"hljs-number\">51.505<\/span>, -<span class=\"hljs-number\">0.09<\/span>], <span class=\"hljs-number\">13<\/span>);<\/p>\n<p>        <span class=\"hljs-comment\">\/\/ Add your base layers here (e.g., OpenStreetMap)<\/span><br \/>\n        L.<span class=\"hljs-title function_\">tileLayer<\/span>(<span class=\"hljs-string\">'https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png'<\/span>).<span class=\"hljs-title function_\">addTo<\/span>(map);<br \/>\n        <span class=\"hljs-comment\">\/\/ Add the custom color picker and opacity slider control<\/span><br \/>\n        L.<span class=\"hljs-property\">control<\/span>.<span class=\"hljs-title function_\">colorPicker<\/span>().<span class=\"hljs-title function_\">addTo<\/span>(map);<\/p>\n<p>    }, []);<\/p>\n<p>    <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"map\"<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">height:<\/span> '<span class=\"hljs-attr\">500px<\/span>', <span class=\"hljs-attr\">width:<\/span> '<span class=\"hljs-attr\">100<\/span>%' }}&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>;<br \/>\n};<br \/>\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-title class_\">MapComponent<\/span>;<br \/>\n<\/code><\/div>\n<div dir=\"ltr\"><\/div>\n<\/div>\n<h2>3. Code Explanation<\/h2>\n<h3>Color Picker<\/h3>\n<ul>\n<li><strong>HTML Input Element<\/strong>: We use the <code>&lt;input type=\"color\"&gt;<\/code> element to allow users to select a color.<\/li>\n<li><strong>Event Listener<\/strong>: Updates the slider\u2019s handle color when a new color is chosen.<\/li>\n<\/ul>\n<h3>Opacity Slider<\/h3>\n<ul>\n<li><strong>noUiSlider<\/strong>: We use this library to create a slider that controls opacity.<\/li>\n<li><strong>CSS Customization<\/strong>: We style the slider handle and the slider background based on the opacity value.<\/li>\n<\/ul>\n<h2>4. Documentation and References<\/h2>\n<ul>\n<li><strong><a href=\"https:\/\/leafletjs.com\/\" target=\"_new\" rel=\"noreferrer noopener\">Leaflet Documentation<\/a><\/strong>: Official documentation for the Leaflet library.<\/li>\n<li><strong><a target=\"_new\" rel=\"noreferrer noopener\">noUiSlider Documentation<\/a><\/strong>: Documentation for the noUiSlider library used for creating sliders.<\/li>\n<li><strong><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/input\/color\" target=\"_new\" rel=\"noreferrer noopener\">Color Picker Documentation<\/a><\/strong>: Reference for the HTML color input element.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we&#8217;ll enhance your Leaflet map on the geospatial dashboard by adding two interactive features: a color palette for selecting colors and an opacity slider for adjusting transparency. These features allow users to dynamically customize the appearance of map layers in real-time, improving the interactivity and flexibility of your map. Prerequisites Before you [&hellip;]<\/p>\n","protected":false},"author":46,"featured_media":167,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-153","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-frontend"],"_links":{"self":[{"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/posts\/153","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/users\/46"}],"replies":[{"embeddable":true,"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/comments?post=153"}],"version-history":[{"count":8,"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/posts\/153\/revisions"}],"predecessor-version":[{"id":170,"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/posts\/153\/revisions\/170"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/media\/167"}],"wp:attachment":[{"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/media?parent=153"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/categories?post=153"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/research.binus.ac.id\/geoecoai\/wp-json\/wp\/v2\/tags?post=153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}