我正在尝试使用画布绘制我网站的Scroll到达地图。我有Y个坐标和到达该点的访客数量。我使用到达该点的访客数量为每个坐标着色。让我们说
有10位用户正在访问我的网站。
5个用户向上滚动= 0,300px 3位用户向上滚动= 300,700px 2位用户向上滚动= 700,800px
现在,我分别有3个色标(300,700,800)px。并且着色应该基于用户数量。我这样做但是停止之间的过渡是平滑的,它看起来很稳固。
var Scroll = function(config, data) {
var container, computed;
this.data = data;
this.config = config;
container = document.querySelector(this.config.container);
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
computed = getComputedStyle(container) || {};
this.canvas.className = 'zarget-scrollmap-canvas';
this.width = this.canvas.width = this.config.width || +(computed.width.replace(/px/, ''));
this.height = this.canvas.height = this.config.height || +(computed.height.replace(/px/, ''));
this.canvas.style.cssText = 'position:absolute; top: 0px; left:0px';
container.appendChild(this.canvas);
var map = function(value, istart, istop, ostart, ostop) {
return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
};
this.mapIntensityToColor = function(intensity, min, max) {
var cint = map(intensity, min, max, 0, 255);
/**
* Based On Rainbow Gradient
*/
if (cint > 204) {
return [255, Math.round(map(intensity, min, max, 255, 0)), 0];
}
if (cint > 153) {
max = (203 / 255 * 100) * (max / 100);
return [Math.round(map(intensity, 0, max, 255, 0)), 255, 0];
}
if (cint > 102) {
max = (153 / 255 * 100) * (max / 100);
return [0, 255, Math.round(map(intensity, 0, max, 255, 0))];
}
if (cint > 0) {
max = (102 / 255 * 100) * (max / 100);
return [0, Math.round(map(intensity, 0, max, 255, 0)), 255];
}
max = (51 / 255 * 100) * (max / 100);
return [0, 0, Math.round(map(intensity, 0, max, 0, 255))];
};
this.draw = function(data) {
var min = 0;
var max = 1300;
var data = [
[0, 50, 1300],
[50, 100, 1100],
[100, 150, 1100],
[150, 200, 1000],
[200, 250, 500],
[250, 300, 400],
[300, 350, 300],
[350, 450, 200],
[450, 500, 400],
[500, 900, 0],
[900, 950, 300],
[950, 3350, 0]
];
var point, startY, endY, alpha, val, color;
this.ctx.globalAlpha = 0.75;
for (var i = 0, l = data.length; i < l; i++) {
point = data[i];
startY = point[0];
endY = point[1];
val = point[2];
color = this.mapIntensityToColor(val, min, max);
this.ctx.fillStyle = "rgb(" + color.join(",") + ")";
this.ctx.fillRect(0, startY, this.width, endY - startY);
}
};};
var a = new Scroll({"container": "#overlay"});
a.draw();
#overlay {
width: 100%;
height: 2000px;
position: absolute;
top: 0px;
left: 0px;
}
<div id="overlay"></div>
以上功能的输出
预期输出
我尝试使用线性渐变,但颜色混合非常差。
线性渐变
答案 0 :(得分:2)
您可以在每个步骤的“中间”使用带有单色停止的线性渐变:
this.draw = function(data) {
var min = 0;
var max = 1300;
var data = [
[0, 50, 1300],
[50, 100, 1100],
[100, 150, 1100],
[150, 200, 1000],
[200, 250, 500],
[250, 300, 400],
[300, 350, 300],
[350, 450, 200],
[450, 500, 400],
[500, 900, 0],
[900, 950, 300],
[950, 3350, 0]
];
var point, startY, endY, alpha, val, color;
this.ctx.globalAlpha = 0.75;
// Calculate the maximum y scrolled
var maxScrollY = 0;
for(var i = 0, l = data.length; i < l; i++){
point = data[i];
if(maxScrollY < point[1]){
maxScrollY = point[1];
}
}
// here, maxScrollY will be 3350
var linearGrad = ctx.createLinearGradient(0, 0, 0, maxScrollY);
// Build the gradient
for (var i = 0, l = data.length; i < l; i++) {
point = data[i];
// You have to divide the coordinate by maxScrollY to get
// coordinates between 0.0 and 1.0
startY = point[0] / maxScrollY;
endY = point[1] / maxScrollY;
// Take the y coordinate between startY and endY for the color stop coordinate
var middleY = startY + (endY-startY)/2;
val = point[2];
color = this.mapIntensityToColor(val, min, max);
linearGrad.addColorStop(middleY, "rgb(" + color.join(",") + ")");
}
// Then just render
ctx.fillStyle = linearGrad;
ctx.fillRect(0, 0, this.width, maxScrollY);
}
答案 1 :(得分:0)
在这里小提琴:https://jsfiddle.net/Lfhdzw2c/
我用这个替换了你的IntensityToColor函数,我借用https://rainbowcoding.com/how-to-create-rainbow-text-in-html-css-javascript/
function color_from_hue(hue)
{
var h = hue/60;
var c = 255;
var x = (1 - Math.abs(h%2 - 1))*255;
var color;
var i = Math.floor(h);
if (i == 0) color = rgb_to_hex(c, x, 0);
else if (i == 1) color = rgb_to_hex(x, c, 0);
else if (i == 2) color = rgb_to_hex(0, c, x);
else if (i == 3) color = rgb_to_hex(0, x, c);
else if (i == 4) color = rgb_to_hex(x, 0, c);
else color = rgb_to_hex(c, 0, x);
return color;
}