1. 程式人生 > >[javascript]canvas 熱點區域圖,框選區域並在區域顯示熱點

[javascript]canvas 熱點區域圖,框選區域並在區域顯示熱點

/*****
 * 作者:jww_dragon@163.com * 依賴: jquery
 * 
 ********************/

var goog = function(tag) {
	this._hotpoint = [];
	this._square = {};
	if (typeof tag === "string") {
		this.canvas = document.getElementById(tag);
	} else {
		this.canvas = tag;
	}
	this.context = this.canvas.getContext('2d');
	this.colorStyle = {};
	this.colorStyle.selectColor = "rgba(255,0,0,0.8)";
	this.colorStyle.selectedColor = "rgba(255,0,0,0.3)";
	this.colorStyle.showColorBG = "rgba(0,0,0,0.2)";
	this.colorStyle.shadowColor = "#000000";
	this.colorStyle.fontStyle = "16px Arial Black";
	this.colorStyle.fontColor = "yellow";
	this.context.shadowOffsetX = 5;
	this.context.shadowOffsetY = 5;
	this.context.shadowBlur = 10;
}

/**
 *換一個id監聽(一般用不到)
 **/
goog.prototype.listen = function(documentId) {
	this.canvas = document.getElementById(documentId);
	this.canvas = document.getElementById(documentId);
	this.context = this.canvas.getContext('2d')
}

/**
 *顏色配置
 * selectColor,selectedColor 框選顏色,預設紅色, showColorBG 展示的背景蒙層色
 * shadowColor 影陰顏色,fontStyle 字型,fontColor 字型顏色
 **/
goog.prototype.setColor = function(type, color) {
	if (typeof color != "undefined" && type != "undefined") {
		this.colorStyle[type] = color;
	}
}

/**
 * 以下是選擇部分
 ***/
goog.prototype.init_mask = function() {
	var position_top = this.canvas.offsetTop;
	var position_left = this.canvas.offsetLeft;
	this.temp_canvas = document.createElement("canvas");
	this.temp_canvas.setAttribute('width', this.canvas.width);
	this.temp_canvas.setAttribute('id', "mask-gogo123");
	this.temp_canvas.setAttribute('height', this.canvas.height);
	this.temp_canvas.setAttribute('style', 'position: absolute;left: '
			+ position_left + 'px;top: ' + position_top + 'px;');
	this.canvas.parentNode.appendChild(this.temp_canvas);
	//return temp_canvas;
}
goog.prototype.drowInitSquare = function(_list) {
	this.context.shadowColor = this.colorStyle.shadowColor;
	this.context.font = this.colorStyle.fontStyle;
	//this.context.strokeStyle=this.colorStyle.fontColor;
	for ( var _i in _list) {
		this.context.fillStyle = this.colorStyle.selectedColor;
		this.context.fillRect(_list[_i].x, _list[_i].y, _list[_i].w,
				_list[_i].h);
		//這裡是業務需求eventName現示出來
		if (!!_list[_i].eventName) {
			this.context.fillStyle = this.colorStyle.fontColor;
			var font_w = (_list[_i].w - this.context
					.measureText(_list[_i].eventName).width) / 2;
			if (font_w < 2)
				font_w = 2;
			this.context.fillText(_list[_i].eventName, _list[_i].x + font_w,
					(_list[_i].y + _list[_i].h / 2 + 4), _list[_i].w - 5);
		}
	}
	this.context.closePath();
}

