1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 /** 27 * the DOM object 28 * @class 29 * @type {Object} 30 */ 31 cc.DOM = {}; 32 /** 33 * Set to true to enalbe DOM debugging/editing, which allows you to move, rotate, scale, skew an element. 34 * Set to false to turn off debugging/editing 35 * @type Boolean 36 */ 37 cc.DOMEditMode = true; 38 /** 39 * @function 40 * @private 41 * @param x 42 */ 43 cc.DOM.addMethods = function (x) { 44 for (funcs in cc.DOM.methods) { 45 x[funcs] = cc.DOM.methods[funcs]; 46 } 47 }; 48 cc.DOM.methods = /** @lends cc.DOM# */{ 49 /** 50 * Replace the set position of ccNode 51 * @param {object|Number} x 52 * @param {Number} y 53 */ 54 setPosition:function (x, y) { 55 if (arguments.length == 2) { 56 this._position.x = x; 57 this._position.y = y; 58 //this._position = cc.p(newPosOrxValue,yValue); 59 } else { 60 this._position = x; 61 } 62 this.dom.translates(this._position.x, -this._position.y); 63 }, 64 /** 65 * replace set Position Y of ccNode 66 * @param {Number} y 67 */ 68 setPositionY:function (y) { 69 this._position.y = y; 70 this.dom.translates(this._position.x, -this._position.y); 71 }, 72 73 /** 74 * replace set Position X of ccNode 75 * @param {Number} x 76 */ 77 setPositionX:function (x) { 78 this._position.x = x; 79 this.dom.translates(this._position.x, -this._position.y); 80 }, 81 82 /** 83 * replace set Scale of ccNode 84 * @param {object|Number} scale 85 * @param {Number} scaleY 86 */ 87 setScale:function (scale, scaleY) { 88 //save dirty region when before change 89 //this._addDirtyRegionToDirector(this.getBoundingBoxToWorld()); 90 91 this._scaleX = scale; 92 this._scaleY = scaleY || scale; 93 94 //save dirty region when after changed 95 //this._addDirtyRegionToDirector(this.getBoundingBoxToWorld()); 96 this.dom.resize(this._scaleX, this._scaleY); 97 }, 98 99 /** 100 * replace set Scale X of ccNode 101 * @param {Number} x 102 */ 103 setScaleX:function (x) { 104 this._scaleX = x; 105 this.dom.resize(this._scaleX, this._scaleY); 106 }, 107 108 /** 109 * replace set Scale Y of ccNode 110 * @param {Number} y 111 */ 112 setScaleY:function (y) { 113 this._scaleY = y; 114 this.dom.resize(this._scaleX, this._scaleY); 115 }, 116 117 /** 118 * replace set anchorpoint of ccNode 119 * @param {object} point 120 */ 121 setAnchorPoint:function (point) { 122 this._anchorPoint = point; 123 this._anchorPointInPoints = cc.p(this._contentSize.width * this._anchorPoint.x, 124 this._contentSize.height * this._anchorPoint.y); 125 this.dom.style[cc.$.pfx + 'TransformOrigin'] = '' + this._anchorPointInPoints.x + 'px ' + this._anchorPointInPoints.y + 'px'; 126 if (this.isIgnoreAnchorPointForPosition()) { 127 this.dom.style.marginLeft = 0; 128 this.dom.style.marginBottom = 0; 129 } 130 else { 131 this.dom.style.marginLeft = (this.isToggler) ? 0 : -this._anchorPointInPoints.x + 'px'; 132 this.dom.style.marginBottom = -this._anchorPointInPoints.y + 'px'; 133 } 134 }, 135 136 /** 137 * replace set ContentSize of ccNode 138 * @param {cc.Size} size 139 */ 140 setContentSize:function (size) { 141 if (!cc.Size.CCSizeEqualToSize(size, this._contentSize)) { 142 this._contentSize = size; 143 this._anchorPointInPoints = cc.p(this._contentSize.width * this._anchorPoint.x, 144 this._contentSize.height * this._anchorPoint.y); 145 this.dom.width = size.width; 146 this.dom.height = size.height; 147 this.setAnchorPoint(this.getAnchorPoint()); 148 } 149 if (this.canvas) { 150 this.canvas.width = this._contentSize.width; 151 this.canvas.height = this._contentSize.height; 152 } 153 if (cc.DOMEditMode && !this.placeholder) { 154 this.dom.style.width = this._contentSize.width + 'px'; 155 this.dom.style.height = this._contentSize.height + 'px'; 156 this.dom.addClass('CCDOMEdit'); 157 } 158 this.redraw(); 159 }, 160 161 /** 162 * replace set Rotation of ccNode 163 * @param {Number} newRotation 164 */ 165 setRotation:function (newRotation) { 166 if (this._rotation == newRotation) 167 return; 168 //save dirty region when before change 169 //this._addDirtyRegionToDirector(this.getBoundingBoxToWorld()); 170 171 this._rotation = newRotation; 172 this._rotationRadians = this._rotation * (Math.PI / 180); 173 this.dom.rotate(newRotation); 174 }, 175 176 /** 177 * replace set SkewX of ccNode 178 * @param {Number} x 179 */ 180 setSkewX:function (x) { 181 this._skewX = x; 182 this.dom.setSkew(this._skewX, this._skewY); 183 }, 184 185 /** 186 * replace set SkewY of ccNode 187 * @param {Number} y 188 */ 189 setSkewY:function (y) { 190 this._skewY = y; 191 this.dom.setSkew(this._skewX, this._skewY); 192 }, 193 194 /** 195 * replace set Visible of ccNode 196 * @param {Boolean} x 197 */ 198 setVisible:function (x) { 199 this._visible = x; 200 if (this.dom) 201 this.dom.style.visibility = (x) ? 'visible' : 'hidden'; 202 }, 203 _setZOrder:function (z) { 204 this._zOrder = z; 205 if (this.dom) 206 this.dom.zIndex = z; 207 }, 208 209 /** 210 * replace set Parent of ccNode 211 * @param {cc.Node} p 212 */ 213 setParent:function (p) { 214 this._parent = p; 215 cc.DOM.parentDOM(this); 216 }, 217 218 /** 219 * replace resume Schedule and actions of ccNode 220 */ 221 resumeSchedulerAndActions:function () { 222 this.getScheduler().resumeTarget(this); 223 this.getActionManager().resumeTarget(this); 224 //if dom does not have parent, but node has no parent and its running 225 if (this.dom && !this.dom.parentNode) { 226 if (!this.getParent()) { 227 this.dom.appendTo(cc.container); 228 } 229 else { 230 cc.DOM.parentDOM(this); 231 } 232 } 233 if (this.dom) 234 this.dom.style.visibility = "visible"; 235 }, 236 237 /** 238 * replace pause Schedule and Actions of ccNode 239 */ 240 pauseSchedulerAndActions:function () { 241 this.getScheduler().pauseTarget(this); 242 this.getActionManager().pauseTarget(this); 243 if (this.dom) { 244 this.dom.style.visibility = 'hidden'; 245 } 246 }, 247 248 /** 249 * replace clean up of ccNode 250 */ 251 cleanup:function () { 252 // actions 253 this.stopAllActions(); 254 this.unscheduleAllCallbacks(); 255 256 // timers 257 this._arrayMakeObjectsPerformSelector(this._children, cc.Node.StateCallbackType.cleanup); 258 if (this.dom) { 259 this.dom.remove(); 260 } 261 }, 262 /** 263 * replace remove from parent and clean up of ccNode 264 */ 265 removeFromParentAndCleanup:function () { 266 this.dom.remove(); 267 }, 268 setOpacity:function (o) { 269 this._opacity = o; 270 this.dom.style.opacity = o / 255; 271 }, 272 /** 273 * refresh/updates the DOM element 274 */ 275 redraw:function () { 276 if (this.isSprite) { 277 var tmp = this._children; 278 this._children = null; 279 cc.Sprite.prototype.visit.call(this, this.ctx); 280 this._children = tmp; 281 } 282 else { 283 cc.Sprite.prototype.visit.call(this, this.ctx); 284 } 285 } 286 }; 287 /** 288 * @function 289 * @private 290 * @param x 291 * @return {Boolean} 292 */ 293 cc.DOM.parentDOM = function (x) { 294 var p = x.getParent(); 295 //if has parent, parent need to have dom too 296 if (!p || !x.dom) 297 return false; 298 if (!p.dom) { 299 cc.DOM.placeHolder(p); 300 p.setParent = cc.DOM.methods.setParent; 301 } 302 //if parent have dom, attach self to parent 303 x.dom.appendTo(p.dom); 304 var pp; 305 if (pp = p.getParent()) { 306 cc.DOM.parentDOM(p); 307 } 308 else { 309 //parent has no more parent, if its running, then add it to the container 310 if (p.isRunning()) { 311 p.dom.appendTo(cc.container); 312 } 313 } 314 return true; 315 }; 316 317 /** 318 * @function 319 * @private 320 * @param x 321 */ 322 cc.DOM.setTransform = function (x) { 323 if (x.ctx) { 324 /* x.ctx.save(); 325 x.ctx.setTransform(1,0,0,1,0,0); 326 x.ctx.clearRect(0,0,x.canvas.width, x.canvas.height); 327 x.ctx.restore();*/ 328 x.ctx.translate(x.getAnchorPointInPoints().x, x.getAnchorPointInPoints().y); 329 if (x.isSprite) { 330 var tmp = x._children; 331 x._children = null; 332 cc.Sprite.prototype.visit.call(x, x.ctx); 333 x._children = tmp; 334 } 335 else { 336 cc.Sprite.prototype.visit.call(x, x.ctx); 337 } 338 } 339 if (x.dom) { 340 x.dom.position.x = x.getPosition().x; 341 x.dom.position.y = -x.getPosition().y; 342 x.dom.rotation = x.getRotation(); 343 x.dom.scale = {x:x.getScaleX(), y:x.getScaleY()}; 344 x.dom.skew = {x:x.getSkewX(), y:x.getSkewY()}; 345 if (x.setAnchorPoint) 346 x.setAnchorPoint(x.getAnchorPoint()); 347 x.dom.transforms(); 348 x.dom.position.y = -x.getPosition().y; 349 x.dom.rotation = x.getRotation(); 350 x.dom.scale = {x:x.getScaleX(), y:x.getScaleY()}; 351 x.dom.skew = {x:x.getSkewX(), y:x.getSkewY()}; 352 if (x.setAnchorPoint) 353 x.setAnchorPoint(x.getAnchorPoint()); 354 x.dom.transforms(); 355 } 356 357 }; 358 359 /** 360 * @function 361 * @private 362 * @param x 363 */ 364 cc.DOM.forSprite = function (x) { 365 x.dom = cc.$new('div'); 366 x.canvas = cc.$new('canvas'); 367 x.canvas.width = x.getContentSize().width; 368 x.canvas.height = x.getContentSize().height; 369 if (cc.DOMEditMode) { 370 x.dom.style.width = x.getContentSize().width + 'px'; 371 x.dom.style.height = x.getContentSize().height + 'px'; 372 x.dom.addClass('CCDOMEdit'); 373 } 374 x.dom.style.position = 'absolute'; 375 x.dom.style.bottom = 0; 376 x.ctx = x.canvas.getContext('2d'); 377 x.dom.appendChild(x.canvas); 378 if (x.getParent()) { 379 cc.DOM.parentDOM(x); 380 } 381 x.isSprite = true; 382 }; 383 384 /** 385 * @function 386 * @private 387 * @param x 388 */ 389 cc.DOM.forMenuToggler = function (x) { 390 x.dom = cc.$new('div'); 391 x.dom2 = cc.$new('div'); 392 x.dom.appendChild(x.dom2); 393 for (var i = 0; i < x._subItems.length; i++) { 394 cc.DOM.convert(x._subItems[i]); 395 x.dom2.appendChild(x._subItems[i].dom); 396 x._subItems[i].setPosition(cc.p(0, 0)); 397 } 398 x.dom.style.marginLeft = 0; 399 x.setSelectedIndex = function (SelectedIndex) { 400 this._selectedIndex = SelectedIndex; 401 for (var i = 0; i < this._subItems.length; i++) { 402 this._subItems[i].setVisible(false); 403 } 404 this._subItems[SelectedIndex].setVisible(true); 405 }; 406 407 408 x.setSelectedIndex(x.getSelectedIndex()); 409 x.dom2.addEventListener('click', function () { 410 x.activate(); 411 }); 412 x.dom2.addEventListener('mousedown', function () { 413 for (var i = 0; i < x._subItems.length; i++) { 414 x._subItems[i]._isEnabled = true; 415 x._subItems[i]._running = true; 416 x._subItems[i].selected(); 417 x._subItems[i]._isEnabled = false; 418 x._subItems[i]._running = false; 419 } 420 x._subItems[x.getSelectedIndex()]._isEnabled = true; 421 x._subItems[x.getSelectedIndex()]._running = true; 422 423 }); 424 x.dom2.addEventListener('mouseup', function () { 425 for (var i = 0; i < x._subItems.length; i++) { 426 x._subItems[i]._isEnabled = true; 427 x._subItems[i].unselected(); 428 x._subItems[i]._isEnabled = false; 429 } 430 x._subItems[x.getSelectedIndex()]._isEnabled = true; 431 }); 432 x.dom2.addEventListener('mouseout', function () { 433 if (x.mouseDown) { 434 for (var i = 0; i < x._subItems.length; i++) { 435 x._subItems[i]._isEnabled = true; 436 x._subItems[i].unselected(); 437 x._subItems[i]._isEnabled = false; 438 } 439 x._subItems[x.getSelectedIndex()]._isEnabled = true; 440 x.mouseDown = false; 441 } 442 }); 443 x.dom.style.position = "absolute"; 444 x.isToggler = true; 445 }; 446 447 /** 448 * @function 449 * @private 450 * @param x 451 */ 452 cc.DOM.forMenuItem = function (x) { 453 x.dom = cc.$new('div'); 454 x.canvas = cc.$new('canvas'); 455 x.canvas.width = x.getContentSize().width; 456 x.canvas.height = x.getContentSize().height; 457 if (cc.DOMEditMode) { 458 x.dom.style.width = x.getContentSize().width + 'px'; 459 x.dom.style.height = x.getContentSize().height + 'px'; 460 x.dom.addClass('CCDOMEdit'); 461 } 462 x.dom.style.position = 'absolute'; 463 x.dom.style.bottom = 0; 464 x.ctx = x.canvas.getContext('2d'); 465 x.dom.appendChild(x.canvas); 466 if (x.getParent()) { 467 cc.DOM.parentDOM(x); 468 } 469 if (x._selector) { 470 //if menu item have callback 471 x.canvas.addEventListener('click', function () { 472 x.activate(); 473 }); 474 x.canvas.addEventListener('mousedown', function () { 475 x.selected(); 476 x.ctx.save(); 477 x.ctx.setTransform(1, 0, 0, 1, 0, 0); 478 x.ctx.clearRect(0, 0, x.canvas.width, x.canvas.height); 479 x.ctx.restore(); 480 x.mouseDown = true; 481 cc.Sprite.prototype.visit.call(x, x.ctx); 482 }); 483 x.canvas.addEventListener('mouseup', function () { 484 x.unselected(); 485 x.ctx.save(); 486 x.ctx.setTransform(1, 0, 0, 1, 0, 0); 487 x.ctx.clearRect(0, 0, x.canvas.width, x.canvas.height); 488 x.ctx.restore(); 489 cc.Sprite.prototype.visit.call(x, x.ctx); 490 }); 491 x.canvas.addEventListener('mouseout', function () { 492 if (x.mouseDown) { 493 x.unselected(); 494 x.ctx.save(); 495 x.ctx.setTransform(1, 0, 0, 1, 0, 0); 496 x.ctx.clearRect(0, 0, x.canvas.width, x.canvas.height); 497 x.ctx.restore(); 498 cc.Sprite.prototype.visit.call(x, x.ctx); 499 x.mouseDown = false; 500 } 501 }) 502 } 503 }; 504 505 /** 506 * This creates divs for parent Nodes that are related to the current node 507 * @function 508 * @private 509 * @param x 510 */ 511 cc.DOM.placeHolder = function (x) { 512 //creating a placeholder dom to simulate other ccNode in the hierachy 513 x.dom = cc.$new('div'); 514 x.placeholder = true; 515 x.dom.style.position = 'absolute'; 516 x.dom.style.bottom = 0; 517 //x.dom.style.display='block'; 518 x.dom.style.width = (x.getContentSize().width || cc.Director.getInstance().getWinSize().width) + "px"; 519 x.dom.style.maxHeight = (x.getContentSize().height || cc.Director.getInstance().getWinSize().height) + "px"; 520 x.dom.style.margin = 0; 521 cc.DOM.setTransform(x); 522 x.dom.transforms(); 523 cc.DOM.addMethods(x); 524 //x.dom.style.border = 'red 1px dotted'; 525 }; 526 527 /** 528 * Converts cc.Sprite or cc.MenuItem to DOM elements <br/> 529 * It currently only supports cc.Sprite and cc.MenuItem 530 * @function 531 * @param {cc.Sprite|cc.MenuItem|Array} 532 * * @example 533 * // example 534 * cc.DOM.convert(Sprite1, Sprite2, Menuitem); 535 * 536 * var myDOMElements = [Sprite1, Sprite2, MenuItem]; 537 * cc.DOM.convert(myDOMElements); 538 */ 539 cc.DOM.convert = function () { 540 //if passing by list, make it an array 541 if (arguments.length > 1) { 542 return cc.DOM.convert(arguments); 543 } 544 else if (arguments.length == 1 && !arguments[0].length) { 545 return cc.DOM.convert([arguments[0]]); 546 } 547 var args = arguments[0]; 548 for (var i = 0; i < args.length; i++) { 549 //first check if its sprite or menuitem 550 if (args[i] instanceof cc.Sprite) { 551 // create a canvas 552 if (!args[i].dom) 553 cc.DOM.forSprite(args[i]); 554 } 555 else if (args[i] instanceof cc.MenuItemToggle) { 556 if (!args[i].dom) 557 cc.DOM.forMenuToggler(args[i]); 558 } 559 560 else if (args[i] instanceof cc.MenuItem) { 561 if (!args[i].dom) 562 cc.DOM.forMenuItem(args[i]); 563 } 564 else { 565 cc.log('DOM converter only supports sprite and menuitems yet'); 566 } 567 cc.DOM.addMethods(args[i]); 568 args[i].visit = function () { 569 }; 570 args[i].transform = function () { 571 }; 572 cc.DOM.setTransform(args[i]); 573 args[i].setVisible(args[i].isVisible()); 574 if (cc.DOMEditMode) { 575 //add hover event to popup inspector 576 if (!cc.DOM.tooltip) { 577 var style = cc.$new('style'); 578 style.textContent = ".CCDOMEdit:hover{border: rgba(255,0,0,0.5) 2px dashed;left: -2px;} .CCDOMEdit " 579 + " #CCCloseButton{width:80px;height:15px;background: rgba(0,0,0,0.4);border:1px solid #aaaaaa;font-size: 9px;line-height:9px;color:#bbbbbb;} " 580 + " .CCTipWindow .CCTipMove{cursor:move;} .CCTipWindow .CCTipRotate{cursor:w-resize;} .CCTipWindow .CCTipScale{cursor:ne-resize;} " 581 + ".CCTipWindow .CCTipSkew{cursor:se-resize;} .CCTipWindow input{width:40px;background: rgba(0,0,0,0.5);color:white;border:none;border-bottom: 1px solid #fff;} " 582 + "div.CCTipWindow:hover{color:rgb(50,50,255);}"; 583 document.body.appendChild(style); 584 cc.container.style.overflow = "visible"; 585 var tip = cc.DOM.tooltip = cc.$new('div'); 586 tip.mouseDown = false; 587 document.body.appendChild(tip); 588 tip.addClass('CCTipWindow'); 589 tip.style.width = '140px'; 590 tip.style.height = '134px'; 591 tip.style.background = 'rgba(50,50,50,0.5)'; 592 tip.style.border = '1px rgba(255,255,255,0.5) solid'; 593 tip.style.borderRadius = '5px'; 594 tip.style.color = 'rgb(255,255,255)'; 595 tip.style.boxShadow = '0 0 10px 1px rgba(0,0,0,0.5)'; 596 tip.style.position = 'absolute'; 597 tip.style.display = 'none'; 598 tip.style.top = 0; 599 tip.style.left = '-150px'; 600 tip.style[cc.$.pfx + "Transform"] = 'translate3d(0,0,100px)'; 601 tip.style[cc.$.pfx + 'UserSelect'] = 'none'; 602 tip.innerHTML = '<table><tr>' + 603 '<td><label class="CCTipMove">Move</label></td><td><input type="text" value="12" id="posx"/></td><td><input type="text" value="12" id="posy"/></td></tr>' + 604 '<tr><td><label class="CCTipRotate">Rotate</label></td><td><input type="text" value="12" id="rot"/></td></tr>' + 605 '<tr><td><label class="CCTipScale">Scale</label></td><td><input type="text" value="12" id="scalex"/></td><td><input type="text" value="12" id="scaley"/></td></tr>' + 606 '<tr><td><label class="CCTipSkew">Skew</label></td><td><input type="text" value="12" id="skewx"/></td><td><input type="text" value="12" id="skewy"/></td></tr>' + 607 '</table><button id="CCCloseButton">Close</button>'; 608 tip.updateNumbers = function () { 609 var t = cc.DOM.tooltip; 610 if (t.target) { 611 t.find("#posx").value = t.target._position.x; 612 t.find("#posy").value = t.target._position.y; 613 t.find("#rot").value = t.target._rotation; 614 t.find("#scalex").value = t.target._scaleX; 615 t.find("#scaley").value = t.target._scaleY; 616 t.find("#skewx").value = t.target._skewX; 617 t.find("#skewy").value = t.target._skewY; 618 } 619 }; 620 tip.find('.CCTipMove').addEventListener('mousedown', function (e) { 621 tip.mode = 'move'; 622 tip.initialpos = {x:e.clientX, y:e.clientY}; 623 tip.mouseDown = true; 624 }); 625 tip.find('.CCTipRotate').addEventListener('mousedown', function (e) { 626 //find out the position of cc.canvas 627 var canvaspos = cc.$.findpos(cc.canvas); 628 //find out the bottom left position of cc.canvas, adding canvas height to canvaspos 629 var canvaspos = {x:canvaspos.x, y:canvaspos.y + cc.canvas.height}; 630 //add the position of the element from canvas bottom left 631 tip.nodepos = tip.target.getPosition(); 632 tip.nodepos = {x:canvaspos.x + tip.nodepos.x, y:canvaspos.y - tip.nodepos.y}; 633 tip.startPos = {x:e.x, y:e.y}; 634 tip.mode = 'rot'; 635 tip.initialpos = {x:e.clientX, y:e.clientY}; 636 tip.mouseDown = true; 637 //also need to find out the starting angle 638 var C = {x:tip.startPos.x, y:tip.nodepos.y}; 639 var A = tip.startPos; 640 var B = tip.nodepos; 641 var a = Math.sqrt(Math.pow((B.x - C.x), 2) + Math.pow((B.y - C.y), 2)); 642 var b = Math.sqrt(Math.pow((A.x - C.x), 2) + Math.pow((A.y - C.y), 2)); 643 var c = Math.sqrt(Math.pow((A.x - B.x), 2) + Math.pow((A.y - B.y), 2)); 644 var theta = ((a * a) + (c * c) - (b * b)) / (2 * a * c); 645 var theta = Math.acos(theta) * (180 / cc.PI); 646 tip.startAngle = theta; 647 tip.startRot = tip.target.getRotation(); 648 }); 649 tip.find('.CCTipScale').addEventListener('mousedown', function (e) { 650 tip.mode = 'scale'; 651 tip.initialpos = {x:e.clientX, y:e.clientY}; 652 tip.mouseDown = true; 653 }); 654 tip.find('.CCTipSkew').addEventListener('mousedown', function (e) { 655 tip.mode = 'skew'; 656 tip.initialpos = {x:e.clientX, y:e.clientY}; 657 tip.mouseDown = true; 658 }); 659 document.body.addEventListener('mousemove', function (e) { 660 if (tip.mode == 'move') { 661 var movex = e.clientX - tip.initialpos.x; 662 var movey = e.clientY - tip.initialpos.y; 663 var nodepos = tip.target.getPosition(); 664 tip.target.setPosition(movex + nodepos.x, -movey + nodepos.y); 665 tip.initialpos = {x:e.clientX, y:e.clientY}; 666 tip.updateNumbers(); 667 } 668 else if (tip.mode == 'rot') { 669 //get the third point position 670 var C = {x:e.x, y:e.y}; 671 var A = tip.startPos; 672 var B = tip.nodepos; 673 var a = Math.sqrt(Math.pow((B.x - C.x), 2) + Math.pow((B.y - C.y), 2)); 674 var b = Math.sqrt(Math.pow((A.x - C.x), 2) + Math.pow((A.y - C.y), 2)); 675 var c = Math.sqrt(Math.pow((A.x - B.x), 2) + Math.pow((A.y - B.y), 2)); 676 var theta = ((a * a) + (c * c) - (b * b)) / (2 * a * c); 677 var theta = Math.acos(theta) * (180 / cc.PI); 678 //console.log({a:a,b:b,c:c,A:A,B:B,C:C}); 679 680 681 //get current mouse 682 var movey = e.clientY - tip.initialpos.y; 683 var movex = e.clientX - tip.initialpos.x; 684 if (e.y > tip.startPos.y) { 685 tip.target.setRotation(-theta + tip.startRot); 686 } 687 else { 688 tip.target.setRotation(theta + tip.startRot); 689 } 690 tip.updateNumbers(); 691 } 692 else if (tip.mode == 'scale') { 693 //find out the position of cc.canvas 694 //find out the bottom left position of cc.canvas 695 //add the position of the element from canvas bottom left 696 var movey = e.clientY - tip.initialpos.y; 697 var movex = e.clientX - tip.initialpos.x; 698 var nodescalex = tip.target.getScaleX(); 699 var nodescaley = tip.target.getScaleY(); 700 tip.target.setScale(nodescalex - (movex / 150), nodescaley + (movey / 150)); 701 tip.initialpos = {x:e.clientX, y:e.clientY}; 702 tip.updateNumbers(); 703 } 704 else if (tip.mode == 'skew') { 705 var movey = e.clientY - tip.initialpos.y; 706 var movex = e.clientX - tip.initialpos.x; 707 var nodeskewx = tip.target.getSkewX(); 708 var nodeskewy = tip.target.getSkewY(); 709 tip.target.setSkewX(nodeskewx - (movex / 4)); 710 tip.target.setSkewY(nodeskewy + (movey / 4)); 711 tip.initialpos = {x:e.clientX, y:e.clientY}; 712 tip.updateNumbers(); 713 } 714 }); 715 tip.find('#CCCloseButton').addEventListener('click', function () { 716 tip.mode = null; 717 tip.style.display = 'none'; 718 tip.mouseDown = false; 719 }); 720 document.addEventListener('mouseup', function () { 721 tip.mode = null; 722 tip.mouseDown = false; 723 }); 724 } 725 args[i].dom.ccnode = args[i]; 726 var that = args[i]; 727 args[i].dom.addEventListener('mouseover', function () { 728 this.style.zIndex = 999999; 729 730 if(this.showTooltipDiv !== undefined && this.showTooltipDiv === false) 731 return; 732 733 if (!cc.DOM.tooltip.mouseDown) { 734 var pos = cc.$.findpos(this); 735 cc.DOM.tooltip.style.display = 'block'; 736 cc.DOM.tooltip.prependTo(this); 737 cc.DOM.tooltip.target = that; 738 this.style.zIndex = 999999; 739 cc.DOM.tooltip.updateNumbers(); 740 } 741 }); 742 args[i].dom.addEventListener('mouseout', function () { 743 this.style.zIndex = this.ccnode._zOrder; 744 }); 745 } 746 } 747 };