Javascript 绘制滚动地图的最佳方法

Javascript 绘制滚动地图的最佳方法,javascript,html,canvas,linear-gradients,processing.js,Javascript,Html,Canvas,Linear Gradients,Processing.js,我想在canvas上画一个scrollmap,它有一堆Y坐标 这样做最有效的方法是什么?我想带一些平均点的梯度是最好的方法,但我不知道怎么做 我现在想做的是用red填充画布,然后从顶部到Y坐标绘制green矩形。如果矩形有一定程度的透明度,应该会产生一个相当体面的滚动热图 还有其他想法吗?或者如果有人知道如何实现梯度,那就太好了 如果您不知道,滚动地图应该如下所示: 根据评论中的附加信息,您可能希望使用装箱方法。如果我们将页面分为X个高度区域(每个区域的高度为pageheight的1/X倍),那

我想在
canvas
上画一个
scrollmap
,它有一堆
Y
坐标

这样做最有效的方法是什么?我想带一些平均点的梯度是最好的方法,但我不知道怎么做

我现在想做的是用
red
填充画布,然后从顶部到
Y
坐标绘制
green
矩形。如果矩形有一定程度的透明度,应该会产生一个相当体面的滚动热图

还有其他想法吗?或者如果有人知道如何实现梯度,那就太好了

如果您不知道,滚动地图应该如下所示:


根据评论中的附加信息,您可能希望使用装箱方法。如果我们将页面分为X个高度区域(每个区域的高度为pageheight的1/X倍),那么我们可以简单地根据用户最终滚动高度的“bin”进行计数。在JSE伪代码中:

var X = 5, bins = [], idx;
userScrollHeights.forEach(function(Y) {
  idx = Math.floor(map(Y, 0, pageHeight, 0, X));
  bins[id] = bins[idx] ? bins[idx]++ : 1;
});
标准JS API中奇怪地缺少映射函数,但很容易实现为:

function map(value, istart, istop, ostart, ostop) {
  return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
}
“箱子”数组现在包含每个箱子的“强度”。你选择的箱子越多,你的滚动地图就越精确

当然,基本的滚动贴图不是彩色的,它只是强度,所以它更自然地是由白到黑的叠加。如果您确实想要一个彩色贴图,将“最高强度”映射为红色,将“最低强度”映射为紫色,则可以使用具有255个存储箱的设置,在找到最大强度后,只需将每个强度级别映射为颜色值:

var bin_max = 0;
bins.forEach(function(value) {
  if(value > bin_max) bin_max= value;
});
然后是基于“彩虹”渐变中的五个切片的颜色映射:

function mapIntensityToColor(intensity, min, max) {
  var cint = map(intensity,min,max,0,255);
  var step = (max - min) / 5;
  if(cint > 204) 
    return [255, map(intensity, max-step,max, 255,0), 0];
  if(cint > 153) 
    return [map(intensity, max-2*step,max-step, 0,255), 255, 0];
  if(cint > 102) 
    return [0, 255, map(intensity, max-3*step,max-2*step, 255,0)];
  if(cint > 51)
    return [0, map(intensity, max-4*step,max-3*step, 0,255), 255];
  return [map(intensity, min,max-4*step, 255,0), 0, 255];
}

将画布(或div)分割为255个步骤,并根据
mapIntensityToColor(bin[step\u number],0,bin\u max)
为每个步骤上色,现在应该可以为您提供准确的滚动地图。

根据注释中的其他信息,您可能希望使用分格方法。如果我们将页面分为X个高度区域(每个区域的高度为pageheight的1/X倍),那么我们可以简单地根据用户最终滚动高度的“bin”进行计数。在JSE伪代码中:

var X = 5, bins = [], idx;
userScrollHeights.forEach(function(Y) {
  idx = Math.floor(map(Y, 0, pageHeight, 0, X));
  bins[id] = bins[idx] ? bins[idx]++ : 1;
});
标准JS API中奇怪地缺少映射函数,但很容易实现为:

