मेरे आवेदन के लिए मैं एक रंग पैलेट बनाना चाहता हूं जो 0 डिग्री से 360 डिग्री तक किसी भी रंग के रंग की सेवा कर सके। मैं वर्तमान में पैलेट बनाने के लिए इस कोड का उपयोग कर रहा हूं। आइए एक उदाहरण के रूप में रंग 120 (शुद्ध हरा) का उपयोग करें:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;

  var grH = ctx.createLinearGradient(0, 0, w, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  var grV = ctx.createLinearGradient(0, 0, 0, h);
  grV.addColorStop(0, 'rgba(0,0,0,0)');
  grV.addColorStop(1, '#000');

  ctx.fillStyle = grV;
  ctx.fillRect(0, 0, w, h);
}

drawPalette(120);
<canvas></canvas>

मेरे पास जो मुद्दा है वह यह है कि यह एक आदर्श ढाल प्रतीत नहीं होता है। उदाहरण के लिए, ऊपर दाईं ओर का रंग #00FF00 (शुद्ध हरा) के बजाय #02FF02 है। आप इसे अपने लिए देखने के लिए रंग बीनने वाले का उपयोग कर सकते हैं।

क्या रंग पैलेट के लिए प्रयोग करने योग्य एक पूर्ण रैखिक ढाल बनाने का कोई तरीका है?

3
Ryan Peschel 9 जिंदा 2021, 07:26
आपको कैसे पता चला कि यह #02FF02 है? ऐसा लगता है कि यह ऊपर दाईं ओर (बहुत कोने में) शुद्ध हरा है
 – 
hashBender
9 जिंदा 2021, 08:09
मैंने एक स्क्रीनशॉट लिया और देखने के लिए एक बाहरी आईड्रॉपर कलर पिकर टूल का उपयोग किया
 – 
Ryan Peschel
9 जिंदा 2021, 08:16
उस विधि से, आपको सटीक परिणाम नहीं मिल सकता है
 – 
hashBender
9 जिंदा 2021, 19:26

1 उत्तर

सबसे बढ़िया उत्तर

नहीं, ग्रेडिएंट सही परिणाम दे रहा है। शीर्ष दायां पिक्सेल ग्रेडिएंट के प्रारंभ और अंत बिंदुओं के बीच है, और इसे प्रतिबिंबित करने के लिए एक प्रक्षेपित मान है।

एक क्षैतिज या लंबवत ढाल वाले एकल पिक्सेल कैनवास की कल्पना करें। ग्रेडिएंट का प्रारंभ बिंदु [0,0] है और ग्रेडिएंट का अंत [1,0] है। हमारे एकमात्र पिक्सेल के मध्य में प्रारंभ और अंत मानों के बीच का मान आधा होना चाहिए। यदि हमारा प्रारंभ मान 255,255,255 है और अंतिम मान 0,255,0 है, तो एकमात्र पिक्सेल 128,255,128 होना चाहिए, जैसा कि नीचे देखा गया है:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;

  var grH = ctx.createLinearGradient(0, 0, w, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  
  let data = ctx.getImageData(w-1,0, 1, 1).data;
  console.log(data);

}

drawPalette(120);
<canvas width="1" height="1"></canvas>

यदि हमारे पास दस पिक्सेल गुणा दस पिक्सेल कैनवास है, तो ग्रेडिएंट 0 से 10 तक फैला है, जिसमें पिक्सेल के अंतिम स्तंभ का मध्य 9.5 पिक्सेल से अधिक है। जिसका अर्थ है, ग्रेडिएंट का प्रक्षेपित मान, ग्रेडिएंट के प्रारंभ और अंत मानों के बीच के रास्ते का ९५% होना चाहिए। ऊपर के समान ढाल का उपयोग करना, वह होना चाहिए: १३, २५५, १३:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;

  var grH = ctx.createLinearGradient(0, 0, w, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  
  let data = ctx.getImageData(w-1,0, 1, 1).data;
  console.log(data);

}

drawPalette(120);
<canvas width="10" height="10"></canvas>

जैसे-जैसे कैनवास बड़ा होता जाता है, लागू ग्रेडिएंट के साथ पहले/अंतिम मानों और ग्रेडिएंट प्रारंभ/समाप्ति मानों के बीच का अंतर कम होता जाता है। यदि आप अपने उदाहरण में कैनवास को 1000x1000 के आकार में बदलते हैं, तो गोल करने के कारण शीर्ष दाएं पिक्सेल का मान 0,255,0 होगा:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;

  var grH = ctx.createLinearGradient(0, 0, w, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  var grV = ctx.createLinearGradient(0, 0, 0, h);
  grV.addColorStop(0, 'rgba(0,0,0,0)');
  grV.addColorStop(1, '#000');

  ctx.fillStyle = grV;
  ctx.fillRect(0, 0, w, h);
  
  let data = ctx.getImageData(w-1,0, 1, 1).data;
  console.log(data);
  
}

drawPalette(120);
<canvas width="1000" height="1000"></canvas>

ग्रेडिएंट में प्रारंभ और अंत बिंदुओं के बीच के पिक्सेल शामिल होते हैं। यदि आप नहीं चाहते कि वे ग्रेडिएंट-आइज़्ड हों, तो आपको ग्रेडिएंट को संशोधित करना होगा ताकि यह एक पिक्सेल बाद में शुरू हो और एक पिक्सेल जल्दी समाप्त हो जाए:

function drawPalette(hue) {
  var ctx = document.querySelector("canvas").getContext("2d");

  let w = ctx.canvas.width;
  let h = ctx.canvas.height;
  
  // to ensure we know we're covering the whole thing:
  ctx.fillRect(0,0,w,h)
  //

  var grH = ctx.createLinearGradient(1, 0, w-2, 0);
  grH.addColorStop(0, '#fff');
  grH.addColorStop(1, 'hsl(' + hue + ', 100%, 50%)');

  ctx.fillStyle = grH;
  ctx.fillRect(0, 0, w, h);

  
  let data = ctx.getImageData(w-1,0, 1, 1).data;
  console.log(data);

}

drawPalette(120);
<canvas width="100" height="100"></canvas>
3
Andrew Reid 9 जिंदा 2021, 09:12
छोटे कैनवास आकारों पर प्रक्षेपित मान के बारे में सही है (मुझे 600x300 कैनवास के साथ 00FF00 मिला)। Google का कलर पिकर वही काम करता है जो आपका है, कोना हरा FE है बल्कि एफएफ की तुलना में - रंग पैलेट के लिए आपको डिस्प्ले के सही होने की आवश्यकता क्यों है? Google मूल्य की गणना करने के लिए चयनकर्ता का उपयोग करता है और चयनकर्ता पूर्ण FF मान पर जाता है।
 – 
Rich DeBourke
9 जिंदा 2021, 09:30
मुझे लगता है कि मुझे सही होने के लिए ढाल की आवश्यकता नहीं है, लेकिन फिर मुझे चयनित रंग क्या है यह निर्धारित करने के लिए getImageData का उपयोग करने के बजाय "उचित" मान की गणना करने के लिए अपना कोड बदलने की आवश्यकता है।
 – 
Ryan Peschel
9 जिंदा 2021, 09:41