一. 介绍
二. 绘制
方法一
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/*假设点坐标为aXY,二维数组*/
var aXY = [ [x1 , y1 ] , [x2 , y2 ] , [x3 , y3 ] , [x4 , y4 ]... ] ; //获取canvas的context var context = canvas. getContext ( '2d' ) ; var pi2 = Math. PI * 2 ; //设置填充样式,透明度为0.1 context. fillStyle = 'rgba(255,30,0,0.1)' ; for ( var i = 0 , len = aXY. length ; i < len ; i ++ ) { var x = aXY [i ] [0 ] , y = aXY [i ] [1 ] ; context. beginPath ( ) ; //绘制圆点 context. arc (x , y , 6 , 0 , pi2 , true ) ; context. closePath ( ) ; context. fill ( ) ; } //获取这个画布的位数据 var imgd = context. getImageData (0 , 0 , 1200 , 2000 ) ; var pix = imgd. data ; // 循环计算rgb,使之根据alpha值映射到红蓝渐变 for ( var i = 0 , n = pix. length ; i < n ; i += 4 ) { //位数据的格式为[rgbargbargba……],每个rgba代表了每个点的rgba四个通道的值 var a = pix [i +3 ] ; //alpha //red pix [i ] = 128 * Math. sin ( (1 / 256 * a - 0.5 ) * Math. PI ) + 200 ; //green pix [i +1 ] = 128 * Math. sin ( (1 / 128 * a - 0.5 ) * Math. PI ) + 127 ; //blue,128之后直接衰减为0 pix [i +2 ] = 256 * Math. sin ( (1 / 256 * a + 0.5 ) * Math. PI ) ; pix [i +3 ] = pix [i +3 ] * 0.8 ; } context. putImageData (imgd , 0 , 0 ) ; |
1
2 3 4 5 6 7 8 9 10 11 12 13 |
var aXY
=
[
[x1
, y1
]
,
[x2
, y2
]
,
[x3
, y3
]
,
[x4
, y4
]...
]
;
var context = canvas. getContext ( '2d' ) ; for ( var i = 0 , len = aXY. length ; i < len ; i ++ ) { var x = aXY [i ] [0 ] , y = aXY [i ] [1 ] ; //绘制径向渐变 var radgrad = this. context. createRadialGradient (x , y , 1 , x , y , 8 ) ; //锚点 radgrad. addColorStop ( 0 , 'rgba(255,30,0,1)' ) ; //锚点 radgrad. addColorStop ( 1 , 'rgba(255,30,0,0)' ) ; context. fillStyle = radgrad ; context. fillRect ( x - 8 , y - 8 , 16 , 16 ) ; } |
方法二
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
var points
=
[
[x1
, y1
]
,
[x2
, y2
]
,
[x3
, y3
]
,
[x4
, y4
]...
]
;
var cache = { } ; //计算每个点的密度 for ( var i = 0 , len = points. length ; i < len ; i ++ ) { for ( var j = 0 , len2 = points [i ]. length ; j < len2 ; j ++ ) { var key = points [i ] [j ] [ 0 ] + '*' + points [i ] [j ] [1 ] ; if (cache [key ] ) { cache [key ] ++; } else { cache [key ] = 1 ; } } } //点数据还原 var oData = [ ] ; for ( var m in cache ) { if (m == '0*0' ) continue ; var x = parseInt (m. split ( '*' ) [0 ] , 10 ) ; var y = parseInt (m. split ( '*' ) [1 ] , 0 ) ; oData. push ( [x , y , cache [m ] ] ) ; } //简单排序,使用数组内建的sort oData. sort ( function (a , b ) { return a [2 ] - b [2 ] ; } ) ; var max = oData [oData. length - 1 ] [2 ] ; var pi2 = Math. PI * 2 ; //设置阈值,可以过滤掉密度极小的点 var threshold = this._points_min_threshold * max ; //alpha增强参数 var pr = (Math. log (245 ) -1 ) / 245 ; for ( var i = 0 , len = oData. length ; i < len ; i ++ ) { if (oData [i ] [2 ] 0 ? 0 : 1 ) ; //q参数用于平衡梯度差,使之符合人的感知曲线log2N,如需要精确梯度,去掉log计算 var q = parseInt (Math. log (oData [i ] [2 ] ) / Math. log (max ) * 255 ) ; var r = parseInt (128 * Math. sin ( (1 / 256 * q - 0.5 ) * Math. PI ) + 200 ) ; var g = parseInt (128 * Math. sin ( (1 / 128 * q - 0.5 ) * Math. PI ) + 127 ) ; var b = parseInt (256 * Math. sin ( (1 / 256 * q + 0.5 ) * Math. PI ) ) ; var alp = (0.92 * q + 20 ) / 255 ; //如果需要灰度增强,则取消此行注释 //var alp = (Math.exp(pr * q + 1) + 10) / 255 var radgrad = this. context. createRadialGradient (oData [i ] [0 ] , oData [i ] [1 ] , 1 , oData [i ] [0 ] ,oData [i ] [1 ] , 8 ) ; radgrad. addColorStop ( 0 , 'rgba(' + r + ',' + g + ',' + b + ',' + alp + ')' ) ; radgrad. addColorStop ( 1 , 'rgba(' + r + ',' + g + ',' + b + ',0)' ) ; this. context. fillStyle = radgrad ; this. context. fillRect ( oData [i ] [0 ] - 8 , oData [i ] [1 ] - 8 , 16 , 16 ) ; } |