function map(value, istart, istop, ostart, ostop) {
  return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
}
“箱子”数组现在包含每个箱子的“强度”。你选择的箱子越多,你的滚动地图就越精确

当然,基本的滚动贴图不是彩色的,它只是强度,所以它更自然地是由白到黑的叠加。如果您确实想要一个彩色贴图,将“最高强度”映射为红色,将“最低强度”映射为紫色,则可以使用具有255个存储箱的设置,在找到最大强度后,只需将每个强度级别映射为颜色值:

var bin_max = 0;
bins.forEach(function(value) {
  if(value > bin_max) bin_max= value;
});
然后是基于“彩虹”渐变中的五个切片的颜色映射:

function mapIntensityToColor(intensity, min, max) {
  var cint = map(intensity,min,max,0,255);
  var step = (max - min) / 5;
  if(cint > 204) 
    return [255, map(intensity, max-step,max, 255,0), 0];
  if(cint > 153) 
    return [map(intensity, max-2*step,max-step, 0,255), 255, 0];
  if(cint > 102) 
    return [0, 255, map(intensity, max-3*step,max-2*step, 255,0)];
  if(cint > 51)
    return [0, map(intensity, max-4*step,max-3*step, 0,255), 255];
  return [map(intensity, min,max-4*step, 255,0), 0, 255];
}

将画布(或div)分割为255个步骤,并根据
mapIntensityToColor(bin[step_number],0,bin_max)
为每个步骤上色,现在应该可以为您提供准确的滚动地图。

为什么要使用画布,而不是使用css3渐变背景()和不透明度为0.3的常规100%高/宽div,难道
canvas
方法不比使用javaScript生成跨设备
CSS3
渐变更容易编码吗?通过使用CSS渐变,我必须为所有浏览器替换所有停止点的位置。我知道坡度或IE有超过2个停止点的情况非常糟糕,特别是如果其中一些点重合的话。好的观点,我也会尝试。(我要求使用canvas,因为我已经将canvas与heatmap.js一起使用,因此,
canvas
已经存在,我只需要在上面绘制渐变…而且真正的问题不是
如何绘制渐变,而是如何通过拥有多个
Y
高度来找到渐变的停止点。这取决于你想要的目标。你想做什么你有一个“它应该在…中工作”和“理想情况下也在…”的列表。例如,css3渐变在所有当前的gen桌面浏览器中都很容易(ie10/11将很乐意做多级渐变)。如果你已经有了画布,那么首先要找到RGB初级+次级的停止点,然后进行简单的插值(在两个简单的LERP中执行255/0/0到255/255/0到0/255/0,而不是复杂的颜色插值,使生活变得简单)是的,我知道,但找到这些停止点最相关、最简单的方法是什么?我在考虑对点进行升序排序,然后如果我需要5个停止点,则获取在该排序数组中的位置0、1*NrY/5、2*NrY/5等处找到的5个元素的Y值。但是如果假设所有Y都相同,则无法生成准确的热图。为什么为此,请使用画布,而不是带有css3渐变背景的常规100%高/宽div()不透明度:0.3还是什么?好吧,
canvas
方法不是更容易编码,然后使用javaScript生成跨设备的
CSS3
渐变吗?通过使用CSS渐变,我必须替换所有浏览器的所有停止点的位置。我知道渐变或具有超过2个停止点的IE确实有问题,特别是如果其中的一些点重合的话。尽管这是一个很好的观点,我也会尝试一下。(我要求使用canvas,因为我已经将canvas与heatmap.js一起使用,因此,
canvas
已经存在,我只需要在上面绘制渐变…而且真正的问题不是
如何绘制渐变,而是如何通过拥有多个
Y
高度来找到渐变的停止点。这取决于你想要的目标。你想做什么你有一个“它应该在…中工作”和“理想情况下也在…”的列表。例如,css3渐变在所有当前的gen桌面浏览器中都很容易(ie10/11将很乐意使用多桌面渐变)。如果你已经有了画布,那么只需找到RGB primaries+seconda的停止点