goog.prototype.selectDetermine = function(opt) {
	if (typeof this.temp_canvas.tempSquare == "undefined") {
		return;
	}
	var select_condtion = {};
	if (typeof opt != "undefined") {
		$.extend(select_condtion, opt);
	}
	this._square = this.temp_canvas.tempSquare;
	this.context.shadowColor = this.colorStyle.shadowColor;
	this.context.fillStyle = this.colorStyle.selectedColor;
	this.context.fillRect(this._square.x, this._square.y, this._square.w,
			this._square.h);
	this.context.closePath();

	//要用到jquery的就這麼一處,如果實在不要jquery就自己寫繼承方法
	$.extend(select_condtion, this._square);
	//可以不要的
	select_condtion.uuid = this._hotpoint.length + "_"
			+ Math.floor(Math.random() * 10000);
	this._hotpoint.push(select_condtion);
	var k = "Coordinate range is generated:" + this._square.x + ','
			+ this._square.y + ',' + (this._square.x + this._square.w) + ','
			+ (this._square.y + this._square.h);
	console.log(k);
}
/**
 * 這個很重要,找了好久,才看見有個老外的回答,不然座標會偏移
 */
function goog_findPos(obj) {
	var curleft = 0, curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
		return {
			x : curleft,
			y : curtop
		};
	}
	return undefined;
}

goog.prototype.selectListen = function() {
	this.init_mask();
	var temp_context = this.temp_canvas.getContext('2d');
	temp_context.strokeStyle = this.colorStyle.selectColor;
	var genCoordinate = this.genCoordinates;
	var f1 = {}, f2 = {};
	this.temp_canvas.onmousedown = function(_e) {
		var pos = goog_findPos(this);
		f1.layerX = _e.pageX - pos.x;
		f1.layerY = _e.pageY - pos.y;
		this.onmousemove = function(e) {
			temp_context.clearRect(0, 0, this.width, this.height);
			f2.layerX = e.pageX - pos.x;
			f2.layerY = e.pageY - pos.y;
			var square = genCoordinate(f1, f2);
			temp_context.roundRect(square.x, square.y, square.w, square.h);
		};
		this.onmouseup = function(e) {
			this.onmousemove = null;
			this.onmouseup = null;
			f2.layerX = e.pageX - pos.x;
			f2.layerY = e.pageY - pos.y;
			this.tempSquare = genCoordinate(f1, f2);
		};
	}
}

goog.prototype.getSelected = function() {
	return this._hotpoint;
}

/**
 * 以下是展示部分
 ***/
goog.prototype.setHotpoint = function(_datas) {
	if (typeof _datas != "undefined") {
		this._hotpoint = _datas;
	}
}
goog.prototype.showListen = function() {
	this.addShowListen(this._hotpoint);
}
goog.prototype.addShowListen = function(_datas) {
	this.canvas.context = this.context;
	this.canvas.googColorStyle = this.colorStyle;
	var _show = this.show;
	var _showDiv = this.showDiv;
	this.goog_DataFormat(_datas);
	this.createDiv(this.canvas, _datas);
	var f = {};
	this.canvas.onmouseover = function(e) {
		this.context.fillStyle = this.googColorStyle.showColorBG;
		this.context.shadowColor = this.googColorStyle.shadowColor;
		this.context.fillRect(0, 0, this.width, this.height);
		_show(this.context, _datas);
	};
	this.canvas.onmouseout = function(e) {
		this.context.closePath();
		this.context.clearRect(0, 0, this.width, this.height);
	};
	this.canvas.onmousemove = function(e) {
		var pos = goog_findPos(this);
		f.layerX = e.pageX - pos.x;
		f.layerY = e.pageY - pos.y;
		if (this.context.isPointInPath(f.layerX, f.layerY)) {
			for ( var cirle in _datas) {
				var amt = _datas[cirle];
				if (f.layerX > Math.min(amt.x, amt.x + amt.w)
						&& f.layerX < Math.max(amt.x, amt.x + amt.w)
						&& f.layerY > Math.min(amt.y, amt.y + amt.h)
						&& f.layerY < Math.max(amt.y, amt.y + amt.h)) {

					$("#goog_poop_" + amt.uuid).show();
				}
			}
		} else {
			$('.goog_tag_v').hide();
		}
	};
}
/**
 *用來現實展示具體值的DIV
 ***/
