// By Aza Raskin, 2010 function Lasso(options){ this.init(options); } Lasso.prototype = { init: function(options){ var canvas = document.createElement("canvas"); var w = window.innerWidth; var h = window.innerHeight; this._selector = options.targets; this._container = options.container || "body"; this._fillColor = options.fillColor || "rgba(0,0,255,.1)"; this._strokeColor = options.strokeColor || "rgba(0,0,255,.4)"; this._onSelect = options.onSelect || function(){}; this._onStart = options.onStart || function(){}; this._lastPos = null; this._isSelecting = false; $(canvas) .attr({width:w,height:h}) .css({position:"fixed", top:0, left:0, width:w, height:h, zIndex:9999}) .appendTo("body") .hide(); this.canvas = canvas; this.ctx = canvas.getContext("2d"); this.on(); }, on: function(){ var self = this; $(this._container) .mousedown( function(e){ if( $(e.target).is(self._selector) ) return; self.startSelection(); return false; }) .mouseup( function(){self.stopSelection()} ) }, startSelection: function(){ var self = this; this._isSelecting = true; this._onStart(); this._draw = function(e){ var pos = {x:e.clientX, y:e.clientY}; self._updatePos( pos ); }; this.ctx.beginPath(); this.ctx.fillStyle = this._fillColor; this.ctx.strokeStyle = this._strokeColor; this.ctx.lineWidth = 1; $(this._container).mousemove(this._draw); $(this.canvas).show(); }, stopSelection: function(){ $(this._container).unbind("mousemove", this._draw); this._isSelecting = false; this._hitTest(); $(this.canvas).hide(); this._onSelect( this.getSelectedElements(), this._lastPos ) this._clear(); }, _updatePos: function(pos){ var self = this; if( ! self._isSelecting ) return; if( self._lastPos == null ){ self._lastPos = pos; return; } with(this.ctx){ clearRect(0,0,this.canvas.width,this.canvas.height) lineTo(pos.x, pos.y); stroke(); fill(); } self._lastPos = pos; }, _clear: function(){ // A fast way of clearing the canvas this.canvas.setAttribute('width', this.canvas.width); this._lastPos = null; }, _hitTest: function(){ var w = this.canvas.width; var h = this.canvas.height; var data = this.ctx.getImageData(0,0, w, h).data; $(this.canvas).hide(); var hitElements = []; // can make this bounding much faster for( var x=0; x