2016-04-13 4 views
1

Я пытаюсь нарисовать карту прокрутки досягаемости моего веб-сайта, используя холст. У меня есть координаты координаты Y и количество посетителей, достигших точки. Я раскрашиваю каждую координату, используя количество посетителей, достигших точки. Скажем,Плавный переход цвета между несколькими остановками цвета

10 пользователей посещают мой сайт.

5 пользователей прокрутки ДО = 0, 300px 3 пользователей прокрутки ДО = 300, 700px 2 пользователей прокрутки ДО = 700, 800px

Теперь у меня есть 3 цвета остановки (300, 700, 800) точек, соответственно, , И раскраска должна основываться на количестве пользователей. Я сделал это, но переход между остановками плавный, он выглядит солидно.

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> 

Выход выше функции

enter image description here

Ожидаемые результаты

enter image description here

Я пробовал использовать линейный градиент, но смешение цветов очень плохое.

Линейный градиент

https://jsfiddle.net/bdxeca48/2/

+1

... что желаемый результат/вопрос? –

+0

Проблема: 1. Переход между цветом не очень хорош. 2. Как остановить цвет @ правильной точкой y. Выход: Мне нужен выход, как изображение прилагается. – kannanrbk

+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); 
} 

Результат: Result

Вот демо: https://jsfiddle.net/4n294hb1/

+0

Я уже пробовал это, но цветное смешивание очень плохое. https://jsfiddle.net/bdxeca48/2/ – kannanrbk

+0

Ох я знаю почему. код – Nasso

+0

Просто добавьте одиночную остановку цвета в «середине» каждого шага. – Nasso

0

Fiddle здесь: 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; 
} 
Смежные вопросы