goog.prototype.createDiv = function(canvas, _datas) {
	$('.goog_tag_v').remove();
	var position_top = canvas.offsetTop;
	var position_left = canvas.offsetLeft;
	for ( var i in _datas) {
		var amt = _datas[i];
		var _tag = document.createElement("div");
		_tag.setAttribute('id', "goog_poop_" + amt.uuid);
		_tag.setAttribute('class', "goog_tag_v");
		_tag.setAttribute('width', 300);
		_tag.setAttribute('height', 50);
		_tag.setAttribute('style',
				'display:none;background:#000; color:#FFF; position: absolute;left: '
						+ (position_left + amt.x) + 'px;top: '
						+ (position_top + amt.y) + 'px;');
		_tag.innerText = "數量:" + amt.data;
		canvas.parentNode.appendChild(_tag);
		//或則加名字什麼的
	}

}

goog.prototype.destroy = function() {
	this.canvas.remove();
	if (typeof this.temp_canvas != "undefined") {
		this.temp_canvas.remove();
	}
	this._hotpoint = [];
	this._square = {};
}

goog.prototype.showListenDestroy = function() {
	this.canvas.onmousemove = null;
	this.canvas.onmouseover = null;
	this.canvas.onmouseout = null;
}

//預留,萬一要轉換陣列型到類物件
goog.prototype.goog_DataFormat = function(_datas) {
	if (_datas.length <= 0) {
		return;
	}
	var sum = 0
	
	for ( var _i in _datas) {
		if (typeof _datas[_i].x == "undefined") {
			//預留,萬一要轉換陣列型到類物件
			return;
		}
		//業務
		_datas[_i].data = _datas[_i].eventAmount;
		if (typeof _datas[_i].data == "undefined") {
			//DEMO 用
			_datas[_i].data = Math.random() * 100;
		}
		sum = sum + _datas[_i].data;
	}
	var avg = sum / _datas.length;
	//分段函式,看情況,這是業務邏輯了
	for ( var _i in _datas) {
		if (_datas[_i].data / avg > 1.5) {
			_datas[_i].type = 1;
		} else if (_datas[_i].data / avg >= 1) {
			_datas[_i].type = 2;
		} else if (_datas[_i].data / avg >= 0.5) {
			_datas[_i].type = 3;
		} else {
			_datas[_i].type = 4;
		}
	}
}

goog.prototype.show = function(context, _datas) {
	if (typeof _datas == "undefined") {
		return;
	}
	if (typeof _datas == null) {
		return;
	}
	if (_datas.length <= 0) {
		return;
	}
	for ( var _i in _datas) {
		cirle = _datas[_i];
		var r = Math.min(cirle.h, cirle.w) / 2;
		r = Math.min(r, 50); //最大半徑為50 ,以後半徑可以和data的大小有關
		//中心點確定.漸變
		my_gradient = context.createRadialGradient((cirle.x + cirle.w / 2),
				(cirle.y + cirle.h / 2), 0, (cirle.x + cirle.w / 2),
				(cirle.y + cirle.h / 2), r);
		if (cirle.type == 1) {
			my_gradient.addColorStop(0.0, "rgba(255,0,0,0.8)"); //定義紅色漸變色
			my_gradient.addColorStop(0.3, "rgba(255,255,0,0.7)"); //定義黃色漸變色
			my_gradient.addColorStop(0.6, "rgba(0,255,0,0.5)"); //定義綠色漸變色
			my_gradient.addColorStop(0.9, "rgba(0,0,255,0.2)"); //定義藍色漸變色	      
		} else if (cirle.type == 2) {
			my_gradient.addColorStop(0.3, "rgba(255,255,0,0.7)"); //定義黃色漸變色
			my_gradient.addColorStop(0.6, "rgba(0,255,0,0.5)"); //定義綠色漸變色
			my_gradient.addColorStop(0.9, "rgba(0,0,255,0.3)"); //定義藍色漸變色
		} else if (cirle.type == 3) {
			my_gradient.addColorStop(0.2, "rgba(0,255,0,0.5)"); //定義綠色漸變色
			my_gradient.addColorStop(0.7, "rgba(0,0,255,0.4)"); //定義藍色漸變色
		} else {
			my_gradient.addColorStop(0.3, "rgba(0,0,255,0.6)"); //定義藍色漸變色
		}

		my_gradient.addColorStop(1, "rgba(0,0,0,0)"); //定義黑色漸變色
		context.fillStyle = my_gradient;
		context.arc((cirle.x + cirle.w / 2), (cirle.y + cirle.h / 2), r, 0,
				Math.PI * 2, true);
		context.fill();
	}
}

