123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642 |
- define("dojox/gfx/canvasWithEvents", ["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/Color", "dojo/dom",
- "dojo/dom-geometry", "./_base","./canvas", "./shape", "./matrix"],
- function(lang, declare, hub, Color, dom, domGeom, g, canvas, shapeLib, m){
- var canvasEvent = g.canvasWithEvents = {};
- declare("dojox.gfx.canvasWithEvents.Shape", canvas.Shape, {
-
- _testInputs: function(/* Object */ctx, /* Array */ pos){
- if (!this.canvasFill && this.strokeStyle) {
-
- this._hitTestPixel(ctx, pos);
- } else {
- this._renderShape(ctx);
- var cnt = pos.length, t = this.getTransform();
- for (var i = 0; i < pos.length; ++i) {
- var input = pos[i];
-
- if (input.target)
- continue;
- var x = input.x, y = input.y;
- var p = t ? m.multiplyPoint(m.invert(t), x, y) : {
- x: x,
- y: y
- };
- input.target = this._hitTestGeometry(ctx, p.x, p.y);
- }
- }
- },
- _hitTestPixel: function(/* Object */ctx, /* Array */ pos){
- for (var i = 0; i < pos.length; ++i) {
- var input = pos[i];
- if (input.target)
- continue;
- var x = input.x, y = input.y;
- ctx.clearRect(0,0,1,1);
- ctx.save();
- ctx.translate(-x, -y);
- this._render(ctx, true);
- input.target = ctx.getImageData(0, 0, 1, 1).data[0] ? this : null;
- ctx.restore();
- }
- },
- _hitTestGeometry: function(ctx, x, y){
- return ctx.isPointInPath(x, y) ? this : null;
- },
-
- _renderFill: function(/* Object */ ctx, /* Boolean */ apply){
-
-
-
-
-
-
- if(ctx.pickingMode){
- if("canvasFill" in this && apply){ ctx.fill(); }
- return;
- }
- this.inherited(arguments);
- },
- _renderStroke: function(/* Object */ ctx, /* Boolean */ apply){
-
-
-
-
-
-
- if (this.strokeStyle && ctx.pickingMode) {
- var c = this.strokeStyle.color;
- try {
- this.strokeStyle.color = new Color(ctx.strokeStyle);
- this.inherited(arguments);
- } finally {
- this.strokeStyle.color = c;
- }
- } else{
- this.inherited(arguments);
- }
- },
-
-
-
- getEventSource: function(){
-
-
- return this.surface.getEventSource();
- },
-
- connect: function(name, object, method){
-
- this.surface._setupEvents(name);
-
-
-
- return arguments.length > 2 ?
- hub.connect(this, name, object, method) : hub.connect(this, name, object);
- },
- disconnect: function(token){
-
- hub.disconnect(token);
- },
-
- oncontextmenu: function(){},
- onclick: function(){},
- ondblclick: function(){},
- onmouseenter: function(){},
- onmouseleave: function(){},
- onmouseout: function(){},
- onmousedown: function(){},
- ontouchstart: function(){},
- touchstart: function(){},
- onmouseup: function(){},
- ontouchend: function(){},
- touchend: function(){},
- onmouseover: function(){},
- onmousemove: function(){},
- ontouchmove: function(){},
- touchmove: function(){},
- onkeydown: function(){},
- onkeyup: function(){}
- });
-
- declare("dojox.gfx.canvasWithEvents.Group", [canvasEvent.Shape, canvas.Group], {
- _testInputs: function(/*Object*/ctx, /*Array*/ pos){
- var children = this.children, t = this.getTransform(), i, j;
- if(children.length == 0){
- return;
- }
- var posbk = [];
- for(i = 0; i < pos.length; ++i){
- var input = pos[i];
-
- posbk[i] = {
- x: input.x,
- y: input.y
- };
- if(input.target) continue;
- var x = input.x, y = input.y;
- var p = t ? m.multiplyPoint(m.invert(t), x, y) : {
- x: x,
- y: y
- };
- input.x = p.x;
- input.y = p.y;
- }
- for(i = children.length - 1; i >= 0; --i){
- children[i]._testInputs(ctx, pos);
-
- var allFound = true;
- for(j = 0; j < pos.length; ++j){
- if(pos[j].target == null){
- allFound = false;
- break;
- }
- }
- if(allFound){
- break;
- }
- }
- for(i = 0; i < pos.length; ++i){
- pos[i].x = posbk[i].x;
- pos[i].y = posbk[i].y;
- }
- }
- });
-
- declare("dojox.gfx.canvasWithEvents.Image", [canvasEvent.Shape, canvas.Image], {
- _renderShape: function(/* Object */ ctx){
-
-
-
-
- var s = this.shape;
- if(ctx.pickingMode){
- ctx.fillRect(s.x, s.y, s.width, s.height);
- }else{
- this.inherited(arguments);
- }
- },
-
- _hitTestGeometry: function(ctx, x, y){
-
- var s = this.shape;
- return x >= s.x && x <= s.x + s.width && y >= s.y && y <= s.y + s.height ? this : null;
- }
- });
-
- declare("dojox.gfx.canvasWithEvents.Text", [canvasEvent.Shape, canvas.Text], {
- _testInputs: function(ctx, pos){
- return this._hitTestPixel(ctx, pos);
- }
- });
- declare("dojox.gfx.canvasWithEvents.Rect", [canvasEvent.Shape, canvas.Rect], {});
- declare("dojox.gfx.canvasWithEvents.Circle", [canvasEvent.Shape, canvas.Circle], {});
- declare("dojox.gfx.canvasWithEvents.Ellipse", [canvasEvent.Shape, canvas.Ellipse],{});
- declare("dojox.gfx.canvasWithEvents.Line", [canvasEvent.Shape, canvas.Line],{});
- declare("dojox.gfx.canvasWithEvents.Polyline", [canvasEvent.Shape, canvas.Polyline],{});
- declare("dojox.gfx.canvasWithEvents.Path", [canvasEvent.Shape, canvas.Path],{});
- declare("dojox.gfx.canvasWithEvents.TextPath", [canvasEvent.Shape, canvas.TextPath],{});
-
-
- var _eventsRedirectMap = {
- onmouseenter : 'onmousemove',
- onmouseleave : 'onmousemove',
- onmouseout : 'onmousemove',
- onmouseover : 'onmousemove',
- touchstart : 'ontouchstart',
- touchend : 'ontouchend',
- touchmove : 'ontouchmove'
- };
- var _eventsShortNameMap = {
- ontouchstart : 'touchstart',
- ontouchend : 'touchend',
- ontouchmove : 'touchmove'
- };
-
- var uagent = navigator.userAgent.toLowerCase(),
- isiOS = uagent.search('iphone') > -1 ||
- uagent.search('ipad') > -1 ||
- uagent.search('ipod') > -1;
-
- declare("dojox.gfx.canvasWithEvents.Surface", canvas.Surface, {
- constructor:function(){
- this._pick = { curr: null, last: null };
- this._pickOfMouseDown = null;
- this._pickOfMouseUp = null;
- },
-
- connect: function(/*String*/name, /*Object*/object, /*Function|String*/method){
-
-
-
-
-
-
-
-
- if (name.indexOf('touch') !== -1) {
-
-
-
-
- this._setupEvents(name);
- name = "_on" + name + "Impl_";
- return hub.connect(this, name, object, method);
- } else {
- this._initMirrorCanvas();
- return hub.connect(this.getEventSource(), name, null,
- shapeLib.fixCallback(this, g.fixTarget, object, method));
- }
- },
-
- _ontouchstartImpl_: function(){},
- _ontouchendImpl_: function(){},
- _ontouchmoveImpl_: function(){},
-
- _initMirrorCanvas: function(){
- if (!this.mirrorCanvas) {
- var p = this._parent, mirror = p.ownerDocument.createElement("canvas");
- mirror.width = 1;
- mirror.height = 1;
- mirror.style.position = 'absolute';
- mirror.style.left = '-99999px';
- mirror.style.top = '-99999px';
- p.appendChild(mirror);
- this.mirrorCanvas = mirror;
- }
- },
- _setupEvents: function(eventName){
-
-
-
- if (eventName in _eventsRedirectMap)
- eventName = _eventsRedirectMap[eventName];
- if (this._eventsH && this._eventsH[eventName]) {
-
- return;
- }
-
- this._initMirrorCanvas();
- if (!this._eventsH)
- this._eventsH = {};
-
- this._eventsH[eventName] = hub.connect(this.getEventSource(), eventName,
- shapeLib.fixCallback(this, g.fixTarget, this, "_" + eventName));
- if (eventName === 'onclick' || eventName==='ondblclick') {
- if(!this._eventsH['onmousedown']){
- this._eventsH['onmousedown'] = hub.connect(this.getEventSource(),
- 'onmousedown', shapeLib.fixCallback(this, g.fixTarget, this, "_onmousedown"));
- }
- if(!this._eventsH['onmouseup']){
- this._eventsH['onmouseup'] = hub.connect(this.getEventSource(),
- 'onmouseup', shapeLib.fixCallback(this, g.fixTarget, this, "_onmouseup"));
- }
- }
- },
-
- destroy: function(){
-
- canvas.Surface.destroy.apply(this);
-
-
- for(var i in this._eventsH){
- hub.disconnect(this._eventsH[i]);
- }
- this._eventsH = this.mirrorCanvas = null;
- },
-
-
- getEventSource: function(){
-
- return this.rawNode;
- },
-
- _invokeHandler: function(base, method, event){
-
- var handler = base[method];
- if(handler && handler.after){
- handler.apply(base, [event]);
- }else if (method in _eventsShortNameMap){
-
- handler = base[_eventsShortNameMap[method]];
- if(handler && handler.after){
- handler.apply(base, [event]);
- }
- }
- if(!handler && method.indexOf('touch') !== -1){
-
- method = "_" + method + "Impl_";
- handler = base[method];
- if(handler){
- handler.apply(base, [event]);
- }
- }
-
-
- if (!isEventStopped(event) && base.parent) {
- this._invokeHandler(base.parent, method, event);
- }
- },
- _oncontextmenu: function(e){
-
-
- if(this._pick.curr){
- this._invokeHandler(this._pick.curr, 'oncontextmenu', e);
- }
- },
- _ondblclick: function(e){
-
-
- if(this._pickOfMouseUp){
- this._invokeHandler(this._pickOfMouseUp, 'ondblclick', e);
- }
- },
- _onclick: function(e){
-
-
- if(this._pickOfMouseUp && this._pickOfMouseUp == this._pickOfMouseDown){
- this._invokeHandler(this._pickOfMouseUp, 'onclick', e);
- }
- },
- _onmousedown: function(e){
-
- this._pickOfMouseDown = this._pick.curr;
-
- if(this._pick.curr){
- this._invokeHandler(this._pick.curr, 'onmousedown', e);
- }
- },
- _ontouchstart: function(e){
-
-
- if (this._pick.curr) {
- this._fireTouchEvent(e);
- }
-
- },
- _onmouseup: function(e){
-
-
- this._pickOfMouseUp = this._pick.curr;
- if(this._pick.curr){
- this._invokeHandler(this._pick.curr, 'onmouseup', e);
- }
- },
- _ontouchend: function(e){
-
-
- if(this._pick.curr){
- for(var i = 0; i < this._pick.curr.length; ++i){
- if(this._pick.curr[i].target){
- e.gfxTarget = this._pick.curr[i].target;
- this._invokeHandler(this._pick.curr[i].target, 'ontouchend', e);
- }
- }
- }
- },
- _onmousemove: function(e){
-
-
- if(this._pick.last && this._pick.last != this._pick.curr){
- this._invokeHandler(this._pick.last, 'onmouseleave', e);
- this._invokeHandler(this._pick.last, 'onmouseout', e);
- }
- if(this._pick.curr){
- if(this._pick.last == this._pick.curr){
- this._invokeHandler(this._pick.curr, 'onmousemove', e);
- }else{
- this._invokeHandler(this._pick.curr, 'onmouseenter', e);
- this._invokeHandler(this._pick.curr, 'onmouseover', e);
- }
- }
- },
- _ontouchmove: function(e){
-
- if(this._pick.curr){
- this._fireTouchEvent(e);
- }
- },
-
- _fireTouchEvent: function(e){
-
- var toFire = [];
-
-
-
- for(var i = 0; i < this._pick.curr.length; ++i){
- var pick = this._pick.curr[i];
- if(pick.target){
-
- var gfxtt = pick.target.__gfxtt;
- if(!gfxtt){
- gfxtt = [];
- pick.target.__gfxtt = gfxtt;
- }
-
- gfxtt.push(pick.t);
-
- if(!pick.target.__inToFire){
- toFire.push(pick.target);
- pick.target.__inToFire=true;
- }
- }
- }
- if(toFire.length === 0){
-
- this._invokeHandler(this, 'on' + e.type, e);
- }else{
- for(i = 0; i < toFire.length; ++i){
- (function(){
- var targetTouches = toFire[i].__gfxtt;
-
-
- var evt = lang.delegate(e, {gfxTarget: toFire[i]});
- if(isiOS){
-
- evt.preventDefault = function(){e.preventDefault();};
- evt.stopPropagation = function(){e.stopPropagation();};
- }
-
- evt.__defineGetter__('targetTouches', function(){return targetTouches;});
-
- delete toFire[i].__gfxtt;
- delete toFire[i].__inToFire;
-
- this._invokeHandler(toFire[i], 'on' + e.type, evt);
- }).call(this);
- }
- }
- },
- _onkeydown: function(){},
- _onkeyup: function(){},
- _whatsUnderEvent: function(evt){
-
-
-
- var surface = this, i,
- pos = domGeom.position(surface.rawNode, true),
- inputs = [], changedTouches = evt.changedTouches, touches = evt.touches;
-
- if(changedTouches){
- for(i = 0; i < changedTouches.length; ++i){
- inputs.push({
- t: changedTouches[i],
- x: changedTouches[i].pageX - pos.x,
- y: changedTouches[i].pageY - pos.y
- });
- }
- }else if(touches){
- for(i = 0; i < touches.length; ++i){
- inputs.push({
- t: touches[i],
- x: touches[i].pageX - pos.x,
- y: touches[i].pageY - pos.y
- });
- }
- }else{
- inputs.push({
- x : evt.pageX - pos.x,
- y : evt.pageY - pos.y
- });
- }
-
- var mirror = surface.mirrorCanvas,
- ctx = mirror.getContext('2d'),
- children = surface.children;
-
- ctx.clearRect(0, 0, mirror.width, mirror.height);
- ctx.save();
- ctx.strokeStyle = "rgba(127,127,127,1.0)";
- ctx.fillStyle = "rgba(127,127,127,1.0)";
- ctx.pickingMode = true;
- var pick = null;
-
- for(i = children.length-1; i >= 0; i--){
- children[i]._testInputs(ctx, inputs);
-
- var allFound = true;
- for(j = 0; j < inputs.length; ++j){
- if(inputs[j].target == null){
- allFound = false;
- break;
- }
- }
- if(allFound){
- break;
- }
- }
- ctx.restore();
-
- return (touches || changedTouches) ? inputs : inputs[0].target;
- }
- });
-
- canvasEvent.createSurface = function(parentNode, width, height){
-
-
-
-
- if(!width && !height){
- var pos = domGeom.position(parentNode);
- width = width || pos.w;
- height = height || pos.h;
- }
- if(typeof width == "number"){
- width = width + "px";
- }
- if(typeof height == "number"){
- height = height + "px";
- }
- var s = new canvasEvent.Surface(),
- p = dom.byId(parentNode),
- c = p.ownerDocument.createElement("canvas");
- c.width = g.normalizedLength(width);
- c.height = g.normalizedLength(height);
- p.appendChild(c);
- s.rawNode = c;
- s._parent = p;
- s.surface = s;
- return s;
- };
-
- var isEventStopped = function(/*Event*/ evt){
-
-
-
-
- if(evt.cancelBubble !== undefined){
- return evt.cancelBubble;
- }
- return false;
- };
-
- canvasEvent.fixTarget = function(event, gfxElement){
-
-
-
-
-
-
-
- if(isEventStopped(event)){
- return false;
- }
- if(!event.gfxTarget){
- gfxElement._pick.last = gfxElement._pick.curr;
- gfxElement._pick.curr = gfxElement._whatsUnderEvent(event);
- if (!lang.isArray(gfxElement._pick.curr))
- event.gfxTarget = gfxElement._pick.curr;
- }
- return true;
- };
- return canvasEvent;
- });
|