/**
 * 以下是工具類
 ***/
//必須保證在第三象限,不然後面的都要出錯。
goog.prototype.genCoordinates = function(_e, e) {
	var square = {};
	var x = _e.layerX;
	var x2 = e.layerX;
	var y = _e.layerY;
	var y2 = e.layerY;
	var w = x2 - x;
	var h = y2 - y;
	if (w < 0) {
		w = 0 - w;
		x = x2;
	}
	if (h < 0) {
		h = 0 - h;
		y = y2;
	}
	square.x = x;
	square.y = y;
	square.w = w;
	square.h = h;
	return square;
}

//圓弧函式,補充的,也可以用方塊函式/
CanvasRenderingContext2D.prototype.roundRect = function(x, y, width, height,
		radius, stroke) {
	if (typeof stroke == "undefined") {
		stroke = true;
	}
	if (typeof radius === "undefined") {
		radius = 5;
	}
	this.beginPath();
	this.moveTo(x + radius, y);
	this.lineTo(x + width - radius, y);
	this.quadraticCurveTo(x + width, y, x + width, y + radius);
	this.lineTo(x + width, y + height - radius);
	this
			.quadraticCurveTo(x + width, y + height, x + width - radius, y
					+ height);
	this.lineTo(x + radius, y + height);
	this.quadraticCurveTo(x, y + height, x, y + height - radius);
	this.lineTo(x, y + radius);
	this.quadraticCurveTo(x, y, x + radius, y);
	this.closePath();
	if (stroke) {
		this.stroke();
	}
};


測試使用,以及例子

相關推薦

[javascript]canvas 熱點區域區域區域顯示熱點

/***** * 作者:[email protected] * 依賴: jquery * ********************/ var goog = function(tag) { this._hotpoint = []; this._square = {}; if (typeof

Echarts統計統計判斷點區域是不是統計區域

下面的程式碼,是獲取點選統計圖區域的,也就是 X 軸和 Y 軸中的這個框框區域,如下圖的紅色框框中。 myCharts.getZr().on('click', function (params) {        const pointInPixel = [params.

js 移動端漂亮input上傳本地顯示可以檢視大

//首先根據id得到input框的檔案,判斷大小,如果大於100M就不給上傳,如果不大於就可以上傳 $("input[type='file']").on("change",function(){ var load =$(this).attr("id"); var fileSize

canvas生成水印並且分享

microsoft 並且 clas etc 對象 text cor draw clear var canvas, context; var img,//圖片對象 imgIsLoaded,//圖片是否加載完成; imgX = 0,

jquery特效---jquery顯示檢視大並且大可自適應原大小

          之前為了實現這樣的效果找了很久,大部分都不是自己想要的。           實現這樣的效果,我用了兩個jquery的框架。一個是 jquery.nailthumb.1.1.js,另一個是jquery.colorbox-min.js。          

JavaScript實現輪播滑鼠移入暫停播放滑鼠移除開始播放

沒有上傳本地圖片,可以自己新增圖片試一下"img/banner-bw.png"這是小圓點圖片點選可以定位到某一張圖片 <!DOCTYPE html> <html><head><meta charset="UTF-8"><

android GridView實現相簿預覽模式下右上角打勾

看到有初學者有這樣的需求: GridView實現相簿預覽圖,多選模式下右上角打勾。(4.0相簿的預覽圖多選時,多了個藍色邊框,其實是藍色背景)        GridView在自己實際開發中也沒用到過,就想試著實現下,寫個demo供初學者參考,高手略過。        先來

python學習之網站的編寫(HTMLCSSJS)(十六)----------示例構造一個左側管理選單的功能主選單才顯示下面的內容

結果: 程式碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>逆水行舟不進則退</title>

jQuery fullpage.js 全屏滾動外掛取消滑鼠滾動事件選單欄定位顯示頁面。

問題:專案中遇到一個頁面,使用了全屏滾動外掛,如下有4屏畫面。使用了 fullpage.js,現在想要取消通過滑鼠滑輪滾動來定位頁面的功能,只通過點選左側選單欄來實現的定位頁面。   (此處前提條件是,原來的滑鼠事件有效,同時點選左側選單欄也能實現定位de)

SuperMap建立標註標註彈窗顯示資訊

    var markers=new SuperMap.Layer.Markers("Markers",{});     var marker;     function processData(data) {   //呼叫了processData函式         ma

AngularJS判斷checkbox/複是否選中實時顯示

最近因為專案原因重新撿起來了AngularJS ,遇到老問題複選框選中和值的問題。 先貼以前網上找的解決方案 http://www.cnblogs.com/CheeseZH/p/4517701.html 個人感覺太麻煩了,程式碼太多,然後自己找了點資料,現在如下自己的解決方

前端輸入密碼顯示**某個控制元件顯示數字

首先這個是回答別人問題的答案。但由於第一次貼上的答案是有bug的,所以想進行第二次回覆,結果被禁言了,一臉懵逼,好吧,禁就禁吧,我將答案寫成部落格不會被禁了吧?首先說明一下,這是基於jquery的 最簡單的是現有的可以用一下辦法         顯示密碼         $

eclipse檢出svn專案後該資料夾沒有顯示綠色

背景 win10作業系統 裝了tortoiseSvn客戶端(最新版), eclipse裝了subclipse外掛 在eclipse中檢出的svn專案,在檔案管理器中檢視沒有顯示綠色,如下: 且右鍵顯示SVN upgrade working copy

ArcGIS API For Javascript之多顯示與隱藏層要素查詢

5、多圖層的載入與隱藏 利用Html+Javascript前端程式設計實現上傳到服務端的地圖服務中的多圖層的載入與隱藏。本實驗中除了底圖之外,添加了共10個圖層,分別為 賓館酒店_point (0) 餐飲_point (1) 超市商城_point (2) 地級市_font

百度api實現顯示區域內的資料並且點資料點顯示詳細資訊

下面我貼上所有原始碼,分享給大家,後臺資料隨便大家如何獲取1.開啟地圖,右上角是繪製多邊形的工具條。引用DrawingManager_min.js和DrawingManager_min.css即可2.選擇框選型別。框選區域,判斷點是否在多邊形中,大家可以參考百度提供的這個j

ArcGIS 實現區域查詢要素後要素點彈出

      提醒說明:本文用了兩種方法,建議直接看第二種,因為第二種比第一種靠譜簡單;       2015.11.12 在webGis 專案的開發中,當前已經實現使用QueryTask來針對要素進行NAME,空間的查詢之後,並使用Symbol將要素顯示出來在圖上,如下圖所

2.1使用canvas畫個圓每次點畫布彈出提示

<body><canvas id="canvas" width="500" height="500" style="border:dashed 1px"></canvas></body><script>var can

JAVASCRIPT】使用ztree樹實現右鍵增加修改刪除節點。帶有複

測試支援火狐,谷歌,IE10等。 主要使用ztree,擁有複選框,增加,修改,刪除功能,這些是要連線後臺的,自己再修改下就可以用。 效果如下圖: 點選增加後會出現 程式碼如下: <!DOCTYPE html> <html> <head>

單選 一個 div bsp style checked 學習java inpu radi 1、分組即,多個單選框,都在一個分組裏,同一時間,只能選中一個單選框 設置name屬性相同即可<p>今天晚上做什麽?</p> 學習java<in

柱形餅狀JavaScript

column 註意 文件 label max number span item pointf <script type="text/javascript"> $(function () { $(‘#container_2‘).highcharts({