1/** 2 * @namespace 3 */ 4var collie = collie || {}; 5 6(function () { 7 /** 8 * ì½ë¦¬ ë²ì 9 * 10 * @name collie.version 11 * @description ìë ì¹íëë¯ë¡ ì§ì ìì íì§ ìëë¤. 12 */ 13 collie.version = "1.1.0"; 14 15 /** 16 * í´ëì¤ ë§ë¤ê¸° 17 * 18 * @method collie#Class 19 * @param {Object} o í´ëì¤ ë©¤ë², $initì ì´ì©í´ ìì±ì를 ì ìí ì ìë¤. 20 * @param {collie.Class} oParent ììë°ì ë¶ëª¨ í´ëì¤ 21 * @return {collie.Class} 22 * @example 23 * var Person = collie.Class({ 24 * gender : false, 25 * walk : function () { return "walking!"; } 26 * }); 27 * 28 * var Male = collie.Class({ 29 * name : "", 30 * gender : "male" 31 * }, Person); 32 * 33 * var oDavid = new Male(); 34 * oDavid.name = "david"; 35 * 36 * alert(oDavid.name); // david 37 * alert(oDavid.gender); // male 38 * alert(oDavid.walk()); // walking! 39 * 40 * @example 41 * override 42 * var Person = collie.Class({ 43 * testMethod : function () { 44 * 45 * } 46 * }); 47 * 48 * var Male = collie.Class({ 49 * testMethod : function () { 50 * // blah 51 * this.constructor.$super.testMethod.apply(this, arguments); 52 * } 53 * }, Person); 54 */ 55 collie.Class = function (o, oParent) { 56 var $init = null; 57 58 if ("$init" in o) { 59 $init = o.$init; 60 delete o.$init; 61 } 62 63 var F = function () { 64 if ($init !== null) { 65 $init.apply(this, arguments); 66 } 67 }; 68 69 if (typeof oParent !== "undefined") { 70 F = function () { 71 // ë¶ëª¨ì ìì±ì ì¤í 72 oParent.apply(this, arguments); 73 74 // ììì ìì±ì ì¤í 75 if ($init !== null) { 76 $init.apply(this, arguments); 77 } 78 }; 79 80 var Parent = function () {}; 81 Parent.prototype = oParent.prototype; 82 F.$super = oParent.prototype; 83 F.prototype = new Parent(); 84 F.prototype.constructor = F; 85 } 86 87 for (var i in o) { 88 if (o.hasOwnProperty(i) && i !== "prototype") { 89 F.prototype[i] = o[i]; 90 } 91 } 92 93 return F; 94 }; 95 96 /** 97 * ì주 ì°ì´ë ì í¸ ëª¨ì 98 * @namespace 99 */ 100 collie.util = new (collie.Class(/** @lends collie.util */{ 101 $init : function () { 102 this._sCSSPrefix = null; 103 this._htDeviceInfo = null; 104 this._bSupport3d = null; 105 this._bSupportCSS3 = null; 106 this._htBoundary = { 107 left : 0, 108 right : 0, 109 top : 0, 110 bottom : 0 111 }; 112 }, 113 114 /** 115 * ìì´ëë¡ íì ê°ì²´ ì¸ì¤í´ì¤ë¥¼ ê°ì ¸ì¨ë¤ 116 * ì£¼ë¡ DOM ë°©ìì¼ ë ì¬ì© ëë¤ 117 * 118 * @param {Number} nId 119 * @return {collie.DisplayObject} 120 */ 121 getDisplayObjectById : function (nId) { 122 return collie.DisplayObject.htFactory[nId]; 123 }, 124 125 /** 126 * nameì¼ë¡ íì ê°ì²´ ì¸ì¤í´ì¤ë¥¼ ê°ì ¸ì¨ë¤ 127 * 128 * @param {String} sName 129 * @return {collie.DisplayObject} 130 */ 131 getDisplayObjectByName : function (sName) { 132 for (var i in collie.DisplayObject.htFactory) { 133 if (collie.DisplayObject.htFactory[i].get("name") === sName) { 134 return collie.DisplayObject.htFactory[i]; 135 } 136 } 137 138 return false; 139 }, 140 141 /** 142 * userAgent ê°ì¼ë¡ íì¬ ë¨ë§ ì 보를 ë°í íë¤ 143 * ê°ì íë² ì»ì´ì¤ë©´ ë¤ìë¶í°ë ìºìë ê°ì ì¬ì© íë¤ 144 * 145 * @return {Object} htInfo 146 * @return {Boolean} htInfo.desktop ë°ì¤í¬í ì¬ë¶ 147 * @return {Boolean} htInfo.supportCanvas ìºë²ì¤ ì§ì ì¬ë¶ 148 * @return {Boolean|Number} htInfo.android ìëë¡ì´ëë¼ë©´ ëë²ì§¸ê¹ì§ì ë²ì ¼, ìëë¡ì´ëê° ìëë¼ë©´ false 149 * @return {Boolean|Number} htInfo.ios iOSë¼ë©´ ëë²ì§¸ê¹ì§ì ë²ì ¼, iOSê° ìëë¼ë©´ false 150 * @return {Boolean|Number} htInfo.ie IE ë¸ë¼ì°ì ë¼ë©´ 첫ë²ì§¸ê¹ì§ì ë²ì , IE ë¸ë¼ì°ì ê° ìëë¼ë©´ false 151 * @return {Boolean|Number} htInfo.chrome Agentì Chromeì´ í¬í¨ë¼ ìëì§ ì¬ë¶ 152 */ 153 getDeviceInfo : function (sAgent) { 154 if (this._htDeviceInfo !== null && typeof sAgent === "undefined") { 155 return this._htDeviceInfo; 156 } 157 158 var aMat = null; 159 var bIsDesktop = false; 160 var bSupportCanvas = typeof CanvasRenderingContext2D !== "undefined"; 161 var bIsAndroid = false; 162 var bIsIOS = false; 163 var bIsIE = false; 164 var bHasChrome = (/chrome/i.test(sAgent)) ? true : false;
165 var sAgent = sAgent || navigator.userAgent; 166 var nVersion = 0; 167 168 if (/android/i.test(sAgent)) { // android 169 bIsAndroid = true; 170 aMat = sAgent.toString().match(/android ([0-9]\.[0-9])\.?([0-9]?)/i); 171 172 if (aMat && aMat[1]) { 173 nVersion = (parseFloat(aMat[1]) + (aMat[2] ? aMat[2] * 0.01 : 0)).toFixed(2); 174 } 175 } else if (/(iphone|ipad|ipod)/i.test(sAgent)) { // iOS 176 bIsIOS = true; 177 aMat = sAgent.toString().match(/([0-9]_[0-9])/i); 178 179 if (aMat && aMat[1]) { 180 nVersion = parseFloat(aMat[1].replace(/_/, '.')); 181 } 182 } else { // PC 183 bIsDesktop = true; 184 185 if (/(MSIE)/i.test(sAgent)) { // IE 186 bIsIE = true; 187 aMat = sAgent.toString().match(/MSIE ([0-9])/i); 188 189 if (aMat && aMat[1]) { 190 nVersion = parseInt(aMat[1], 10); 191 } 192 } 193 } 194 195 this._htDeviceInfo = { 196 supportCanvas : bSupportCanvas, 197 desktop : bIsDesktop, 198 android : bIsAndroid ? nVersion : false, 199 ios : bIsIOS ? nVersion : false, 200 ie : bIsIE ? nVersion : false, 201 chrome : bHasChrome 202 }; 203 204 return this._htDeviceInfo; 205 }, 206 207 /** 208 * ë¸ë¼ì°ì ì ë°ë¥¸ CSS Prefix를 ë°í 209 * 210 * @param {String} sName ëì CSS ìì± ëª (- í¬í¨), ê°ì´ ìì¼ë©´ prefixë§ ë°í 211 * @param {Boolean} bJavascript ìë°ì¤í¬ë¦½í¸ ìì± íì ì¼ë¡ ë°í 212 * @example 213 * collie.util.getCSSPrefix("transform"); // -webkit-transform 214 * collie.util.getCSSPrefix("transform", true); // webkitTransform 215 * 216 * // prefixê° ìì ë 217 * collie.util.getCSSPrefix("transform"); // transform 218 * collie.util.getCSSPrefix("transform", true); // transform 219 * @return {String} ì¡°í©ë CSS Prefix, í¹ì ìì± ëª 220 */ 221 getCSSPrefix : function (sName, bJavascript) { 222 var sResult = ''; 223 224 if (this._sCSSPrefix === null) { 225 this._sCSSPrefix = ''; 226 227 // webkitì´ ê°ì¥ 먼ì ì°ì¼ ê² ê°ìì webkitì ìµìë¨ì¼ë¡ ì®ê¹ 228 if (typeof document.body.style.webkitTransform !== "undefined") { 229 this._sCSSPrefix = "-webkit-"; 230 } else if (typeof document.body.style.MozTransform !== "undefined") { 231 this._sCSSPrefix = "-moz-"; 232 } else if (typeof document.body.style.OTransform !== "undefined") { 233 this._sCSSPrefix = "-o-"; 234 } else if (typeof document.body.style.msTransform !== "undefined") { 235 this._sCSSPrefix = "-ms-"; 236 } 237 } 238 239 sResult = this._sCSSPrefix + (sName ? sName : ''); 240 241 // - 빼기 242 if (bJavascript) { 243 var aTmp = sResult.split("-"); 244 sResult = ''; 245 246 for (var i = 0, len = aTmp.length; i < len; i++) { 247 if (aTmp[i]) { 248 sResult += sResult ? aTmp[i].substr(0, 1).toUpperCase() + aTmp[i].substr(1) : aTmp[i]; 249 } 250 } 251 252 if (this._sCSSPrefix === "-moz-" || this._sCSSPrefix === "-o-") { 253 sResult = sResult.substr(0, 1).toUpperCase() + sResult.substr(1); 254 } 255 } 256 257 return sResult; 258 }, 259 260 /** 261 * CSS3를 ì§ìíëì§ ì¬ë¶ 262 * 263 * @return {Boolean} 264 */ 265 getSupportCSS3 : function () { 266 if (this._bSupportCSS3 === null) { 267 this._bSupportCSS3 = typeof document.body.style[collie.util.getCSSPrefix("transform", true)] !== "undefined" || typeof document.body.style.transform != "undefined"; 268 } 269 270 return this._bSupportCSS3; 271 }, 272 273 /** 274 * CSS3d를 ì§ìíëì§ ì¬ë¶ 275 * 276 * @return {Boolean} 277 */ 278 getSupportCSS3d : function () { 279 if (this._bSupport3d === null) { 280 this._bSupport3d = (typeof document.body.style[collie.util.getCSSPrefix("perspective", true)] !== "undefined" || typeof document.body.style.perspective != "undefined") && (!collie.util.getDeviceInfo().android || collie.util.getDeviceInfo().android >= 4); 281 } 282 283 return this._bSupport3d; 284 }, 285 286 /** 287 * ê°ë를 ë¼ëìì¼ë¡ ë³í 288 * 289 * @param {Number} nDeg 290 * @return {Number} 291 */ 292 toRad : function (nDeg) { 293 return nDeg * Math.PI / 180; 294 }, 295 296 /** 297 * ë¼ëìì ê°ëë¡ ë³í 298 * 299 * @param {Number} nRad 300 * @return {Number} 301 */ 302 toDeg : function (nRad) { 303 return nRad * 180 / Math.PI; 304 }, 305 306 /** 307 * ê·¼ì¬ê° 구í¨(ìì 7ì리 미ë§ì ë²ë¦¼)
308 * - javascript ìì«ì ì°ì° ì¤ë¥ë¡ ì¸í ê·¼ì¬ê° ì°ì°ì 309 * 310 * @param {Number} nValue ê° 311 * @return {Number} 312 */ 313 approximateValue : function (nValue) { 314 return Math.round(nValue * 10000000) / 10000000; 315 }, 316 317 /** 318 * ê°ë를 0~360 ê° ì¬ì´ë¡ ë§ì¶¤ 319 * 320 * @param {Number} nAngleRad ë¼ëì ê° 321 * @return {Number} 322 */ 323 fixAngle : function (nAngleRad) { 324 var nAngleDeg = collie.util.toDeg(nAngleRad); 325 nAngleDeg -= Math.floor(nAngleDeg / 360) * 360; 326 return collie.util.toRad(nAngleDeg); 327 }, 328 329 /** 330 * 거리를 ë°í 331 * 332 * @param {Number} x1 333 * @param {Number} y1 334 * @param {Number} x2 335 * @param {Number} y2 336 * @return {Number} 거리 337 */ 338 getDistance : function (x1, y1, x2, y2) { 339 return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); 340 }, 341 342 /** 343 * ì ë°°ì´ìì ìµì ì¬ê°í ììì 구íë¤ 344 * 345 * @param {Array} aPoints ëì ë°°ì´ [[x1, y1], [x2, y2], ... ] 346 * @return {Object} htResult 347 * @return {Number} htResult.left 348 * @return {Number} htResult.right 349 * @return {Number} htResult.bottom 350 * @return {Number} htResult.top 351 */ 352 getBoundary : function (aPoints) { 353 var nMinX = aPoints[0][0]; 354 var nMaxX = aPoints[0][0]; 355 var nMinY = aPoints[0][1]; 356 var nMaxY = aPoints[0][1]; 357 358 for (var i = 1, len = aPoints.length; i < len; i++) { 359 nMinX = Math.min(nMinX, aPoints[i][0]); 360 nMaxX = Math.max(nMaxX, aPoints[i][0]); 361 nMinY = Math.min(nMinY, aPoints[i][1]); 362 nMaxY = Math.max(nMaxY, aPoints[i][1]); 363 } 364 365 return { 366 left : nMinX, 367 right : nMaxX, 368 top : nMinY, 369 bottom : nMaxY 370 }; 371 }, 372 373 /** 374 * boundary를 pointsë¡ ë³ííë¤ 375 * 376 * @param {Object} htBoundary 377 * @param {Number} htBoundary.left 378 * @param {Number} htBoundary.right 379 * @param {Number} htBoundary.top 380 * @param {Number} htBoundary.bottom 381 * @return {Array} points [[left, top], [right, top], [right, bottom], [left, bottom]] 382 */ 383 getBoundaryToPoints : function (htBoundary) { 384 return [[htBoundary.left, htBoundary.top], [htBoundary.right, htBoundary.top], [htBoundary.right, htBoundary.bottom], [htBoundary.left, htBoundary.bottom]]; 385 }, 386 387 /** 388 * 주ìì queryStringì ê°ì²´í íë¤ 389 * @return {Object} 390 */ 391 queryString : function () { 392 var htResult = {}; 393 394 if (location.search) { 395 var aParam = location.search.substr(1).split("&"); 396 397 for (var i = 0, len = aParam.length; i < len; i++) { 398 var aKeyValue = aParam[i].split("="); 399 htResult[aKeyValue.shift()] = aKeyValue.join("="); 400 } 401 } 402 403 return htResult; 404 }, 405 406 /** 407 * ê°ì²´ë¥¼ ë³µì¬ 408 * 409 * @param {Object} oSource ì본 ê°ì²´ 410 * @return {Object} 411 */ 412 cloneObject : function (oSource) { 413 var oReturn = {}; 414 415 for (var i in oSource) { 416 oReturn[i] = oSource[i]; 417 } 418 419 return oReturn; 420 }, 421 422 /** 423 * zIndexì ë°ë¼ ì¤ë¦ì°¨ì ì ë ¬ë ììë¡ ë°°ì´ì ë£ëë¤ 424 * 425 * @private 426 * @param {Array} aTarget 427 * @param {collie.DisplayObject} oDisplayObject 428 */ 429 pushWithSort : function (aTarget, oDisplayObject) { 430 var bAdded = false; 431 432 for (var i = 0, len = aTarget.length; i < len; i++) { 433 if (aTarget[i]._htOption.zIndex > oDisplayObject._htOption.zIndex) { 434 aTarget.splice(i, 0, oDisplayObject); 435 bAdded = true; 436 break; 437 } 438 } 439 440 if (!bAdded) { 441 aTarget.push(oDisplayObject); 442 } 443 }, 444 445 /** 446 * DOMì addEventListener 447 * 448 * @param {HTMLElement} el 449 * @param {String} sName ì´ë²¤í¸ ì´ë¦, onì ì ì¸í ì´ë¦ 450 * @param {Function} fHandler ë°ì¸ë©í í¨ì 451 * @param {Boolean} bUseCapture ìº¡ì³ ì¬ì© ì¬ë¶ 452 */ 453 addEventListener : function (el, sName, fHandler, bUseCapture) { 454 if ("addEventListener" in el) { 455 el.addEventListener(sName, fHandler, bUseCapture); 456 } else { 457 el.attachEvent("on" + sName, fHandler, bUseCapture); 458 } 459 }, 460 461 /** 462 * DOMì removeEventListener 463 * 464 * @param {HTMLElement} el 465 * @param {String} sName ì´ë²¤í¸ ì´ë¦, onì ì ì¸í ì´ë¦ 466 * @param {Function} fHandler ë°ì¸ë©í í¨ì 467 * @param {Boolean} bUseCapture ìº¡ì³ ì¬ì© ì¬ë¶ 468 */ 469 removeEventListener : function (el, sName, fHandler, bUseCapture) { 470 if ("removeEventListener" in el) { 471 el.removeEventListener(sName, fHandler, bUseCapture); 472 } else { 473 el.detachEvent("on" + sName, fHandler, bUseCapture); 474 } 475 }, 476 477 /** 478 * ì´ë²¤í¸ì 기본 ëìì ë©ì¶ë¤ 479 * 480 * @param {HTMLEvent} e 481 */ 482 stopEventDefault : function (e) { 483 e = e || window.event; 484 485 if ("preventDefault" in e) { 486 e.preventDefault(); 487 } 488 489 e.returnValue = false;
490 }, 491 492 /** 493 * ì리먼í¸ì ìì¹ë¥¼ 구íë¤ 494 * 495 * @param {HTMLElement} 496 * @return {Object} htResult 497 * @return {Number} htResult.x 498 * @return {Number} htResult.y 499 * @return {Number} htResult.width 500 * @return {Number} htResult.height 501 */ 502 getPosition : function (el) { 503 var elDocument = el.ownerDocument || el.document || document; 504 var elHtml = elDocument.documentElement; 505 var elBody = elDocument.body; 506 var htPosition = {}; 507 508 if ("getBoundingClientRect" in el) { 509 var htBox = el.getBoundingClientRect(); 510 htPosition.x = htBox.left; 511 htPosition.x += elHtml.scrollLeft || elBody.scrollLeft; 512 htPosition.y = htBox.top; 513 htPosition.y += elHtml.scrollTop || elBody.scrollTop; 514 htPosition.width = htBox.width; 515 htPosition.height = htBox.height; 516 } else { 517 htPosition.x = 0; 518 htPosition.y = 0; 519 htPosition.width = el.offsetWidth; 520 htPosition.height = el.offsetHeight; 521 522 for (var o = el; o; o = o.offsetParent) { 523 htPosition.x += o.offsetLeft; 524 htPosition.y += o.offsetTop; 525 } 526 527 for (var o = el.parentNode; o; o = o.parentNode) { 528 if (o.tagName === 'BODY') { 529 break; 530 } 531 532 if (o.tagName === 'TR') { 533 htPosition.y += 2; 534 } 535 536 htPosition.x -= o.scrollLeft; 537 htPosition.y -= o.scrollTop; 538 } 539 } 540 541 return htPosition; 542 } 543 }))(); 544 545 // iOSìì ìë¨ë° ì¨ê¸°ê¸° 546 if (collie.util.getDeviceInfo().ios) { 547 window.addEventListener("load", function () { 548 setTimeout(function () { 549 document.body.scrollTop = 0; 550 }, 300); 551 }); 552 } 553 554 // bind polyfill, https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind 555 if (!Function.prototype.bind) { 556 Function.prototype.bind = function (oThis) { 557 if (typeof this !== "function") { 558 // closest thing possible to the ECMAScript 5 internal IsCallable function 559 throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); 560 } 561 562 var aArgs = Array.prototype.slice.call(arguments, 1), 563 fToBind = this, 564 fNOP = function () {}, 565 fBound = function () { 566 return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); 567 }; 568 569 fNOP.prototype = this.prototype; 570 fBound.prototype = new fNOP(); 571 return fBound; 572 }; 573 } 574 575 // Implementation the dashedLine method in Canvas 576 // I had fix some difference with Raphael.js 577 // special thanks to Phrogz and Rod MacDougall 578 // http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas 579 var CP = window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype; 580 if (CP && CP.lineTo) { 581 CP._dashedLineProperty = { 582 index : 0, 583 length : 0 584 }; 585 586 CP.resetDashedLine = function () { 587 this._dashedLineProperty = { 588 index : 0, 589 length : 0 590 }; 591 }; 592 593 CP.dashedLine = function(x, y, x2, y2, da, width) { 594 if (!da) da = [10, 5]; 595 var dx = (x2-x), dy = (y2-y); 596 var len = Math.sqrt(dx * dx + dy * dy); 597 var rot = Math.atan2(dy, dx); 598 var dc = da.length; 599 var di = this._dashedLineProperty.index || 0; 600 var cx = this._dashedLineProperty.length || 0; 601 var cy = 0; 602 var sx = 0; 603 var sy = 0; 604 605 while (len > cx) { 606 if (sx !== 0 || cx === 0) { 607 cx += da[di++ % dc] * width; 608 } 609 610 if (cx > len) { 611 this._dashedLineProperty.length = cx - len; 612 cx = len; 613 } 614 615 sx = x + cx * Math.cos(rot); 616 sy = y + cx * Math.sin(rot); 617 di % 2 === 1 ? this.lineTo(sx, sy) : this.moveTo(sx, sy); 618 } 619 620 this._dashedLineProperty.index = di; 621 } 622 } 623 624 collie.raphaelDashArray = { 625 "": [0], 626 "none": [0], 627 "-": [3, 1], 628 ".": [1, 1], 629 "-.": [3, 1, 1, 1], 630 "-..": [3, 1, 1, 1, 1, 1], 631 ". ": [1, 3], 632 "- ": [4, 3], 633 "--": [8, 3], 634 "- .": [4, 3, 1, 3], 635 "--.": [8, 3, 1, 3], 636 "--..": [8, 3, 1, 3, 1, 3] 637 }; 638})(); 639/*
640 * TERMS OF USE - EASING EQUATIONS 641 * Open source under the BSD License. 642 * Copyright (c) 2001 Robert Penner, all rights reserved. 643 */ 644/** 645 * ìë¡ì´ ì´íí¸ í¨ì를 ìì±íë¤. 646 * ì§ë íë ììí¬ì jindo.Effect를 ì¬ì© 647 * @namespace ìì¹ì ì¤ê°ê°ì ì½ê² ì»ì ì ìê² íë static ì»´í¬ëí¸ 648 * @function 649 * @param {Function} fEffect 0~1 ì¬ì´ì ì«ì를 ì¸ìë¡ ë°ì ì í´ì§ ê³µìì ë°ë¼ 0~1 ì¬ì´ì ê°ì 리í´íë í¨ì 650 * @return {Function} ì´íí¸ í¨ì. ì´ í¨ìë ììê°ê³¼ ì¢ ë£ê°ì ì ë ¥íì¬ í¹ì ìì ì í´ë¹íë ê°ì 구íë íì´ë° í¨ì를 ìì±íë¤. 651 */ 652collie.Effect = function(fEffect) { 653 if (this instanceof arguments.callee) { 654 throw new Error("You can't create a instance of this"); 655 } 656 657 var rxNumber = /^(\-?[0-9\.]+)(%|px|pt|em)?$/, 658 rxRGB = /^rgb\(([0-9]+)\s?,\s?([0-9]+)\s?,\s?([0-9]+)\)$/i, 659 rxHex = /^#([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i, 660 rx3to6 = /^#([0-9A-F])([0-9A-F])([0-9A-F])$/i; 661 662 var getUnitAndValue = function(v) { 663 var nValue = v, sUnit; 664 665 if (rxNumber.test(v)) { 666 nValue = parseFloat(v); 667 sUnit = RegExp.$2 || ""; 668 } else if (rxRGB.test(v)) { 669 nValue = [parseInt(RegExp.$1, 10), parseInt(RegExp.$2, 10), parseInt(RegExp.$3, 10)]; 670 sUnit = 'color'; 671 } else if (rxHex.test(v = v.replace(rx3to6, '#$1$1$2$2$3$3'))) { 672 nValue = [parseInt(RegExp.$1, 16), parseInt(RegExp.$2, 16), parseInt(RegExp.$3, 16)]; 673 sUnit = 'color'; 674 } 675 676 return { 677 nValue : nValue, 678 sUnit : sUnit 679 }; 680 }; 681 682 return function(nStart, nEnd) { 683 var sUnit; 684 if (arguments.length > 1) { 685 nStart = getUnitAndValue(nStart); 686 nEnd = getUnitAndValue(nEnd); 687 sUnit = nEnd.sUnit; 688 } else { 689 nEnd = getUnitAndValue(nStart); 690 nStart = null; 691 sUnit = nEnd.sUnit; 692 } 693 694 // ëê°ì ë¨ìê° ë¤ë¥´ë©´ 695 if (nStart && nEnd && nStart.sUnit != nEnd.sUnit) { 696 throw new Error('unit error'); 697 } 698 699 nStart = nStart && nStart.nValue; 700 nEnd = nEnd && nEnd.nValue; 701 702 var fReturn = function(p) { 703 var nValue = fEffect(p), 704 getResult = function(s, d) { 705 return (d - s) * nValue + s + sUnit; 706 }; 707 708 if (sUnit == 'color') { 709 var r = Math.max(0, Math.min(255, parseInt(getResult(nStart[0], nEnd[0]), 10))) << 16; 710 r |= Math.max(0, Math.min(255, parseInt(getResult(nStart[1], nEnd[1]), 10))) << 8; 711 r |= Math.max(0, Math.min(255, parseInt(getResult(nStart[2], nEnd[2]), 10))); 712 713 r = r.toString(16).toUpperCase(); 714 for (var i = 0; 6 - r.length; i++) { 715 r = '0' + r; 716 } 717 718 return '#' + r; 719 } 720 return getResult(nStart, nEnd); 721 }; 722 723 if (nStart === null) { 724 fReturn.setStart = function(s) { 725 s = getUnitAndValue(s); 726 727 if (s.sUnit != sUnit) { 728 throw new Error('unit eror'); 729 } 730 nStart = s.nValue; 731 }; 732 } 733 return fReturn; 734 }; 735}; 736 737/** 738 * linear ì´íí¸ í¨ì 739 */ 740collie.Effect.linear = collie.Effect(function(s) { 741 return s; 742}); 743 744/** 745 * easeInSine ì´íí¸ í¨ì 746 */ 747collie.Effect.easeInSine = collie.Effect(function(s) { 748 return (s == 1) ? 1 : -Math.cos(s * (Math.PI / 2)) + 1; 749}); 750/** 751 * easeOutSine ì´íí¸ í¨ì 752 */ 753collie.Effect.easeOutSine = collie.Effect(function(s) { 754 return Math.sin(s * (Math.PI / 2)); 755}); 756/** 757 * easeInOutSine ì´íí¸ í¨ì 758 */ 759collie.Effect.easeInOutSine = collie.Effect(function(s) { 760 return (s < 0.5) ? collie.Effect.easeInSine(0, 1)(2 * s) * 0.5 : collie.Effect.easeOutSine(0, 1)((2 * s) - 1) * 0.5 + 0.5; 761}); 762/** 763 * easeOutInSine ì´íí¸ í¨ì 764 */ 765collie.Effect.easeOutInSine = collie.Effect(function(s) { 766 return (s < 0.5) ? collie.Effect.easeOutSine(0, 1)(2 * s) * 0.5 : collie.Effect.easeInSine(0, 1)((2 * s) - 1) * 0.5 + 0.5; 767}); 768 769/** 770 * easeInQuad ì´íí¸ í¨ì 771 */ 772collie.Effect.easeInQuad = collie.Effect(function(s) { 773 return s * s; 774}); 775/** 776 * easeOutQuad ì´íí¸ í¨ì 777 */ 778collie.Effect.easeOutQuad = collie.Effect(function(s) { 779 return -(s * (s - 2)); 780}); 781/** 782 * easeInOutQuad ì´íí¸ í¨ì 783 */ 784collie.Effect.easeInOutQuad = collie.Effect(function(s) { 785 return (s < 0.5) ? collie.Effect.easeInQuad(0, 1)(2 * s) * 0.5 : collie.Effect.easeOutQuad(0, 1)((2 * s) - 1) * 0.5 + 0.5; 786}); 787/** 788 * easeOutInQuad ì´íí¸ í¨ì 789 */ 790collie.Effect.easeOutInQuad = collie.Effect(function(s) { 791 return (s < 0.5) ? collie.Effect.easeOutQuad(0, 1)(2 * s) * 0.5 : collie.Effect.easeInQuad(0, 1)((2 * s) - 1) * 0.5 + 0.5; 792}); 793 794/** 795 * easeInCubic ì´íí¸ í¨ì 796 */ 797collie.Effect.easeInCubic = collie.Effect(function(s) { 798 return Math.pow(s, 3); 799}); 800/** 801 * easeOutCubic ì´íí¸ í¨ì 802 */ 803collie.Effect.easeOutCubic = collie.Effect(function(s) { 804 return Math.pow((s - 1), 3) + 1; 805}); 806/** 807 * easeInOutCubic ì´íí¸ í¨ì 808 */ 809collie.Effect.easeInOutCubic = collie.Effect(function(s) { 810 return (s < 0.5) ? collie.Effect.easeIn(0, 1)(2 * s) * 0.5 : collie.Effect.easeOut(0, 1)((2 * s) - 1) * 0.5 + 0.5; 811}); 812/** 813 * easeOutInCubic ì´íí¸ í¨ì 814 */ 815collie.Effect.easeOutInCubic = collie.Effect(function(s) { 816 return (s < 0.5) ? collie.Effect.easeOut(0, 1)(2 * s) * 0.5 : collie.Effect.easeIn(0, 1)((2 * s) - 1) * 0.5 + 0.5; 817}); 818 819/** 820 * easeInQuart ì´íí¸ í¨ì 821 */ 822collie.Effect.easeInQuart = collie.Effect(function(s) { 823 return Math.pow(s, 4); 824}); 825/** 826 * easeOutQuart ì´íí¸ í¨ì 827 */ 828collie.Effect.easeOutQuart = collie.Effect(function(s) { 829 return -(Math.pow(s - 1, 4) - 1); 830}); 831/** 832 * easeInOutQuart ì´íí¸ í¨ì 833 */ 834collie.Effect.easeInOutQuart = collie.Effect(function(s) { 835 return (s < 0.5) ? collie.Effect.easeInQuart(0, 1)(2 * s) * 0.5 : collie.Effect.easeOutQuart(0, 1)((2 * s) - 1) * 0.5 + 0.5; 836}); 837/** 838 * easeOutInQuart ì´íí¸ í¨ì 839 */ 840collie.Effect.easeOutInQuart = collie.Effect(function(s) { 841 return (s < 0.5) ? collie.Effect.easeOutQuart(0, 1)(2 * s) * 0.5 : collie.Effect.easeInQuart(0, 1)((2 * s) - 1) * 0.5 + 0.5; 842}); 843 844/** 845 * easeInQuint ì´íí¸ í¨ì 846 */ 847collie.Effect.easeInQuint = collie.Effect(function(s) { 848 return Math.pow(s, 5); 849}); 850/** 851 * easeOutQuint ì´íí¸ í¨ì 852 */ 853collie.Effect.easeOutQuint = collie.Effect(function(s) { 854 return Math.pow(s - 1, 5) + 1; 855}); 856/** 857 * easeInOutQuint ì´íí¸ í¨ì 858 */ 859collie.Effect.easeInOutQuint = collie.Effect(function(s) { 860 return (s < 0.5) ? collie.Effect.easeInQuint(0, 1)(2 * s) * 0.5 : collie.Effect.easeOutQuint(0, 1)((2 * s) - 1) * 0.5 + 0.5; 861}); 862/** 863 * easeOutInQuint ì´íí¸ í¨ì 864 */ 865collie.Effect.easeOutInQuint = collie.Effect(function(s) { 866 return (s < 0.5) ? collie.Effect.easeOutQuint(0, 1)(2 * s) * 0.5 : collie.Effect.easeInQuint(0, 1)((2 * s) - 1) * 0.5 + 0.5; 867}); 868 869/** 870 * easeInCircle ì´íí¸ í¨ì 871 */ 872collie.Effect.easeInCircle = collie.Effect(function(s) { 873 return -(Math.sqrt(1 - (s * s)) - 1); 874}); 875/** 876 * easeOutCircle ì´íí¸ í¨ì 877 */ 878collie.Effect.easeOutCircle = collie.Effect(function(s) { 879 return Math.sqrt(1 - (s - 1) * (s - 1)); 880}); 881/** 882 * easeInOutCircle ì´íí¸ í¨ì 883 */ 884collie.Effect.easeInOutCircle = collie.Effect(function(s) { 885 return (s < 0.5) ? collie.Effect.easeInCircle(0, 1)(2 * s) * 0.5 : collie.Effect.easeOutCircle(0, 1)((2 * s) - 1) * 0.5 + 0.5; 886}); 887/** 888 * easeOutInCircle ì´íí¸ í¨ì 889 */ 890collie.Effect.easeOutInCircle = collie.Effect(function(s) { 891 return (s < 0.5) ? collie.Effect.easeOutCircle(0, 1)(2 * s) * 0.5 : collie.Effect.easeInCircle(0, 1)((2 * s) - 1) * 0.5 + 0.5; 892}); 893 894/** 895 * easeInBack ì´íí¸ í¨ì 896 */ 897collie.Effect.easeInBack = collie.Effect(function(s) { 898 var n = 1.70158; 899 return (s == 1) ? 1 : (s / 1) * (s / 1) * ((1 + n) * s - n); 900}); 901/** 902 * easeOutBack ì´íí¸ í¨ì 903 */ 904collie.Effect.easeOutBack = collie.Effect(function(s) { 905 var n = 1.70158; 906 return (s === 0) ? 0 : (s = s / 1 - 1) * s * ((n + 1) * s + n) + 1; 907}); 908/** 909 * easeInOutBack ì´íí¸ í¨ì 910 */ 911collie.Effect.easeInOutBack = collie.Effect(function(s) { 912 return (s < 0.5) ? collie.Effect.easeInBack(0, 1)(2 * s) * 0.5 : collie.Effect.easeOutBack(0, 1)((2 * s) - 1) * 0.5 + 0.5; 913}); 914 915/** 916 * easeInElastic ì´íí¸ í¨ì 917 */ 918collie.Effect.easeInElastic = collie.Effect(function(s) { 919 var p = 0, a = 0, n; 920 if (s === 0) { 921 return 0; 922 } 923 if ((s/=1) == 1) { 924 return 1; 925 } 926 if (!p) { 927 p = 0.3; 928 } 929 if (!a || a < 1) { 930 a = 1; n = p / 4; 931 } else { 932 n = p / (2 * Math.PI) * Math.asin(1 / a); 933 } 934 return -(a * Math.pow(2, 10 * (s -= 1)) * Math.sin((s - 1) * (2 * Math.PI) / p)); 935}); 936 937/** 938 * easeOutElastic ì´íí¸ í¨ì 939 */ 940collie.Effect.easeOutElastic = collie.Effect(function(s) { 941 var p = 0, a = 0, n; 942 if (s === 0) { 943 return 0; 944 } 945 if ((s/=1) == 1) { 946 return 1; 947 } 948 if (!p) { 949 p = 0.3; 950 } 951 if (!a || a < 1) { 952 a = 1; n = p / 4; 953 } else { 954 n = p / (2 * Math.PI) * Math.asin(1 / a); 955 } 956 return (a * Math.pow(2, -10 * s) * Math.sin((s - n) * (2 * Math.PI) / p ) + 1); 957}); 958/** 959 * easeInOutElastic ì´íí¸ í¨ì 960 */ 961collie.Effect.easeInOutElastic = collie.Effect(function(s) { 962 var p = 0, a = 0, n; 963 if (s === 0) { 964 return 0; 965 } 966 if ((s/=1/2) == 2) { 967 return 1; 968 } 969 if (!p) { 970 p = (0.3 * 1.5); 971 } 972 if (!a || a < 1) { 973 a = 1; n = p / 4; 974 } else { 975 n = p / (2 * Math.PI) * Math.asin(1 / a); 976 } 977 if (s < 1) { 978 return -0.5 * (a * Math.pow(2, 10 * (s -= 1)) * Math.sin( (s - n) * (2 * Math.PI) / p )); 979 } 980 return a * Math.pow(2, -10 * (s -= 1)) * Math.sin( (s - n) * (2 * Math.PI) / p ) * 0.5 + 1; 981}); 982 983/** 984 * easeOutBounce ì´íí¸ í¨ì 985 */ 986collie.Effect.easeOutBounce = collie.Effect(function(s) { 987 if (s < (1 / 2.75)) { 988 return (7.5625 * s * s); 989 } else if (s < (2 / 2.75)) { 990 return (7.5625 * (s -= (1.5 / 2.75)) * s + 0.75); 991 } else if (s < (2.5 / 2.75)) { 992 return (7.5625 * (s -= (2.25 / 2.75)) * s + 0.9375); 993 } else { 994 return (7.5625 * (s -= (2.625 / 2.75)) * s + 0.984375); 995 } 996}); 997/** 998 * easeInBounce ì´íí¸ í¨ì 999 */ 1000collie.Effect.easeInBounce = collie.Effect(function(s) { 1001 return 1 - collie.Effect.easeOutBounce(0, 1)(1 - s); 1002}); 1003/** 1004 * easeInOutBounce ì´íí¸ í¨ì 1005 */ 1006collie.Effect.easeInOutBounce = collie.Effect(function(s) { 1007 return (s < 0.5) ? collie.Effect.easeInBounce(0, 1)(2 * s) * 0.5 : collie.Effect.easeOutBounce(0, 1)((2 * s) - 1) * 0.5 + 0.5; 1008}); 1009 1010/** 1011 * easeInExpo ì´íí¸ í¨ì 1012 */ 1013collie.Effect.easeInExpo = collie.Effect(function(s) { 1014 return (s === 0) ? 0 : Math.pow(2, 10 * (s - 1)); 1015}); 1016/** 1017 * easeOutExpo ì´íí¸ í¨ì 1018 */ 1019collie.Effect.easeOutExpo = collie.Effect(function(s) { 1020 return (s == 1) ? 1 : -Math.pow(2, -10 * s / 1) + 1; 1021}); 1022/** 1023 * easeInOutExpo ì´íí¸ í¨ì 1024 */ 1025collie.Effect.easeInOutExpo = collie.Effect(function(s) { 1026 return (s < 0.5) ? collie.Effect.easeInExpo(0, 1)(2 * s) * 0.5 : collie.Effect.easeOutExpo(0, 1)((2 * s) - 1) * 0.5 + 0.5; 1027}); 1028/** 1029 * easeOutExpo ì´íí¸ í¨ì 1030 */ 1031collie.Effect.easeOutInExpo = collie.Effect(function(s) { 1032 return (s < 0.5) ? collie.Effect.easeOutExpo(0, 1)(2 * s) * 0.5 : collie.Effect.easeInExpo(0, 1)((2 * s) - 1) * 0.5 + 0.5; 1033}); 1034 1035/** 1036 * Cubic-Bezier curve 1037 * @param {Number} x1 1038 * @param {Number} y1 1039 * @param {Number} x2 1040 * @param {Number} y2 1041 * @see http://www.netzgesta.de/dev/cubic-bezier-timing-function.html 1042 */ 1043collie.Effect._cubicBezier = function(x1, y1, x2, y2){ 1044 return function(t){ 1045 var cx = 3.0 * x1, 1046 bx = 3.0 * (x2 - x1) - cx, 1047 ax = 1.0 - cx - bx, 1048 cy = 3.0 * y1, 1049 by = 3.0 * (y2 - y1) - cy, 1050 ay = 1.0 - cy - by; 1051 1052 function sampleCurveX(t) { 1053 return ((ax * t + bx) * t + cx) * t; 1054 } 1055 function sampleCurveY(t) { 1056 return ((ay * t + by) * t + cy) * t; 1057 } 1058 function sampleCurveDerivativeX(t) { 1059 return (3.0 * ax * t + 2.0 * bx) * t + cx; 1060 } 1061 function solveCurveX(x,epsilon) { 1062 var t0, t1, t2, x2, d2, i; 1063 for (t2 = x, i = 0; i<8; i++) { 1064 x2 = sampleCurveX(t2) - x; 1065 if (Math.abs(x2) < epsilon) { 1066 return t2; 1067 } 1068 d2 = sampleCurveDerivativeX(t2); 1069 if(Math.abs(d2) < 1e-6) { 1070 break; 1071 } 1072 t2 = t2 - x2 / d2; 1073 } 1074 t0 = 0.0; 1075 t1 = 1.0; 1076 t2 = x; 1077 if (t2 < t0) { 1078 return t0; 1079 } 1080 if (t2 > t1) { 1081 return t1; 1082 } 1083 while (t0 < t1) { 1084 x2 = sampleCurveX(t2); 1085 if (Math.abs(x2 - x) < epsilon) { 1086 return t2; 1087 } 1088 if (x > x2) { 1089 t0 = t2; 1090 } else { 1091 t1 = t2; 1092 } 1093 t2 = (t1 - t0) * 0.5 + t0; 1094 } 1095 return t2; // Failure. 1096 } 1097 return sampleCurveY(solveCurveX(t, 1 / 200)); 1098 }; 1099}; 1100 1101/** 1102 * Cubic-Bezier í¨ì를 ìì±íë¤. 1103 * @see http://en.wikipedia.org/wiki/B%C3%A9zier_curve 1104 * @param {Number} x1 control point 1ì xì¢í 1105 * @param {Number} y1 control point 1ì yì¢í 1106 * @param {Number} x2 control point 2ì xì¢í 1107 * @param {Number} y2 control point 2ì yì¢í 1108 * @return {Function} ìì±ë ì´íí¸ í¨ì 1109 */ 1110collie.Effect.cubicBezier = function(x1, y1, x2, y2){ 1111 return collie.Effect(collie.Effect._cubicBezier(x1, y1, x2, y2)); 1112}; 1113 1114/** 1115 * Cubic-Bezier 커ë¸ë¥¼ ì´ì©í´ CSS3 Transition Timing Functionê³¼ ëì¼í ease í¨ì 1116 * collie.Effect.cubicBezier(0.25, 0.1, 0.25, 1); 1117 * @see http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag 1118 */ 1119collie.Effect.cubicEase = collie.Effect.cubicBezier(0.25, 0.1, 0.25, 1); 1120 1121/** 1122 * Cubic-Bezier 커ë¸ë¥¼ ì´ì©í´ CSS3 Transition Timing Functionê³¼ ëì¼í easeIn í¨ì 1123 * collie.Effect.cubicBezier(0.42, 0, 1, 1); 1124 * @see http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag 1125 */ 1126collie.Effect.cubicEaseIn = collie.Effect.cubicBezier(0.42, 0, 1, 1); 1127 1128/** 1129 * Cubic-Bezier 커ë¸ë¥¼ ì´ì©í´ CSS3 Transition Timing Functionê³¼ ëì¼í easeOut í¨ì 1130 * collie.Effect.cubicBezier(0, 0, 0.58, 1); 1131 * @see http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag 1132 */ 1133collie.Effect.cubicEaseOut = collie.Effect.cubicBezier(0, 0, 0.58, 1); 1134 1135/** 1136 * Cubic-Bezier 커ë¸ë¥¼ ì´ì©í´ CSS3 Transition Timing Functionê³¼ ëì¼í easeInOut í¨ì 1137 * collie.Effect.cubicBezier(0.42, 0, 0.58, 1); 1138 * @see http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag 1139 */ 1140collie.Effect.cubicEaseInOut = collie.Effect.cubicBezier(0.42, 0, 0.58, 1); 1141 1142/** 1143 * Cubic-Bezier 커ë¸ë¥¼ ì´ì©í´ easeOutIn í¨ì를 구íë¤. 1144 * collie.Effect.cubicBezier(0, 0.42, 1, 0.58); 1145 */ 1146collie.Effect.cubicEaseOutIn = collie.Effect.cubicBezier(0, 0.42, 1, 0.58); 1147 1148/**
1149 * overphase ì´íí¸ í¨ì 1150 */ 1151collie.Effect.overphase = collie.Effect(function(s){ 1152 s /= 0.652785; 1153 return (Math.sqrt((2 - s) * s) + (0.1 * s)).toFixed(5); 1154}); 1155 1156/** 1157 * sin 곡ì ì ì¼ë¶ë¥¼ ì´ì©í sinusoidal ì´íí¸ í¨ì 1158 */ 1159collie.Effect.sinusoidal = collie.Effect(function(s) { 1160 return (-Math.cos(s * Math.PI) / 2) + 0.5; 1161}); 1162 1163/** 1164 * mirror ì´íí¸ í¨ì 1165 * sinusoidal ì´íí¸ í¨ì를 ì¬ì©íë¤. 1166 */ 1167collie.Effect.mirror = collie.Effect(function(s) { 1168 return (s < 0.5) ? collie.Effect.sinusoidal(0, 1)(s * 2) : collie.Effect.sinusoidal(0, 1)(1 - (s - 0.5) * 2); 1169}); 1170 1171/** 1172 * nPulseì ì§ëì를 ê°ì§ë cos í¨ì를 구íë¤. 1173 * @param {Number} nPulse ì§ëì 1174 * @return {Function} ìì±ë ì´íí¸ í¨ì 1175 * @example 1176var f = collie.Effect.pulse(3); //ì§ëì 3ì ê°ì§ë í¨ì를 ë¦¬í´ 1177//ìì ìì¹ê°ê³¼ ì¢ ë£ ìì¹ê°ì ì¤ì í´ collie.Effect í¨ì를 ìì± 1178var fEffect = f(0, 100); 1179fEffect(0); => 0 1180fEffect(1); => 100 1181 */ 1182collie.Effect.pulse = function(nPulse) { 1183 return collie.Effect(function(s){ 1184 return (-Math.cos((s * (nPulse - 0.5) * 2) * Math.PI) / 2) + 0.5; 1185 }); 1186}; 1187 1188/** 1189 * nPeriodì 주기ì nHeightì ì§íì ê°ì§ë sin í¨ì를 구íë¤. 1190 * @param {Number} nPeriod 주기 1191 * @param {Number} nHeight ì§í 1192 * @return {Function} ìì±ë ì´íí¸ í¨ì 1193 * @example 1194var f = collie.Effect.wave(3, 1); //주기 3, ëì´ 1ì ê°ì§ë í¨ì를 ë¦¬í´ 1195//ìì ìì¹ê°ê³¼ ì¢ ë£ ìì¹ê°ì ì¤ì í´ collie.Effect í¨ì를 ìì± 1196var fEffect = f(0, 100); 1197fEffect(0); => 0 1198fEffect(1); => 0 1199 */ 1200collie.Effect.wave = function(nPeriod, nHeight) { 1201 return collie.Effect(function(s){ 1202 return (nHeight || 1) * (Math.sin(nPeriod * (s * 360) * Math.PI / 180)).toFixed(5); 1203 }); 1204}; 1205 1206/** 1207 * easeIn ì´íí¸ í¨ì 1208 * easeInCubic í¨ìì ëì¼íë¤. 1209 * @see easeInCubic 1210 */ 1211collie.Effect.easeIn = collie.Effect.easeInCubic; 1212/** 1213 * easeOut ì´íí¸ í¨ì 1214 * easeOutCubic í¨ìì ëì¼íë¤. 1215 * @see easeOutCubic 1216 */ 1217collie.Effect.easeOut = collie.Effect.easeOutCubic; 1218/** 1219 * easeInOut ì´íí¸ í¨ì 1220 * easeInOutCubic í¨ìì ëì¼íë¤. 1221 * @see easeInOutCubic 1222 */ 1223collie.Effect.easeInOut = collie.Effect.easeInOutCubic; 1224/** 1225 * easeOutIn ì´íí¸ í¨ì 1226 * easeOutInCubic í¨ìì ëì¼íë¤. 1227 * @see easeOutInCubic 1228 */ 1229collie.Effect.easeOutIn = collie.Effect.easeOutInCubic; 1230/** 1231 * bounce ì´íí¸ í¨ì 1232 * easeOutBounce í¨ìì ëì¼íë¤. 1233 * @see easeOutBounce 1234 */ 1235collie.Effect.bounce = collie.Effect.easeOutBounce; 1236/** 1237 * elastic ì´íí¸ í¨ì 1238 * easeInElastic í¨ìì ëì¼íë¤. 1239 * @see easeInElastic 1240 */ 1241collie.Effect.elastic = collie.Effect.easeInElastic; 1242/** 1243 * ë³ëì ì´ë²¤í¸ë¥¼ ë¤ë£° ì ìê³ ìµì ê°ì ê°ë ì»´í¬ëí¸ í´ëì¤ 1244 * @class collie.Component 1245 */ 1246collie.Component = collie.Class(/** @lends collie.Component.prototype */{ 1247 /** 1248 * @constructs 1249 */ 1250 $init : function () { 1251 this._bInitOption = false; 1252 this._htOption = {}; 1253 this._htOptionSetter = {}; 1254 this._htHandler = {}; 1255 }, 1256 1257 /** 1258 * ì»´í¬ëí¸ì ìµì ì ì¤ì íë¤. 1259 * @example 1260 * component.option({ 1261 * a : 1, 1262 * b : true 1263 * }); 1264 * 1265 * component.option("a", 1); 1266 * component.option("a"); // return 1 1267 * @param {Object|String} vName ìµì ì´ë¦ì´ë ì¬ë¬ ìµì ì ì¤ì í ì ìë ê°ì²´ë¥¼ ë£ì ì ìë¤. 1268 * @param {Variables} [vValue] ìµì ê°, ê°ì´ ìë¤ë©´ í´ë¹ ìµì ê°ì ë°ííë¤. 1269 * @param {Boolean} [bNotOverwrite] ì´ ê°ì´ trueë©´ 기존ì ê°ì´ ìì ê²½ì° ë®ì´ ìì°ì§ ìëë¤ 1270 */ 1271 option : function (vName, vValue, bNotOverwrite) { 1272 if (typeof vName === "object") { 1273 // ì´ê¸°ì ë£ì ëë 기본 ê°ì¼ë¡ ì¤ì 1274 if (!this._bInitOption) { 1275 this._htOption = collie.util.cloneObject(vName); 1276 this._bInitOption = true; 1277 } else { 1278 for (var i in vName) { 1279 this.option(i, vName[i], bNotOverwrite); 1280 } 1281 } 1282 } else if (typeof vName === "string") { 1283 // setter 1284 if (vValue !== undefined) { 1285 if (!bNotOverwrite || typeof this._htOption[vName] === "undefined") { 1286 this._htOption[vName] = vValue; 1287 1288 if (this._htOptionSetter[vName] !== undefined) { 1289 this._htOptionSetter[vName](vValue); 1290 } 1291 1292 this._bInitOption = true; 1293 } 1294 } else { // getter 1295 return this._htOption[vName]; 1296 } 1297 } else { 1298 return this._htOption; 1299 } 1300 }, 1301 1302 /** 1303 * DisplayObjectì Layerì ìë¡ ë¤ë¥¸ ì¸í°íì´ì¤ë¥¼ ë§ì¶ê¸° ìí ìì ë©ìë 1304 * 1305 * @see collie.Component#option 1306 * @param {String} sName 1307 * @return {Variables} 1308 */ 1309 get : function (sName) { 1310 return this.option(sName); 1311 }, 1312 1313 /** 1314 * DisplayObjectì Layerì ìë¡ ë¤ë¥¸ ì¸í°íì´ì¤ë¥¼ ë§ì¶ê¸° ìí ìì ë©ìë 1315 * 1316 * @see collie.Component#option 1317 * @param {String} sName 1318 * @param {Variables} vValue 1319 * @param {Boolean} [bNotOverwrite] 1320 * @return {Object} For method chaining 1321 */ 1322 set : function (sName, vValue, bNotOverwrite) { 1323 this.option(sName, vValue, bNotOverwrite); 1324 return this; 1325 }, 1326 1327 /** 1328 * ìµì ì ì ê±°íë¤ 1329 * 1330 * @param {String} sKey 1331 */ 1332 unset : function (sKey) { 1333 if (this._htOption && typeof this._htOption[sKey] !== "undefined") { 1334 delete this._htOption[sKey]; 1335 } 1336 }, 1337 1338 /** 1339 * ìµì ê°ì´ ì¤ì ë ë ì¤íë í¨ì를 ì§ì íë¤. Setterë í ìì± ë¹ í ê°ì í¨ìë§ ì¤ì í ì ìë¤. 1340 * 1341 * @param {String} sName 1342 * @param {Function} fSetter 1343 */ 1344 optionSetter : function (sName, fSetter) { 1345 this._htOptionSetter[sName] = fSetter; 1346 }, 1347 1348 /** 1349 * ì´ë²¤í¸ ë°ì 1350 * 1351 * @param {String} sName 1352 * @param {Object} oEvent 1353 * @return {Boolean} ì´ë²¤í¸ ë°ì ì¤ collie.ComponentEventì stop ë©ìëê° ì¤íë ê²½
1353ì° false를 ë°ííë¤ 1354 */ 1355 fireEvent : function (sName, oEvent) { 1356 if (typeof this._htHandler[sName] !== "undefined" && this._htHandler[sName].length > 0) { 1357 oEvent = oEvent || {}; 1358 oCustomEvent = new collie.ComponentEvent(sName, oEvent); 1359 var aHandler = this._htHandler[sName].concat(); 1360 var bCanceled = false; 1361 1362 for (var i = 0, len = aHandler.length; i < len; i++) { 1363 this._htHandler[sName][i](oCustomEvent); 1364 1365 // stopíì¼ë©´ false를 ë°í 1366 if (oCustomEvent.isStop()) { 1367 bCanceled = true; 1368 } 1369 } 1370 1371 if (bCanceled) { 1372 return false; 1373 } 1374 } 1375 1376 return true; 1377 }, 1378 1379 /** 1380 * ì´ë²¤í¸ í¸ë¤ë¬ ì¶ê° 1381 * 1382 * @param {Object|String} vEvent 1383 * @param {Function} fHandler 1384 * @return {collie.Component} ë©ìë ì²´ì´ë ì§ì 1385 */ 1386 attach : function (vEvent, fHandler) { 1387 if (typeof vEvent !== "string") { 1388 for (var i in vEvent) { 1389 this.attach(i, vEvent[i]); 1390 } 1391 } else { 1392 this._htHandler[vEvent] = this._htHandler[vEvent] || []; 1393 var aHandler = this._htHandler[vEvent]; 1394 1395 // í¸ë¤ë¬ê° ìì ëë§ ë±ë¡ 1396 if (!fHandler) { 1397 return this; 1398 } 1399 1400 // ì¤ë³µë í¸ë¤ë¬ë ë±ë¡íì§ ìì 1401 for (var i = 0, len = aHandler.length; i < len; i++) { 1402 if (aHandler[i] === fHandler) { 1403 return this; 1404 } 1405 } 1406 1407 // í¸ë¤ë¬ ë±ë¡ 1408 aHandler.push(fHandler); 1409 } 1410 1411 return this; 1412 }, 1413 1414 /** 1415 * ì´ë²¤í¸ í¸ë¤ë¬ë¥¼ í´ì íë¤ 1416 * 1417 * @param {Object|String} vEvent 1418 * @param {Function} fHandler ê°ì´ ìì ê²½ì° ì´ ì´ë²¤í¸ì í ë¹ë ì ì²´ í¸ë¤ë¬ë¥¼ í´ì íë¤ 1419 */ 1420 detach : function (vEvent, fHandler) { 1421 if (typeof vEvent !== "string") { 1422 for (var i in vEvent) { 1423 this.detach(i, vEvent[i]); 1424 } 1425 } else if (this._htHandler[vEvent] !== undefined) { 1426 var aHandler = this._htHandler[vEvent]; 1427 1428 // ëë²ì§¸ ì¸ìê° ìì ë ì 체를 detach 1429 if (!fHandler) { 1430 delete this._htHandler[vEvent]; 1431 } else { 1432 for (var i = 0, len = aHandler.length; i < len; i++) { 1433 if (aHandler[i] === fHandler) { 1434 this._htHandler[vEvent].splice(i, 1); 1435 1436 // ë°°ì´ì´ ë¤ ìì´ì¡ë¤ë©´ ì ê±° 1437 if (this._htHandler[vEvent].length < 1) { 1438 delete this._htHandler[vEvent]; 1439 } 1440 break; 1441 } 1442 } 1443 } 1444 } 1445 }, 1446 1447 /** 1448 * 모ë ì´ë²¤í¸ í¸ë¤ë¬ë¥¼ í´ì 1449 * 1450 * @param {String} sName ì´ë²¤í¸ ì´ë¦, ê°ì´ ìì¼ë©´ ì´ ì»´í¬ëí¸ì í ë¹ë 모ë ì´ë²¤í¸ë¥¼ í´ì íë¤ 1451 */ 1452 detachAll : function (sName) { 1453 if (sName) { 1454 if (this._htHandler[sName] !== undefined) { 1455 this._htHandler[sName] = []; 1456 } 1457 } else { 1458 this._htHandler = {}; 1459 } 1460 } 1461}); 1462 1463/** 1464 * ì»´í¬ëí¸ í´ëì¤ì ì´ë²¤í¸ê° ë°ìë ë ìì±ëë ì´ë²¤í¸ í´ëì¤ 1465 * @class 1466 * @private 1467 * @param {String} sName ì´ë²¤í¸ ì´ë¦ 1468 * @param {Object} oEvent 1469 */ 1470collie.ComponentEvent = collie.Class(/** @lends collie.ComponentEvent.prototype */{ 1471 /** 1472 * @constructs 1473 */ 1474 $init : function (sName, oEvent) { 1475 this.type = sName; 1476 this._bCanceled = false; 1477 1478 //TODO í¥íì ì´ êµ¬ì¡°ë¥¼ ë°ê¾¸ëê² ì¢ì 1479 if (oEvent) { 1480 for (var i in oEvent) { 1481 this[i] = oEvent[i]; 1482 } 1483 } 1484 }, 1485 1486 /** 1487 * ì´ë²¤í¸ë¥¼ ë©ì¶ê³ ì¶ì ê²½ì° ì¤í 1488 */ 1489 stop : function () { 1490 this._bCanceled = true; 1491 }, 1492 1493 /** 1494 * ì´ë²¤í¸ê° ë©ì·ëì§ íì¸ 1495 * 1496 * @return {Boolean} ë©ì·ì¼ë©´ true 1497 */ 1498 isStop : function () { 1499 return this._bCanceled; 1500 } 1501}); 1502/** 1503 * @class 1504 * @private 1505 * @example 1506 * collie.ImageManager.add({ 1507 * "sample" : "sample.png" 1508 * }); 1509 * collie.ImageManager.addSprite("sample", { 1510 * normal : [0, 0], 1511 * action : [30, 0] 1512 * }); 1513 * new collie.DisplayObject({ 1514 * spriteSheet : "normal", 1515 * backgroundImage : "sample" 1516 * }); 1517 */ 1518collie.SpriteSheet = collie.Class(/** @lends collie.SpriteSheet.prototype */{ 1519 $init : function () { 1520 this._htSpriteSheet = {}; 1521 }, 1522 1523 /** 1524 * ì¤íë¼ì´í¸ë¥¼ ì¶ê° 1525 * 1526 * @param {String} sImageName collie.ImageManagerì ë±ë¡ë ì´ë¯¸ì§ ì´ë¦ 1527 * @param {String|Object} vSpriteName ê°ì²´ë¡ í ë²ì ì¬ë¬ ê°ì ì 보를 ë±ë¡í ì ìì 1528 * @param {Number} nOffsetX 1529 * @param {Number} nOffsetY 1530 * @param {Number} [nWidth] 1531 * @param {Number} [nHeight] 1532 * @param {Number} [nSpriteLength] 1533 */ 1534 add : function (sImageName, vSpriteName, nOffsetX, nOffsetY, nWidth, nHeight, nSpriteLength) { 1535 if (typeof vSpriteName === "object") { 1536 if (vSpriteName instanceof Array) { 1537 for (var i = 0, l = vSpriteName.length; i < l; i++) { 1538 this.add.apply(this, [sImageName, i].concat(vSpriteName[i])); 1539 } 1540 } else { 1541 for (var i in vSpriteName) { 1542 this.add.apply(this, [sImageName, i].concat(vSpriteName[i])); 1543 } 1544 } 1545 } else { 1546 this._htSpriteSheet[sImageName] = this._htSpriteSheet[sImageName] || {}; 1547 1548 if (typeof nWidth !== "undefined") { 1549 collie.ImageManager.getImage(sImageName, function (el) { 1550 this._addWithSpriteLength(el, sImageName, vSpriteName, nOffsetX, nOffsetY, nWidth, nHeight, nSpriteLength); 1551 }.bind(this)); 1552 } else { 1553 this._htSpriteSheet[sImageName][vSpriteName] = [nOffsetX, nOffsetY]; 1554 } 1555 } 1556 }, 1557 1558 /** 1559 * @private 1560 */ 1561 _addWithSpriteLength : function (elImage, sImageName, sSpriteName, nOffsetX, nOffsetY, nWidth, nHeight, nSpriteLength) { 1562 var aSpriteList = this._htSpriteSheet[sImageName][sSpriteName] = []; 1563 var nImageWidth = elImage.width; 1564 var nImageHeight = elImage.height; 1565 1566 // ë í°ë ì´ë¯¸ì§ë©´ ë°ì¼ë¡ ëë 1567 if (collie.Renderer.isRetinaDisplay()) { 1568 nImageWidth /= 2; 1569 nImageHeight /= 2; 1570 } 1571 1572 var x = nOffsetX; 1573 var y = nOffsetY; 1574 1575 for (i = 0; i < nSpriteLength; i++) { 1576 // ì´ë¯¸ì§ë¥¼ ëì´ìë©´ ì¤ì ë°ê¿ 1577 // ë¤ì ì¤ì nOffsetX ë¶í° ììíë ê²ì´ ìëë¼ 0ë¶í° ììí¨ 1578 if (x >= nImageWidth) { 1579 x = 0; 1580 y += nHeight; 1581 } 1582 1583 // ì´ë¯¸ì§ë¥¼ ëì´ìë©´ ëë¨ 1584 if (y >= nImageHeight) { 1585 break; 1586 } 1587 1588 aSpriteList.push([x, y]); 1589 x += nWidth; 1590 } 1591 }, 1592 1593 /** 1594 * í´ë¹ ì´ë¯¸ì§ì ë±ë¡ë¼ ìë ì¤íë¼ì´í¸ ì 보를 ì ê±° 1595 * 1596 * @param {String} sImageName collie.ImageManagerì ë±ë¡ë ì´ë¯¸ì§ ì´ë¦ 1597 */ 1598 remove : function (sImageName) { 1599 if (this._htSpriteSheet[sImageName]) { 1600 delete this._htSpriteSheet[sImageName]; 1601 } 1602 }, 1603 1604 /** 1605 * SpriteSheet ì 보를 ë°í 1606 * 1607 * @param {String} sImageName collie.ImageManagerì ë±ë¡ë ì´ë¯¸ì§ ì´ë¦ 1608 * @return {Object} 1609 */ 1610 get : function (sImageName) { 1611 return this._htSpriteSheet[sImageName] ? this._htSpriteSheet[sImageName] : false;
1612 }, 1613 1614 /** 1615 * ì¤íë¼ì´í¸ ìí¸ ì 보를 ì´ê¸°í íë¤ 1616 */ 1617 reset : function () { 1618 this._htSpriteSheet = {}; 1619 } 1620}); 1621/** 1622 * ì´ë¯¸ì§ 리ìì¤ ê´ë¦¬ 1623 * @example 1624 * // í ê°ì ì´ë¯¸ì§ë¥¼ ë¡ë© 1625 * collie.ImageManager.add("key", "sample.png"); 1626 * new collie.DisplayObject({ 1627 * backgroundImage: "key" 1628 * }); 1629 * @example 1630 * // ì¬ë¬ ì´ë¯¸ì§ë¥¼ í ë²ì ë¡ë© 1631 * collie.ImageManager.add({ 1632 * image1 : "image1.png", 1633 * image2 : "image2.png" 1634 * }, function () { 1635 * alert("complete"); 1636 * }); 1637 * @namespace 1638 */ 1639collie.ImageManager = collie.ImageManager || new (collie.Class(/** @lends collie.ImageManager */{ 1640 /** 1641 * ì´ë¯¸ì§ ë¡ë© ì¤í¨ì ì¬ìë íì 1642 * @type {Number} 1643 */ 1644 RETRY_COUNT : 3, 1645 1646 /** 1647 * ì´ë¯¸ì§ ë¡ë© ì¤í¨ì ì¬ìë ëë ì´ ms 1648 * @type {Number} 1649 */ 1650 RETRY_DELAY : 500, 1651 1652 /** 1653 * DOMì¼ ë css3d ì리먼í¸ë¥¼ 미리 ë§ë¤ì´ëëì§ ì¬ë¶ 1654 * - ê¸°ë¥ ë¶ìì ì¼ë¡ 기본 ì¬ì© falseë¡ ë³ê²½, top, left를 ë©ë¦¬ ë³´ë´ë²ë¦¬ë©´ 3d ë ëë§ì ë¶ë´ì´ ë ì ìë¤. 1655 * @type {Boolean} 1656 */ 1657 USE_PRERENDERING_DOM : false, 1658 1659 $init : function () { 1660 this._aImages = []; 1661 this._htImageNames = {}; 1662 this._htImageRetryCount = {}; 1663 this._htImageWhileLoading = {}; 1664 this._nCount = 0; 1665 this._oSpriteSheet = new collie.SpriteSheet(); 1666 }, 1667 1668 /** 1669 * ì´ë¯¸ì§ë¥¼ ì¶ê° 1670 * - ì¸ë¶ìì ì§ì ì¬ì©íë©´ countê° ì´ê¸ë기 ë문ì private ì²ë¦¬ 1671 * 1672 * @private 1673 * @param {String} sName 리ìì¤ ì´ë¦, ëì¤ì ì´ ì´ë¦ì¼ë¡ 리ìì¤ë¥¼ ì°¾ëë¤ 1674 * @param {HTMLElement} elImage ì ì¥í ìë¦¬ë¨¼í¸ 1675 */ 1676 _addImage : function (elImage, sName) { 1677 var nLength = this._aImages.push({ 1678 element : elImage, 1679 name : sName 1680 }); 1681 1682 var aCallback = this._htImageNames[sName]; 1683 this._htImageNames[sName] = nLength - 1; 1684 delete this._htImageRetryCount[sName]; 1685 1686 // callback ì¤í 1687 if (aCallback && aCallback instanceof Array) { 1688 for (var i = 0, len = aCallback.length; i < len; i++) { 1689 aCallback[i](elImage, sName); 1690 } 1691 1692 aCallback = null; 1693 } 1694 1695 /** 1696 * íê°ì ì´ë¯¸ì§ê° ë¡ë©ëìì ë ë°ì 1697 * @name collie.ImageManager#process 1698 * @event 1699 * @param {Object} oEvent 1700 * @param {String} oEvent.name ì´ë¯¸ì§ ì´ë¦ 1701 * @param {String} oEvent.url ì´ë¯¸ì§ URL 1702 * @param {Number} oEvent.count íì¬ ë¡ë©ë ê°¯ì 1703 * @param {Number} oEvent.total ì ì²´ ì´ë¯¸ì§ ê°¯ì 1704 * @param {Number} oEvent.ratio ë¡ë©ë ì´ë¯¸ì§ì ë¹ì¨ (0~1) 1705 */ 1706 this.fireEvent("process", { 1707 name : sName, 1708 url : elImage.src, 1709 count : nLength, 1710 total : this._nCount, 1711 ratio : Math.round((nLength / this._nCount) * 1000) / 1000 1712 }); 1713 1714 if (this._nCount === nLength) { 1715 /** 1716 * ë±ë¡ë ì´ë¯¸ì§ê° 모ë ë¡ë ëìì ê²½ì° 1717 * @name collie.ImageManager#complete 1718 * @event 1719 * @param {Object} oEvent 1720 */ 1721 this.fireEvent("complete"); 1722 } 1723 }, 1724 1725 /** 1726 * ì리를 ì°, ì´ë¯¸ ìë¦¬ê° ìë ê²½ì°ìë ì무ê²ë í
1726ì§ ìëë¤ 1727 * 1728 * @private 1729 * @param {String} sName ì´ë¯¸ì§ ì´ë¦ 1730 */ 1731 _markImage : function (sName) { 1732 if (!this._htImageNames[sName]) { 1733 this._htImageNames[sName] = []; 1734 } 1735 1736 if (!this._htImageRetryCount[sName]) { 1737 this._htImageRetryCount[sName] = 0; 1738 } 1739 }, 1740 1741 /** 1742 * í´ì¬ë¥¼ ë¤ì ë§ë¦ 1743 * @private 1744 */ 1745 _makeHash : function () { 1746 this._htImageNames = {}; 1747 1748 for (var i = 0, len = this._aImages.length; i < len; i++) { 1749 this._htImageNames[this._aImages[i].name] = i; 1750 } 1751 }, 1752 1753 /** 1754 * ì´ë¯¸ì§ë¥¼ ê°ì ¸ì¨ë¤ 1755 * 1756 * @static 1757 * @param {String} sName 리ìì¤ ì´ë¦ 1758 * @param {Function} fCallback 리ìì¤ê° ë¡ëëì§ ììì ìë ìì¼ë¯ë¡ ì½ë°±ì¼ë¡ ì²ë¦¬ 1759 * @return {HTMLElement} 1760 */ 1761 getImage : function (sName, fCallback) { 1762 if (!sName && sName !== 0) { 1763 return false; 1764 } 1765 1766 // ë§í¬ëì§ ìì ì´ë¦ì´ë¼ë©´ ë§í¬í¨ 1767 if (!(sName in this._htImageNames)) { 1768 this._markImage(sName); 1769 } 1770 1771 // ë§í¬ê° ë ìí©ì´ê³ ìì§ ë¡ë©ëì§ ììë¤ë©´ 1772 if (this._htImageNames[sName] instanceof Array) { 1773 return (fCallback && this._addMarkCallback(sName, fCallback)); 1774 } else { 1775 if (fCallback) { 1776 fCallback(this._aImages[this._htImageNames[sName]].element); 1777 } else { 1778 return this._aImages[this._htImageNames[sName]].element; 1779 } 1780 } 1781 }, 1782 1783 /** 1784 * ë§í¬ë ììì ì½ë°±ì ë±ë¡, ë¡ë©ì´ ìë£ëë©´ ì½ë°±ì´ ì¤íëë¤ 1785 * @private 1786 * @param {String} sName 1787 * @param {Function} fCallback 1788 * @param {Function} fFail 1789 * @return {Boolean} callbackì´ ë±ë¡ë ê²½ì° true를 ë°í 1790 */ 1791 _addMarkCallback : function (sName, fCallback, fFail) { 1792 if ((sName in this._htImageNames) && this._htImageNames[sName] instanceof Array) { 1793 if (fFail) { 1794 var fError = function fError(oEvent) { 1795 if (oEvent.name === sName) { 1796 fFail(); 1797 this.detach("error", fError); 1798 } 1799 }; 1800 1801 this.attach("error", fError); 1802 } 1803 1804 if (fCallback) { 1805 this._htImageNames[sName].push(fCallback); 1806 } 1807 1808 return true; 1809 } else { 1810 return false; 1811 } 1812 }, 1813 1814 /** 1815 * ì´ë¯¸ì§ë¥¼ ìì íë¤ 1816 * @param {String} sName 리ìì¤ ì´ë¦ 1817 */ 1818 removeImage : function (sName) { 1819 if (!(sName in this._htImageNames)) { 1820 return false; 1821 } 1822 1823 var elImage = this._aImages.splice(this._htImageNames[sName], 1); 1824 this._makeHash(); 1825 elImage.onload = null; 1826 elImage.onerror = null; 1827 elImage.src = null; 1828 elImage = null; 1829 this._oSpriteSheet.remove(sName); 1830 }, 1831 1832 /** 1833 * ì´ë¯¸ì§ë¥¼ ìì íë¤ 1834 * @see collie.ImageManager.removeImage 1835 */ 1836 remove : function (sName) { 1837 this.removeImage(sName); 1838 }, 1839 1840 /** 1841 * ì´ë¯¸ì§ 리ìì¤ë¥¼ ì¶ê°íë¤ 1842 * 1843 * @example 1844 * // 1ê°ì ì´ë¯¸ì§ë¥¼ ì¶ê° 1845 * collie.ImageManager.add("key", "sample.png", function () { 1846 * // callback 1847 * }); 1848 * @example 1849 * // ì¬ë¬ ê°ì ì´ë¯¸ì§ë¥¼ ì¶ê° 1850 * collie.ImageManager.add({ 1851 * key : "sample.png", 1852 * key2 : "sample2.png" 1853 * }, function () { 1854 * // callback 1855 * }); 1856 * 1857 * @see collie.ImageManager.addImage 1858 * @see collie.ImageManager.addImages 1859 */ 1860 add : function () { 1861 if (typeof arguments[0] === "object") { 1862 this.addImages.apply(this, arguments); 1863 } else { 1864 this.addImage.apply(this, arguments); 1865 } 1866 }, 1867 1868 /** 1869 * ì¬ë¬ ê°ì ì´ë¯¸ì§ 리ìì¤ë¥¼ íë²ì ì¶ê° íë¤. 1870 * 1871 * @param {Object} htList { sName : sURL , sName2 : sURL2 } 1872 * @param {Function} fCallback ì íí íì¼ì´ 모ë ë¡ëë ë ì¤íë í¨ì. ìì¼ë©´ ì¤íëì§ ìëë¤. ì¸ìë¡ htList를 ë°í 1873 * @param {Function} fFail ì íí íì¼ ì¤ì íê°ë¼ë ë¡ëëì§ ììì ë ì¤íë í¨ì. ì¤í¨í ì´ë¯¸ì§ì [el, sName, sURL] ë°°ì´ ëª©ë¡ì ì¸ìë¡ ê°ëë¤ 1874 */ 1875 addImages : function (htList, fCallback, fFail) { 1876 var fOnComplete = null; 1877 var fOnFail = null; 1878 var nTotalCount = 0; 1879 var nCurrentCount = 0; 1880 var aFailedImages = []; 1881 1882 // ëë©´ì ê°¯ì 먼ì íì 1883 for (var i in htList) { 1884 nTotalCount++; 1885 } 1886 1887 // ì½ë°± 1888 if (fCallback && fCallback !== null) { 1889 fOnComplete = (function () { 1890 nCurrentCount++; 1891 1892 if (nCurrentCount >= nTotalCount) { 1893 fCallback(htList); 1894 } 1895 }).bind(this); 1896 } 1897 1898 // ì¤í¨íì ê²½ì° 1899 if (fFail && fFail !== null) { 1900 fOnFail = (function (el, sName, sURL) { 1901 aFailedImages.push([el, sName, sURL]); 1902 1903 if (aFailedImages.length + nCurrentCount >= nTotalCount) { 1904 fFail(aFailedImages); 1905 } 1906 }).bind(this); 1907 } 1908 1909 // ë¡ë 1910 for (var i in htList) { 1911 this.addImage(i, htList[i], fOnComplete, fOnFail); 1912 } 1913 }, 1914 1915 /** 1916 * ë¹ëê¸°ë¡ ì´ë¯¸ì§ë¥¼ ë¡ë© 1917 * 1918 * @param {String} sName ì´ë¯¸ì§ ì´ë¦, ì´ë¦ì´ ìì ê²½ì° Loaderì ì ì¥íì§ ìëë¤ 1919 * @param {String} sURL ì´ë¯¸ì§ 주ì 1920 * @param {Function} fCallback ì±ê³µì ì¤íë í¨ì 1921 * @param {HTMLElement} fCallback.elImage ìë¦¬ë¨¼í¸ 1922 * @param {String} fCallback.sName 리ìì¤ ì´ë¦ 1923 * @param {String} fCallback.sURL URL 1924 * @param {Function} fFail ì¤í¨ì ì¤íë í¨ì 1925 */ 1926 addImage : function (sName, sURL, fCallback, fFail) { 1927 // ì´ë¯¸ ì´ë¯¸ì§ê° ìì¼ë©´ ë°ë¡ ì½ë°± ì¤í 1928 if (this.getImage(sName)) { 1929 if (fCallback && fCallback !== null) { 1930 fCallback(this.getImage(sName), sName, sURL); 1931 } 1932 return; 1933 } 1934 1935 // ì´ë¯¸ ë¡ë© ì¤ì´ê³ ë§í¬ê° ë ìí©ì´ë¼ë©´ ì½ë°± ë±ë¡íê³ ë©ì¶¤ 1936 if ((sName in this._htImageWhileLoading) && this._addMarkCallback(sName, fCallback, fFail)) { 1937 return; 1938 } 1939 1940 this._nCount++; 1941 this._markImage(sName); 1942 var el = new Image(); 1943 1944 // DOM모ëë©´ 미리 OpenGL ë ì´ì´ë¡ ë³íí´ ëëë¤ 1945 if (this.USE_PRERENDERING_DOM && collie.Renderer.getRenderingMode() === "dom" && collie.util.getSupp
1945ortCSS3d() && !collie.util.getDeviceInfo().android) { 1946 el.style.webkitTransform = "translateZ(0)"; 1947 el.style.position = "absolute"; 1948 el.style.visibility = "hidden"; 1949 collie.Renderer.getElement().appendChild(el); 1950 } 1951 1952 this._htImageWhileLoading[sName] = el; 1953 1954 el.onload = (function (e) { 1955 this._addImage(el, sName); 1956 1957 if (fCallback && fCallback !== null) { 1958 fCallback(el, sName, sURL); 1959 } 1960 1961 el.onerror = el.onload = null; 1962 this._deleteWhileLoading(sName); 1963 }).bind(this); 1964 1965 el.onerror = (function (e) { 1966 // ì¬ìë 1967 if (this._htImageRetryCount[sName] < this.RETRY_COUNT) { 1968 this._htImageRetryCount[sName]++; 1969 1970 /** 1971 * í ê°ì ì´ë¯¸ì§ê° ë¡ë© ì¤í¨ íì ë ì¤í 1972 * @name collie.ImageManager#retry 1973 * @event 1974 * @param {Object} oEvent 1975 * @param {String} oEvent.name ì¤í¨ë ì´ë¯¸ì§ ì´ë¦ 1976 * @param {String} oEvent.url ì¤í¨ë ì´ë¯¸ì§ URL 1977 * @param {Number} oEvent.count íì¬ ë¡ë©ë ê°¯ì 1978 * @param {Number} oEvent.total ì ì²´ ì´ë¯¸ì§ ê°¯ì 1979 */ 1980 this.fireEvent("retry", { 1981 count : this._aImages.length, 1982 total : this._nCount, 1983 name : sName, 1984 url : sURL, 1985 delay : this.RETRY_DELAY, 1986 retryCount : this._htImageRetryCount[sName] 1987 }); 1988 1989 setTimeout(function () { 1990 // workaround http://code.google.com/p/chromium/issues/detail?id=7731 1991 el.src = "about:blank"; 1992 el.src = sURL; 1993 }, this.RETRY_DELAY); 1994 return; 1995 } 1996 1997 if (fFail && fFail !== null) { 1998 fFail(el, sName, sURL); 1999 } 2000 2001 /** 2002 * í ê°ì ì´ë¯¸ì§ê° ë¡ë© ì¤í¨ íì ë ì¤í 2003 * @name collie.ImageManager#error 2004 * @event 2005 * @param {Object} oEvent 2006 * @param {String} oEvent.name ì¤í¨ë ì´ë¯¸ì§ ì´ë¦ 2007 * @param {String} oEvent.url ì¤í¨ë ì´ë¯¸ì§ URL 2008 * @param {Number} oEvent.count íì¬ ë¡ë©ë ê°¯ì 2009 * @param {Number} oEvent.total ì ì²´ ì´ë¯¸ì§ ê°¯ì 2010 */ 2011 this.fireEvent("error", { 2012 count : this._aImages.length, 2013 total : this._nCount, 2014 name : sName, 2015 url : sURL 2016 }); 2017 2018 el.onerror = el.onload = null; 2019 this._deleteWhileLoading(sName); 2020 }).bind(this); 2021 2022 // Webkit ë²ê·¸ë¡ ì¸í´ì CORS 주ì ì²ë¦¬ 2023 // el.crossOrigin = ""; 2024 el.src = sURL; 2025 }, 2026 2027 /** 2028 * ë¡ë© ì¤ì ììë¡ ë´ìëë ë³ì를 ì ê±° 2029 * @private 2030 * @param {String} sName 2031 */ 2032 _deleteWhileLoading : function (sName) { 2033 delete this._htImageWhileLoading[sName]; 2034 }, 2035 2036 /** 2037 * ë¡ëëê³ ìë íì¼ì 모ë ë©ì¶¤ 2038 */ 2039 abort : function () { 2040 for (var i in this._htImageWhileLoading) { 2041 this._htImageWhileLoading[i].onload = this._htImageWhileLoading[i].onerror = null; 2042 this._htImageWhileLoading[i].src = null; 2043 this._htImageWhileLoading[i] = null; 2044 } 2045 2046 this._htImageWhileLoading = {}; 2047 this._htImageStartedLoading = {}; 2048 }, 2049 2050 /**
2051 * ë±ë¡ë íì¼ì 모ë ì ê±° 2052 */ 2053 reset : function () { 2054 this.abort(); 2055 this._aImages = []; 2056 this._htImageNames = {}; 2057 this._htImageRetryCount = {}; 2058 this._htImageWhileLoading = {}; 2059 this._nCount = 0; 2060 this._oSpriteSheet.reset(); 2061 }, 2062 2063 /** 2064 * ë¹ëê¸°ë¡ ë±ë¡ë ì´ë¯¸ì§ ì½ë°±ì ì·¨ì íë¤ 2065 * DisplayObjectìì setImageì²ë¦¬í ë ìëì¼ë¡ í¸ì¶ ëë¤ 2066 * @private 2067 * @arguments collie.ImageManager.getImage 2068 */ 2069 cancelGetImage : function (sName, fCallback) { 2070 if (this._htImageNames[sName] instanceof Array) { 2071 for (var i = 0, len = this._htImageNames[sName].length; i < len; i++) { 2072 if (this._htImageNames[sName][i] === fCallback) { 2073 this._htImageNames[sName].splice(i, 1); 2074 return; 2075 } 2076 } 2077 } 2078 }, 2079 2080 /** 2081 * ì´ë¯¸ì§ì ì¤íë¼ì´í¸ ìí¸ ì 보를 ì¶ê°íë¤ 2082 * 2083 * @param {String} sImageName collie.ImageManagerì ë±ë¡ë ì´ë¯¸ì§ ì´ë¦ 2084 * @param {String|Object} vSpriteName ê°ì²´ë¡ í ë²ì ì¬ë¬ ê°ì ì 보를 ë±ë¡í ì ìì 2085 * @example 2086 * collie.ImageManager.add({ 2087 * "sample" : "sample.png" 2088 * }); 2089 * 2090 * // Add Sprites with key-value object 2091 * collie.ImageManager.addSprite("sample", { 2092 * normal : [0, 0], // [offsetX, offsetY] 2093 * action : [30, 0], 2094 * jump : [60, 0, 30, 30, 8] // [startOffsetX, startOffsetY, a width per one frame, a height per one frame, spriteLength] 2095 * }); 2096 * 2097 * // or Add Sprites with array 2098 * collie.ImageManager.addSprite("sample", [ 2099 * [0, 0], // key 0 2100 * [30, 0], // key 1 2101 * [60, 0, 30, 30, 8] // key 2 and [startOffsetX, startOffsetY, a width per one frame, a height per one frame, spriteLength] 2102 * ]); 2103 * 2104 * var item = new collie.DisplayObject({ 2105 * spriteSheet : "normal", // or 0 2106 * backgroundImage : "sample" 2107 * }); 2108 * 2109 * // with Timer 2110 * collie.Timer.cycle(item, 1000, { 2111 * from: 0, 2112 * to: 1, 2113 * set: "spriteSheet" 2114 * }); 2115 * 2116 * // If you use five parameters in the addSprite method, you can use spriteX option with spriteSheet 2117 * item.set("spriteSheet", "jump"); 2118 * collie.Timer.cycle(item, 1000, { 2119 * from: 0, 2120 * to: 7 // spriteLength 8 2121 * }); 2122 */ 2123 addSprite : function (sImageName, vSpriteName, nOffsetX, nOffsetY) { 2124 this._oSpriteSheet.add(sImageName, vSpriteName, nOffsetX, nOffsetY); 2125 }, 2126 2127 /** 2128 * ì¤íë¼ì´í¸ ìí¸ ì 보를 ë°ííë¤ 2129 * 2130 * @private 2131 * @param {String} sImageName collie.ImageManagerì ë±ë¡ë ì´ë¯¸ì§ ì´ë¦ 2132 * @return {Object} 2133 */ 2134 getSprite : function (sImageName) { 2135 return this._oSpriteSheet.get(sImageName); 2136 }, 2137 2138 /** 2139 * ì¤íë¼ì´í¸ ì 보를 ì ê±°íë¤ 2140 * 2141 * @param {String} sImageName collie.ImageManagerì ë±ë¡ë ì´ë¯¸ì§ ì´ë¦ 2142 */ 2143 removeSprite : function (sImageName) { 2144 this._oSpriteSheet.remove(sImageName); 2145 } 2146 2147 /** 2148 * ì´ë¯¸ì§ë¥¼ ì¬ì© ê°ë¥í ìíë¡ ë¯¸ë¦¬ ë§ë¤ì´ ëëë¤. markë ì´ë¯¸ì§ë DisplayObjectìì ì¬ì©í ì ìë¤ 2149 * 2150 * @name collie.ImageManager.mark 2151 * @param {Object|String} vName ì ì°ì ì´ë¯¸ì§ ì´ë¦, loadìì ì°ì´ë sNameì ë»íë©° addImagesì HashTable ííë¡ ë£ì ê²½ì° í¤ ê°ì´ ì´ë¦ì¼ë¡ ë¤ì´ê°ê² ëë¤ 2152 * @deprecated ì ìëì§ ìì ì´ë¦ì ë¶ë¥¼ ë ìëì¼ë¡ markëëë¡ ìì 2153 */ 2154 /** 2155 * @name collie.ImageManager.load 2156 * @deprecated addë¡ ë³ê²½ 2157 */ 2158}, collie.Component))(); 2159/** 2160 * íë ¬ 2161 * @namespace 2162 */ 2163collie.Matrix = { 2164 /** 2165 * íë ¬ ê³±ì 2166 * 2167 * @param {Array} a1 2168 * @param {Array} a2 2169 */ 2170 multiple : function (a1, a2) { 2171 var matrix = []; 2172 2173 for (var row2 = 0, len = a2.length; row2 < len; row2++) { 2174 var r = []; 2175 2176 for (var col2 = 0, len2 = a2[0].length; col2 < len2; col2++) { 2177 var s = 0; 2178 2179 for (var col1 = 0, len3 = a1[0].length; col1 < len3; col1++) { 2180 s += a1[row2][col1] * a2[col1][col2]; 2181 } 2182 2183 r.push(s); 2184 } 2185 2186 matrix.push(r); 2187 } 2188 2189 return matrix; 2190 }, 2191 2192 /** 2193 * translateì ê´ë ¨ë ê³ì° íë ¬ì ë°í 2194 * 2195 * @param {Number} nX 2196 * @param {Number} nY 2197 * @return {Array} 2198 */ 2199 translate : function (nX, nY) { 2200 return [ 2201 [1, 0, nX], 2202 [0, 1, nY], 2203 [0, 0, 1] 2204 ]; 2205 }, 2206 2207 /** 2208 * scale ê³ì° íë ¬ ë°í 2209 * 2210 * @param {Number} nX 2211 * @param {Number} nY 2212 * @return {Array} 2213 */ 2214 scale : function (nX, nY) { 2215 return [ 2216 [nX, 0, 0], 2217 [0, nY, 0], 2218 [0, 0, 1] 2219 ]; 2220 }, 2221 2222 /** 2223 * íì ê³ì° íë ¬ ë°í 2224 * 2225 * @param {Number} nAngle 2226 * @return {Array} 2227 */ 2228 rotate : function (nAngle) { 2229 var nRad = collie.util.toRad(nAngle); 2230 var nCos = Math.cos(nRad); 2231 var nSin = Math.sin(nRad); 2232 2233 return [ 2234 [nCos, -nSin, 0], 2235 [nSin, nCos, 0], 2236 [0, 0, 1] 2237 ]; 2238 }, 2239 2240 /** 2241 * ëì point를 ë³í 2242 * 2243 * @param {Array} a ì ì©í ê³ì° íë ¬ 2244 * @param {Number} nX ëì xì¢í 2245 * @param {Number} nY ëì yì¢í 2246 * @return {Object} htResult 2247 * @return {Number} htResult.x ë³ê²½ë xì¢í 2248 * @return {Number} htResult.y ë³ê²½ë yì¢í 2249 */ 2250 transform : function (a, nX, nY) { 2251 var aResult = this.multiple(a, [ 2252 [nX], 2253 [nY], 2254 [1] 2255 ]); 2256 2257 return { 2258 x : aResult[0][0], 2259 y : aResult[1][0] 2260 }; 2261 } 2262}; 2263/** 2264 * Transform Matrix
2265 * - 기본ì¼ë¡ ìë ì¢íë¡ ê³ì°íë¤ 2266 * - getBoundaryì ê°ì í¹ìí ê²½ì°ë§ ì ëì¢íë¡ ë°í 2267 * - ëì¤ì IE filterë¡ ì¬ì©í ëë pointsì ì ëì¢í 기ë¥ì ë£ì´ì¼ í¨ 2268 * @namespace 2269 */ 2270collie.Transform = { 2271 _htBoundary : { 2272 left : 0, 2273 top : 0, 2274 right : 0, 2275 bottom : 0 2276 }, 2277 _bIsIEUnder8 : collie.util.getDeviceInfo().ie && collie.util.getDeviceInfo().ie < 9, 2278 2279 /** 2280 * Transformë íì ê°ì²´ì Boundary를 ë°í íë¤ (0, 0ìì ìì) 2281 * TODO Transform ìì 구í ìë¨! 2282 * 2283 * @param {collie.DisplayObject} oDisplayObject 2284 * @param {Boolean} bWithPoints ì¢í를 ë°ííëì§ ì¬ë¶, Sensorì box hittestìì ì°ì 2285 * @return {Object} htResult ìë ì¢í ìì 2286 * @return {Number} htResult.left 2287 * @return {Number} htResult.right 2288 * @return {Number} htResult.top 2289 * @return {Number} htResult.bottom 2290 * @return {Number} htResult.isTransform 2291 * @return {Number} htResult.points 2292 */ 2293 getBoundary : function (oDisplayObject, bWithPoints) { 2294 var htInfo = oDisplayObject.get(); 2295 var aPoints = [[0, 0], [htInfo.width, 0], [htInfo.width, htInfo.height], [0, htInfo.height]]; 2296 var aTransformedPoints = this.points(oDisplayObject, aPoints); 2297 var htBoundary = collie.util.getBoundary(aTransformedPoints); 2298 this._htBoundary.left = htBoundary.left; 2299 this._htBoundary.right = htBoundary.right; 2300 this._htBoundary.bottom = htBoundary.bottom; 2301 this._htBoundary.top = htBoundary.top; 2302 this._htBoundary.isTransform = this.isUseTransform(oDisplayObject); 2303 2304 if (bWithPoints) { 2305 this._htBoundary.points = aTransformedPoints; // sensorì© point 2306 } 2307 2308 return this._htBoundary; 2309 }, 2310 2311 /** 2312 * í´ë¹ íì ê°ì²´ì ë§ê² ì ë¤ì transformí 결과를 ë°í íë¤ 2313 * 2314 * @param {collie.DisplayObject} oDisplayObject ëì íì ê°ì²´ 2315 * @param {Array} aPoints transformì ì ì©í ì ë¤ (ex: [[x1, y1], [x2, y2], ...]) 2316 */ 2317 points : function (oDisplayObject, aPoints) { 2318 var aMatrix 2319 2320 if (!this._bIsIEUnder8) { 2321 aMatrix = this.getMatrixRecusively(oDisplayObject); 2322 } 2323 2324 // ê³ì°í íìê° ìë¤ë©´ ê·¸ëë¡ ë°í 2325 if (!aMatrix) { 2326 return aPoints; 2327 } 2328 2329 var aPointsAfter = []; 2330 2331 for (var i = 0, len = aPoints.length; i < len; i++) { 2332 var htPoint = collie.Matrix.transform(aMatrix, aPoints[i][0], aPoints[i][1]); 2333 aPointsAfter.push([htPoint.x, htPoint.y]); 2334 } 2335 2336 return aPointsAfter; 2337 }, 2338 2339 /** 2340 * ììë Transformì ì ì©í Matrix를 ë°í 2341 * TODO ìë ì²´í¬í´ ë´ì¼ í¨! 2342 * 2343 * @param {collie.DisplayObject} oDisplayObject ìµíì ê°ì²´ 2344 * @return {Array} Matrix 2345 */ 2346 getMatrixRecusively : function (oDisplayObject) { 2347 var self = oDisplayObject; 2348 var aMatrix = null; 2349 var nX = 0; 2350 var nY = 0; 2351 2352 while (self) { 2353 if (this.isUseTransform(self)) { 2354 var aSelfMatrix = this.getMatrix(self, nX, nY); 2355 aMatrix = aMatrix !== null ? collie.Matrix.multiple(aMatrix, aSelfMatrix) : aSelfMatrix; 2356 } 2357 2358 nX -= self._htOption.x; 2359 nY -= self._htOption.y; 2360 self = self.getParent(); 2361 } 2362 2363 return aMatrix; 2364 }, 2365 2366 /** 2367 * ëì íì ê°ì²´ì ë§ë Matrix를 구íë¤ 2368 * ìëì¢íì matrixë¡ ë°íëë©° ìµì¢ ê²°ê³¼ì translateë ë³ëë¡ ì ì©í´ì¼ íë¤ 2369 * 2370 * @param {collie.DisplayObject} oDisplayObject 2371 * @param {Number} nX ì¢í ë³´ì ì¹ 2372 * @param {Number} nY 2373 * @return {Array} Matrix 2374 */ 2375 getMatrix : function (oDisplayObject, nX, nY) { 2376 if (typeof nX === "undefined") { 2377 nX = 0; 2378 } 2379 2380 if (typeof nY === "undefined") { 2381 nY = 0; 2382 } 2383 2384 var htOrigin = oDisplayObject.getOrigin(); 2385 var htInfo = oDisplayObject.get(); 2386 var aMatrix = collie.Matrix.translate(htOrigin.x + nX, htOrigin.y + nY); 2387 2388 if (htInfo.angle !== 0) { 2389 aMatrix = collie.Matrix.multiple(aMatrix, collie.Matrix.rotate(htInfo.angle)); 2390 } 2391 2392 if (htInfo.scaleX !== 1 || htInfo.scaleY !== 1) { 2393 aMatrix = collie.Matrix.multiple(aMatrix, collie.Matrix.scale(htInfo.scaleX, htInfo.scaleY)); 2394 } 2395 2396 aMatrix = collie.Matrix.multiple(aMatrix, collie.Matrix.translate(-(htOrigin.x + nX), -(htOrigin.y + nY))); 2397 return aMatrix; 2398 }, 2399 2400 /** 2401 * Transformì ì¬ì©íê³ ìë ê²½ì° 2402 * @return {Boolean} 2403 */ 2404 isUseTransform : function (oDisplayObject) { 2405 return (oDisplayObject._htOption.scaleX !== 1 || oDisplayObject._htOption.scaleY !== 1 || oDisplayObject._htOption.angle !== 0); 2406 } 2407}; 2408/** 2409 * ìºë²ì¤ ë°©ìì ë ëë§ 2410 * 2411 * @private 2412 * @class collie.LayerCanvas 2413 * @param {collie.Layer} oLayer 2414 */
2415collie.LayerCanvas = collie.Class(/** @lends collie.LayerCanvas.prototype */{ 2416 /** 2417 * @private 2418 * @constructs 2419 */ 2420 $init : function (oLayer) { 2421 this._oLayer = oLayer; 2422 this._oEvent = oLayer.getEvent(); 2423 this._htDeviceInfo = collie.util.getDeviceInfo(); 2424 this._initCanvas(); 2425 }, 2426 2427 _initCanvas : function () { 2428 var htSize = this._getLayerSize(); 2429 this._elCanvas = document.createElement("canvas"); 2430 this._elCanvas.width = htSize.width; 2431 this._elCanvas.height = htSize.height; 2432 this._elCanvas.className = "_collie_layer"; 2433 this._elCanvas.style.position = "absolute"; 2434 this._elCanvas.style.left = this._oLayer.option("x") + "px"; 2435 this._elCanvas.style.top = this._oLayer.option("y") + "px"; 2436 2437 if (collie.Renderer.isRetinaDisplay()) { 2438 this._elCanvas.style.width = (htSize.width / 2) + "px"; 2439 this._elCanvas.style.height = (htSize.height / 2) + "px"; 2440 } 2441 2442 this._oContext = this._elCanvas.getContext('2d'); 2443 }, 2444 2445 /** 2446 * íì¬ ë ì´ì´ ì¬ì´ì¦ë¥¼ ë°í, ë í°ëì¼ ê²½ì°ìë ëë°°ë¡ ë°í íë¤ (ìºë²ì¤ì¼ ê²½ì°ìë§) 2447 * 2448 * @param {Number} nWidth ë ì´ì´ ëë¹, ì§ì íì§ ìì¼ë©´ Layerìì ê°ì ê°ì ¸ì¨ë¤ 2449 * @param {Number} nHeight ë ì´ì´ ëì´, ì§ì íì§ ìì¼ë©´ Layerìì ê°ì ê°ì ¸ì¨ë¤ 2450 * @return {Object} htSize 2451 * @return {Number} htSize.width 2452 * @return {Number} htSize.height 2453 */ 2454 _getLayerSize : function (nWidth, nHeight) { 2455 nWidth = nWidth || this._oLayer.option("width"); 2456 nHeight = nHeight || this._oLayer.option("height"); 2457 2458 // ë í°ë ëì¤íë ì´ ëì 2459 if (collie.Renderer.isRetinaDisplay()) { 2460 nWidth *= 2; 2461 nHeight *= 2; 2462 } 2463 2464 return { 2465 width : nWidth, 2466 height : nHeight 2467 }; 2468 }, 2469 2470 /** 2471 * Canvas Context를 ë°í 2472 * @private 2473 * @return {Boolean|Object} 2474 */ 2475 getContext : function () { 2476 return this._oContext; 2477 }, 2478 2479 /** 2480 * @private 2481 */ 2482 getElement : function () { 2483 return this._elCanvas; 2484 }, 2485 2486 /** 2487 * @private 2488 */ 2489 clear : function (oContext) { 2490 oContext = oContext || this.getContext(); 2491 2492 // workaround: samsung galaxy s3 LTE 4.0.4, LG Optimus G pro 4.1.1ìì ë± ë§ì¶°ì clearíë©´ ììì´ ì기거ë ì¤ë¥ê° ìê¹ 2493 if (!this._htDeviceInfo.android || (this._htDeviceInfo.android < 4.12 && this._htDeviceInfo.android >= 4.2)) { 2494 oContext.clearRect(0, 0, this._elCanvas.width + 1, this._elCanvas.height + 1); 2495 } else { 2496 // but 4.1.2 still has problem with the clearRect method 2497 this._elCanvas.width = this._elCanvas.width; 2498 } 2499 }, 2500 2501 /** 2502 * ìºë²ì¤ 리ì¬ì´ì¦ 2503 * 2504 * @param {Number} nWidth 2505 * @param {Number} nHeight 2506 * @param {Boolean} bExpand 2507 */ 2508 resize : function (nWidth, nHeight, bExpand) { 2509 var htSize = this._getLayerSize(nWidth, nHeight); 2510 2511 if (bExpand) { 2512 this._elCanvas.style.width = nWidth + "px"; 2513 this._elCanvas.style.height = nHeight + "px"; 2514 var nRatioWidth = nWidth / this._oLayer.option("width"); 2515 var nRatioHeight = nHeight / this._oLayer.option("height"); 2516 this._oEvent.setEventRatio(nRatioWidth, nRatioHeight); 2517 } else { 2518 var nCanvasWidth = typeof nWidth === 'number' ? htSize.width : this._elCanvas.width; 2519 var nCanvasHeight = typeof nHeight === 'number' ? htSize.height : this._elCanvas.height; 2520 this.clear(this._oContext); 2521 this._oLayer.setChanged(); 2522 this._elCanvas.width = nCanvasWidth; 2523 this._elCanvas.height = nCanvasHeight; 2524 2525 if (collie.Renderer.isRetinaDisplay()) { 2526 this._elCanvas.style.width = nCanvasWidth / 2 + "px"; 2527 this._elCanvas.style.height = nCanvasHeight / 2 + "px"; 2528 } 2529 } 2530 } 2531}); 2532/** 2533 * DOM ë°©ìì ë ëë§ 2534 * 2535 * @private 2536 * @class collie.LayerDOM 2537 * @param {collie.Layer} oLayer 2538 */ 2539collie.LayerDOM = collie.Class(/** @lends collie.LayerDOM.prototype */{ 2540 /** 2541 * @private 2542 * @constructs 2543 */ 2544 $init : function (oLayer) { 2545 this._oLayer = oLayer; 2546 this._oEvent = oLayer.getEvent(); 2547 this._htOption = oLayer.option(); 2548 this._initElement(); 2549 this._rxDisplayObjectId = new RegExp(collie.DisplayObjectDOM.ID + '([0-9]+)'); 2550 }, 2551 2552 _initElement : function () { 2553 this._el = document.createElement("div"); 2554 this._el.className = "_collie_layer"; 2555 this._el.style.position = "absolute"; 2556 this._el.style.left = this._htOption.x + "px"; 2557 this._el.style.top = this._htOption.y + "px"; 2558 this._el.style.width = this._htOption.width + "px"; 2559 this._el.style.height = this._htOption.height + "px"; 2560 }, 2561 2562 /** 2563 * ë¶ëª¨ë¥¼ íìíë©´ì íì ê°ì²´ ì리먼í¸ë¥¼ ì°¾ëë¤ 2564 * 2565 * @deprecated 2566 * @private 2567 * @param {HTMLElement} el 2568 * @return {HTMLElement|Boolean} 2569 */ 2570 findDisplayObjectElement : function (el) { 2571 while (el && el.nodeType == 1) { 2572 if (this.isDisplayObjectElement(el) && el.parentNode === this._el) { 2573 return el; 2574 } 2575 2576 el = el.parentNode; 2577 } 2578 2579 return false;
2580 }, 2581 2582 /** 2583 * íì ê°ì²´ ì리먼í¸ì¸ ê²½ì° 2584 * 2585 * @deprecated 2586 * @private 2587 * @param {HTMLElement} el 2588 * @return {Boolean} íì ê°ì²´ ì리먼í¸ì¼ ë true 2589 */ 2590 isDisplayObjectElement : function (el) { 2591 if ("classList" in el) { 2592 return el.classList.contains(collie.DisplayObjectDOM.CLASSNAME); 2593 } else { 2594 return (" " + el.className + " ").indexOf(" " + collie.DisplayObjectDOM.CLASSNAME + " ") > -1; 2595 } 2596 }, 2597 2598 /** 2599 * íì¬ ë ì´ì´ ì리먼í¸ë¥¼ ë°í 2600 * 2601 * @private 2602 * @return {HTMLElement} 2603 */ 2604 getElement : function () { 2605 return this._el; 2606 }, 2607 2608 /** 2609 * íë©´ì ê°±ì 2610 * @private 2611 */ 2612 clear : function () { 2613 return true; 2614 }, 2615 2616 /** 2617 * 리ì¬ì´ì¦ 2618 * @private 2619 * @param {Number} nWidth ëë¹ 2620 * @param {Number} nHeight ëì´ 2621 * @param {Boolean} bExpand íì¥ ì¬ë¶ 2622 */ 2623 resize : function (nWidth, nHeight, bExpand) { 2624 if (bExpand) { 2625 var nRatioWidth = nWidth / this._oLayer.option("width"); 2626 var nRatioHeight = nHeight / this._oLayer.option("height"); 2627 this._oEvent.setEventRatio(nRatioWidth, nRatioHeight); 2628 this._el.style[collie.util.getCSSPrefix("transform-origin", true)] = "0 0"; 2629 2630 if (collie.util.getSupportCSS3d()) { 2631 this._el.style[collie.util.getCSSPrefix("transform", true)] = "scale3d(" + nRatioWidth + ", " + nRatioHeight + ", 1)"; 2632 } else if (collie.util.getSupportCSS3()) { 2633 this._el.style[collie.util.getCSSPrefix("transform", true)] = "scale(" + nRatioWidth + ", " + nRatioHeight + ")"; 2634 } else { 2635 // support IE, This method is very heavy. 2636 this._el.style.filter = "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand',M11=" + nRatioWidth + ",M12=0,M21=0,M22=" + nRatioHeight + ");"; 2637 } 2638 } else { 2639 this._el.style.width = nWidth + 'px'; 2640 this._el.style.height = nHeight + 'px'; 2641 } 2642 } 2643}); 2644/** 2645 * ë ì´ì´ ì´ë²¤í¸ ì²ë¦¬ 2646 * 2647 * @class collie.LayerEvent 2648 * @param {collie.Layer} oLayer 2649 */ 2650collie.LayerEvent = collie.Class(/** @lends collie.LayerEvent.prototype */{ 2651 /** 2652 * í´ë¦ íì§ ê° (px) 2653 * TODO Androindììë ë°ìì´ ëê»´ì§ ì ìì¼ë¯ë¡ ìì¹ë¥¼ í¬ê² íë ê²ì´ ì¢ë¤. (ì½ 12ì ë?) 2654 * @constant 2655 */ 2656 THRESHOLD_CLICK : 7, 2657 2658 /** 2659 * @constructs 2660 */ 2661 $init : function (oLayer) { 2662 this._oLayer = oLayer; 2663 this._bHasTouchEvent = !!('ontouchstart' in window); 2664 this._fOnEvent = this._onEvent.bind(this); 2665 this._oMousedownObject = null; 2666 this._htEventRatio = { 2667 width : 1, 2668 height : 1 2669 }; 2670 this._bAttached = false; 2671 }, 2672 2673 /** 2674 * @private 2675 */ 2676 attachEvent : function () { 2677 var el = this._oLayer.getParent(); 2678 2679 if (this._bHasTouchEvent) { 2680 collie.util.addEventListener(el, "touchstart", this._fOnEvent); 2681 collie.util.addEventListener(el, "touchend", this._fOnEvent); 2682 collie.util.addEventListener(el, "touchmove", this._fOnEvent); 2683 collie.util.addEventListener(el, "touchcancel", this._fOnEvent); 2684 } else { 2685 collie.util.addEventListener(el, "mousedown", this._fOnEvent); 2686 collie.util.addEventListener(el, "mouseup", this._fOnEvent); 2687 collie.util.addEventListener(el, "mousemove", this._fOnEvent); 2688 } 2689 2690 this._bAttached = true; 2691 }, 2692 2693 /** 2694 * @private 2695 */ 2696 detachEvent : function () { 2697 var el = this._oLayer.getParent(); 2698 2699 if (this._bAttached) { 2700 if (this._bHasTouchEvent) { 2701 collie.util.removeEventListener(el, "touchstart", this._fOnEvent); 2702 collie.util.removeEventListener(el, "touchend", this._fOnEvent); 2703 collie.util.removeEventListener(el, "touchmove", this._fOnEvent); 2704 collie.util.removeEventListener(el, "touchcancel", this._fOnEvent); 2705 } else { 2706 collie.util.removeEventListener(el, "mousedown", this._fOnEvent); 2707 collie.util.removeEventListener(el, "mouseup", this._fOnEvent); 2708 collie.util.removeEventListener(el, "mousemove", this._fOnEvent); 2709 } 2710 2711 this._bAttached = false; 2712 } 2713 }, 2714 2715 /** 2716 * ì´ë²¤í¸ í¸ë¤ë¬ 2717 * @private 2718 * @param {HTMLEvent} e 2719 */ 2720 _onEvent : function (e) { 2721 // ì´ë²¤í¸ë¥¼ ì¬ì©íì§ ìì¼ë©´ 무ì 2722 if (!this._oLayer._htOption.useEvent) { 2723 return; 2724 } 2725 2726 e = e || window.event; 2727 var oEvent = this._bHasTouchEvent ? e.changedTouches[0] : e || window.event; 2728 var el = this._bHasTouchEvent ? this._getEventTargetElement(e) : e.target || e.srcElement; 2729 var oDocument = el.ownerDocument || document; 2730 var oBody = oDocument.body || oDocument.documentElement; 2731 var nPageX = this._bHasTouchEvent ? oEvent.pageX : oEvent.pageX || oEvent.clientX + oBody.scrollLeft - oDocument.body.clientLeft; 2732 var nPageY = this._bHasTouchEvent ? oEvent.pageY : oEvent.pageY || oEvent.clientY + oBody.scrollTop - oDocument.body.clientTop; 2733 var sType = e.type; 2734 var oDisplayObject = null; 2735 2736 // ì´ë²¤í¸ê° ì¼ì´ë ê³³ì ìë ì¢í를 ê³ì° 2737 var htPosition = this._oLayer.getParentPosition(); 2738 var nRelatedX = nPageX - htPosition.x - this._oLayer._htOption.x; 2739 var nRelatedY = nPageY - htPosition.y - this._oLayer._htOption.y; 2740 nRelatedX = nRelatedX / this._htEventRatio.width; 2741 nRelatedY = nRelatedY / this._htEventRatio.height; 2742 2743 if (sType === "touchcancel") { 2744 if (this._htEventStartPos !== null) { 2745 nRelatedX = this._htEventStartPos.x; 2746 nRelatedY = this._htEventStartPos.y; 2747 } 2748 } 2749 2750 sType = this._convertEventType(sType); 2751 2752 // 기본 ì¡ì ì ë©ì¶ë¤(isPreventDefault ìíì¼ ëë§) 2753 if (sType === "mousemove" || sType === "mousedown") { 2754 if (collie.Renderer.isPreventDefault()) { 2755 collie.util.stopEventDefault(e); 2756 } 2757 } 2758 2759 // ì¢í ê¸°ë¡ 2760 //@TODO ê°ì²´ ì¬ ì¬ì© í´ì¼ í¨ 2761 if (sType === "mousedown") { 2762 this._htEventStartPos = { 2763 x : nRelatedX, 2764 y : nRelatedY 2765 }; 2766 } 2767 2768 // Layer íí ë°©ìëë¡ ì´ë²¤í¸ë¥¼ ë°ìíë¤ 2769 var bFiredEventOnTarget = this._fireEvent(e, sType, nRelatedX, nRelatedY); 2770 2771 // í´ë¦ ì²ë¦¬ 2772 if (sType === "mouseup") {
2773 // íì§ ììë resizeì ë§ì¶°ì ë³ê²½íë¤ 2774 var nThresholdX = this.THRESHOLD_CLICK; 2775 var nThresholdY = this.THRESHOLD_CLICK; 2776 2777 if ( 2778 this._htEventStartPos && 2779 this._htEventStartPos.x - nThresholdX <= nRelatedX && 2780 nRelatedX <= this._htEventStartPos.x + nThresholdX && 2781 this._htEventStartPos.y - nThresholdY <= nRelatedY && 2782 nRelatedY <= this._htEventStartPos.y + nThresholdY 2783 ) { 2784 this._fireEvent(e, "click", nRelatedX, nRelatedY); 2785 } 2786 2787 this._htEventStartPos = null; 2788 } 2789 2790 // ì´ë²¤í¸ ìí를 ì ì¥í´ì ë¤ë¥¸ ë ì´ì´ì íìê°ì²´ ì´ë²¤í¸ê° íµê³¼ëì§ ìëë¡ ë°©ì´íë¤ 2791 collie.Renderer.setEventStatus(sType, bFiredEventOnTarget); 2792 }, 2793 2794 /** 2795 * ë ì´ì´ìì ì´ë²¤í¸ê° ì¼ì´ë¬ì ë íì ê°ì²´ì ì´ë²¤í¸ë¥¼ ë°ì ìí¨ë¤ 2796 * 2797 * @param {Object} e ì´ë²¤í¸ ì본 2798 * @param {String} sType ì´ë²¤í¸ íì , mouse ì´ë²¤í¸ë¡ ë³íëì ë¤ì´ì¨ë¤ 2799 * @param {Number} nX ì´ë²¤í¸ê° ì¼ì´ë ìëì¢í 2800 * @param {Number} nY ì´ë²¤í¸ê° ì¼ì´ë ìëì¢í 2801 * @return {Boolean} íì ê°ì²´ì ì´ë²¤í¸ê° ë°ìíëì§ ì¬ë¶ 2802 * @private 2803 */ 2804 _fireEvent : function (e, sType, nX, nY) { 2805 var oDisplayObject = null; 2806 var bIsNotStoppedBubbling = true; 2807 2808 // ìºë²ì¤ìì ì´ì ë ì´ì´ì ê°ì²´ì ì´ë²¤í¸ê° ì¼ì´ë¬ì¼ë©´ ë¤ì ë ì´ì´ì ê°ì²´ì ì ë¬ëì§ ìëë¤ 2809 if (sType !== "mousemove" && !collie.Renderer.isStopEvent(sType)) { 2810 var aDisplayObjects = this._oLayer.getChildren(); 2811 oDisplayObject = this._getTargetOnHitEvent(aDisplayObjects, nX, nY); 2812 2813 // mousedownì¼ ê²½ì° ê°ì²´ë¥¼ ì ì¥íë¤ 2814 if (oDisplayObject) { 2815 bIsNotStoppedBubbling = this._bubbleEvent(oDisplayObject, sType, e, nX, nY); 2816 2817 if (sType === "mousedown") { 2818 this._setMousedownObject(oDisplayObject); 2819 } 2820 if (sType === "mouseup") { 2821 this._unsetMousedownObject(oDisplayObject); 2822 } 2823 } 2824 } 2825 2826 // mouseup ì²ë¦¬ê° ìë ê²½ì° ìì ë°ì 2827 if (sType === "mouseup" && this._getMousedownObject() !== null) { 2828 oDisplayObject = this._getMousedownObject(); 2829 this._bubbleEvent(oDisplayObject, sType, e, nX, nY); 2830 this._unsetMousedownObject(oDisplayObject); 2831 } 2832 2833 /** 2834 * click ì´ë²¤í¸, 모ë°ì¼ íê²½ì¼ ëë touchstart, touchend를 ë¹êµí´ì ì¢íê° ì¼ì ì´ë´ë¡ ìì§ìì ê²½ì° click ì´ë²¤í¸ë¥¼ ë°ìíë¤d 2835 * @name collie.Layer#click 2836 * @event 2837 * @param {Object} htEvent 2838 * @param {collie.DisplayObject} htEvent.displayObject ëì ê°ì²´ 2839 * @param {HTMLEvent} htEvent.event ì´ë²¤í¸ ê°ì²´ 2840 * @param {Number} htEvent.x ìë xì¢í 2841 * @param {Number} htEvent.y ìë yì¢í 2842 */ 2843 /** 2844 * mousedown ì´ë²¤í¸, 모ë°ì¼ íê²½ì¼ ëë touchstart ì´ë²¤í¸ë í´ë¹ ëë¤. 2845 * @name collie.Layer#mousedown 2846 * @event 2847 * @param {Object} htEvent 2848 * @param {collie.DisplayObject} htEvent.displayObject ëì ê°ì²´ 2849 * @param {HTMLEvent} htEvent.event ì´ë²¤í¸ ê°ì²´ 2850 * @param {Number} htEvent.x ìë xì¢í 2851 * @param {Number} htEvent.y ìë yì¢í 2852 */ 2853 /** 2854 * mouseup ì´ë²¤í¸, 모ë°ì¼ íê²½ì¼ ëë touchend ì´ë²¤í¸ë í´ë¹ ëë¤. 2855 * @name collie.Layer#mouseup 2856 * @event 2857 * @param {Object} htEvent 2858 * @param {collie.DisplayObject} htEvent.displayObject ëì ê°ì²´ 2859 * @param {HTMLEvent} htEvent.event ì´ë²¤í¸ ê°ì²´ 2860 * @param {Number} htEvent.x ìë xì¢í 2861 * @param {Number} htEvent.y ìë yì¢í 2862 */ 2863 /** 2864 * mousemove ì´ë²¤í¸, 모ë°ì¼ íê²½ì¼ ëë touchmove ì´ë²¤í¸ë í´ë¹ ëë¤. 2865 * @name collie.Layer#mouseup 2866 * @event 2867 * @param {Object} htEvent 2868 * @param {collie.DisplayObject} htEvent.displayObject ëì ê°ì²´ 2869 * @param {HTMLEvent} htEvent.event ì´ë²¤í¸ ê°ì²´ 2870 * @param {Number} htEvent.x ìë xì¢í 2871 * @param {Number} htEvent.y ìë yì¢í 2872 */ 2873 if (bIsNotStoppedBubbling) { // stopëë©´ Layerì´ë²¤í¸ë ì¼ì´ëì§ ìëë¤ 2874 this._oLayer.fireEvent(sType, { 2875 event : e, 2876 displayObject : oDisplayObject, 2877 x : nX, 2878 y : nY 2879 }); 2880 } 2881 2882 return !!oDisplayObject; 2883 }, 2884 2885 /** 2886 * ì´ë²¤í¸ ëìì ê³ ë¥¸ë¤ 2887 * - ê°ì¥ ìì ìë ëìì´ ì ì ëì´ì¼ íë¤ 2888 * @private 2889 * @param {Array|collie.DisplayObject} vDisplayObject 2890 * @param {Number} nX ì´ë²¤í¸ ìë x ì¢í 2891 * @param {Number} nY ì´ë²¤í¸ ìë y ì¢í 2892 * @return {collie.DisplayObject|Boolean} 2893 */ 2894 _getTargetOnHitEvent : function (vDisplayObject, nX, nY) { 2895 var oTargetObject = null; 2896 2897 if (vDisplayObject instanceof Array) { 2898 for (var i = vDisplayObject.length - 1; i >= 0; i--) { 2899 // ììë¶í° 2900 if (vDisplayObject[i].hasChild()) { 2901 oTargetObject = this._getTargetOnHitEvent(vDisplayObject[i].getChildren(), nX, nY); 2902 2903 // ì°¾ìì¼ë©´ ë©ì¶¤ 2904 if (oTargetObject) { 2905 return oTargetObject; 2906 } 2907 } 2908 2909 // 본ì¸ë 2910 oTargetObject = this._getTargetOnHitEvent(vDisplayObject[i], nX, nY); 2911 2912 // ì°¾ìì¼ë©´ ë©ì¶¤ 2913 if (oTargetObject) { 2914 return oTargetObject; 2915 } 2916 } 2917 } else { 2918 return this._isPointInDisplayObjectBoundary(vDisplayObject, nX, nY) ? vDisplayObject : false;
2919 } 2920 }, 2921 2922 /** 2923 * ì´ë²¤í¸ëª ë³´ì 2924 * 2925 * @private 2926 * @param {String} sType ì´ë²¤í¸ íì 2927 * @return {String} ë³íë ì´ë²¤í¸ íì 2928 */ 2929 _convertEventType : function (sType) { 2930 var sConvertedType = sType; 2931 2932 switch (sType) { 2933 case "touchstart" : 2934 sConvertedType = "mousedown"; 2935 break; 2936 2937 case "touchmove" : 2938 sConvertedType = "mousemove"; 2939 break; 2940 2941 case "touchend" : 2942 case "touchcancel" : 2943 sConvertedType = "mouseup"; 2944 break; 2945 2946 case "tap" : 2947 sConvertedType = "click"; 2948 break; 2949 } 2950 2951 return sConvertedType; 2952 }, 2953 2954 _getEventTargetElement : function (e) { 2955 var el = e.target; 2956 2957 while (el.nodeType != 1) { 2958 el = el.parentNode; 2959 } 2960 2961 return el; 2962 }, 2963 2964 /** 2965 * ì´ë²¤í¸ ëìì ì´ë²¤í¸ë¥¼ ë²ë¸ë§ì¼ë¡ ì²ë¦¬ íë¤ 2966 * 2967 * @private 2968 * @param {collie.DisplayObject} oDisplayObject ë²ë¸ë§ ëì 2969 * @param {String} sType ì´ë²¤í¸ëª 2970 * @param {HTMLEvent} e 2971 * @param {Number} nX ì´ë²¤í¸ ìë x ì¢í 2972 * @param {Number} nY ì´ë²¤í¸ ìë y ì¢í 2973 * @param {collie.DisplayObject} oCurrentObject ì´ë²¤í¸ ëì 2974 * @return {Boolean} ì´ë²¤í¸ê° ëì¤ì ë©ì·ì¼ë©´ false를 ë°í 2975 */ 2976 _bubbleEvent : function (oDisplayObject, sType, e, nX, nY, oCurrentObject) { 2977 /** 2978 * click ì´ë²¤í¸, 모ë°ì¼ íê²½ì¼ ëë touchstart, touchend를 ë¹êµí´ì ì¢íê° ì¼ì ì´ë´ë¡ ìì§ìì ê²½ì° click ì´ë²¤í¸ë¥¼ ë°ìíë¤d 2979 * @name collie.DisplayObject#click 2980 * @event 2981 * @param {Object} htEvent 2982 * @param {collie.DisplayObject} htEvent.displayObject ëì ê°ì²´ 2983 * @param {HTMLEvent} htEvent.event ì´ë²¤í¸ ê°ì²´ 2984 * @param {Number} htEvent.x ì´ë²¤í¸ ìë x ì¢í 2985 * @param {Number} htEvent.y ì´ë²¤í¸ ìë y ì¢í 2986 */ 2987 /** 2988 * mousedown ì´ë²¤í¸, 모ë°ì¼ íê²½ì¼ ëë touchstart ì´ë²¤í¸ë í´ë¹ ëë¤. 2989 * @name collie.DisplayObject#mousedown 2990 * @event 2991 * @param {Object} htEvent 2992 * @param {collie.DisplayObject} htEvent.displayObject ëì ê°ì²´ 2993 * @param {HTMLEvent} htEvent.event ì´ë²¤í¸ ê°ì²´ 2994 * @param {Number} htEvent.x ì´ë²¤í¸ ìë x ì¢í 2995 * @param {Number} htEvent.y ì´ë²¤í¸ ìë y ì¢í 2996 */ 2997 /** 2998 * mouseup ì´ë²¤í¸, 모ë°ì¼ íê²½ì¼ ëë touchend ì´ë²¤í¸ë í´ë¹ ëë¤. 2999 * @name collie.DisplayObject#mouseup 3000 * @event 3001 * @param {Object} htEvent 3002 * @param {collie.DisplayObject} htEvent.displayObject ëì ê°ì²´ 3003 * @param {Event} htEvent.event ì´ë²¤í¸ ê°ì²´ 3004 * @param {HTMLEvent} htEvent.event ì´ë²¤í¸ ê°ì²´ 3005 * @param {Number} htEvent.x ì´ë²¤í¸ ìë x ì¢í 3006 * @param {Number} htEvent.y ì´ë²¤í¸ ìë y ì¢í 3007 */ 3008 if (oDisplayObject.fireEvent(sType, { // stop() íê² ëë©´ ë²ë¸ë§ ë©ì¶ë¤ 3009 displayObject : oCurrentObject || oDisplayObject, 3010 event : e, 3011 x : nX, 3012 y : nY 3013 }) === false) { 3014 return false; 3015 } 3016 3017 // ë¶ëª¨ì ì´ë²¤í¸ê° ì ë¬ëë¤ 3018 if (oDisplayObject.getParent() && !this._bubbleEvent(oDisplayObject.getParent(), sType, e, nX, nY, oDisplayObject)) { 3019 return false; 3020 } 3021 3022 return true; 3023 }, 3024 3025 /** 3026 * DisplayObject ë²ì ìì PointX, PointYê° ë¤ì´ê°ëì§ íì¸ 3027 * 3028 * @private 3029 * @param {collie.DisplayObject} oDisplayObject 3030 * @param {Number} nPointX íì¸í í¬ì¸í¸ X ì¢í 3031 * @param {Number} nPointY íì¸í í¬ì¸í¸ Y ì¢í 3032 * @return {Boolean} ë¤ì´ê°ë¤ë©´ true 3033 */ 3034 _isPointInDisplayObjectBoundary : function (oDisplayObject, nPointX, nPointY) { 3035 // ìë³´ì´ë ìíê±°ë ì´ë²¤í¸ë¥¼ ë°ì§ ìëë¤ë©´ ì§ëê° 3036 if ( 3037 !oDisplayObject._htOption.useEvent || 3038 !oDisplayObject._htOption.visible || 3039 !oDisplayObject._htOption.width || 3040 !oDisplayObject._htOption.height || 3041 (oDisplayObject._htOption.useEvent === "auto" && !oDisplayObject.hasAttachedHandler()) 3042 ) { 3043 return false; 3044 } 3045 3046 var htHitArea = oDisplayObject.getHitAreaBoundary(); 3047 3048 // ìì ìì ë¤ì´ìì ê²½ì° 3049 if ( 3050 htHitArea.left <= nPointX && nPointX <= htHitArea.right && 3051 htHitArea.top <= nPointY && nPointY <= htHitArea.bottom 3052 ) { 3053 // hitArea ì¤ì ì´ ìì¼ë©´ ì¬ê° ììì¼ë¡ ì²´í¬ 3054 if (!oDisplayObject._htOption.hitArea) { 3055 return true; 3056 } else { 3057 var htPos = oDisplayObject.getRelatedPosition(); 3058 3059 // ëì Point를 ìë ì¢íë¡ ë³ê²½ 3060 nPointX -= htPos.x; 3061 nPointY -= htPos.y; 3062 3063 // transform ì ì© 3064 var aHitArea = oDisplayObject._htOption.hitArea; 3065 aHitArea = collie.Transform.points(oDisplayObject, aHitArea); 3066 return this._isPointInPolygon(aHitArea, nPointX, nPointY); 3067 } 3068 } 3069 3070 return false;
3071 }, 3072 3073 /** 3074 * ëì Pointê° í´ë¦¬ê³¤ ìì ìëì§ ì¬ë¶ë¥¼ ë°í 3075 * 3076 * @private 3077 * @param {Array} ê¼ì§ì 모ì [[x1, y1], [x2, y2], ... ] 3078 * @param {Number} nX ëì ì x ì¢í 3079 * @param {Number} nY ëì ì y ì¢í 3080 * @return {Boolean} trueë©´ ìì ìì 3081 */ 3082 _isPointInPolygon : function (aVertices, nX, nY) { 3083 var bIntersects = false; 3084 3085 for (var i = 0, j = aVertices.length - 1, len = aVertices.length; i < len; j = i++) { 3086 if ( 3087 (aVertices[i][1] > nY) !== (aVertices[j][1] > nY) && 3088 (nX < (aVertices[j][0] - aVertices[i][0]) * (nY - aVertices[i][1]) / (aVertices[j][1] - aVertices[i][1]) + aVertices[i][0]) 3089 ) { 3090 bIntersects = !bIntersects; 3091 } 3092 } 3093 3094 return bIntersects; 3095 }, 3096 3097 /** 3098 * mousedown ê°ì²´ë¥¼ ì¤ì íë¤ 3099 * ì´ ê°ì²´ë¥¼ ì¤ì íë©´ mouseup ì´ë²¤í¸ê° ëìì ë í´ë¹ ê°ì²´ìì íì§ ìëë¼ë í´ë¹ ê°ì²´ì mouseupì ì¼ì¼ì¼ì¤ë¤ 3100 * @param {collie.DisplayObject} oDisplayObject 3101 * @private 3102 */ 3103 _setMousedownObject : function (oDisplayObject) { 3104 this._oMousedownObject = oDisplayObject; 3105 }, 3106 3107 /** 3108 * ì§ì ë mousedown ê°ì²´ë¥¼ í´ì íë¤. ê°ì ê°ì²´ì¬ì¼ë§ í´ì ëë¤ 3109 * @private 3110 */ 3111 _unsetMousedownObject : function (oDisplayObject) { 3112 if (this._oMousedownObject === oDisplayObject) { 3113 this._oMousedownObject = null; 3114 } 3115 }, 3116 3117 /** 3118 * mousedown ê°ì²´ë¥¼ ë°í íë¤ 3119 * @private 3120 * @return {collie.DisplayObject} 3121 */ 3122 _getMousedownObject : function () { 3123 return this._oMousedownObject; 3124 }, 3125 3126 /** 3127 * ì´ë²¤í¸ ì¢í ë³´ì ì¹ë¥¼ ì¤ì íë¤ 3128 * 3129 * @param {Number} nWidth 3130 * @param {Number} nHeight 3131 */ 3132 setEventRatio : function (nWidth, nHeight) { 3133 this._htEventRatio.width = nWidth || this._htEventRatio.width; 3134 this._htEventRatio.height = nHeight || this._htEventRatio.height; 3135 }, 3136 3137 /** 3138 * ì´ë²¤í¸ ì¢í ë³´ì ì¹ê° ìë¤ë©´ ë°í íë¤ 3139 * @private 3140 * @deprecated 3141 * @return {Object} htEventRatio 3142 * @return {Number} htEventRatio.width 3143 * @return {Number} htEventRatio.height 3144 */ 3145 getEventRatio : function () { 3146 return this._htEventRatio; 3147 } 3148}); 3149/** 3150 * íì ê°ì²´ë¥¼ ë´ê³ ìë ë ì´ì´, Stage ê°ë 3151 * @class collie.Layer 3152 * @extends collie.Component 3153 * @param {Object} [htOption] 3154 * @param {Number} [htOption.width=320] ëë¹ (px) 3155 * @param {Number} [htOption.height=480] ëì´ (px) 3156 * @param {Number} [htOption.x=0] xì¢í (px) 3157 * @param {Number} [htOption.y=0] yì¢í (px) 3158 * @param {Boolean} [htOption.useEvent=true] ì´ë²¤í¸ë¥¼ ì¬ì©íë¤. ìë를 ìí´ íì¬ ë ì´ì´ìì ì´ë²¤í¸ë¥¼ ì¬ì©íì§ ìì ì ìë¤ 3159 * @param {Boolean} [htOption.visible=true] íë©´ íì ì¬ë¶ 3160 * @param {Boolean} [htOption.freeze=false] trueë¡ ì¤ì íë©´ í´ë¹ ë ì´ì´ë¥¼ ì ë°ì´í¸ë¥¼ íì§ ìëë¤ 3161 * @param {Boolean} [htOption.renderingMode=inherit] ë ì´ì´ ë³ë¡ ë ëë§ ëª¨ë를 ì¤ì í¨ [inherit|dom|canvas] 3162 */ 3163collie.Layer = collie.Class(/** @lends collie.Layer.prototype */{ 3164 /** 3165 * í´ëì¤ íì 3166 * @type {String} 3167 */ 3168 type : "layer", 3169 3170 /** 3171 * @constructs 3172 */ 3173 $init : function (htOption) { 3174 this.option({ 3175 x : 0, 3176 y : 0, 3177 width : 320, // ëë¹ 3178 height : 480, // ëì´ 3179 useEvent : true, 3180 visible : true, 3181 freeze : false, 3182 renderingMode : "inherit" 3183 }); 3184 3185 // ì ë ¬ì í´ì¼íë¤ë©´ ì¼ë¨ 0ì¼ë¡ ë§ë¤ì´ ëê³ loadë ë ì ë ¬í¨ 3186 this._sAlignLeft = null; 3187 this._sAlignTop = null; 3188 3189 3190 if (htOption !== undefined) { 3191 if (("x" in htOption) && (htOption.x === "left" || htOption.x === "right" || htOption.x === "center")) { 3192 this._sAlignLeft = htOption.x; 3193 htOption.x = 0; 3194 } 3195 3196 if (("y" in htOption) && (htOption.y === "top" || htOption.y === "bottom" || htOption.y === "center")) { 3197 this._sAlignTop = htOption.y; 3198 htOption.y = 0; 3199 } 3200 3201 this.option(htOption); 3202 } 3203 3204 this._renderingMode = this._htOption.renderingMode === "inherit" ? collie.Renderer.getRenderingMode() : this._htOption.renderingMode; 3205 3206 if (this._renderingMode === "canvas" && !collie.util.getDeviceInfo().supportCanvas) { 3207 this._renderingMode = "dom"; 3208 } 3209 3210 this.drawCount = 0; // debugging ì© draw count 3211 this.optionSetter("visible", this._setVisible.bind(this)); // ì²ì setì Drawingì´ ìì±ë íì ì¤í ëë¤ 3212 this._elParent = null; 3213 this._bChanged = false;
3214 this._aDisplayObjects = []; 3215 this._bLoaded = false; 3216 this._oEvent = new collie.LayerEvent(this); 3217 this._makeDrawing(); 3218 this._setVisible(); 3219 }, 3220 3221 /** 3222 * ë ëë§ ë°©ë²ì ì íí´ì Drawing ê°ì²´ë¥¼ ìì± íë¤ 3223 * @private 3224 */ 3225 _makeDrawing : function () { 3226 this._oDrawing = this._renderingMode === "dom" ? new collie.LayerDOM(this) : new collie.LayerCanvas(this); 3227 }, 3228 3229 /** 3230 * ëë¡ì ê°ì²´ë¥¼ ë°í íë¤ 3231 * @return {collie.LayerCanvas|collie.LayerDOM} 3232 */ 3233 getDrawing : function () { 3234 return this._oDrawing; 3235 }, 3236 3237 /** 3238 * íì¬ ë ì´ì´ì ë ëë§ ëª¨ë를 ë°í 3239 * 3240 * @return {String} [dom|canvas] 3241 */ 3242 getRenderingMode : function () { 3243 return this._renderingMode; 3244 }, 3245 3246 /** 3247 * ì´ë²¤í¸ ê°ì²´ë¥¼ ë°í íë¤ 3248 * @return {collie.LayerEvent} 3249 */ 3250 getEvent : function () { 3251 return this._oEvent; 3252 }, 3253 3254 /** 3255 * ë¶ëª¨ë¥¼ ë°í 3256 * 3257 * @return {HTMLElement} 3258 */ 3259 getParent : function () { 3260 return this._elParent || false; 3261 }, 3262 3263 /** 3264 * 컨í ì´ëì ìë¦¬ë¨¼í¸ ì¶ê°. ë ëë¬ìì loadí ë ì¤í ëë¤ 3265 * - ë¡ëí ë ê°ì¥ í° ë ì´ì´ë¥¼ 기ì¤ì¼ë¡ 컨í ì´ëì í¬ê¸°ë¥¼ ì í¨ 3266 * 3267 * @private 3268 * @param {HTMLElement} elParent 3269 * @param {Number} nZIndex 3270 */ 3271 load : function (elParent, nZIndex) { 3272 this.unload(); 3273 this._bLoaded = true; 3274 this._elParent = this._elParent || elParent; 3275 this._elParent.style.width = Math.max(parseInt(this._elParent.style.width || 0, 10), this.option("width")) + "px"; 3276 this._elParent.style.height = Math.max(parseInt(this._elParent.style.height || 0, 10), this.option("height")) + "px"; 3277 this.getElement().style.zIndex = nZIndex; 3278 3279 // ìì±ì ìµì ì ì ë ¬ì´ í¬í¨ë¼ ìì¼ë©´ load, unload를 ë°ë³µíëë¼ë ì ë ¬ì ê³ìíë¤. 3280 // íì§ë§ ì¬ì©ìê° ì§ì offsetì ì¬ì©íë ê²½ì°ìë resetëëë¡ ì¸ ë²ì§¸ ì¸ì를 íµí´ ì¡°ì¹íë¤. 3281 if (this._sAlignLeft !== null) { 3282 this.offset(this._sAlignLeft, null, true); 3283 } 3284 3285 if (this._sAlignTop !== null) { 3286 this.offset(null, this._sAlignTop, true); 3287 } 3288 3289 this._elParent.appendChild(this.getElement()); 3290 }, 3291 3292 /** 3293 * @private 3294 */ 3295 unload : function () { 3296 if (this.isLoaded()) { 3297 this._oEvent.detachEvent(); 3298 this._elParent.removeChild(this.getElement()); 3299 this._elParent = null; 3300 this._bLoaded = false; 3301 } 3302 }, 3303 3304 /** 3305 * Layerì attach Event를 ìì ì¡°ìì ìí´ Layerê° íì§ ìê³ Rendererê° íë¤ 3306 * - ê°ë°ì© 3307 * @private 3308 */ 3309 attachEvent : function () { 3310 this._oEvent.attachEvent(); 3311 }, 3312 3313 /** 3314 * Layerì detach Event를 ìì ì¡°ìì ìí´ Layerê° íì§ ìê³ Rendererê° íë¤ 3315 * - ê°ë°ì© 3316 * @private 3317 */ 3318 detachEvent : function () { 3319 this._oEvent.detachEvent(); 3320 }, 3321 3322 /** 3323 * CSSì display ìì±ê³¼ ì ì¬ 3324 * @private 3325 */ 3326 _setVisible : function () { 3327 // Drawingì´ ìì±ë기 ì ì ìµì ì´ ì¤ì ë ìë ìì 3328 if (this.getElement()) { 3329 this.getElement().style.display = this.option("visible") ? "block" : "none"; 3330 } 3331 }, 3332 3333 /** 3334 * @private 3335 * @return {Boolean} ë¡ë© ëì´ìëì§ ì¬ë¶ 3336 */ 3337 isLoaded : function () { 3338 return this._bLoaded; 3339 }, 3340 3341 /** 3342 * ììì¼ë¡ DisplayObject를 ì¶ê°íë¤ 3343 * 3344 * @param {collie.DisplayObject} oDisplayObject 3345 * @param {Boolean} bSkipSort ì ë ¬ì´ë 기í ì²ë¦¬ë¥¼ ì¤íµíë¤. privateì© 3346 */ 3347 addChild : function (oDisplayObject) {
3348 // ì¶ê°í ëë§ë¤ ì ë ¬í기 3349 collie.util.pushWithSort(this._aDisplayObjects, oDisplayObject); 3350 oDisplayObject.setLayer(this); 3351 this.setChanged(); 3352 }, 3353 3354 /** 3355 * ë°°ì´ë¡ ììì ì¬ë¬ê° í꺼ë²ì ë£ëë¤. ìë 측면ìì íê°ì© ë£ë ê² ë³´ë¤ ì´ëì´ë¤ 3356 * 3357 * @param {Array} aList DisplayObject ë°°ì´ 3358 */ 3359 addChildren : function (aList) { 3360 for (var i = 0, len = aList.length; i < len; i++) { 3361 this.addChild(aList[i]); 3362 } 3363 }, 3364 3365 /** 3366 * ìììì ì ê±°íë¤ 3367 * 3368 * @param {collie.DisplayObject} oDisplayObject 3369 * @param {Number} nIdx ì¸ë±ì¤ ë²í¸ë¥¼ ìê³ ìë¤ë©´ ì¸ë±ì¤ ë²í¸ë¥¼ ì§ì 3370 */ 3371 removeChild : function (oDisplayObject, nIdx) { 3372 oDisplayObject.unsetLayer(); 3373 3374 if (typeof nIdx !== "undefined") { 3375 this._aDisplayObjects.splice(nIdx, 1); 3376 } else { 3377 for (var i = 0, len = this._aDisplayObjects.length; i < len; i++) { 3378 if (this._aDisplayObjects[i] === oDisplayObject) { 3379 this._aDisplayObjects.splice(i, 1); 3380 break; 3381 } 3382 } 3383 } 3384 3385 this.setChanged(); 3386 }, 3387 3388 /** 3389 * 목ë¡ì ë°ìì ìììì ì ê±°íë¤ 3390 * 3391 * @param {Array} aList 3392 */ 3393 removeChildren : function (aList) { 3394 for (var i = aList.length - 1; i >= 0; i--) { 3395 if (aList[i]) { 3396 this.removeChild(aList[i], i); 3397 } 3398 } 3399 }, 3400 3401 /** 3402 * ë ëë¬ì ë ì´ì´ë¥¼ ì¶ê°íë¤ (DisplayObjectì ì ì¬) 3403 * @TODO ì¶í collie.Rendererê° ë¤ì¤ ì¸ì¤í´ì¤ê° ë ê²½ì° íë¼ë¯¸í°ë¥¼ ë£ì ì ìì 3404 * @example before 3405 * var layer = new collie.Layer(); 3406 * collie.Renderer.addLayer(layer); 3407 * @example after 3408 * var layer = new collie.Layer().addTo(); 3409 * 3410 * @param {collie.Renderer} [oRenderer] ì¶ê°ë ë ëë¬ë¥¼ ì§ì , ìì¼ë©´ collie.Renderer를 기본ì¼ë¡ íë¤ 3411 * @return {collie.Layer} ì기 ìì ì ë°í 3412 */ 3413 addTo : function (oRenderer) { 3414 oRenderer = oRenderer || collie.Renderer; 3415 oRenderer.addLayer(this); 3416 return this; 3417 }, 3418 3419 /** 3420 * zIndexê° ë³ê²½ëìë¤ë©´ ì´ ë©ìë를 í¸ì¶ 3421 * 3422 * @private 3423 * @param {collie.DisplayObject} oDisplayObject 3424 */ 3425 changeDisplayObjectZIndex : function (oDisplayObject) { 3426 this.removeChild(oDisplayObject); 3427 this.addChild(oDisplayObject); 3428 }, 3429 3430 /** 3431 * ììì ë°í íë¤ 3432 * 3433 * @return {Array} 3434 */ 3435 getChildren : function () { 3436 return this._aDisplayObjects; 3437 }, 3438 3439 /** 3440 * ììì´ ìëì§ ì¬ë¶ë¥¼ ë°í 3441 * 3442 * @return {Boolean} trueë©´ ììì´ ìì 3443 */ 3444 hasChild : function () { 3445 return this._aDisplayObjects && this._aDisplayObjects.length > 0; 3446 }, 3447 3448 /** 3449 * ë³ê²½ë ì¬íì´ ìì ê²½ì° DisplayObjectìì Layerì setChanged를 í´ì ì린ë¤. setChangeë ë ì´ì´ë§ 그리기 ëì 3450 * 3451 * @private 3452 */ 3453 setChanged : function () { 3454 this._bChanged = true; 3455 }, 3456 3457 /** 3458 * ë³ê²½ë ë´ì©ì´ ìëì§ ì¬ë¶ë¥¼ ë°í 3459 * 3460 * @return {Boolean} trueë©´ ë³ê²½ë ì ìì 3461 */ 3462 isChanged : function () { 3463 return this._bChanged; 3464 }, 3465 3466 /** 3467 * ë³ê²½ëì§ ìì ìíë¡ ëëë¦°ë¤ 3468 * 3469 * @private 3470 */ 3471 unsetChanged : function () { 3472 this._bChanged = false; 3473 }, 3474 3475 /** 3476 * Canvas Context를 ë°í 3477 * 3478 * @return {Boolean|Object} 3479 */ 3480 getContext : function () { 3481 return ("getContext" in this._oDrawing) ? this._oDrawing.getContext() : false; 3482 }, 3483 3484 /** 3485 * ë ì´ì´ì ì리먼í¸ë¥¼ ë°í 3486 * @return {HTMLElement} 3487 */ 3488 getElement : function () { 3489 return ("getElement" in this._oDrawing) ? this._oDrawing.getElement() : false; 3490 }, 3491 3492 /** 3493 * Layerì ë±ë¡ë DisplayObject를 ì ë°ì´í¸ 3494 * 3495 * @private 3496 * @param {Number} nFrameDuration ì§íë íë ì ìê° 3497 */ 3498 update : function (nFrameDuration) { 3499 this.drawCount = 0; 3500 3501 // ë°ëê² ìì¼ë©´ ì§ëê° 3502 if (!this.isChanged() || this.option("freeze")) { 3503 return; 3504 } 3505 3506 this.clear(); 3507 this.unsetChanged(); 3508 var nWidth = this.option("width"); 3509 var nHeight = this.option("height"); 3510 3511 // ë±ë¡ë ê°ì²´ ì ë°ì´í¸ 3512 for (var i = 0, len = this._aDisplayObjects.length; i < len; i++) { 3513 this._aDisplayObjects[i].update(nFrameDuration, 0, 0, nWidth, nHeight); 3514 } 3515 }, 3516 3517 /** 3518 * íë©´ì ì§ì´ë¤. Canvasì¼ ëë§ ìë 3519 */ 3520 clear : function () { 3521 this._oDrawing.clear(); 3522 }, 3523 3524 /** 3525 * ë ì´ì´ì í¬ê¸°ë¥¼ ë³ê²½ íë¤ 3526 * 모ë ë ì´ì´ì í¬ê¸°ë¥¼ ë³ê²½íê³ ì¶ì ê²½ì° Rendererì resize를 ì´ì©íë¤ 3527 * 3528 * @param {Number} nWidth ëë¹ 3529 * @param {Number} nHeight ëì´ 3530 * @param {Boolean} bExpand íì¥ ì¬ë¶ 3531 * @see collie.Renderer#resize 3532 */ 3533 resize : function (nWidth, nHeight, bExpand) { 3534 if (!bExpand) { 3535 this.option("width", nWidth || this._htOption.width); 3536 this.option("height", nHeight || this._htOption.height); 3537 } 3538 3539 if (this._oDrawing) { 3540 this._oDrawing.resize(nWidth, nHeight, bExpand); 3541 } 3542 3543 if (this._elParent) { 3544 this._elParent.style.width = Math.max(parseInt(this._elParent.style.width || 0, 10), nWidth || this.option("width")) + "px"; 3545 this._elParent.style.height = Math.max(parseInt(this._elParent.style.height || 0, 10), nHeight || this.option("height")) + "px"; 3546 } 3547 3548 /** 3549 * resize ë©ìëê° ì¤íë ë ë°ì 3550 * @event 3551 * @name collie.Layer#resize 3552 */ 3553 this.fireEvent("resize"); 3554 }, 3555 3556 /** 3557 * ë ì´ì´ì ìì¹ë¥¼ ë³ê²½ íë¤ 3558 * ë ì´ì´ì ë¶ëª¨ì í¬ê¸°ë ë±ë¡ë ë ì´ì´ ì¤ ê°ì¥ í° ë ì´ì´ì í¬ê¸°ì ë§ê²
3558 ë³ê²½ëë¤. 3559 * 3560 * @param {Number|String} [nX] xì¢í(px), left, right, center를 ì ë ¥íë©´ Rendererì í¬ê¸° 기ì¤ì¼ë¡ ì ë ¬ëë¤. ë ëë¬ì í¬ê¸°ê° ë³íëë¼ë ìëì¼ë¡ ìì§ì´ì§ ìëë¤. 3561 * @param {Number|String} [nY] yì¢í(px), top, bottom, center를 ì ë ¥íë©´ Rendererì í¬ê¸° 기ì¤ì¼ë¡ ì ë ¬ëë¤. ë ëë¬ì í¬ê¸°ê° ë³íëë¼ë ìëì¼ë¡ ìì§ì´ì§ ìëë¤. 3562 * @param {Boolean} [bSkipResetInitAlign] privateì© ë³ì, ì§ì ì°ì§ ìëë¤. 3563 */ 3564 offset : function (nX, nY, bSkipResetInitAlign) { 3565 var el = this.getElement(); 3566 3567 if (typeof nX !== "undefined" && nX !== null) { 3568 switch (nX) { 3569 case "left" : 3570 nX = 0; 3571 break; 3572 3573 case "right" : 3574 nX = parseInt(this._elParent.style.width, 10) - this._htOption.width; 3575 break; 3576 3577 case "center" : 3578 nX = parseInt(this._elParent.style.width, 10) / 2 - this._htOption.width / 2; 3579 break; 3580 } 3581 3582 this.option("x", nX); 3583 el.style.left = nX + "px"; 3584 3585 if (!bSkipResetInitAlign) { 3586 this._sAlignLeft = null; 3587 } 3588 } 3589 3590 if (typeof nY !== "undefined" && nY !== null) { 3591 switch (nY) { 3592 case "top" : 3593 nY = 0; 3594 break; 3595 3596 case "bottom" : 3597 nY = parseInt(this._elParent.style.height, 10) - this._htOption.height; 3598 break; 3599 3600 case "center" : 3601 nY = parseInt(this._elParent.style.height, 10) / 2 - this._htOption.height / 2; 3602 break; 3603 } 3604 3605 this.option("y", nY); 3606 el.style.top = nY + "px"; 3607 3608 if (!bSkipResetInitAlign) { 3609 this._sAlignTop = null; 3610 } 3611 } 3612 }, 3613 3614 /** 3615 * ê³ ë¯¼ ì¤... ë¶ëª¨ë¥¼ ë ëë¬ê° ìë ë¤ë¥¸ ì리먼í¸ì ë¶ì´ë íì 3616 * 3617 * @param {HTMLElement} elParent 3618 */ 3619 setParent : function (elParent) { 3620 if (this._bLoaded) { 3621 this._oEvent.detachEvent(); 3622 this._elParent.removeChild(this.getElement()); 3623 this._elParent = elParent; 3624 this._elParent.appendChild(this.getElement()); 3625 this._oEvent.attachEvent(); 3626 } else { 3627 this._elParent = elParent; 3628 } 3629 }, 3630 3631 /** 3632 * @private 3633 * @return {Object} 3634 */ 3635 getParentPosition : function () { 3636 if (this._elParent !== null) { 3637 return this._elParent === collie.Renderer.getElement() ? collie.Renderer.getPosition() : collie.util.getPosition(this._elParent); 3638 } 3639 }, 3640 3641 /** 3642 * ë ì´ì´ë¥¼ ë³µì¬ 3643 * 3644 * @param {Boolean} bRecursive ë±ë¡ë¼ ìë ê°ì²´ê¹ì§ ë³µì¬í ì§ ì¬ë¶ 3645 * @return {collie.Layer} 3646 */ 3647 clone : function (bRecursive) { 3648 var oLayer = new this.constructor(this._htOption); 3649 3650 if (bRecursive && this._aDisplayObjects.length) { 3651 for (var i = 0, l = this._aDisplayObjects.length; i < l; i++) { 3652 this._aDisplayObjects[i].clone(true).addTo(oLayer); 3653 } 3654 } 3655 3656 return oLayer; 3657 } 3658}, collie.Component); 3659/** 3660 * Canvasì ê°ì²´ë¥¼ 그릴 ê²½ì° ì¬ì©í Drawing í´ëì¤ 3661 * - ì§ì ì¬ì©ëì§ ìë í´ëì¤ 3662 * 3663 * @private 3664 * @class collie.DisplayObjectCanvas 3665 * @param {collie.DisplayObject} oDisplayObject 3666 */ 3667collie.DisplayObjectCanvas = collie.Class(/** @lends collie.DisplayObjectCanvas.prototype */{ 3668 /** 3669 * @private 3670 * @constructs 3671 */ 3672 $init : function (oDisplayObject) { 3673 this._oDisplayObject = oDisplayObject; 3674 this._bUseCache = false; 3675 this._oDebugHitArea = null; 3676 this._htEvent = {}; 3677 this._oLayer = null; 3678 this._htInfo = this._oDisplayObject.get(); 3679 this._bIsRetinaDisplay = null; 3680 3681 // ìºì ì¬ì© 3682 if (this._htInfo.useCache) { 3683 this.loadCache(); 3684 } 3685 }, 3686 3687 /** 3688 * ìºë²ì¤ ìºì ì¬ì© 3689 * 3690 * @private 3691 */ 3692 loadCache : function () { 3693 if (!this._bUseCache) { 3694 this._bUseCache = true; 3695 this._elCache = document.createElement("canvas"); 3696 this._elCache.width = this._htInfo.width; 3697 this._elCache.height = this._htInfo.height; 3698 this._oContextCache = this._elCache.getContext("2d"); 3699 } 3700 }, 3701 3702 /** 3703 * ìºë²ì¤ ë²í¼ í´ì 3704 * @private 3705 */ 3706 unloadCache : function () { 3707 if (this._bUseCache) { 3708 this._oContextCache = null; 3709 this._elCache = null; 3710 this._bUseCache = false; 3711 } 3712 }, 3713 3714 /** 3715 * ë²í¼ë¥¼ ë¹ì 3716 * @private 3717 */ 3718 clearCache : function () { 3719 if (this._bUseCache) { 3720 this._oContextCache.clearRect(0, 0, this._elCache.width, this._elCache.height); 3721 this._elCache.width = this._htInfo.width * (this._bIsRetinaDisplay ? 2 : 1); 3722 this._elCache.height = this._htInfo.height * (this._bIsRetinaDisplay ? 2 : 1); 3723 } 3724 }, 3725 3726 /** 3727 * ì´ë¯¸ì§ë¥¼ ê·¸ë¦°ë¤ 3728 * - ì¸ìë drawImageì 첫ë²ì§¸ë§ ë¤ë¥¸ ì¸ì 3729 * ì§ì í¸ì¶íì§ ìì 3730 * @private 3731 * @param {CanvasRenderingContext2D}
3731 oContext canvas Context 3732 * @param {Number} sx 3733 * @param {Number} sy 3734 * @param {Number} sw 3735 * @param {Number} sh 3736 * @param {Number} dx 3737 * @param {Number} dy 3738 * @param {Number} dw 3739 * @param {Number} dh 3740 */ 3741 drawImage : function (oContext, sx, sy, sw, sh, dx, dy, dw, dh) { 3742 var oSource = this._oDisplayObject.getImage(); 3743 var nImageWidth = this._oDisplayObject._nImageWidth; //TODO ìì 3744 var nImageHeight = this._oDisplayObject._nImageHeight; 3745 3746 // ë í°ë ëì¤íë ì´ì¼ ê²½ì° ëë°°ì© ì¦ê° 3747 if (collie.Renderer.isRetinaDisplay()) { 3748 for (i = 1, len = arguments.length; i < len; i++) { 3749 arguments[i] *= 2; 3750 } 3751 3752 nImageWidth *= 2; 3753 nImageHeight *= 2; 3754 } 3755 3756 try { 3757 oContext.drawImage(oSource, sx, sy, sw, sh, dx, dy, dw, dh); 3758 } catch (e) { 3759 throw new Error('invalid drawImage value : ' + sx + ',' + sy + ',' + sw + ',' + sh + ',' + dx + ',' + dy + ',' + dw + ',' + dh + ',' + this._oDisplayObject.getImage().src + ', original : ' + this._oDisplayObject.getImage().width + ',' + this._oDisplayObject.getImage().height + ',source : ' + oSource.width + ',' + oSource.height + ', isCached : ' + (this._elImageCached !== null ? 'true' : 'false')); 3760 } 3761 }, 3762 3763 /** 3764 * Layerì ë¶ì ë ì¤í 3765 * 3766 * @private 3767 */ 3768 load : function () { 3769 this._oLayer = this._oDisplayObject.getLayer(); 3770 this._oContext = this._oDisplayObject.getLayer().getContext(); 3771 this._bIsRetinaDisplay = collie.Renderer.isRetinaDisplay(); 3772 }, 3773 3774 /** 3775 * Layerìì ë¹ ì§ ë 3776 * 3777 * @private 3778 */ 3779 unload : function () { 3780 this._oLayer = null; 3781 this._oContext = null; 3782 }, 3783 3784 /** 3785 * 그리기 3786 * 3787 * @param {Number} nFrameDuration ì§íë íë ì ìê° 3788 * @param {Number} nX ê°ì²´ì ì ë xì¢í 3789 * @param {Number} nY ê°ì²´ì ì ë yì¢í 3790 * @param {Number} nLayerWidth ë ì´ì´ ëë¹, updateë tickìì ìë ë¡ì§ì´ê¸° ë문ì ì±ë¥ ê·¹ëí를 ìí´ ì ë¬ 3791 * @param {Number} nLayerHeight ë ì´ì´ ëì´ 3792 * @param {Object} oContext Canvas Context, ìì¼ë©´ 기본 Context를 ì¬ì©. ë¶ëª¨ì ë²í¼ Context를 ë¬¼ë ¤ ë°ì ë ì¬ì© 3793 * @private 3794 */ 3795 draw : function (nFrameDuration, nX, nY, nLayerWidth, nLayerHeight, oContext) { 3796 var bUseParentContext = oContext ? true : false; 3797 oContext = oContext || this._oContext; 3798 var oTargetContext = this._bUseCache ? this._oContextCache : oContext; 3799 var oParentContext = oContext; 3800 var htInfo = this._htInfo; 3801 var htDirty = this._oDisplayObject.getDirty(); 3802 var htOrigin = this._oDisplayObject.getOrigin(); 3803 var nTargetWidth = htInfo.width; 3804 var nTargetHeight = htInfo.height; 3805 var nOriginX = htOrigin.x; 3806 var nOriginY = htOrigin.y; 3807 var nSavedX = nX; 3808 var nSavedY = nY; 3809 var nRatio = (this._bIsRetinaDisplay ? 2 : 1); 3810 var nSavedXRatio = nX * nRatio; 3811 var nSavedYRatio = nY * nRatio; 3812 var nSavedOpacity = 0; 3813 var bUseTransform = false; 3814 var oTransformContext = oContext; 3815 3816 // ìºì를 ì¬ì© ì¤ì´ë©´ oContext ê°ì ìì ì ë²í¼ë¡ ë³ê²½ 3817 if (htInfo.useCache) { 3818 oContext = this._oContextCache; 3819 } 3820 3821 // ë í°ë ëì¤íë ì´ ëì 3822 if (this._bIsRetinaDisplay) { 3823 nX *= 2; 3824 nY *= 2; 3825 nOriginX *= 2; 3826 nOriginY *= 2; 3827 nTargetWidth *= 2; 3828 nTargetHeight *= 2; 3829 } 3830 3831 // transform ê°ì ì¨ì¼í ê²½ì°ìë§ ì¬ì© 3832 if (this._bUseCache || htInfo.scaleX !== 1 || htInfo.scaleY !== 1 || htInfo.angle !== 0 || htInfo.opacity !== 1) { 3833 bUseTransform = true; 3834 3835 if (this._bUseCache) { 3836 oTransformContext = !bUseParentContext ? this._oContext : oParentContext; 3837 } 3838 3839 oTransformContext.save(); 3840 oTransformContext.translate(nX + nOriginX, nY + nOriginY); 3841 3842 if (htInfo.opacity !== 1) { 3843 nSavedOpacity = oTransformContext.globalAlpha; 3844 oTransformContext.globalAlpha = oTransformContext.globalAlpha === 0 ? htInfo.opacity : oTransformContext.globalAlpha * htInfo.opacity; 3845 } 3846 3847 if (htInfo.angle !== 0) { 3848 oTransformContext.rotate(collie.util.toRad(htInfo.angle)); 3849 } 3850 3851 if (htInfo.scaleX !== 1 || htInfo.scaleY !== 1) { 3852 oTransformContext.scale(htInfo.scaleX, htInfo.scaleY); 3853 } 3854 3855 oTransformContext.translate(-nOriginX, -nOriginY); 3856 nX = nY = 0; 3857 } 3858 3859 // ì´ë²¤í¸ ê°ì²´ ì¬ì¬ì© 3860 this._htEvent.displayObject = this; 3861 this._htEvent.context = oTargetContext; 3862 this._htEvent.x = nX; 3863 this._htEvent.y = nY; 3864 3865 // ìºì를 ì¬ì©íì§ ìê±°ë ë³ê²½ëìì ëë§ ì²ë¦¬ 3866 if (!this._bUseCache || (this._oDisplayObject.isChanged() && !this._oDisplayObject.isChanged(true))) { 3867 // ìºì 그리기 ì ì ë¹ìì¤ 3868 this.clearCache(); 3869 3870 // ë°°ê²½ì ì²ë¦¬ 3871 if (htInfo.backgroundColor) { 3872 oTargetContext.fillStyle = htInfo.backgroundColor; 3873 oTargetContext.fillRect(nX, nY, nTargetWidth, nTargetHeight); 3874 } 3875 3876 if (this._oDisplayObject.getImage()) { 3877 var elSourceImage = this._oDisplayObject.getImage(); 3878 var htImageSize = this._oDisplayObject.getImageSize(); 3879 3880 // ë°ë³µ ì²ë¦¬ 3881 if (htInfo.backgroundRepeat && htInfo.backgroundRepeat !== 'no-repeat') { 3882 var nCountWidth = (htInfo.backgroundRepeat === 'repeat' || htInfo.backgroundRepeat === 'repeat-x') ? Math.ceil(htInfo.width / htImageSize.width) : 1; 3883 var nCountHeight = (htInfo.backgroundRepeat === 'repeat' || htInfo.backgroundRepeat === 'repeat-y') ? Math.ceil(htInfo.height / htImageSize.height) : 1; 3884 3885 // ì´ë¯¸ì§ ë°ë³µ ì²ë¦¬ 3886 if (nCountWidth > 0 || nCountHeight > 0) { 3887 for (var nLeftOffset = 0; nLeftOffset < nCountWidth; nLeftOffset++) { 3888 for (var nTopOffset = 0; nTopOffset < nCountHeight; nTopOffset++) { 3889 var nOffsetX = nLeftOffset * htImageSize.width + htImageSize.width; 3890 var nOffsetY = nTopOffset * htImageSize.height + htImageSize.height; 3891 var nPieceWidth = nOffsetX > htInfo.width ? htImageSize.width - (nOffsetX - htInfo.width) : htImageSize.width; 3892 var nPieceHeight = nOffsetY > htInfo.height ? htImageSize.height - (nOffsetY - htInfo.height) : htImageSize.height; 3893 3894 this.drawImage( 3895 oTargetContext, 3896 0, 3897 0, 3898 nPieceWidth, 3899 nPieceHeight, 3900 (nX / nRatio) + nLeftOffset * htImageSize.width, 3901 (nY / nRatio) + nTopOffset * htImageSize.height, 3902 nPieceWidth, 3903 nPieceHeight 3904 ); 3905 } 3906 } 3907 } 3908 } else { 3909 var nDrawingWidth = Math.min(htImageSize.width, htInfo.width); 3910 var nDrawingHeight = Math.min(htImageSize.height, htInfo.height); 3911 3912 //TODO ì¬ì´í¸ ì´íí¸ ëë°ì´ì¤ í ì¤í¸ í´ì¼ í¨ 1.0.8 3913 this.drawImage( 3914 oTargetContext, 3915 htInfo.offsetX, 3916 htInfo.offsetY, 3917 htInfo.fitImage ? htImageSize.width : nDrawingWidth, 3918 htInfo.fitImage ? htImageSize.height : nDrawingHeight, 3919 nX / nRatio, //TODO floating value ì´ë»ê² í´ì¼í ê¹... ì²ë¦¬íë©´ ê³ë¨íì ìê¹ 3920 nY / nRatio, 3921 htInfo.fitImage ? htInfo.width : nDrawingWidth, 3922 htInfo.fitImage ? htInfo.height : nDrawingHeight 3923 ); 3924 } 3925 } 3926 3927 /** 3928 * Delegate 3929 * @name collie.DisplayObject#onCanvasDraw 3930 * @event 3931 * @delegate 3932 * @param {Object} htEvent 3933 * @param {collie.DisplayObject} htEvent.displayObject 3934 * @param {Object} htEvent.context ìºë²ì¤ Context ê°ì²´ 3935 * @param {Number} htEvent.x ìë xì¢í 3936 * @param {Number} htEvent.y ìë yì¢í 3937 */ 3938 if ("onCanvasDraw" in this._oDisplayObject) { 3939 this._oDisplayObject.onCanvasDraw(this._htEvent); 3940 } 3941 } 3942 3943 // hitArea 그리기 3944 if (htInfo.debugHitArea && htInfo.hitArea) { 3945 if (this._oDebugHitArea === null) { 3946 this._oDebugHitArea = new collie.Polyline({ 3947 x : 0, 3948 y : 0, 3949 width : htInfo.width, 3950 height : htInfo.height, 3951 strokeColor : htInfo.debugHitArea === true ? "yellow" : htInfo.debugHitArea, 3952 strokeWidth : 3 3953 }).addTo(this._oDisplayObject); 3954 this._oDebugHitArea.setPointData(htInfo.hitArea); 3955 } 3956 } 3957
3958 // ìììê² ì í 3959 // ë¶ëª¨ìê²ì Context를 ë¬¼ë ¤ ë°ìê±°ë, ìì ì´ useCache를 ì¬ì©íê³ ìë¤ë©´ ìììê² Context를 ë¬¼ë ¤ì¤. ë¶ëª¨ì ì¤ì ì´ ì°ì ì ë¨ 3960 if (this._oDisplayObject.hasChild() && (!htInfo.useCache || (this._oDisplayObject.isChanged() && !this._oDisplayObject.isChanged(true)))) { 3961 var aDisplayObjects = this._oDisplayObject.getChildren(); 3962 3963 for (var i = 0, len = aDisplayObjects.length; i < len; i++) { 3964 aDisplayObjects[i].update( 3965 nFrameDuration, 3966 // 0, 3967 // 0, 3968 // htInfo.useCache ? 0 : nSavedX, // cache를 ì¬ì©íë©´ íì¬ ê¸°ì¤ì¼ë¡ ì ë ì¢í를 ëê¹ 3969 // htInfo.useCache ? 0 : nSavedY, 3970 htInfo.useCache || bUseTransform ? 0 : nSavedX, // cache를 ì¬ì©íë©´ íì¬ ê¸°ì¤ì¼ë¡ ì ë ì¢í를 ëê¹ 3971 htInfo.useCache || bUseTransform ? 0 : nSavedY, 3972 nLayerWidth, 3973 nLayerHeight, 3974 bUseParentContext || htInfo.useCache ? oContext : null 3975 ); 3976 aDisplayObjects[i].unsetChanged(); 3977 aDisplayObjects[i]._resetDirty(); 3978 } 3979 } 3980 3981 // ìºì 기ë¥ì ì¬ì©íë©´ ììê¹ì§ 그린 íì ì기를 그림 3982 if (htInfo.useCache) { 3983 // (bUseParentContext ? oParentContext : this._oContext).drawImage(oContext.canvas, nSavedXRatio, nSavedYRatio); 3984 // (bUseParentContext ? oParentContext : this._oContext).drawImage(oContext.canvas, bUseParentContext ? nSavedXRatio : 0, bUseParentContext ? nSavedYRatio : 0); 3985 (bUseParentContext ? oParentContext : this._oContext).drawImage(oContext.canvas, 0, 0); 3986 } 3987 3988 this._oLayer.drawCount++; 3989 3990 // ììì¹ 3991 if (bUseTransform) { 3992 oTransformContext.restore(); 3993 } 3994 } 3995}); 3996/** 3997 * DisplayObjectì DOM íì ë¶ë¶ 3998 * @todo ê°¤ëì ë¥ìì¤ ICSìì CSS3d rotate ì¬ì© ì overflow boundaryê° ì못ëë 문ì ì ì´ ìì´ì ê·¸ ë¶ë¶ë§ css2dë¡ ëìíëë¡ ë³ê²½ íì§ë§, ë ëë§ ìëê° 2d, 3d ì°¨ì´ëë ë²ê·¸ê° ë¨ì ìì. 3999 * @private 4000 * @class collie.DisplayObjectDOM 4001 * @param {collie.DisplayObject} oDisplayObject 4002 */ 4003collie.DisplayObjectDOM = collie.Class(/** @lends collie.DisplayObjectDOM.prototype */{ 4004 /** 4005 * @private 4006 * @constructs 4007 */ 4008 $init : function (oDisplayObject) { 4009 this._oDisplayObject = oDisplayObject; 4010 this._htInfo = this._oDisplayObject.get(); 4011 this._oLayer = null; 4012 this._elImage = null; 4013 this._aTransformValue = []; 4014 this._sTransformValue = null; 4015 this._sTransform = collie.util.getCSSPrefix("transform", true); 4016 this._sOrigin = collie.util.getCSSPrefix("transform-origin", true); 4017 this._bSupportCSS3 = collie.util.getSupportCSS3(); 4018 this._bSupportCSS3d = collie.util.getSupportCSS3d(); 4019 this._bUseTransform = this._bSupportCSS3 || this._bSupportCSS3d; 4020 this._htDeviceInfo = collie.util.getDeviceInfo(); 4021 this._bIsAndroid = !!this._htDeviceInfo.android; 4022 this._nAndroidVersion = this._htDeviceInfo.android; 4023 this._bIsIEUnder8 = this._htDeviceInfo.ie && this._htDeviceInfo.ie < 9; 4024 this._bUseTranslateZ = true; 4025 this._bIsRetinaDisplay = null; 4026 this._htEvent = {}; 4027 this._oEmptyObject = {}; 4028 this._sCacheTransformValue = null; 4029 this._initElement(); 4030 }, 4031 4032 _initElement : function () { 4033 // container 4034 this._elContainer = document.createElement("div"); 4035 this._elContainer.id = collie.DisplayObjectDOM.ID + this._oDisplayObject.getId() + (this._htInfo.name ? "_" + this._htInfo.name : ""); 4036 this._elContainer.className = collie.DisplayObjectDOM.CLASSNAME; 4037 this._elContainerStyle = this._elContainer.style; 4038 this._elContainerStyle.position = "absolute"; 4039 4040 // IEì ê²½ì° í¬ê¸°ê° ì í´ì ¸ ìì§ ìì¼ë©´ filterê° ì ìì ì¼ë¡ ìëíì§ ìì 4041 if (this._bIsIEUnder8) { 4042 this._elContainerStyle.width = this._htInfo.width + "px"; 4043 this._elContainerStyle.height = this._htInfo.height + "px"; 4044 } 4045 4046 // element 4047 this._el = document.createElement("div"); 4048 this._elStyle = this._el.style; 4049 4050 if (this._bSupportCSS3d) { 4051 this._elStyle[this._sTransform] = "translateZ(0)"; 4052 } 4053 4054 this._elStyle.position = "absolute"; 4055 this._elStyle.width = this._htInfo.width + "px"; 4056 this._elStyle.height = this._htInfo.height + "px"; 4057 this._elStyle.overflow = "hidden"; 4058 this._elContainer.appendChild(this._el); 4059 }, 4060 4061 load : function () { 4062 this._oLayer = this._oDisplayObject.getLayer(); 4063 4064 // ë¶ëª¨ê° ìì¼ë©´ ë¶ëª¨ ì리먼í¸ì ì§ì ë¶ì 4065 if (this._oDisplayObject.getParent()) { 4066 this._oDisplayObject.getParent().getDrawing().getElement().appendChild(this._elContainer); 4067 } else { 4068 this._oLayer.getElement().appendChild(this._elContainer); 4069 } 4070 4071 this._bIsRetinaDisplay = collie.Renderer.isRetinaDisplay(); 4072 }, 4073 4074 unload : function () { 4075 this._oLayer = null; 4076 this._elContainer.parentNode.removeChild(this._elContainer); 4077 }, 4078 4079 /** 4080 * íì¬ ê°ì²´ì ì리먼í¸ë¥¼ ë°í 4081 * 4082 * @return {HTMLElement} 4083 */ 4084 getElement : function () { 4085 return this._elContainer; 4086 }, 4087 4088 /** 4089 * íì¬ ê°ì²´ì ìì´í ì리먼í¸ë¥¼ ë°í 4090 * 4091 * @return {HTMLElement} 4092 */ 4093 getItemElement : function () { 4094 return this._el; 4095 }, 4096 4097 /** 4098 * 그리기 4099 * 4100 * @private 4101 * @param {Number} nFrameDuration ì§íë íë ì ìê° 4102 * @param {Number} nX ê°ì²´ì ì ë xì¢í 4103 * @param {Number} nY ê°ì²´ì ì ë yì¢í 4104 * @param {Number} nLayerWidth ë ì´ì´ ëë¹, updateë tickìì ìë ë¡ì§ì´ê¸° ë문ì ì±ë¥ ê·¹ëí를 ìí´ ì ë¬ 4105 * @param {Number} nLayerHeight ë ì´ì´ ëì´ 4106 */ 4107 draw : function (nFrameDuration, nX, nY, nLayerWidth, nLayerHeight) { 4108 // ê°ì²´ ì¬ì¬ì© 4109 this._htEvent.displayObject = this; 4110 this._htEvent.element = this._el; 4111 this._htEvent.x = nX; 4112 this._htEvent.y = nY; 4113 4114 var htInfo = this._htInfo; 4115 var htDirty = this._oDisplayObject.getDirty() || this._oEmptyObject; 4116 var htOrigin = this._oDisplayObject.getOrigin(); 4117 var nRatio = (this._bIsRetinaDisplay ? 2 : 1); 4118 4119 if (htDirty.visible) { 4120 this._elContainerStyle.display = htInfo.visible ? "block" : "none"; 4121 } 4122 4123 if (htDirty.width) { 4124 this._elStyle.width = htInfo.width + "px"; 4125 4126 if (this._bIsIEUnder8) { 4127 this._elContainerStyle.width = htInfo.width + "px"; 4128 } 4129 } 4130 4131 if (htDirty.height) { 4132 this._elStyle.height = htInfo.height + "px"; 4133 } 4134 4135 if (htDirty.opacity) { 4136 if (this._bIsIEUnder8) { 4137 this._elContainerStyle.filter = "alpha(opacity=" + (htInfo.opacity * 100) + ")"; 4138 } else { 4139 this._elContainerStyle.opacity = htInfo.opacity; 4140 4141 // Androind 4.1 workaround 4142 // TODO Androind 4.2ìì ìì´ì¡ëì§ íì¸í´ë´ì¼ í¨ 4143 if (this._elImage && this._nAndroidVersion && this._nAndroidVersion >= 4.1) { 4144 this._elImage.style.opacity = htInfo.opacity; 4145 } 4146 } 4147 } 4148 4149 if (htDirty.zIndex) { 4150 this._elContainerStyle.zIndex = htInfo.zIndex; 4151 } 4152 4153 if (htDirty.backgroundColor) { 4154 this._elStyle.backgroundColor = htInfo.backgroundColor; 4155 } 4156 4157 // ì´ë 4158 // transformì ì¬ë¬ í목ì ëìì ì¬ì©í기 ë문ì ê²¹ì³ë ê³ì°í´ì¼ íë¤. 4159 // íì§ë§ ì§ì styleì ì ê·¼íë ê²½ì°ë ë³ê²½ë ëìë§ ê°ì ì ê·¼í´ reflow를 ì¤ì¸ë¤ 4160 if (this._bUseTransform) { 4161 this._aTransformValue.push(this._makeTranslate(htInfo.x, htInfo.y, htInfo.zIndex)); 4162 } else if (htDirty.x || htDirty.y) { 4163 this._elContainerStyle.left = htInfo.x + "px"; 4164 this._elContainerStyle.top = htInfo.y + "px"; 4165 } 4166 4167 //48~49 4168 4169 // origin ì ì© 4170 if (this._bUseTransform) { 4171 if (htDirty.originX || htDirty.originY || htDirty.width || htDirty.height) { 4172 this._elContainerStyle[this._sOrigin] = htOrigin.x + "px " + htOrigin.y + "px"; 4173 } 4174 4175 if (htInfo.angle !== 0) {
4176 this._aTransformValue.push("rotate", (this._bSupportCSS3d && !this._bIsAndroid ? "Z" : ""), "(", htInfo.angle, "deg) "); 4177 } 4178 4179 // scaleì´ translateë³´ë¤ ëì¤ì ëì¼ íë¤ 4180 if (htInfo.scaleX !== 1 || htInfo.scaleY !== 1) { 4181 this._aTransformValue.push("scale(", htInfo.scaleX, ", ", htInfo.scaleY, ") "); 4182 } 4183 } 4184 4185 //46~47 4186 if (this._bUseTransform) { 4187 this._applyTransform(); 4188 } 4189 4190 //24 4191 this._drawImage(htInfo, htDirty); 4192 4193 /** 4194 * Delegate 4195 * @name collie.DisplayObject#onDOMDraw 4196 * @delegate 4197 * @event 4198 * @param {Object} htEvent 4199 * @param {collie.DisplayObject} htEvent.displayObject 4200 * @param {HTMLElement} htEvent.element íì¬ ìë¦¬ë¨¼í¸ 4201 * @param {Number} htEvent.x ê°ì²´ì ì ë x ì¢í 4202 * @param {Number} htEvent.y ê°ì²´ì ì ë y ì¢í 4203 */ 4204 if ("onDOMDraw" in this._oDisplayObject) { 4205 this._oDisplayObject.onDOMDraw(this._htEvent); 4206 } 4207 4208 this._oLayer.drawCount++; 4209 }, 4210 4211 /** 4212 * ì´ë¯¸ì§ì ê´ë ¨ë ìì ì ìí 4213 * 4214 * @private 4215 */ 4216 _drawImage : function (htInfo, htDirty) { 4217 var elSourceImage = this._oDisplayObject.getImage(); 4218 var bUseRepeat = htInfo.backgroundRepeat && htInfo.backgroundRepeat !== 'no-repeat'; 4219 var nImageWidth = 0; 4220 var nImageHeight = 0; 4221 4222 // ì´ë¯¸ì§ ë리기 4223 if (this._oDisplayObject._htOption.fitImage) { 4224 nImageWidth = this._oDisplayObject._htOption.width; 4225 nImageHeight = this._oDisplayObject._htOption.height; 4226 } else { 4227 var htImageSize = this._oDisplayObject.getImageSize(); 4228 nImageWidth = htImageSize.width; 4229 nImageHeight = htImageSize.height; 4230 } 4231 4232 // CSSText를 ì°ë©´ Dirtyë ë¹¼ì¼ íë¤ 4233 if (htDirty.backgroundImage || htDirty.backgroundRepeat) { 4234 4235 // android trasnformìì ì리먼í¸ë¥¼ ì§ì°ë©´ ê¹ë¹¡ê±°ë¦¼, ìµëí ì¬ì¬ì© í¨ 4236 if (this._elImage !== null && (!htInfo.backgroundImage || (htInfo.backgroundRepeat && htInfo.backgroundRepeat !== "no-repeat"))) { 4237 // if (this._elImage !== null) { 4238 this._el.removeChild(this._elImage); 4239 this._elImage = null; 4240 } 4241 4242 if (htInfo.backgroundImage && elSourceImage) { 4243 if (!bUseRepeat && htInfo.backgroundImage) { 4244 var elImageStyle; 4245 4246 if (this._elImage === null) { 4247 // android 3d trasnforms ë²ê·¸ ë문ì divë¡ ê°ì 4248 this._elImage = elSourceImage.cloneNode(); 4249 elImageStyle = this._elImage.style; 4250 elImageStyle.position = "absolute"; 4251 elImageStyle.top = 0; 4252 elImageStyle.left = 0; 4253 elImageStyle.width = nImageWidth + "px"; 4254 elImageStyle.height = nImageHeight + "px"; 4255 elImageStyle.visibility = "visible"; 4256 4257 // Androind 4.1 workaround 4258 // TODO Androind 4.2ìì ìì´ì¡ëì§ íì¸í´ë´ì¼ í¨ 4259 if (this._nAndroidVersion && this._nAndroidVersion >= 4.1) { 4260 elImageStyle.opacity = htInfo.opacity; 4261 } 4262 4263 if (this._bSupportCSS3d && this._bUseTranslateZ) { 4264 elImageStyle[this._sTransform] = "translateZ(0)"; 4265 } 4266 4267 if (this._el.hasChildNodes()) { 4268 this._el.insertBefore(this._elImage, this._el.childNodes[0]); 4269 } else { 4270 this._el.appendChild(this._elImage); 4271 } 4272 } else { 4273 this._elImage.src = elSourceImage.src; 4274 elImageStyle = this._elImage.style; 4275 elImageStyle.width = nImageWidth + "px"; 4276 elImageStyle.height = nImageHeight + "px"; 4277 elImageStyle.visibility = "visible"; 4278 } 4279 } else if (bUseRepeat) { 4280 this._elStyle.backgroundImage = 'url("' + elSourceImage.src + '")'; 4281 this._elStyle.backgroundRepeat = htInfo.backgroundRepeat; 4282 } 4283 } 4284 } 4285 4286 if (htInfo.backgroundImage && this._elImage !== null) { 4287 // ë í°ë ì´ë¯¸ì§ ì²ë¦¬ 4288 if (this._bIsRetinaDisplay && bUseRepeat && (htDirty.width || htDirth.height || htDirty.backgroundRepeat || htDirty.backgroundImage)) { 4289 this._elStyle.backgroundSize = htInfo.width + "px " + htInfo.height + "px"; 4290 } 4291 4292 if (htDirty.offsetX || htDirty.offsetY) { 4293 if (this._bUseTransform) { 4294 this._elImage.style[this._sTransform] = this._makeTranslate(-htInfo.offsetX, -htInfo.offsetY, 1); 4295 } else { 4296 this._elImage.style.left = -htInfo.offsetX + "px"; 4297 this._elImage.style.top = -htInfo.offsetY + "px"; 4298 } 4299 } 4300 } 4301 }, 4302 4303 /** 4304 * translate 구문 ìì±, 2d, 3d를 구ë¶í´ì ìì±íë¤ 4305 * 4306 * @private 4307 * @param {Number} nX 4308 * @param {Number} nY 4309 * @param {Number} nZ 4310 * @return {String} transformì ì ë ¥í translate ê° 4311 */ 4312 _makeTranslate : function (nX, nY, nZ) { 4313 var sTranslate = ''; 4314 var bUseCSS3d = (this._htInfo.angle !== 0 && this._bIsAndroid) ? false : this._bSupp
4314ortCSS3d; 4315 // getAngle 4316 4317 if (bUseCSS3d) { 4318 sTranslate = "translate3d(" + nX + "px, " + nY + "px, " + nZ + "px) "; 4319 } else if (this._bSupportCSS3) { 4320 sTranslate = "translate(" + nX + "px, " + nY + "px) "; 4321 } 4322 4323 return sTranslate; 4324 }, 4325 4326 /** 4327 * ëì ë transform ìì±ì ì ì©íë¤ 4328 * @private 4329 */ 4330 _applyTransform : function () { 4331 var sValue = this._aTransformValue.join(""); 4332 4333 if (this._sCacheTransformValue !== sValue) { 4334 this._elContainerStyle[this._sTransform] = sValue; 4335 this._sCacheTransformValue = sValue; 4336 4337 if (this._bIsAndroid && this._bUseTranslateZ && this._htInfo.angle !== 0) { 4338 this._elStyle[this._sTransform] = ""; 4339 4340 if (this._elImage) { 4341 this._oDisplayObject.setChanged(); 4342 } 4343 4344 this._bUseTranslateZ = false; 4345 } else if (!this._bUseTranslateZ && (this._htInfo.angle === 0 || !this._bIsAndroid) && this._bSupportCSS3d) { 4346 this._elStyle[this._sTransform] = "translateZ(0)"; 4347 4348 if (this._elImage) { 4349 this._oDisplayObject.setChanged(); 4350 } 4351 4352 this._bUseTranslateZ = true; 4353 } 4354 } 4355 4356 this._aTransformValue = []; 4357 } 4358}, collie.Component); 4359 4360/** 4361 * ìë¦¬ë¨¼í¸ í´ëì¤ ì´ë¦ 4362 * @constants 4363 * @memberOf collie.DisplayObjectDOM 4364 */ 4365collie.DisplayObjectDOM.CLASSNAME = "_collie_displayObject"; 4366 4367/** 4368 * ìë¦¬ë¨¼í¸ ìì´ë prefixt 4369 * @constants 4370 * @memberOf collie.DisplayObjecDOM 4371 */ 4372collie.DisplayObjectDOM.ID = "_collie_displayObject_"; 4373/** 4374 * - A DisplayObject is basic class for display object. 4375 * - A DisplayObject can have one or many displayObject like a DOM Element. 4376 * - A offset values changed by when you set a spriteX and spriteY options, but there is no change when you set offsetX and offsetY values. 4377 * - You can use the addTo method with the method chaining 4378 * - A DisplayObject should be set useCache option as true if it doesn't change frequently. 4379 * 4380 * @class collie.DisplayObject 4381 * @extends collie.Component 4382 * @param {Object} [htOption] Options 4383 * @param {String} [htOption.name] ê°ì²´ ì´ë¦, ì¤ë³µ ê°ë¥ 4384 * @param {Number|String} [htOption.width="auto"] ëë¹, auto ê°ì¼ ê²½ì° backgroundImageê° ì¤ì ëë©´ í´ë¹ ì´ë¯¸ì§ ëë¹ ë§í¼ ìëì¼ë¡ ë³ê²½ ëë¤ 4385 * @param {Number|String} [htOption.height="auto"] ëì´, auto ê°ì¼ ê²½ì° backgroundImageê° ì¤ì ëë©´ í´ë¹ ì´ë¯¸ì§ ëì´ ë§í¼ ìëì¼ë¡ ë³ê²½ ëë¤ 4386 * @param {Number|String} [htOption.x=0] xì¶ ìì¹, left, right, center ê°ì ì¬ì©íë©´ ë¶ëª¨ë¥¼ 기ì¤ì¼ë¡ ì ë ¬ 4387 * @param {Number|String} [htOption.y=0] yì¶ ìì¹, top, bottom, center ê°ì ì¬ì©íë©´ ë¶ëª¨ë¥¼ 기ì¤ì¼ë¡ ì ë ¬ 4388 * @param {Number} [htOption.zIndex=0] íì ìì. ëì ìë¡ ìì ìì. ê°ì¼ë©´ ì¶ê°í ììëë¡ 4389 * @param {Number} [htOption.opacity=1] í¬ëª ë(0~1) 4390 * @param {Number} [htOption.angle=0] íì ê°(0~360 deg) 4391 * @param {Number} [htOption.scaleX=1] xì¶ ë¹ì¨ 4392 * @param {Number} [htOption.scaleY=1] yì¶ ë¹ì¨ 4393 * @param {Number} [htOption.originX=center] scale, angle ì ì© ê°ë¡ ê¸°ì¤ [left, right, center, ì«ì] 4394 * @param {Number} [htOption.originY=center] scale, angle ì ì© ì¸ë¡ ê¸°ì¤ [top, bottom, center, ì«ì] 4395 * @param {Number} [htOption.offsetX=0] ë°°ê²½ ì´ë¯¸ì§ ìì xì¢í 4396 * @param {Number} [htOption.offsetY=0] ë°°ê²½ ì´ë¯¸ì§ ìì yì¢í 4397 * @param {Number} [htOption.spriteX=null] ë°°ê²½ ê°ë¡ ì¤íë¼ì´í¸ index, ëë¹ * index ê°ì¼ë¡ offsetXê° ì¤ì ëë¤ 4398 * @param {Number} [htOption.spriteY=null] ë°°ê²½ ì¸ë¡ ì¤íë¼ì´í¸ index, ëì´ * index ê°ì¼ë¡ offsetYê° ì¤ì ëë¤ 4399 * @param {Number} [htOption.spriteLength=0] ë°°ê²½ ì¤íë¼ì´í¸ frameì, ê°ë¡í ì í ì¤íë¼ì´í¸ì¼ ê²½ì°ì ì ì²´ íë ì ì를 ì§ì íë¤. ëì´ê° heightë³´ë¤ í¬ì§ ìì ê²½ì° ì ì©ëì§ ìëë¤ 4400 * @param {Number} [htOption.spriteSheet=null] ë°°ê²½ ì¤íë¼ì´í¸ ìí¸ ì´ë¦, ImageManagerìì addSpriteë¡ ì 보를 ë£ìì ê²½ì° ì¬ì©í ì ìë¤ 4401 * @param {Array} [htOption.rangeX=null] Xì¢í ê°ì© ë²ì. ë°°ì´ë¡ ìµì, ìµëê°ì ì¤ì [min, max], ìë ì¢íì(íì¬ ê°ì²´ì x, yì¢íì ëì¼) 4402 * @param {Array} [htOption.rangeY=null] Yì¢í ê°ì© ë²ì. ë°°ì´ë¡ ìµì, ìµëê°ì ì¤ì [min, max], ìë ì¢íì(íì¬ ê°ì²´ì x, yì¢íì ëì¼) 4403 * @param {Boolean} [htOption.positionRepeat=false] x,y ì¢íì ë²ì ì¤ì (rangeX, rangeY)ì´ ëì´ ìë ê²½ì° ë²ì를 ë²ì´ëë©´ ìì ì¼ë¡ ëìì¤ëì§ ì¬ë¶ë¥¼ ì
4403¤ì . fasleë©´ ê²½ê³ê°ê¹ì§ë§ ìì§ì´ê³ ë©ì¶¤ 4404 * @param {String} [htOption.backgroundColor] ë°°ê²½ì 4405 * @param {String} [htOption.backgroundImage] ë°°ê²½ì´ë¯¸ì§, ì´ë¯¸ì§ë§¤ëì ¸ 리ìì¤ ì´ë¦ì´ë ìë¦¬ë¨¼í¸ 4406 * @param {String} [htOption.backgroundRepeat='no-repeat'] ë°°ê²½ ì´ë¯¸ì§ ë°ë³µ ë°©ë² repeat, repeat-x, repeat-y, no-repeat, no-repeatì´ ìëë¼ë©´ useCacheê° ìëì¼ë¡ trueë¡ ë³í¨ 4407 * @param {Boolean} [htOption.fitImage=false] ì´ë¯¸ì§ë¥¼ ê°ì²´ í¬ê¸°ì ë§ì¶ê¸° 4408 * @param {collie.DisplayObject|Array} [htOption.hitArea] ì´ë²¤í¸ ììì¼ë¡ ì¬ì©ë ë¤ë¥¸ ê°ì²´ë Polyline Path를 ë°°ì´ë¡ ì¤ì íë¤. ì´ ë ì¢íë ìë ì¢í [[x1, y1], [x2, y2], ...] 4409 * @param {Boolean} [htOption.debugHitArea=false] ì´ë²¤í¸ ììì¼ë¡ ì¬ì©ë hitArea를 íë©´ìì ì§ì íì¸í ì ìë¤. ì±ë¥ì ì¢ì§ ì기 ë문ì ëë²ê¹ í ëë§ ì¬ì©í´ì¼ íë¤. 4410 * @param {Number} [htOption.velocityX=0] xì¶ ìë(ì´ë¹ px) 4411 * @param {Number} [htOption.velocityY=0] yì¶ ìë(ì´ë¹ px) 4412 * @param {Number} [htOption.velocityRotate=0] íì ìë(ì´ë¹ 1ë) 4413 * @param {Number} [htOption.forceX=0] xì¶ í(ì´ë¹ px) 4414 * @param {Number} [htOption.forceY=0] yì¶ í(ì´ë¹ px) 4415 * @param {Number} [htOption.forceRotate=0] íì í(ì´ë¹ 1ë) 4416 * @param {Number} [htOption.mass=1] ì§ë 4417 * @param {Number} [htOption.friction=0] ë§ì°°ë ¥ 4418 * @param {Boolean} [htOption.useRealTime=true] SkippedFrameì ì ì©í´ì ì¸ì´í´ì íì¬ ìê°ê³¼ ì¼ì¹ 4419 * @param {Boolean} [htOption.useCache=false] íì¼ ìºì ì¬ì© ì¬ë¶. ìì ê°ì²´ë¥¼ 모ë ìì ì Contextì ê·¸ë ¤ ëëë¤. 4420 * @param {String|Boolean} [htOption.useEvent="auto"] ì´ë²¤í¸ ì¬ì© ì¬ë¶, Layerìµì ê³¼ DisplayObject ìµì ì¤ì íëë¼ë falseë¼ë©´ ëìíì§ ìëë¤. autoë©´ attachë ì´ë²¤í¸ê° ìì ê²½ì°ìë§ ëìíë¤ 4421 * @param {Boolean} [htOption.visible=true] íë©´ íì ì¬ë¶. falseë©´ ìì ê°ì²´ë ë³´ì´ì§ ìëë¤. "hidden" ê°ì¼ë¡ ì¤ì íë©´ ìì ê°ì²´ë íìíê³ ìì ë§ ë³´ì´ì§ ìê² íë¤ 4422 */ 4423collie.DisplayObject = collie.Class(/** @lends collie.DisplayObject.prototype */{ 4424 /** 4425 * í´ëì¤ íì 4426 * @type {String} 4427 */ 4428 type : "displayobject", 4429 4430 /** 4431 * @constructs 4432 */ 4433 $init : function (htOption) { 4434 this._bInitOption = true; 4435 this._htOption = { 4436 name : "", // ê°ì²´ ì´ë¦ 4437 width : 'auto', 4438 height : 'auto', 4439 x : 0, 4440 y : 0, 4441 zIndex : 0, // íì ìì 4442 opacity : 1, // í¬ëª ë 4443 angle : 0, // ë¡í ì´ì (ê°ë) 4444 scaleX : 1, 4445 scaleY : 1, 4446 originX : "center", 4447 originY : "center", 4448 offsetX : 0, 4449 offsetY : 0, 4450 spriteX : null, 4451 spriteY : null, 4452 spriteLength : 0, 4453 spriteSheet : null, 4454 rangeX : null, // Xì¢í ê°ì© ë²ì를 ì¤ì , ë°°ì´ë¡ min, max ì¤ì í¨ [min, max] 4455 rangeY : null, // Yì¢í ê°ì© ë²ì를 ì¤ì , ë°°ì´ë¡ min, max ì¤ì í¨ [min, max] 4456 positionRepeat : false, // x,y ì¢íì ë²ì ì¤ì ì´ ëì´ ìë ê²½ì° ë²ì를 ë²ì´ëë©´ ìì ì¼ë¡ ëìì¤ëì§ ì¬ë¶ë¥¼ ì¤ì . fasleë©´ ê²½ê³ê°ê¹ì§ë§ ìì§ì´ê³ ë©ì¶¤ 4457 backgroundColor : '', // ë°°ê²½ì 4458 backgroundImage : '', // ë°°ê²½ì´ë¯¸ì§, ì´ë¯¸ì§ë§¤ëì ¸ 리ìì¤ ì´ë¦ì´ë ìë¦¬ë¨¼í¸ 4459 backgroundRepeat : 'no-repeat', // ë°°ê²½ ì´ë¯¸ì§ ë°ë³µ repeat, repeat-x, repeat-y, no-repeat 4460 hitArea : null, 4461 debugHitArea : false, 4462 useCache : false, 4463 useEvent : "auto", 4464 fitImage : false, // ì´ë¯¸ì§ë¥¼ ê°ì²´ í¬ê¸°ì ë§ê² ë리기 4465 velocityX : 0, 4466 velocityY : 0, 4467 velocityRotate : 0, 4468 forceX : 0, 4469 forceY : 0, 4470 forceRotate : 0, 4471 mass : 1, // ì§ë 4472 friction : 0, // ë§ì°° 4473 useRealTime : true, 4474 visible : true // íë©´ íì ì¬ë¶ 4475 }; 4476 4477 if (htOption) { 4478 this.option(htOption); 4479 } 4480 4481 this._htDirty = {}; 4482 this._htMatrix = {}; 4483 this._sId = ++collie.DisplayObject._idx; 4484 this._elImage = null; 4485 this._aDisplayObjects = []; 4486 this._oLayer = null; 4487 this._oParent = null; 4488 this._oDrawing = null; 4489 this._bIsSetOption = false; 4490 this._bChanged = true; 4491 this._bChangedTransforms = true; 4492 this._bCustomSize = false;
4493 this._aChangedQueue = null; 4494 this._htGetImageData = null; 4495 this._htRelatedPosition = {}; 4496 this._htParentRelatedPosition = {}; 4497 this._htBoundary = {}; 4498 this._sRenderingMode = null; 4499 this._bRetinaDisplay = collie.Renderer.isRetinaDisplay(); 4500 this._oTimerMove = null; 4501 this._nPositionRight = null; 4502 this._nPositionBottom = null; 4503 this._nImageWidth = 0; 4504 this._nImageHeight = 0; 4505 this._htImageSize = null; 4506 this._htSpriteSheet = null; 4507 this._htOrigin = { 4508 x : 0, 4509 y : 0 4510 }; 4511 4512 this.set(this._htOption); 4513 this._bIsSetOption = true; 4514 }, 4515 4516 /** 4517 * ì¤ì ê°ì ë³ê²½íë¤ 4518 * @example 4519 * oDisplayObject.set({ 4520 * visible : false, 4521 * opacity : 1 4522 * }); 4523 * 4524 * oDisplayObject.set("visible", true); 4525 * 4526 * @param {String|Object} vKey ì¤ì ì´ë¦. ì¬ë¬ê°ì ê°ì Objectë¡ íë²ì ì¤ì í ì ìë¤. 4527 * @param {Variables} vValue ê° 4528 * @param {Boolean} [bSkipSetter] setter를 ìííì§ ìì. ì¼ë°ì ì¼ë¡ ì¬ì©íë ê²ì ê¶ì¥íì§ ìëë¤ 4529 * @param {Boolean} [bSkipChanged] ìí ë³ê²½ì íì§ ìëë¤. ìíë³ê²½ì íì§ ìê² ëë©´ ë¤ì ê·¸ë¦¬ì§ ìëë¤ 4530 * @return {collie.DisplayObject} For Method Chaining 4531 */ 4532 set : function (vKey, vValue, bSkipSetter, bSkipChanged) { 4533 if (typeof vKey === "object") { 4534 // ëë¨¸ì§ ì¤í 4535 for (var i in vKey) { 4536 this.set(i, vKey[i]); 4537 } 4538 } else { 4539 // ê°ì´ ë³íì§ ììë¤ë©´ ì²ë¦¬íì§ ìì 4540 if (this._bIsSetOption && this._htOption[vKey] === vValue) { 4541 return; 4542 } 4543 4544 // í¬ê¸° ìë ë³ê²½ ê° ì ì© 4545 if (vKey === "width" || vKey === "height") { 4546 if (vValue !== "auto") { 4547 this._bCustomSize = true; 4548 } else if (vValue === "auto" && this.getImage() !== null) { 4549 vValue = this.getImageSize()[vKey]; 4550 } else { 4551 vValue = 100; 4552 } 4553 } 4554 4555 this._htOption[vKey] = vValue; 4556 this.setDirty(vKey); // record value to find 4557 4558 if (!bSkipSetter) { 4559 this._setter(vKey, vValue); 4560 } 4561 4562 if (!bSkipChanged) { 4563 // check if DisplayObject changed only transform values 4564 this.setChanged((vKey === 'x' || vKey === 'y' || vKey === 'angle' || vKey === 'scaleX' || vKey === 'scaleY' || vKey === 'opacity') ? true : false); 4565 } 4566 } 4567 4568 return this; 4569 }, 4570 4571 /** 4572 * setter 4573 * @private 4574 * @param {String} vKey ì¤ì ì´ë¦ 4575 * @param {Variables} vValue ê° 4576 */ 4577 _setter : function (vKey, vValue) { 4578 // zIndex hash ê°±ì 4579 if (vKey === "zIndex") { 4580 if (this._oParent) { 4581 this._oParent.changeDisplayObjectZIndex(this); 4582 } else if (this.getLayer()) { 4583 this._oLayer.changeDisplayObjectZIndex(this); 4584 } 4585 } 4586 4587 // ê° ë³´ì 4588 if (vKey === "x" || vKey === "y") { 4589 if (typeof vValue === "string") { 4590 this.align(vKey === "x" ? vValue : false, vKey === "y" ? vValue : false); 4591 } 4592 4593 this._fixPosition(); 4594 this.resetPositionCache(); 4595 } 4596 4597 // ì´ë¯¸ì§ ì¤ì 4598 if (vKey === "backgroundImage") { 4599 this.setImage(vValue); 4600 } 4601 4602 // ì¤íë¼ì´í¸ ìì± ì ì© 4603 if (vKey === 'spriteX' || vKey === 'spriteY' || vKey === 'spriteSheet') { 4604 this._setSpritePosition(vKey, vValue); 4605 } 4606 4607 // hitArea ë°°ì´ ìºì± 4608 if (vKey === 'hitArea' && vValue instanceof Array) { 4609 this._makeHitAreaBoundary(); 4610 } 4611 4612 // origin ë³í 4613 if (vKey === 'width' || vKey === 'height' || vKey === 'originX' || vKey === 'originY') { 4614 this._setOrigin(); 4615 } 4616 4617 // ë°°ê²½ ë°ë³µ ìíë©´ ìºì ì¬ì© 4618 if ((vKey === 'backgroundRepeat' && vValue !== 'no-repeat')) { 4619 this.set("useCache", true); 4620 } 4621 4622 // ìºë²ì¤ ìºì ìì± 4623 if (vKey === 'useCache' && this._oDrawing !== null && this._oDrawing.loadCache) { 4624 if (vValue) { 4625 this._oDrawing.loadCache(); 4626 } else { 4627 this._oDrawing.unloadCache(); 4628 } 4629 } 4630 }, 4631 4632 /** 4633 * ì¤ì ê°ì ê°ì ¸ì¨ë¤ 4634 * @param {String} sKey ê°ì´ ìì¼ë©´ ì ì²´ ê°ì ë°í 4635 * @return {Variable|Object} ì¤ì ê° 4636 * @example 4637 * var htData = oDisplayObject.get(); 4638 * var bVisible = oDisplayObject.get("visible"); 4639 * @example 4640 * <caption>ì±ë¥ì ì¬ë¦¬ê¸° ìí´ìë ë©ìë í¸ì¶ì ìµìíì¼ë¡ ì¤ì´ë ê²ì´ ì¢ë¤ 4641 * If you want to improve performance to your service, you should use less method call.</caption> 4642 * // before 4643 * var x = oDisplayObject.get("x"); 4644 * var y = oDisplayObject.get("y"); 4645 * var width = oDisplayObject.get("width"); 4646 * var height = oDisplayObject.get("height"); 4647 * 4648 * // after 4649 * var htInfo = oDisplayObject.get(); 4650 * htInfo.x; 4651 * htInfo.y; 4652 * htInfo.width; 4653 * htInfo.height; 4654 * 4655 * // or you can access a htOption object directly. It's not recommend but It's better than frequently method call. 4656 * oDisplayObject._htOption.x; 4657 * oDisplayObject._htOption.y; 4658 * oDisplayObject._htOption.width; 4659 * oDisplayObject._htOption.height; 4660 */ 4661 get : function (sKey) { 4662 if (!sKey) { 4663 return this._htOption; 4664 } else { 4665 return this._htOption[sKey]; 4666 } 4667 }, 4668 4669 /** 4670 * ê°ì´ ë³ê²½ë ê²ì¼ë¡ ì¤ì 4671 * 4672 * @param {String} sKey í¤ ì´ë¦, ê°ì´ ìì¼ë©´ 모ë ê°ì ë¤ì ì ì©í¨ 4673 */ 4674 setDirty : function (sKey) { 4675 if (this._htDirty === null) { 4676 this._htDirty = {}; 4677 } 4678 4679 if (typeof sKey === "undefined") { 4680 for (var i in this._htOption) { 4681 this._htDirty[i] = true; 4682 } 4683 } else { 4684 this._htDirty[sKey] = true; 4685 } 4686 }, 4687 4688 /** 4689 * ê°ì´ ë³ê²½ë ê²ì ì림 4690 * 4691 * @param {String} sKey í¤ ì´ë¦ 4692 * @return {Boolean} trueë©´ ê°ì´ ë³ê²½ ëì 4693 */ 4694 getDirty : function (sKey) { 4695 if (!sKey) { 4696 return this._htDirty; 4697 } else { 4698 return this._htDirty[sKey] ? true : false;
4699 } 4700 }, 4701 4702 /** 4703 * Dirty ê°ì ì´ê¸°í, ë¤ ê·¸ë¦¬ê³ ë íì ì¤í íë¤ 4704 * @private 4705 */ 4706 _resetDirty : function () { 4707 this._htDirty = null; 4708 }, 4709 4710 /** 4711 * DisplayObjectì ììì ì¶ê° íë¤ 4712 * - ììì¼ë¡ ë¤ì´ê° DisplayObjectë íì¬ DisplayObjectì zIndex ìí¥ì ë°ê² ëë¤ 4713 * 4714 * @param {collie.DisplayObject} oDisplayObject 4715 */ 4716 addChild : function (oDisplayObject) { 4717 collie.util.pushWithSort(this._aDisplayObjects, oDisplayObject); 4718 oDisplayObject.setParent(this); 4719 4720 if (this._oLayer !== null) { 4721 oDisplayObject.setLayer(this._oLayer); 4722 } 4723 4724 this.setChanged(); 4725 }, 4726 4727 /** 4728 * ììì ì ê±° íë¤ 4729 * @param {collie.DisplayObject} oDisplayObject 4730 * @param {Number} nIdx ì¸ë±ì¤ ë²í¸ë¥¼ ìê³ ìë¤ë©´ ì¸ë±ì¤ ë²í¸ë¥¼ ì§ì 4731 */ 4732 removeChild : function (oDisplayObject, nIdx) { 4733 if (typeof nIdx !== "undefined") { 4734 this._aDisplayObjects[nIdx].unsetLayer(); 4735 this._aDisplayObjects[nIdx].unsetParent(); 4736 this._aDisplayObjects.splice(nIdx, 1); 4737 } else { 4738 for (var i = 0, len = this._aDisplayObjects.length; i < len; i++) { 4739 if (this._aDisplayObjects[i] === oDisplayObject) { 4740 this._aDisplayObjects[i].unsetLayer(); 4741 this._aDisplayObjects[i].unsetParent(); 4742 this._aDisplayObjects.splice(i, 1); 4743 break; 4744 } 4745 } 4746 } 4747 4748 this.setChanged(); 4749 }, 4750 4751 /** 4752 * zIndexê° ë³ê²½ëìë¤ë©´ ì´ ë©ìë를 í¸ì¶ 4753 * 4754 * @private 4755 * @param {collie.DisplayObject} oDisplayObject 4756 */ 4757 changeDisplayObjectZIndex : function (oDisplayObject) { 4758 this.removeChild(oDisplayObject); 4759 this.addChild(oDisplayObject); 4760 }, 4761 4762 /** 4763 * ë ì´ì´ë DisplayObject ê°ì²´ì íì¬ ê°ì²´ë¥¼ ì¶ê° íë¤. 4764 * 4765 * @param {collie.Layer|collie.DisplayObject} oTarget 4766 * @return {collie.DisplayObject} 4767 */ 4768 addTo : function (oTarget) { 4769 // ì´ë¯¸ ì¶ê°ë¼ ìë¤ë©´ ë¹¼ê³ ë¤ì ë£ì 4770 if (this._oLayer || this._oParent) { 4771 // ê°ìë°ë¼ë©´ ëì ì·¨ì 4772 if (this._oLayer === oTarget || this._oParent === oTarget) { 4773 return this; 4774 } else { 4775 this.leave(); 4776 } 4777 } 4778 4779 oTarget.addChild(this); 4780 return this; 4781 }, 4782 4783 /** 4784 * ììì´ ìëì§ ë°í 4785 * 4786 * @return {Boolean} ììì´ ìë¤ë©´ true 4787 */ 4788 hasChild : function () { 4789 return this._aDisplayObjects.length > 0; 4790 }, 4791 4792 /** 4793 * ììì ë°í 4794 * 4795 * @return {Array} 4796 */ 4797 getChildren : function () { 4798 return this._aDisplayObjects; 4799 }, 4800 4801 /** 4802 * ë¶ëª¨ë¥¼ ë°í 4803 * 4804 * @return {collie.DisplayObject} 4805 */ 4806 getParent : function () { 4807 return this._oParent || false; 4808 }, 4809 4810 /** 4811 * ë¶ëª¨ë¥¼ ì¤ì 4812 * - ì§ì í¸ì¶íì§ ìëë¤ 4813 * @private 4814 * @param {collie.DisplayObject} oDisplayObject 4815 */ 4816 setParent : function (oDisplayObject) { 4817 this._oParent = oDisplayObject; 4818 }, 4819 4820 /** 4821 * ë¶ëª¨ë¥¼ í´ì 4822 * @private 4823 */ 4824 unsetParent : function () { 4825 this._oParent = null; 4826 }, 4827 4828 /** 4829 * ë¶ëª¨ê° ìì ê²½ì° ë¶ëª¨ìì ìì ì ëºë¤ 4830 * @return {collie.DisplayObject} ìì ì ë°í 4831 */ 4832 leave : function () { 4833 var oParent = null; 4834 4835 if (this._oParent !== null) { 4836 oParent = this._oParent; 4837 } else if (this._oLayer) { 4838 oParent = this.getLayer(); 4839 } 4840 4841 if (oParent) { 4842 oParent.removeChild(this); 4843 } 4844 4845 return this; 4846 }, 4847 4848 /** 4849 * ìì´ë를 ë°í íë¤ 4850 * 4851 * @return {String} 4852 */ 4853 getId : function () { 4854 return this._sId; 4855 }, 4856 4857 /** 4858 * íì¬ ê°ì²´ì ë°°ê²½ ì´ë¯¸ì§ë¥¼ ê°ì ¸ì¨ë¤ 4859 * 4860 * @return {HTMLElement} 4861 */ 4862 getImage : function () { 4863 return this._elImage || null; 4864 }, 4865 4866 /** 4867 * ì´ë¯¸ì§ í¬ê¸°ë¥¼ ë°í, ë í°ëì¼ ê²½ì° ë³´ì ë ê°ì ë°í íë¤ 4868 * Return a size of the image set to backgroundImage property. 4869 * If The User has a retina display, this method would return a half of size. 4870 * ex) 640*940 -> 320*480 4871 * 4872 * @return {Boolean|Object} htSize ì´ë¯¸ì§ê° ë¡ëëì§ ììì¼ë©´ false를 ë°í. It would return as false when it has not loaded the image yet. 4873 * @return {Number} htSize.width 4874 * @return {Number} htSize.height 4875 */ 4876 getImageSize : function () { 4877 return this._htImageSize || false; 4878 }, 4879 4880 /** 4881 * ì´ë¯¸ì§ë¥¼ ì¤ì íë¤ 4882 * - TODO ë¹ë기 주ìí´ì¼ í¨ 4883 * - TODO setImage ë°ë¡ 못íê² í´ì¼ í¨ backgroundImageë¡... ê°ì´ ì´ê¸ë¨ 4884 * @param {String|HTMLImageElement} vImage ImageManagerì 리ìì¤ ì´ë¦ì´ë ì´ë¯¸ì§ ìë¦¬ë¨¼í¸ 4885 * @private 4886 */ 4887 setImage : function (vImage) { 4888 if (typeof vImage === "string" || !vImage) { 4889 // ì´ë¯¸ 걸ì´ëì ì´ë¯¸ì§ê° ìë¤ë©´ ì·¨ì 4890 if (this._htGetImageData !== null && this._htGetImageData.name !== vImage) { 4891 collie.ImageManager.cancelGetImage(this._htGetImageData.name, this._htGetImageData.callback); 4892 this._htGetImageData = null; 4893 } 4894 4895 if (!vImage) { 4896 this._elImage = null; 4897 this.setChanged(); 4898 } else { 4899 this._htGetImageData = { 4900 name : vImage, 4901 callback : (function (elImage) { 4902 this.setImage(elImage); 4903 }).bind(this) 4904 }; 4905 4906 collie.ImageManager.getImage(this._htGetImageData.name, this._htGetImageData.callback); 4907 } 4908 4909 return; 4910 } 4911 4912 // ê°ì ì´ë¯¸ì§ë©´ ì ì©íì§ ìì 4913 if (this._elImage && this._elImage === vImage) { 4914 return; 4915 } 4916 4917 // reflow ìë°©ì ìí ì´ë¯¸ì§ í¬ê¸° ìºì 4918 this._elImage = vImage;
4919 this._nImageWidth = vImage.width; 4920 this._nImageHeight = vImage.height; 4921 this._htImageSize = { 4922 width : this._bRetinaDisplay ? this._nImageWidth / 2 : this._nImageWidth, 4923 height : this._bRetinaDisplay ? this._nImageHeight / 2 : this._nImageHeight 4924 }; 4925 this._htSpriteSheet = collie.ImageManager.getSprite(this._htOption.backgroundImage); 4926 4927 // ì¬ì©ìê° í¬ê¸°ë¥¼ ì¤ì ìíì¼ë©´ ìëì¼ë¡ ì´ë¯¸ì§ í¬ê¸°ë¡ ì¤ì ë¨ 4928 if (!this._bCustomSize) { 4929 this.set({ 4930 width : this._htImageSize.width, 4931 height : this._htImageSize.height 4932 }); 4933 } 4934 4935 this._setSpritePosition("spriteSheet", this._htOption.spriteSheet); 4936 this._setSpritePosition("spriteX", this._htOption.spriteX); 4937 this._setSpritePosition("spriteY", this._htOption.spriteY); 4938 this.setDirty("backgroundImage"); 4939 this.setChanged(); 4940 }, 4941 4942 /** 4943 * ëë¡ì ê°ì²´ë¥¼ ë°í 4944 * @return {collie.DisplayObjectCanvas|collie.DisplayObjectDOM} 4945 */ 4946 getDrawing : function () { 4947 return this._oDrawing; 4948 }, 4949 4950 /** 4951 * ë³ê²½ë ë´ì©ì´ ìì ê²½ì° Layerì ìë¦°ë¤ 4952 * - ê°ë°ì© 4953 * TODO setChanged ì¤í íìê° ë§ìë° ì¤ë³µ ì¤íì ì¤ì´ë©´ ì±ë¥ì´ í¥ìëë? 4954 * -> flagë§ ëê³ ì¤ì setChanged ì íë drawí기 ì ì íë ê²ì 4955 * 4956 * @private 4957 * @param {Boolean} bChangedTransforms transform ê°ì´ ë³ê²½ëëì§ ì¬ë¶ 4958 */ 4959 setChanged : function (bChangedTransforms) { 4960 // ì´ë¯¸ ë³ê²½ë ê²ì¼ë¡ ë¼ ìë¤ë©´ ì¤ííì§ ìì 4961 if (this._bChanged || (bChangedTransforms && this._bChangedTransforms)) { 4962 return; 4963 } 4964 4965 if (this._oLayer !== null) { 4966 this._oLayer.setChanged(); 4967 } 4968 4969 if (!bChangedTransforms) { 4970 this._bChanged = true; 4971 } 4972 4973 this._bChangedTransforms = true; 4974 4975 // ë¶ëª¨ê° ìë¤ë©´ ë¶ëª¨ë ë°ë ìíë¡ ë³ê²½, ë°ë³µì ì¼ë¡ ë¶ëª¨ìê² ì ë¬ë¨ 4976 if (this._oParent) { 4977 this._oParent.setChanged(false); // transformsë§ ë°ê¼ì´ë ë¶ëª¨ìê²ë ì ì²´ê° ë°ëê²ì¼ë¡ íµë³´ 4978 } 4979 }, 4980 4981 /** 4982 * ë³ê²½ë ë´ì©ì´ ë°ì ëìì ë 4983 * TODO changedë¼ë ì´ë¦ ë³ê²½í íìì± ìì 4984 * @private 4985 */ 4986 unsetChanged : function () { 4987 this._bChanged = false; 4988 this._bChangedTransforms = false; 4989 }, 4990 4991 /** 4992 * íì¬ ê°ì²´ì ë³ê²½ë ë´ì© ì¬ë¶ë¥¼ ë°í 4993 * DOMì¼ ê²½ì° ë³ê²½ëê² ìì¼ë©´ ë¤ì ì그림 4994 * 4995 * @param {Boolean} bChangedOnlyTranforms 4996 * @return {Boolean} 4997 */ 4998 isChanged : function (bChangedOnlyTranforms) { 4999 return !bChangedOnlyTranforms ? (this._bChanged || this._bChangedTransforms) : !this._bChanged && this._bChangedTransforms; 5000 }, 5001 5002 /** 5003 * ë ì´ì´ì ê°ì²´ë¥¼ ì¶ê° 5004 * 5005 * - ì§ì ì¬ì©íì§ ìëë¤ 5006 * @private 5007 * @param {collie.Layer} oLayer 5008 */ 5009 setLayer : function (oLayer) { 5010 // ì¤ë³µë ê°ì´ ìì¼ë©´ ìë¬ 5011 if (this._sId in collie.DisplayObject.htFactory) { 5012 throw new Error('Exists DisplayObject Id ' + this._sId); 5013 } 5014 5015 collie.DisplayObject.htFactory[this._sId] = this; 5016 this._oLayer = oLayer; 5017 this._sRenderingMode = this._oLayer.getRenderingMode(); 5018 this._makeDrawing(); 5019 this._oDrawing.load(); 5020 this.setChanged(); 5021 5022 // ì ë ¬ ì ì© 5023 if (typeof this._htOption.x === "string" || typeof this._htOption.y === "string") { 5024 this.align(typeof this._htOption.x === "string" ? this._htOption.x : false, typeof this._htOption.y === "string" ? this._htOption.y : false); 5025 } 5026 5027 if (this._nPositionRight !== null) { 5028 this.right(this._nPositionRight); 5029 this._nPositionRight = null; 5030 } 5031 5032 if (this._nPositionBottom !== null) { 5033 this.bottom(this._nPositionBottom); 5034 this._nPositionBottom = null; 5035 } 5036 5037 // ììë setLayer ì ì© 5038 for (var i = 0, len = this._aDisplayObjects.length; i < len; i++) { 5039 this._aDisplayObjects[i].setLayer(oLayer); 5040 } 5041 }, 5042 5043 /** 5044 * ë ì´ì´ìì ê°ì²´ë¥¼ ëº 5045 * @private 5046 */ 5047 unsetLayer : function () { 5048 if (this.getLayer()) { 5049 for (var i = 0, len = this._aDisplayObjects.length; i < len; i++) { 5050 this._aDisplayObjects[i].unsetLayer(); 5051 } 5052 5053 this._oDrawing.unload(); 5054 this.setDirty(); 5055 this.setChanged(); 5056 this._sRenderingMode = null; 5057 this._oDrawing = null; 5058 this._oLayer = null; 5059 delete collie.DisplayObject.htFactory[this._sId]; 5060 } 5061 }, 5062 5063 /** 5064 * @private 5065 */ 5066 _makeDrawing : function () { 5067 if (this._oDrawing === null) { 5068 this._oDrawing = this._sRenderingMode === "dom" ? new collie.DisplayObjectDOM(this) : new collie.DisplayObjectCanvas(this); 5069 } 5070 }, 5071 5072 /** 5073 * ë ì´ì´ ë°í 5074 * 5075 * @return {collie.Layer|Boolean} 5076 */ 5077 getLayer : function () { 5078 return this._oLayer || false; 5079 }, 5080 5081 /** 5082 * ë¤ìí ìì±ì ë³ê²½íë©° ì¬ì©í ê²½ì° addMatrix를 ì´ì©í´ ì¤ì ì 미리 ë§ë¤ê³ changeMatrixë¡ ë³ê²½í´ ì¬ì©í ì ìë¤. 5083 * 5084 * @param {Array|Object} vMatrix ë°°ì´ë¡ ì¬ë¬ê°ë¥¼ íë²ì ë£ì ì ìì 5085 * @param {String} vMatrix.name Matrix ì´ë¦ 5086 * @param {Number} vMatrix.property ë³ê²½í ì¤ì ì ì ë ¥íë¤ 5087 * @example 5088 * oDisplayObject.addMatrix({ 5089 * name : "test" 5090 * offsetX : 0, 5091 * offsetY : 100 5092 * }); 5093 * oDisplayObject.addMatrix([ 5094 * { name : "test2", offsetX : 100, offsetY : 100, width : 50, height : 50 }, 5095 * { name : "test3", offsetX : 200, offsetY : 100, width : 80, height : 80 } 5096 * ]); 5097 * 5098 * oDisplayObject.changeMatrix("test2"); 5099 * oDisplayObject.changeMatrix("test3"); 5100 */ 5101 addMatrix : function (vMatrix) { 5102 if (vMatrix instanceof Array) { 5103 for (var i = 0, len = vMatrix.length; i < len; i++) { 5104 this.addMatrix(vMatrix[i]); 5105 } 5106 return; 5107 } 5108 5109 this._htMatrix[vMatrix.name] = vMatrix; 5110 delete this._htMatrix[vMatrix.name].name; 5111 }, 5112 5113 /**
5114 * í´ë¹ Matrixë¡ ë³ê²½íë¤ 5115 * 5116 * @param {String} sName 매í¸ë¦ì¤ ì´ë¦ 5117 */ 5118 changeMatrix : function (sName) { 5119 if (sName in this._htMatrix) { 5120 this.set(this._htMatrix[sName]); 5121 } 5122 }, 5123 5124 /** 5125 * DisplayObject를 ê°±ì íë¤. 5126 * 5127 * @param {Number} nFrameDuration ì§íë íë ì ìê° 5128 * @param {Number} nX ë¶ëª¨ë¡ ë¶í° ë´ë ¤ì¨ xì¢í 5129 * @param {Number} nY ë¶ëª¨ë¡ ë¶í° ë´ë ¤ì¨ yì¢í 5130 * @param {Number} nLayerWidth ë ì´ì´ ëë¹, updateë tickìì ìë ë¡ì§ì´ê¸° ë문ì ì±ë¥ ê·¹ëí를 ìí´ ì ë¬ 5131 * @param {Number} nLayerHeight ë ì´ì´ ëì´ 5132 * @param {Object} oContext ë¶ëª¨ì Canvas Context, useCache를 ì¬ì©íë©´ ëì´ì¨ë¤ 5133 * @return {Boolean} true를 ë°ííë©´ ê³ì ë°ëê² ìë¤ë ë» 5134 * @private 5135 */ 5136 update : function (nFrameDuration, nX, nY, nLayerWidth, nLayerHeight, oContext) { 5137 this._updateMovableOption(nFrameDuration); 5138 5139 // Canvas ë°©ìì´ê³ , ë³´ì´ì§ ìë ê°ì²´ë©´ ê·¸ë¦°ê±¸ë¡ ì¹ë¤, ììë ê·¸ë¦¬ì§ ììë ëë¤. 5140 if (this._sRenderingMode === "canvas" && !this._htOption.visible) { 5141 this.unsetChanged(); 5142 return; 5143 } 5144 5145 nX += this._htOption.x; 5146 nY += this._htOption.y; 5147 5148 // Canvasìì íë©´ ë°ì¼ë¡ ëê°ê±°ë DOMìì ë°ëê² ìì ë 그림 5149 if ( 5150 (this._sRenderingMode === "dom" && this.isChanged()) || ( 5151 this._sRenderingMode === "canvas" && ( 5152 nX + this._htOption.width >= 0 || 5153 nX <= nLayerWidth || 5154 nY + this._htOption.height >= 0 || 5155 nY <= nLayerHeight 5156 ) 5157 )) { 5158 this._oDrawing.draw(nFrameDuration, nX, nY, nLayerWidth, nLayerHeight, oContext); 5159 } 5160 5161 this.unsetChanged(); 5162 this._resetDirty(); 5163 5164 // ìì§ìì´ ìì¼ë©´ ë¤ì ë°ë ìíë¡ ë 5165 if ( 5166 this._htOption.velocityX !== 0 || 5167 this._htOption.velocityY !== 0 || 5168 this._htOption.velocityRotate !== 0 || 5169 this._htOption.forceX !== 0 || 5170 this._htOption.forceY !== 0 || 5171 this._htOption.forceRotate !== 0 5172 ) { 5173 this.setChanged(true); 5174 } 5175 5176 // Canvas ë°©ìì ììì ì§ì ê·¸ë¦¬ê³ , DOM ë°©ìì´ë©´ ë¶ëª¨ê° ë³´ì´ì§ ìë ìíë©´ ììë ê·¸ë¦¬ì§ ìëë¤ 5177 if (this._sRenderingMode === "canvas" || !this._htOption.visible) { 5178 return; 5179 } 5180 5181 // update ìììê² ì í 5182 if (this.hasChild()) { 5183 for (var i = 0, len = this._aDisplayObjects.length; i < len; i++) { 5184 this._aDisplayObjects[i].update(nFrameDuration, nX, nY, nLayerWidth, nLayerHeight); 5185 } 5186 } 5187 }, 5188 5189 _updateMovableOption : function (nFrameDuration) { 5190 if ( 5191 this._htOption.velocityX !== 0 || 5192 this._htOption.velocityY !== 0 || 5193 this._htOption.velocityRotate !== 0 || 5194 this._htOption.forceX !== 0 || 5195 this._htOption.forceY !== 0 || 5196 this._htOption.forceRotate !== 0 5197 ) { 5198 var nFrame = Math.max(17, nFrameDuration) / 1000; 5199 5200 // skippedFrame ì ì©ì íì§ ìëë¤ë©´ 1frame ì©ë§ 그림 5201 if (!this._htOption.useRealTime) { 5202 nFrame = 1; 5203 } 5204 5205 var nVelocityX = this._htOption.velocityX; 5206 var nVelocityY = this._htOption.velocityY; 5207 var nX = this._htOption.x; 5208 var nY = this._htOption.y; 5209 5210 // í ì ì© a = F / m 5211 nVelocityX += (this._htOption.forceX / this._htOption.mass) * nFrame; 5212 nVelocityY += (this._htOption.forceY / this._htOption.mass) * nFrame; 5213 5214 // ë§ì°°ë ¥ ì ì© 5215 var nForceFrictionX = this._htOption.friction * nVelocityX * this._htOption.mass * nFrame; 5216 var nForceFrictionY = this._htOption.friction * nVelocityY * this._htOption.mass * nFrame; 5217 5218 if (nVelocityX !== 0) { 5219 nVelocityX = (Math.abs(nVelocityX) / nVelocityX !== Math.abs(nVelocityX - nForceFrictionX) / (nVelocityX - nForceFrictionX)) ? 0 : nVelocityX - nForceFrictionX; 5220 } 5221 5222 if (nVelocityY !== 0) { 5223 nVelocityY = (Math.abs(nVelocityY) / nVelocityY !== Math.abs(nVelocityY - nForceFrictionY) / (nVelocityY - nForceFrictionY)) ? 0 : nVelocityY - nForceFrictionY; 5224 } 5225 5226 nX += nVelocityX * nFrame; 5227 nY += nVelocityY * nFrame; 5228 nVelocityX = Math.floor(nVelocityX * 1000) / 1000; 5229 nVelocityY = Math.floor(nVelocityY * 1000) / 1000; 5230 5231 if (this._htOption.friction && Math.abs(nVelocityX) < 0.05) { 5232 nVelocityX = 0; 5233 } 5234 5235 if (this._htOption.friction && Math.abs(nVelocityY) < 0.05) { 5236 nVelocityY = 0; 5237 } 5238 5239 // ë³ê²½ì´ ìì ëë§ ì¤ì 5240 if ( 5241 nX !== this._htOption.x || 5242 nY !== this._htOption.y || 5243 nVelocityX !== this._htOption.velocityX || 5244 nVelocityY !== this._htOption.velocityY 5245 ) { 5246 this.set("x", nX); 5247 this.set("y", nY); 5248 this.set("velocityX", nVelocityX); 5249 this.set("velocityY", nVelocityY); 5250 } 5251 5252 if (this._htOption.forceRotate !== 0) { 5253 this.set("velocityRotate", this._htOption.velocityRotate + this._htOption.forceRotate); 5254 } 5255 5256 if (this._htOption.velocityRotate !== 0) { 5257 var nAngleRad = collie.util.fixAngle(collie.util.toRad(this._htOption.angle + this._htOption.velocityRotate * nFrame)); 5258 this.set("angle", Math.round(collie.util.toDeg(nAngleRad) * 1000) / 1000); 5259 } 5260 } 5261 }, 5262 5263 /** 5264 * ë¶ëª¨ì ì°ê´ë ì ì²´ ì¢í를 구íë¤(ì ëì¢í) 5265 * @todo ë©ìë ëª ì´ ì§ê´ì ì´ì§ 못íë¤ 5266 * 5267 * @return {Object} htPos 5268 * @return {Number} htPos.x 5269 * @return {Number} htPos.y 5270 */ 5271 getRelatedPosition : function () { 5272 if (this._htRelatedPosition.x === null) { 5273 this._htRelatedPosition.x = this._htOption.x; 5274 this._htRelatedPosition.y = this._htOption.y; 5275 5276 if (this._oParent) { 5277 var htPosition = this._oParent.getRelatedPosition(); 5278 this._htRelatedPosition.x += htPosition.x; 5279 this._htRelatedPosition.y += htPosition.y; 5280 } 5281 } 5282 5283 return this._htRelatedPosition; 5284 }, 5285 5286 /** 5287 * íì¬ íì ê°ì²´ì ì¬ê°í ììì ë°í íë¤ 5288 * - transformë ììì ë°í 5289 * TODO Transform Matrixì originì ìëì¢í를 ì ì©í´ì¼ í기 ë문ì ìºì를 ì ì©í ì ìì 5290 * TODO Transform ì ëì§ë ë¶ëª¨ë¥¼ íê³ ê°ë´ì¼ ì ì ìì! 5291 * 5292 * @param {Boolean} bWithRelatedPosition ì ëì¢íë¡ ë³ê²½í´ì ë°ííëì§ ì¬ë¶ 5293 * @param {Boolean} bWithPoints ì¢í를 ë°ííëì§ ì¬ë¶, Sensorì box hittestìì ì°ì 5294 * @return {Object} oBoundary 5295 * @return {Number} oBoundary.left 5296 * @return {Number} oBoundary.right 5297 * @return {Number} oBoundary.top 5298 * @return {Number} oBoundary.bottom 5299 * @return {Number} oBoundary.isTransform í¸ëì¤í¼ ì¬ì© ì¬ë¶ 5300 * @return {Array} oBoundary.points bWithPoints를 trueë¡ íë©´ ì¢í ë°°ì´ì´ ëì´ì´, [[x, y], [x, y], ...] 5301 */ 5302 getBoundary : function (bWithRelatedPosition, bWithPoints) { 5303 var htBoundary = collie.Transform.getBoundary(this, bWithPoints); 5304 this._htBoundary.left = htBoundary.left; 5305 this._htBoundary.right = htBoundary.right; 5306 this._htBoundary.top = htBoundary.top; 5307 this._htBoundary.bottom = htBoundary.bottom; 5308 this._htBoundary.isTransform = htBoundary.isTransform; 5309 this._htBoundary.points = htBoundary.points; 5310 5311 // ì ë ì¢íë¡ ë³íí´ì ë°í 5312 if (bWithRelatedPosition) { 5313 var htPos = this.getRelatedPosition(); 5314 5315 if (this._htBoundary.points) { 5316 for (var i = 0, l = this._htBoundary.points.length; i < l; i++) { 5317 this._htBoundary.points[i][0] += htPos.x; 5318 this._htBoundary.points[i][1] += htPos.y; 5319 } 5320 } 5321 5322 this._htBoundary.left += htPos.x; 5323 this._htBoundary.right += htPos.x; 5324 this._htBoundary.top += htPos.y; 5325 this._htBoundary.bottom += htPos.y; 5326 } 5327 5328 return this._htBoundary; 5329 }, 5330 5331 /** 5332 * ìì¹ê° ë³ê²½ëë ê²½ì° ìºì를 ì´ê¸°í í´ ì¤ 5333 * @private 5334 */ 5335 resetPositionCache : function () { 5336 this._htRelatedPosition.x = null; 5337 this._htRelatedPosition.y = null; 5338
5339 // ìì²´ì ì¼ë¡ ì í 5340 // TODO ìë ì°¨ì´ ë°ëì íì¸í´ ë´ì¼ í¨!! 5341 if (this.hasChild()) { 5342 for (var i = 0, l = this._aDisplayObjects.length; i < l; i++) { 5343 this._aDisplayObjects[i].resetPositionCache(); 5344 } 5345 } 5346 }, 5347 5348 /** 5349 * ì´ë²¤í¸ì ê´ë ¨ë ììì ë°í íë¤ 5350 * - transformë ììì ë°í 5351 * - ì ë ì¢íë¡ ë³íí´ì ë°ííë¤ 5352 * 5353 * @return {Object} htReturn 5354 * @return {Number} htReturn.left minX 5355 * @return {Number} htReturn.right maxX 5356 * @return {Number} htReturn.top minY 5357 * @return {Number} htReturn.bottom maxY 5358 */ 5359 getHitAreaBoundary : function () { 5360 if (!this._htOption.hitArea) { 5361 return this.getBoundary(true); 5362 } else if (this._htOption.hitArea instanceof Array) { 5363 var aPoints = collie.Transform.points(this, collie.util.getBoundaryToPoints(this._htHitAreaBoundary)); 5364 var htBoundary = collie.util.getBoundary(aPoints); 5365 var htPos = this.getRelatedPosition(); 5366 5367 return { 5368 left : htBoundary.left + htPos.x, 5369 right : htBoundary.right + htPos.x, 5370 top : htBoundary.top + htPos.y, 5371 bottom : htBoundary.bottom + htPos.y 5372 }; 5373 } else { // displayObjectì¼ ê²½ì° 5374 return this._htOption.hitArea.getBoundary(true); 5375 } 5376 }, 5377 5378 /** 5379 * Scale, Angle ë³ê²½ì ì¤ì¬ì ì 구íë¤ 5380 * 5381 * @private 5382 * @return {Object} htResult 5383 * @return {Number} htResult.x xì¶ Origin 5384 * @return {Number} htResult.y yì¶ Origin 5385 */ 5386 getOrigin : function () { 5387 return this._htOrigin; 5388 }, 5389 5390 /** 5391 * originì pxë¡ ì¤ì íë¤ 5392 * @private 5393 */ 5394 _setOrigin : function () { 5395 switch (this._htOption.originX) { 5396 case "left" : 5397 this._htOrigin.x = 0; 5398 break; 5399 5400 case "right" : 5401 this._htOrigin.x = this._htOption.width; 5402 break; 5403 5404 case "center" : 5405 this._htOrigin.x = this._htOption.width / 2; 5406 break; 5407 5408 default : 5409 this._htOrigin.x = parseInt(this._htOption.originX, 10); 5410 } 5411 5412 switch (this._htOption.originY) { 5413 case "top" : 5414 this._htOrigin.y = 0; 5415 break; 5416 5417 case "bottom" : 5418 this._htOrigin.y = this._htOption.height; 5419 break; 5420 5421 case "center" : 5422 this._htOrigin.y = this._htOption.height / 2; 5423 break; 5424 5425 default : 5426 this._htOrigin.y = parseInt(this._htOption.originY, 10); 5427 } 5428 }, 5429 5430 /** 5431 * range를 ì¬ì©íê³ ìë ê²½ì° rangeì ë§ê² í¬ì§ì ì ë³ê²½ íë¤ 5432 * 5433 * @private 5434 */ 5435 _fixPosition : function () { 5436 var nX = this._htOption.x; 5437 var nY = this._htOption.y; 5438 var nMinX; 5439 var nMaxX; 5440 var nMinY; 5441 var nMaxY; 5442 5443 if (this._htOption.rangeX) { 5444 // ìë를 ì ë ê°ì¼ë¡ 5445 nMinX = this._htOption.rangeX[0]; 5446 nMaxX = this._htOption.rangeX[1]; 5447 5448 if (this._htOption.positionRepeat) { 5449 if (nX < nMinX) { // ìµìê° ë³´ë¤ ìì ë 5450 do { 5451 nX += (nMaxX - nMinX); 5452 } while (nX < nMinX); 5453 } else if (nX > nMaxX) { // ìµëê° ë³´ë¤ í´ ë 5454 do { 5455 nX -= (nMaxX - nMinX); 5456 } while (nX > nMaxX); 5457 } 5458 } else { 5459 nX = Math.max(nMinX, nX); 5460 nX = Math.min(nMaxX, nX); 5461 } 5462 5463 if (nX !== this._htOption.x) { 5464 // ì ë를 ìë ê°ì¼ë¡ 5465 this.set("x", nX, true); 5466 } 5467 } 5468 5469 if (this._htOption.rangeY) { 5470 nMinY = this._htOption.rangeY[0]; 5471 nMaxY = this._htOption.rangeY[1]; 5472 5473 if (this._htOption.positionRepeat) { 5474 if (nY < nMinY) { // ìµìê° ë³´ë¤ ìì ë 5475 do { 5476 nY += (nMaxY - nMinY); 5477 } while (nY < nMinY); 5478 } else if (nY >
5478 nMaxY) { // ìµëê° ë³´ë¤ í´ ë 5479 do { 5480 nY -= (nMaxY - nMinY); 5481 } while (nY > nMaxY); 5482 } 5483 } else { 5484 nY = Math.max(nMinY, nY); 5485 nY = Math.min(nMaxY, nY); 5486 } 5487 5488 if (nY !== this._htOption.y) { 5489 this.set("y", nY, true); 5490 } 5491 } 5492 }, 5493 5494 /** 5495 * hitArea ìµì ì´ ë°°ì´ë¡ ë¤ì´ì¬ ê²½ì° boundary를 구í´ì ì ì¥í´ëëë¤ 5496 * @private 5497 */ 5498 _makeHitAreaBoundary : function () { 5499 this._htHitAreaBoundary = collie.util.getBoundary(this._htOption.hitArea); 5500 }, 5501 5502 /** 5503 * ê°ì²´ì ìì¹ë¥¼ ì ë ¬íë¤. 5504 * 5505 * @param {String|Boolean} [sHorizontal=center] ìí ì ë ¬ [left|right|center], falseë©´ ì ë ¬íì§ ìì 5506 * @param {String|Boolean} [sVertical=center] ìì§ ì ë ¬ [top|bottom|center], falseë©´ ì ë ¬íì§ ìì 5507 * @param {collie.DisplayObject} [oBaseObject] ê¸°ì¤ ê°ì²´, ê°ì´ ìì ê²½ì° ë¶ëª¨, ë¶ëª¨ê° ìì ê²½ì° ë ì´ì´ë¥¼ 기ì¤ì¼ë¡ ì ë ¬ íë¤. 5508 */ 5509 align : function (sHorizontal, sVertical, oBaseObject) { 5510 if (!this.getLayer()) { 5511 return; 5512 } 5513 5514 oBaseObject = oBaseObject || this.getParent(); 5515 var nWidth = 0; 5516 var nHeight = 0; 5517 var nX = 0; 5518 var nY = 0; 5519 5520 // ê¸°ì¤ í¬ê¸° êµ¬í¨ 5521 if (oBaseObject) { 5522 nWidth = oBaseObject._htOption.width; 5523 nHeight = oBaseObject._htOption.height; 5524 } else { 5525 nWidth = this._oLayer._htOption.width; 5526 nHeight = this._oLayer._htOption.height; 5527 } 5528 5529 if (sHorizontal !== false) { 5530 nX = (sHorizontal === "right") ? nWidth - this._htOption.width : nWidth / 2 - this._htOption.width / 2; 5531 this.set("x", nX); 5532 } 5533 5534 if (sVertical !== false) { 5535 nY = (sVertical === "bottom") ? nHeight - this._htOption.height : nHeight / 2 - this._htOption.height / 2; 5536 this.set("y", nY); 5537 } 5538 }, 5539 5540 /** 5541 * ê°ì²´ì ìì¹ë¥¼ ì°ì¸¡ 기ì¤ì¼ë¡ ì¢íë§í¼ ì´ëíë¤ 5542 * ë§ì¼ Layerì ë¶ì ìíê° ìëë¼ë©´ ë¶ì íì ì´ëí ì ìëë¡ í´ ì¤ë¤ 5543 * 5544 * @param {Number} nPosition ì°ì¸¡ ê¸°ì¤ xì¢í 5545 * @return {collie.DisplayObject} ì기 ìì ì ë°í 5546 */ 5547 right : function (nPosition) { 5548 var nWidth = 0; 5549 5550 // ê¸°ì¤ í¬ê¸° êµ¬í¨ 5551 if (this._oParent) { 5552 nWidth = this._oParent._htOption.width; 5553 } 5554 5555 if (!nWidth && this._oLayer) { 5556 nWidth = this._oLayer._htOption.width; 5557 } 5558 5559 // í¬ê¸°ê° 구í´ì¡ì ëë§ ì ë ¬ 5560 if (nWidth) { 5561 this.set("x", nWidth - (this._htOption.width + nPosition)); 5562 } else { 5563 this._nPositionRight = nPosition; 5564 } 5565 5566 return this; 5567 }, 5568 5569 /** 5570 * ê°ì²´ì ìì¹ë¥¼ íë¨ ê¸°ì¤ì¼ë¡ ì¢íë§í¼ ì´ëíë¤ 5571 * ë§ì¼ Layerì ë¶ì ìíê° ìëë¼ë©´ ë¶ì íì ì´ëí ì ìëë¡ í´ ì¤ë¤ 5572 * 5573 * @param {Number} nPosition íë¨ ê¸°ì¤ xì¢í 5574 * @return {collie.DisplayObject} ì기 ìì ì ë°í 5575 */ 5576 bottom : function (nPosition) { 5577 var nHeight = 0; 5578 5579 // ê¸°ì¤ í¬ê¸° êµ¬í¨ 5580 if (this._oParent) { 5581 nHeight = this._oParent.get("height"); 5582 } 5583 5584 if (!nHeight && this._oLayer) { 5585 nHeight = this._oLayer.option("height"); 5586 } 5587 5588 // í¬ê¸°ê° 구í´ì¡ì ëë§ ì ë ¬ 5589 if (nHeight) { 5590 this.set("y", nHeight - (this._htOption.height + nPosition)); 5591 } else { 5592 this._nPositionBottom = nPosition; 5593 } 5594 5595 return this; 5596 }, 5597 5598 /** 5599 * ì§ì í ë¹ì¨ì ë§ê² í¬ê¸°ë¥¼ ë³ê²½ íë¤. 리ìíë§ê³¼ë ë¤ë¥´ë¤ 5600 * ì¸ì ë ì¤ íë를 ì¤ì íë©´ ì¤ì í ë¶ë¶ì ë¹ì¨ì ë§ì¶°ì í¬ê¸°ë¥¼ ë³ê²½ íë¤ 5601 * 5602 * @param {Number} [nWidth] ëë¹ 5603 * @param {Number} [nHeight] ëì´ 5604 */ 5605 resizeFixedRatio : function (nWidth, nHeight) { 5606 if (this.getImage()) { 5607 var nImageWidth = this.getImage().width; 5608 var nImageHeight = this.getImage().height; 5609 5610 if (nWidth) { 5611 nHeight = nWidth * (nImageHeight / nImageWidth); 5612 } else if (nHeight) { 5613 nWidth = nHeight * (nImageWidth / nImageHeight); 5614 } 5615 5616 this.set("width", Math.round(nWidth)); 5617 this.set("height", Math.round(nHeight)); 5618 } 5619 }, 5620 5621 /** 5622 * Sprite ìì¹ë¥¼ ì¤ì 5623 * offsetX, offsetYë¡ ê°ì ì¤ì í ê²½ì°ì spriteX, spriteYë ì ìì ì¼ë¡ ë기íëì§ ëª»íë 문ì ê° ìì ìì¶ì ë¶ê°ë¥ 5624 * @private 5625 * @param {String} sKey ìì± ì´ë¦ 5626 * @param {Number} nValue ê° 5627 */ 5628 _setSpritePosition : function (sKey, nValue) { 5629 if (this._elImage && nValue !== null) { 5630 // spriteSheet ì¬ì© ì 5631 if (this._htOption.spriteSheet !== null) { 5632 var sheet = this._htSpriteSheet[this._htOption.spriteSheet]; 5633 var nOffsetX; 5634 var nOffsetY; 5635 5636 if (sKey === "spriteSheet" && this._htSpriteSheet && this._htSpriteSheet[nValue]) { 5637 if (typeof sheet[0][0] !== "undefined") { 5638 if (this._htOption.spriteX !== null) { // ì´ë¯¸ spriteXê° ìë¤ë©´ 5639 nOffsetX = sheet[this._htOption.spriteX][0]; 5640 nOffsetY = sheet[this._htOption.spriteX][1]; 5641 } else { 5642 nOffsetX = sheet[0][0]; 5643 nOffsetY = sheet[0][1]; 5644 } 5645 } else { 5646 nOffsetX = sheet[0]; 5647 nOffsetY = sheet[1]; 5648 } 5649 5650 // ì´ê¸° ìì¹ ì¡ìì¤ 5651 this.set("offsetX", nOffsetX, true); 5652 this.set("offsetY", nOffsetY, true); 5653 } else if (sKey === "spriteX" && typeof sheet[nValue] !== "undefined") { 5654 this.set("offsetX", sheet[nValue][0], true); 5655 this.set("offsetY", sheet[nValue][1], true); 5656 } 5657 } else { 5658 var htImageSize = this.getImageSize(); 5659 var nWidth = this._htOption.width; 5660 var nHeight = this._htOption.height; 5661 var nSpriteLength = this._htOption.spriteLength - 1; // 0ë¶í° ìì 5662 var nMaxSpriteX = (htImageSize.width / this._htOption.width) - 1; 5663 var nMaxSpriteY = (htImageSize.height / this._htOption.height) - 1; 5664 var nMaxOffsetX = htImageSize.width - 1; 5665 var nMaxOffsetY = htImageSize.height - 1; 5666 5667 // spriteLengthê° ì ì©ëì´ ìë ê²½ì° ìµë offsetì´ ë³ê²½ ë¨ 5668 if (nSpriteLength >= 0 && nHeight < htImageSize.height) { 5669 nMaxOffsetX = nMaxSpriteX * htImageSize.width; 5670 nMaxOffsetY = nMaxSpriteY * htImageSize.height; 5671 } 5672 5673 switch (sKey) { 5674 case "spriteX" : 5675 var nOffsetX = 0; 5676 var nOffsetY = 0; 5677 5678 // sprite길ì´ë¥¼ ì§ì íê³ ê·¸ê² ìµë ì¤íë¼ì´í¸ ìë³´ë¤ í¬ë¤ë©´ ê·¸ê²ì ë°ë¼ê° 5679 if (nSpriteLength > nMaxSpriteX && nHeight < htImageSize.height) { 5680 nOffsetY = Math.floor(nValue / (nMaxSpriteX + 1)) * nHeight; 5681 nOffsetX = (nValue % (nMaxSpriteX + 1)) * nWidth; 5682 } else { 5683 nOffsetX = Math.min(nValue, nMaxSpriteX) * nWidth; 5684 } 5685 5686 //TODO android ì±ë¥ 문ì , DisplayObject#set, timer, Animation#triggerCallback, spriteX ì²ë¦¬ 5687 this.set("offsetX", nOffsetX, true); 5688 this.set("offsetY", nOffsetY, true); 5689 break; 5690 5691 case "spriteY" : 5692 nValue = Math.min(nValue, nMaxSpriteY); 5693 this.set("offsetY", nValue * nHeight, true); 5694 break; 5695 } 5696 } 5697 } 5698 }, 5699 5700 /** 5701 * attachë ì´ë²¤í¸ í¸ë¤ë¬ê° ìëì§ ì¬ë¶ë¥¼ ë°í 5702 * 5703 * @return {Boolean} 5704 */ 5705 hasAttachedHandler : function () { 5706 if ( 5707 this._htHandler && 5708 (("click" in this._htHandler) && this._htHandler.click.length > 0) || 5709 (("mousedown" in this._htHandler) && this._htHandler.mousedown.length > 0) || 5710 (("mouseup" in this._htHandler) && this._htHandler.mouseup.length > 0) 5711 ) { 5712 return true; 5713 } else { 5714 return false;
5715 } 5716 }, 5717 5718 /** 5719 * í¹ì ìëë¡ í´ë¹ ì§ì ê¹ì§ ì´ë 5720 * 5721 * @param {Number} nX ê°ê³ ì íë ê³³ì x ì¢í 5722 * @param {Number} nY ê°ê³ ì íë ê³³ì y ì¢í 5723 * @param {Number} nVelocity ì´ë¹ ì´ë 거리(px), ìëê° 0 ì´ë©´ ë°ë¡ ì´ëíë¤. 5724 * @param {Function} fCallback ì´ëì´ ëë í ì¤íë ì½ë°± 5725 * @param {collie.DisplayObject} fCallback.displayobject íì¬ ê°ì²´ê° ì¸ìë¡ ëì´ê°= 5726 * @return {collie.AnimationTransition} ì´ëì ì¬ì©ëë íì´ë¨¸ë¥¼ ë°í 5727 */ 5728 move : function (nX, nY, nVelocity, fCallback) { 5729 var nCurrentX = this._htOption.x; 5730 var nCurrentY = this._htOption.y; 5731 var nDistance = collie.util.getDistance(nCurrentX, nCurrentY, nX, nY); 5732 var nDuration = Math.round((nDistance / nVelocity) * 1000); 5733 5734 if (this._oTimerMove !== null) { 5735 this._oTimerMove.stop(); 5736 this._oTimerMove = null; 5737 } 5738 5739 // durationì´ ìì ì ëë¡ ì§§ê±°ë ìëê° 0ì¼ ê²½ì° Timer를 ì´ì©íì§ ìê³ ë°ë¡ ì´ë 5740 if (!nVelocity || nDuration < collie.Renderer.getInfo().fps) { 5741 this.set({ 5742 x : nX, 5743 y : nY 5744 }); 5745 5746 5747 if (fCallback) { 5748 fCallback(this); 5749 } 5750 } else { 5751 var htOption = { 5752 from : [nCurrentX, nCurrentY], 5753 to : [nX, nY], 5754 set : ["x", "y"] 5755 }; 5756 5757 if (fCallback) { 5758 htOption.onComplete = function () { 5759 fCallback(this); 5760 }; 5761 } 5762 5763 this._oTimerMove = collie.Timer.transition(this, nDuration, htOption); 5764 return this._oTimerMove; 5765 } 5766 }, 5767 5768 /** 5769 * ìë ê²½ë¡ë¡ ì´ë 5770 * 5771 * @param {Number} nX ê°ê³ ì íë ê³³ì x ì¢í 5772 * @param {Number} nY ê°ê³ ì íë ê³³ì y ì¢í 5773 * @param {Number} nVelocity ì´ë¹ ì´ë 거리(px), ìëê° 0 ì´ë©´ ë°ë¡ ì´ëíë¤. 5774 * @param {Function} fCallback ì´ëì´ ëë í ì¤íë ì½ë°± 5775 * @return {collie.AnimationTransition} ì´ëì ì¬ì©ëë íì´ë¨¸ë¥¼ ë°í 5776 */ 5777 moveBy : function (nX, nY, nVelocity, fCallback) { 5778 var nCurrentX = this._htOption.x; 5779 var nCurrentY = this._htOption.y; 5780 return this.move(nCurrentX + nX, nCurrentY + nY, nVelocity, fCallback); 5781 }, 5782 5783 /** 5784 * 문ìì´ë¡ í´ëì¤ ì ë³´ ë°í 5785 * 5786 * @return {String} 5787 */ 5788 toString : function () { 5789 return "DisplayObject" + (this._htOption.name ? " " + this._htOption.name : "")+ " #" + this.getId() + (this.getImage() ? "(image:" + this.getImage().src + ")" : ""); 5790 }, 5791 5792 /** 5793 * ê°ì²´ ë³µì¬ 5794 * ì´ë²¤í¸ë ë³µì¬ëì§ ìëë¤. 5795 * @param {Boolean} bRecursive ììê¹ì§ 모ë ë³µì¬íëì§ ì¬ë¶ 5796 * @return {collie.DisplayObject} 5797 * @example 5798 * var box = new collie.DisplayObject({ 5799 * width: 100, 5800 * height: 100, 5801 * backgroundColor: "blue" 5802 * }).addTo(layer); 5803 * 5804 * var box2 = box.clone().addTo(layer); 5805 */ 5806 clone : function (bRecursive) { 5807 var oDisplayObject = new this.constructor(this._htOption); 5808 5809 if (bRecursive && this._aDisplayObjects.length) { 5810 for (var i = 0, l = this._aDisplayObjects.length; i < l; i++) { 5811 this._aDisplayObjects[i].clone(true).addTo(oDisplayObject); 5812 } 5813 } 5814 5815 return oDisplayObject; 5816 } 5817}, collie.Component); 5818 5819/** 5820 * íì ê°ì²´ ìì´ë를 í ë¹íë¤. 1ì© ëì´ë¨ 5821 * 5822 * @static 5823 * @private 5824 */ 5825collie.DisplayObject._idx = 0; 5826 5827/** 5828 * ìì±ë íì ê°ì²´ë¥¼ ë´ëë¤. Layerì ì¶ê°íì§ ììë íì ê°ì²´ë¥¼ ìì´ëë¡ë§ ê°ì ¸ì¬ ì ìë¤ 5829 * 5830 * @static 5831 * @private 5832 */ 5833collie.DisplayObject.htFactory = {}; 5834/** 5835 * ìë, ê°ìë, ë§ì°°ë ¥, ì§ëì í¬í¨í íì ê°ì²´ 5836 * - rotateë ë§ì°°ë ¥ì´ ìë¤ 5837 * @class collie.MovableObject 5838 * @deprecated DisplayObjectì ê¸°ë¥ ì¶ê° 5839 * @extends collie.DisplayObject 5840 * @param {Object} [htOption] ì¤ì 5841 * @param {Number} [htOption.velocityX=0] xì¶ ìë(ì´ë¹ px) 5842 * @param {Number} [htOption.velocityY=0] yì¶ ìë(ì´ë¹ px) 5843 * @param {Number} [htOption.velocityRotate=0] íì ìë(ì´ë¹ 1ë) 5844 * @param {Number} [htOption.forceX=0] xì¶ í(ì´ë¹ px) 5845 * @param {Number} [htOption.forceY=0] yì¶ í(ì´ë¹ px) 5846 * @param {Number} [htOption.forceRotate=0] íì í(ì´ë¹ 1ë) 5847 * @param {Number} [htOption.mass=1] ì§ë 5848 * @param {Number} [htOption.friction=0] ë§ì°°ë ¥ 5849 * @param {Boolean} [htOption.useRealTime=true] SkippedFrameì ì ì©í´ì ì¸ì´í´ì íì¬ ìê°ê³¼ ì¼ì¹ 5850 */
5851collie.MovableObject = collie.Class(/** @lends collie.MovableObject.prototype */{ 5852 /** 5853 * @constructs 5854 */ 5855 $init : function (htOption) { 5856 // this.option({ 5857 // velocityX : 0, 5858 // velocityY : 0, 5859 // velocityRotate : 0, 5860 // forceX : 0, 5861 // forceY : 0, 5862 // forceRotate : 0, 5863 // mass : 1, // ì§ë 5864 // friction : 0, // ë§ì°° 5865 // useRealTime : true 5866 // }, null, true); 5867 } 5868 5869 /** 5870 * íë©´ì ì ë°ì´í¸ 5871 * 5872 * @private 5873 */ 5874 // update : function (nFrameDuration, nX, nY, nLayerWidth, nLayerHeight) { 5875 // var nFrame = Math.max(17, nFrameDuration) / 1000; 5876// 5877 // // skippedFrame ì ì©ì íì§ ìëë¤ë©´ 1frame ì©ë§ 그림 5878 // if (!this._htOption.useRealTime) { 5879 // nFrame = 1; 5880 // } 5881// 5882 // this._applyForce(nFrame); 5883 // this._applyRotation(nFrame); 5884 // this.constructor.$super.update.call(this, nFrameDuration, nX, nY, nLayerWidth, nLayerHeight); 5885// 5886 // // ìì§ìì´ ìì¼ë©´ ë¤ì ë°ë ìíë¡ ë 5887 // if ( 5888 // this._htOption.velocityX !== 0 || 5889 // this._htOption.velocityY !== 0 || 5890 // this._htOption.velocityRotate !== 0 || 5891 // this._htOption.forceX !== 0 || 5892 // this._htOption.forceY !== 0 || 5893 // this._htOption.forceRotate !== 0 5894 // ) { 5895 // this.setChanged(true); 5896 // } 5897 // }, 5898 5899 /** 5900 * @private 5901 */ 5902 // _getValueDirection : function (nValue) { 5903 // return Math.abs(nValue) / nValue; 5904 // }, 5905 5906 /** 5907 * íì í, ìë를 ë°ì 5908 * @private 5909 */ 5910 // _applyRotation : function (nFrame) { 5911 // if (this._htOption.forceRotate !== 0) { 5912 // this.set("velocityRotate", this._htOption.velocityRotate + this._htOption.forceRotate); 5913 // } 5914// 5915 // if (this._htOption.velocityRotate !== 0) { 5916 // var nAngleRad = collie.util.fixAngle(collie.util.toRad(this._htOption.angle + this._htOption.velocityRotate * nFrame)); 5917 // this.set("angle", Math.round(collie.util.toDeg(nAngleRad) * 1000) / 1000); 5918 // } 5919 // }, 5920 5921 /** 5922 * íì ìëì ë°ì 5923 * 5924 * @private 5925 */ 5926 // _applyForce : function (nFrame) { 5927 // var htInfo = this.get(); 5928 // var nVelocityX = htInfo.velocityX; 5929 // var nVelocityY = htInfo.velocityY; 5930 // var nX = htInfo.x; 5931 // var nY = htInfo.y; 5932// 5933 // // í ì ì© a = F / m 5934 // nVelocityX += (htInfo.forceX / htInfo.mass) * nFrame; 5935 // nVelocityY += (htInfo.forceY / htInfo.mass) * nFrame; 5936// 5937 // // ë§ì°°ë ¥ ì ì© 5938 // var nForceFrictionX = htInfo.friction * nVelocityX * htInfo.mass * nFrame; 5939 // var nForceFrictionY = htInfo.friction * nVelocityY * htInfo.mass * nFrame; 5940// 5941 // if (nVelocityX !== 0) { 5942 // nVelocityX = (this._getValueDirection(nVelocityX) !== this._getValueDirection(nVelocityX - nForceFrictionX)) ? 0 : nVelocityX - nForceFrictionX; 5943 // } 5944// 5945 // if (nVelocityY !== 0) { 5946 // nVelocityY = (this._getValueDirection(nVelocityY) !== this._getValueDirection(nVelocityY - nForceFrictionY)) ? 0 : nVelocityY - nForceFrictionY; 5947 // } 5948// 5949 // nX += nVelocityX * nFrame; 5950 // nY += nVelocityY * nFrame; 5951 // nVelocityX = Math.floor(nVelocityX * 1000) / 1000; 5952 // nVelocityY = Math.floor(nVelocityY * 1000) / 1000; 5953// 5954 // if (htInfo.friction && Math.abs(nVelocityX) < 0.05) { 5955 // nVelocityX = 0; 5956 // } 5957// 5958 // if (htInfo.friction && Math.abs(nVelocityY) < 0.05) { 5959 // nVelocityY = 0; 5960 // } 5961// 5962 // // ë³ê²½ì´ ìì ëë§ ì¤ì 5963 // if ( 5964 // nX != htInfo.x || 5965 // nY != htInfo.y || 5966 // nVelocityX != htInfo.velocityX || 5967 // nVelocityY != htInfo.velocityY 5968 // ) { 5969 // this.set({ 5970 // x : nX, 5971 // y : nY, 5972 // velocityX : nVelocityX, 5973 // velocityY : nVelocityY 5974 // }); 5975 // } 5976 // }, 5977 5978 /** 5979 * 문ìì´ë¡ í´ëì¤ ì ë³´ ë°í 5980 * 5981 * @deprecated 5982 * @return {String} 5983 */ 5984 // toString : function () { 5985 // return "MovableObject" + (this._htOption.name ? " " + this._htOption.name : "")+ " #" + this.getId() + (this.getImage() ? "(image:" + this.getImage().src + ")" : ""); 5986 // } 5987}, collie.DisplayObject); 5988/** 5989 * Rectangle 5990 * - Rounded 5991 * @class collie.Rectangle 5992 * @extends collie.DisplayObject 5993 * @param {Object} [htOption] ì¤ì 5994 * @param {Number} [htOption.radius=0] í ë리 굴림 ê° (px) 5995 * @param {String} [htOption.strokeColor] í ë리 ìì 5996 * @param {Number} [htOption.strokeWidth=0] í ë리 굵기(0ì´ë©´ í ë리 ìì) 5997 * @param {String} [htOption.fillColor] ì±ì¸ ìì(ìì¼ë©´ í¬ëª ) 5998 * @param {String} [htOption.fillImage] ì±ì¸ ì´ë¯¸ì§ 5999 */
6000collie.Rectangle = collie.Class(/** @lends collie.Rectangle.prototype */{ 6001 /** 6002 * @constructs 6003 */ 6004 $init : function (htOption) { 6005 this.option({ 6006 radius : 0, 6007 strokeColor : '', 6008 strokeWidth : 0, 6009 fillColor : '', 6010 fillImage : '' 6011 }, null, true); 6012 6013 this._sBorderRadius = collie.util.getCSSPrefix("border-radius", true); 6014 }, 6015 6016 /** 6017 * Delegate 6018 * @private 6019 */ 6020 onDOMDraw : function (oEvent) { 6021 if (this._bChanged) { 6022 if (this._htOption.radius) { 6023 oEvent.element.style[this._sBorderRadius] = this._htOption.radius + "px"; 6024 oEvent.element.style.borderRadius = this._htOption.radius + "px"; 6025 } 6026 6027 if (this._htOption.fillImage) { 6028 collie.ImageManager.getImage(this._htOption.fillImage, function (el) { 6029 oEvent.element.style.backgroundImage = "url('" + el.src + "')"; 6030 }); 6031 } else if (this._htOption.fillColor) { 6032 oEvent.element.style.backgroundColor = this._htOption.fillColor; 6033 } 6034 6035 if (this._htOption.strokeWidth) { 6036 oEvent.element.style.border = this._htOption.strokeWidth + "px solid " + this._htOption.strokeColor; 6037 } 6038 6039 this._bChanged = false; 6040 } 6041 }, 6042 6043 /** 6044 * Delegate 6045 * @private 6046 */ 6047 onCanvasDraw : function (oEvent) { 6048 var oContext = oEvent.context; 6049 var nRadius = this._htOption.radius; 6050 var bIsRetinaDisplay = collie.Renderer.isRetinaDisplay(); 6051 var nWidth = this._htOption.width; 6052 var nHeight = this._htOption.height; 6053 var nStrokeWidth = this._htOption.strokeWidth; 6054 6055 // ë í°ë ëì¤íë ì´ ëì 6056 if (bIsRetinaDisplay) { 6057 nWidth *= 2; 6058 nHeight *= 2; 6059 nRadius *= 2; 6060 nStrokeWidth *= 2; 6061 } 6062 6063 if (htInfo.fillImage) { 6064 var el = collie.ImageManager.getImage(htInfo.fillImage); 6065 6066 if (!el) { 6067 collie.ImageManager.getImage(htInfo.fillImage, function () { 6068 this.setChanged(); 6069 }.bind(this)); 6070 } else { 6071 var pattern = oContext.createPattern(el, "repeat"); 6072 oContext.fillStyle = pattern; 6073 } 6074 } else if (htInfo.fillColor) { 6075 oContext.fillStyle = htInfo.fillColor; 6076 } 6077 6078 if (this._htOption.strokeColor) { 6079 oContext.strokeStyle = this._htOption.strokeColor; 6080 } 6081 6082 if (this._htOption.strokeWidth) { 6083 oContext.lineWidth = nStrokeWidth; 6084 } 6085 6086 if (nRadius) { 6087 oContext.save(); 6088 oContext.translate(oEvent.x, oEvent.y); 6089 oContext.beginPath(); 6090 oContext.moveTo(nRadius, 0); 6091 oContext.lineTo(nWidth - nRadius, 0); 6092 oContext.quadraticCurveTo(nWidth, 0, nWidth, nRadius);
6093 oContext.lineTo(nWidth, nHeight - nRadius); 6094 oContext.quadraticCurveTo(nWidth, nHeight, nWidth - nRadius, nHeight); 6095 oContext.lineTo(nRadius, nHeight); 6096 oContext.quadraticCurveTo(0, nHeight, 0, nHeight - nRadius); 6097 oContext.lineTo(0, nRadius); 6098 oContext.quadraticCurveTo(0, 0, nRadius, 0); 6099 oContext.closePath(); 6100 oContext.restore(); 6101 6102 if (this._htOption.fillColor || this._htOption.fillImage) { 6103 oContext.fill(); 6104 } 6105 6106 if (this._htOption.strokeWidth) { 6107 oContext.stroke(); 6108 } 6109 } else { 6110 if (this._htOption.fillColor || this._htOption.fillImage) { 6111 oContext.fillRect(oEvent.x, oEvent.y, nWidth, nHeight); 6112 } 6113 6114 if (this._htOption.strokeWidth) { 6115 oContext.strokeRect(oEvent.x, oEvent.y, nWidth, nHeight); 6116 } 6117 } 6118 6119 this._bChanged = false; 6120 }, 6121 6122 /** 6123 * 문ìì´ë¡ í´ëì¤ ì ë³´ ë°í 6124 * 6125 * @return {String} 6126 */ 6127 toString : function () { 6128 return "Rectangle" + (this.get("name") ? " " + this.get("name") : "")+ " #" + this.getId() + (this.getImage() ? "(image:" + this.getImage().src + ")" : ""); 6129 } 6130}, collie.DisplayObject); 6131/** 6132 * Drawing Circle 6133 * If you want to see a circle using DOM Rendering, you need the <a href="http://raphaeljs.com" target="_blank">Raphael.js</a> 2.1.0 or above. 6134 * 6135 * @class 6136 * @extends collie.DisplayObject 6137 * @requires http://raphaeljs.com 6138 * @param {Object} [htOption] Options 6139 * @param {Number} [htOption.radius=0] Radius(px) 6140 * @param {String} [htOption.strokeColor] Stroke color 6141 * @param {Number} [htOption.strokeWidth=0] Border width. It'll be disappear when you set this option as 0. 6142 * @param {String} [htOption.fillColor] Inside color. The Default value is a transparent color. 6143 * @param {String} [htOption.fillImage] Fill the image inside a polyline 6144 * @param {Number} [htOption.startAngle=0] Starting Angle(degree) 6145 * @param {Number} [htOption.endAngle=360] Ending Angle(degree), The Circle would be fully filled when you set starting angle as 0 and set ending angle as 360. 6146 * @param {Boolean} [htOption.closePath=false] Closing a Path. like a pac-man. 6147 * @param {Boolean} [htOption.autoExpand=true] When this options set as true, the circle object expands to fit size to diameter. 6148 * @param {Boolean} [htOption.anticlockwise=false] The Circle will be filled anticlockwise when you set this option as true. 6149 * @example 6150 * // Draw a Circle 6151 * var circle = new collie.Circle({ 6152 * radius : 20 // The circle object just expands to fit size to diameter. (width:40, height:40) 6153 * }).addTo(layer); 6154 * 6155 * // arc 6156 * circle.set({ 6157 * startAngle : 0, 6158 * endAngle : 270 6159 * }); 6160 * 6161 * // a pac-man 6162 * circle.set({ 6163 * startAngle : 45, 6164 * endAngle : 315, 6165 * closePath : true 6166 * }); 6167 */ 6168collie.Circle = collie.Class(/** @lends collie.Circle.prototype */{ 6169 /** 6170 * @constructs 6171 */ 6172 $init : function (htOption) { 6173 this.option({ 6174 radius : 0, 6175 strokeColor : '#000000', 6176 strokeWidth : 0, 6177 fillColor : '', 6178 fillImage : '', 6179 startAngle : 0, 6180 endAngle : 360, 6181 closePath : false, 6182 anticlockwise : false, 6183 autoExpand : true 6184 }, null, true); 6185 6186 this._oPaper = null; 6187 this.optionSetter("radius", this._expandSize.bind(this)); 6188 this._expandSize(); 6189 }, 6190 6191 _expandSize : function () { 6192 if (this._htOption.autoExpand && this._htOption.radius) { 6193 var size = this._htOption.radius * 2 + this._htOption.strokeWidth; 6194 this.set("width", size); 6195 this.set("height", size); 6196 } 6197 }, 6198 6199 /** 6200 * Delegate 6201 * @private 6202 */ 6203 onDOMDraw : function (oEvent) { 6204 var el = oEvent.element; 6205 6206 if (typeof Raphael === "undefined") { 6207 return; 6208 } 6209 6210 var htInfo = this.get(); 6211 var nStrokeWidth = htInfo.strokeWidth; 6212 var nRadius = htInfo.radius; 6213 var nWidth = htInfo.width; 6214 var nHeight = htInfo.height; 6215 var htDirty = this.getDirty(); 6216 var circle; 6217 6218 if (this._oPaper === null) { 6219 this._oPaper = Raphael(el, nWidth + nStrokeWidth, nHeight + nStrokeWidth); 6220 this._oPaper.canvas.style.zIndex = 10; 6221 } else if (htDirty && (htDirty.width || htDirty.height)) { 6222 this._oPaper.setSize(nWidth, nHeight); 6223 } 6224 6225 el.style.left = -(nStrokeWidth / 2) + "px"; 6226 el.style.top = -(nStrokeWidth / 2) + "px"; 6227 this._oPaper.clear(); 6228 6229 if (nRadius) { 6230 var rx = nRadius; 6231 var ry = nRadius; 6232 var x1 = rx + nRadius * Math.cos(collie.util.toRad(htInfo.startAngle)); 6233 var y1 = ry + nRadius * Math.sin(collie.util.toRad(htInfo.startAngle)); 6234 var x2 = rx + nRadius * Math.cos(collie.util.toRad(htInfo.endAngle)); 6235 var y2 = ry + nRadius * Math.sin(collie.util.toRad(htInfo.endAngle)); 6236 var angle = htInfo.anticlockwise ? htInfo.startAngle - htInfo.endAngle : htInfo.endAngle - htInfo.startAngle; 6237 6238 if (Math.abs(angle) >= 360) { 6239 angle = 360; 6240 } else if (angle < 0) {
6241 angle += 360; 6242 } 6243 6244 var flag1 = (angle > 180 ? 1 : 0); 6245 var flag2 = htInfo.anticlockwise ? 0 : 1; 6246 6247 if (angle >= 360) { 6248 circle = this._oPaper.circle(rx, ry, nRadius); 6249 } else { 6250 circle = this._oPaper.path("M" + x1 + "," + y1 + "a" + nRadius + "," + nRadius + ",0," + flag1 + "," + flag2 + "," + (x2 -x1) + "," + (y2 -y1) + (htInfo.closePath ? "L" + rx + "," + ry + "L" + x1 + "," + y1 + "Z" : "")); 6251 } 6252 } 6253 6254 if (circle) { 6255 circle.transform("t" + (nStrokeWidth / 2) + "," + (nStrokeWidth / 2)); 6256 6257 if (htInfo.fillImage) { 6258 collie.ImageManager.getImage(htInfo.fillImage, function (el) { 6259 circle.attr("fill", "url('" + el.src + "')"); 6260 }); 6261 } else if (htInfo.fillColor) { 6262 circle.attr("fill", htInfo.fillColor); 6263 } 6264 6265 if (htInfo.strokeColor) { 6266 circle.attr("stroke", htInfo.strokeColor); 6267 } 6268 6269 circle.attr("stroke-width", htInfo.strokeWidth); 6270 } 6271 }, 6272 6273 /** 6274 * Delegate 6275 * @private 6276 */ 6277 onCanvasDraw : function (oEvent) { 6278 var htInfo = this.get(); 6279 var oContext = oEvent.context; 6280 var nX = oEvent.x; 6281 var nY = oEvent.y; 6282 var bIsRetinaDispaly = collie.Renderer.isRetinaDisplay(); 6283 var nRadius = htInfo.radius; 6284 var nStrokeWidth = htInfo.strokeWidth; 6285 var nWidth = htInfo.width; 6286 var nHeight = htInfo.height; 6287 6288 if (bIsRetinaDispaly) { 6289 nWidth *= 2; 6290 nHeight *= 2; 6291 nRadius *= 2; 6292 nStrokeWidth *= 2; 6293 } 6294 6295 if (htInfo.fillImage) { 6296 var el = collie.ImageManager.getImage(htInfo.fillImage); 6297 6298 if (!el) { 6299 collie.ImageManager.getImage(htInfo.fillImage, function () { 6300 this.setChanged(); 6301 }.bind(this)); 6302 } else { 6303 var pattern = oContext.createPattern(el, "repeat"); 6304 oContext.fillStyle = pattern; 6305 } 6306 } else if (htInfo.fillColor) { 6307 oContext.fillStyle = htInfo.fillColor; 6308 } 6309 6310 if (htInfo.strokeColor) { 6311 oContext.strokeStyle = htInfo.strokeColor; 6312 } 6313 6314 if (nStrokeWidth) { 6315 oContext.lineWidth = nStrokeWidth; 6316 } 6317 6318 if (nRadius) { 6319 var rx = nX + nRadius; 6320 var ry = nY + nRadius; 6321 var bFullCircle = Math.abs(htInfo.startAngle - htInfo.endAngle) >= 360; 6322 6323 oContext.beginPath(); 6324 6325 if (htInfo.closePath && !bFullCircle) { 6326 oContext.moveTo(rx, ry); 6327 } 6328 6329 oContext.arc(rx, ry, nRadius, collie.util.toRad(htInfo.startAngle), collie.util.toRad(htInfo.endAngle), htInfo.anticlockwise); 6330 6331 if (htInfo.closePath) { 6332 oContext.closePath(); 6333 } 6334 6335 if (htInfo.fillColor || htInfo.fillImage) { 6336 oContext.fill(); 6337 } 6338 6339 if (htInfo.strokeWidth) { 6340 oContext.stroke(); 6341 } 6342 6343 } 6344 }, 6345 6346 /** 6347 * Move a position by a center of the circle. 6348 * 6349 * @param {Number} nCenterX 6350 * @param {Number} nCenterY 6351 * @return {collie.Circle} For the method chaining 6352 */ 6353 center : function (nCenterX, nCenterY) { 6354 this.set("x", nCenterX - this._htOption.radius); 6355 this.set("y", nCenterY - this._htOption.radius); 6356 return this; 6357 }, 6358 6359 /** 6360 * Returns information of The Class as String 6361 * 6362 * @return {String} 6363 */ 6364 toString : function () { 6365 return "Circle" + (this._htOption.name ? " " + this._htOption.name : "")+ " #" + this.getId() + (this.getImage() ? "(image:" + this.getImage().src + ")" : ""); 6366 } 6367}, collie.DisplayObject); 6368/** 6369 * Drawing Polyline 6370 * If you want to see a polyline using DOM Rendering, you need the <a href="http://raphaeljs.com" target="_blank">Raphael.js</a> 2.1.0 or above. 6371 * 6372 * @class collie.Polyline 6373 * @extends collie.DisplayObject 6374 * @requires http://raphaeljs.com 6375 * @param {Object} [htOption] Options 6376 * @param {String} [htOption.strokeColor] 6377 * @param {Number} [htOption.strokeWidth=0] When this option set as 0, The stroke disappears. 6378 * @param {String} [htOption.fillColor] 6379 * @param {String} [htOption.fillImage] Fill the image inside a polyline 6380 * @param {String} [htOption.closePath=false] Closing a Path 6381 * @param {String} [htOption.dashArray] ["", "-", ".", "-.", "-..", ". ", "- ", "--", "- .", "--.", "--.."] 6382 * @param {String} [htOption.lineCap="butt"] ["butt", "square", "round"] 6383 * @param {String} [htOption.lineJoin="miter"] ["bevel", "round", "miter"] 6384 * @param {Number} [htOption.miterLimit=10] 6385 * @example 6386 * // Draw a Rectangle 6387 * var line = new collie.Polyline({
6388 * closePath : true 6389 * }).addTo(layer); 6390 * line.setPointData([ 6391 * [0, 0], 6392 * [100, 0], 6393 * [100, 100], 6394 * [0, 100] 6395 * ]); 6396 * 6397 * // using moveTo 6398 * line.moveTo(200, 0); 6399 * line.lineTo(300, 0); 6400 * line.lineTo(300, 100); 6401 * line.lineTo(200, 100); 6402 * line.lineTo(200, 0); // expand boundary and set change status. 6403 */ 6404collie.Polyline = collie.Class(/** @lends collie.Polyline.prototype */{ 6405 /** 6406 * @constructs 6407 */ 6408 $init : function (htOption) { 6409 this.option({ 6410 strokeColor : '#000000', 6411 strokeWidth : 1, 6412 fillColor : '', 6413 fillImage : '', 6414 lineCap : "butt", 6415 lineJoin : "miter", 6416 miterLimit : 10, 6417 dashArray : "", 6418 closePath : false // ë§ì§ë§ì ìëì¼ë¡ ì°ê²°í´ ì¤ 6419 }, null, true); 6420 this._aPointData = []; 6421 this._oPaper = null; 6422 this._htPointBoundary = { 6423 right : null, 6424 bottom : null 6425 }; 6426 }, 6427 6428 /** 6429 * Set points for drawing 6430 * 6431 * @param {Array} aPointData [[x1, y1, bMoveTo], [x2, y2, bMoveTo], ...] 6432 * @param {Boolean} bSkipExpandSize You can this option set as true if you don't want to expand size 6433 */ 6434 setPointData : function (aPointData, bSkipExpandSize) { 6435 this._aPointData = aPointData; 6436 this.setChanged(); 6437 6438 if (!bSkipExpandSize) { 6439 this._expandBoundary(aPointData); 6440 } 6441 }, 6442 6443 /** 6444 * Return points 6445 * 6446 * @return {Array} 6447 */ 6448 getPointData : function () { 6449 return this._aPointData; 6450 }, 6451 6452 /** 6453 * Add a point 6454 * @param {Number} nX 6455 * @param {Number} nY 6456 * @param {Boolean} bSkipExpandSize You can this option set as true if you don't want to expand size 6457 */ 6458 addPoint : function (nX, nY, bSkipExpandSize) { 6459 this._aPointData.push([nX, nY]); 6460 this.setChanged(); 6461 6462 if (!bSkipExpandSize) { 6463 this._expandBoundary(nX, nY); 6464 } 6465 }, 6466 6467 /** 6468 * Move a cursor position 6469 * 6470 * @param {Number} nX 6471 * @param {Number} nY 6472 */ 6473 moveTo : function (nX, nY) { 6474 this._aPointData.push([nX, nY, true]); 6475 }, 6476 6477 /** 6478 * Alias for the addPoint method 6479 * @see collie.Polyline#addPoint 6480 */ 6481 lineTo : function (nX, nY, bSkipExpandSize) { 6482 this.addPoint(nX, nY, bSkipExpandSize); 6483 }, 6484 6485 /** 6486 * Reset points 6487 */ 6488 resetPointData : function () { 6489 this._aPointData = []; 6490 this._htPointBoundary = { 6491 right : null, 6492 bottom : null 6493 }; 6494 this.setChanged(); 6495 }, 6496 6497 /** 6498 * í¬ì¸í¸ ììì ëë¦°ë¤ 6499 * @private 6500 * 6501 * @param {Array|Number} nX ë°°ì´ë¡ ë¤ì´ì¤ë©´ ë°°ì´ì ëë©´ì íì¥ íë¤ 6502 * @param {Number} nY 6503 * @param {Boolean} bSkipAdoptSize í¬ê¸°ë¥¼ ê°ì²´ì ì ì©íë ê²ì ìëµíë¤ 6504 */ 6505 _expandBoundary : function (nX, nY, bSkipAdoptSize) { 6506 if (nX instanceof Array) { 6507 for (var i = 0, len = nX.length; i < len; i++) { 6508 this._expandBoundary(nX[i][0], nX[i][1], true); 6509 } 6510 } else { 6511 this._htPointBoundary.right = this._htPointBoundary.right === null ? nX : Math.max(nX, this._htPointBoundary.right); 6512 this._htPointBoundary.bottom = this._htPointBoundary.bottom === null ? nY : Math.max(nY, this._htPointBoundary.bottom); 6513 } 6514 6515 // í¬ê¸° ì ì© 6516 if (!bSkipAdoptSize) { 6517 var nStrokeWidth = this._htOption.strokeWidth * (collie.Renderer.isRetinaDisplay() ? 2 : 1); 6518 var nWidth = this._htPointBoundary.right + nStrokeWidth * 2; 6519 var nHeight = this._htPointBoundary.bottom + nStrokeWidth * 2; 6520 this.set({ 6521 width : nWidth, 6522 height : nHeight 6523 }); 6524 6525 6526 if (this._oPaper !== null) { 6527 this._oPaper.setSize(nWidth, nHeight); 6528 } 6529 } 6530 }, 6531 6532 /** 6533 * Delegate 6534 * @private 6535 */ 6536 onDOMDraw : function (oEvent) { 6537 var el = oEvent.element; 6538 6539 // ì ì´ 2ê° ë¯¸ë§ì´ë©´ ê·¸ë¦¬ì§ ìëë¤ 6540 if (this._aPointData.length < 2) { 6541 return; 6542 } 6543 6544 if (typeof Raphael === "undefined") { 6545 return; 6546 } 6547 6548 var htInfo = this.get(); 6549 var nStrokeWidth = htInfo.strokeWidth; 6550 var htDirty = this.getDirty(); 6551 6552 if (this._oPaper === null) { 6553 this._oPaper = Raphael(el, htInfo.width, htInfo.height); 6554 this._oPaper.canvas.style.zIndex = 10; 6555 } else if (htDirty && (htDirty.width || htDirty.height)) { 6556 this._oPaper.setSize(htInfo.width, htInfo.height); 6557 } 6558 6559 el.style.left = -(nStrokeWidth / 2) + "px"; 6560 el.style.top = -(nStrokeWidth / 2) + "px"; 6561 this._oPaper.clear(); 6562 6563 var str = "M" + this._aPointData[0][0] + "," + this._aPointData[0][1]; 6564 6565 for (var i = 1, len = this._aPointData.length; i < len; i++) { 6566 str += (this._aPointData[i][2] ? "M" : "L") + this._aPointData[i][0] + "," + this._aPointData[i][1]; 6567 } 6568 6569 // ë§ì§ë§ì´ ì°ê²°ëì´ ìì§ ìë¤ë©´ 6570 if ( 6571 htInfo.closePath && ( 6572 this._aPointData[0][0] !== this._aPointData[this._aPointData.length - 1][0] || 6573 this._aPointData[0][1] !== this._aPointData[this._aPointData.length - 1][1] 6574 ) 6575 ) { 6576 str += "L" + this._aPointData[0][0] + "," + this._aPointData[0][1]; 6577 } 6578 6579 var line = this._oPaper.path(str + (htInfo.closePath ? "Z" : "")); 6580 line.transform("t" + (nStrokeWidth / 2) + "," + (nStrokeWidth / 2)); 6581 6582 if (htInfo.fillImage) { 6583 collie.ImageManager.getImage(htInfo.fillImage, function (el) { 6584 line.attr("fill", "url('" + el.src + "')"); 6585 }); 6586 } else if (htInfo.fillColor) { 6587 line.attr("fill", htInfo.fillColor); 6588 } 6589 6590 if (htInfo.lineCap) { 6591 line.attr("stroke-linecap", htInfo.lineCap); 6592 } 6593 6594 if (htInfo.lineJoin) { 6595 line.attr("stroke-linejoin", htInfo.lineJoin); 6596 } 6597 6598 if (htInfo.miterLimit !== null) { 6599 line.attr("stroke-miterlimit", htInfo.miterLimit); 6600 } 6601 6602 if (htInfo.strokeColor) { 6603 line.attr("stroke", htInfo.strokeColor); 6604 } 6605 6606 line.attr("stroke-width", nStrokeWidth); 6607 6608 if (htInfo.dashArray) { 6609 line.attr("stroke-dasharray", htInfo.dashArray); 6610 } 6611 }, 6612 6613 /** 6614 * Delegate 6615 * @private 6616 */ 6617 onCanvasDraw : function (oEvent) { 6618 // ì ì´ 2ê° ë¯¸ë§ì´ë©´ ê·¸ë¦¬ì§ ìëë¤ 6619 if (this._aPointData.length < 2) { 6620 return; 6621 } 6622 6623 var htInfo = this.get(); 6624 var oContext = oEvent.context; 6625 var bIsRetinaDisplay = collie.Renderer.isRetinaDisplay(); 6626 var nStrokeWidth = htInfo.strokeWidth; 6627 var nRatio = (bIsRetinaDisplay ? 2 : 1); 6628 6629 oContext.save(); 6630 oContext.translate(oEvent.x, oEvent.y); 6631 6632 // ë í°ë ëì¤íë ì´ ëì 6633 if (bIsRetinaDisplay) { 6634 nStrokeWidth *= 2; 6635 } 6636 6637 if (htInfo.fillImage) { 6638 var el = collie.ImageManager.getImage(htInfo.fillImage); 6639 6640 if (!el) { 6641 collie.ImageManager.getImage(htInfo.fillImage, function () { 6642 this.setChanged(); 6643 }.bind(this)); 6644 } else { 6645 var pattern = oContext.createPattern(el, "repeat"); 6646 oContext.fillStyle = pattern; 6647 } 6648 } else if (htInfo.fillColor) { 6649 oContext.fillStyle = htInfo.fillColor; 6650 } 6651 6652 if (htInfo.strokeColor) { 6653 oContext.strokeStyle = htInfo.strokeColor; 6654 } 6655 6656 oContext.lineWidth = nStrokeWidth; 6657 6658 if (htInfo.lineCap) { 6659 oContext.lineCap = htInfo.lineCap; 6660 } 6661 6662 if (htInfo.lineJoin) { 6663 oContext.lineJoin = htInfo.lineJoin; 6664 } 6665 6666 if (htInfo.miterLimit) { 6667 oContext.miterLimit = htInfo.miterLimit; 6668 } 6669 6670 if (htInfo.dashArray) { 6671 // moveTo를 íë©´ fillì´ ìëë¤ ì°ê²°ë ì ì íë ë ê·¸ë ¤ì í´ê²°íë¤ 6672 if (htInfo.fillColor || htInfo.fillImage) { 6673 oContext.beginPath(); 6674 oContext.moveTo(this._aPointData[0][0] * nRatio, this._aPointData[0][1] * nRatio); 6675 6676 for (var i = 1, len = this._aPointData.length; i < len; i++) { 6677 if (this._aPointData[i][2]) { 6678 oContext.moveTo(this._aPointData[i][0] * nRatio, this._aPointData[i][1] * nRatio); 6679 continue; 6680 } 6681 6682 oContext.lineTo(this._aPointData[i][0] * nRatio, this._aPointData[i][1] * nRatio); 6683 } 6684 6685 if (htInfo.closePath) { 6686 oContext.closePath(); 6687 } 6688 6689 oContext.fill(); 6690 } 6691 6692 oContext.resetDashedLine(); 6693 } 6694 6695 // ìì 그린 ì ì ì§ìì§ë¤ 6696 oContext.beginPath(); 6697 oContext.moveTo(this._aPointData[0][0] * nRatio, this._aPointData[0][1] * nRatio); 6698 6699 for (var i = 1, len = this._aPointData.length; i < len; i++) { 6700 // moveTo 6701 if (this._aPointData[i][2]) { 6702 oContext.moveTo(this._aPointData[i][0] * nRatio, this._aPointData[i][1] * nRatio); 6703 continue; 6704 } 6705 6706 if (htInfo.dashArray) { 6707 oContext.dashedLine(this._aPointData[i - 1][0] * nRatio, this._aPointData[i - 1][1] * nRatio, this._aPointData[i][0] * nRatio, this._aPointData[i][1] * nRatio, collie.raphaelDashArray[htInfo.dashArray], nStrokeWidth); 6708 } else { 6709 oContext.lineTo(this._aPointData[i][0] * nRatio, this._aPointData[i][1] * nRatio); 6710 } 6711 } 6712 6713 // ë§ì§ë§ì´ ì°ê²°ëì´ ìì§ ìë¤ë©´ 6714 if ( 6715 htInfo.dashArray && htInfo.closePath && ( 6716 this._aPointData[0][0] !== this._aPointData[this._aPointData.length - 1][0] || 6717 this._aPointData[0][1] !== this._aPointData[this._aPointData.length - 1][1] 6718 )) { 6719 oContext.dashedLine(this._aPointData[i - 1][0] * nRatio, this._aPointData[i - 1][1] * nRatio, this._aPointData[0][0] * nRatio, this._aPointData[0][1] * nRatio, collie.raphaelDashArray[htInfo.dashArray], nStrokeWidth); 6720 } 6721 6722 if (htInfo.closePath) { 6723 oContext.closePath(); 6724 } 6725 6726 if (!htInfo.dashArray && (htInfo.fillColor || htInfo.fillImage)) { 6727 oContext.fill(); 6728 } 6729 6730 if (htInfo.strokeWidth) { 6731 oContext.stroke(); 6732 } 6733
6734 oContext.restore(); 6735 }, 6736 6737 /** 6738 * Returns information of The Class as String 6739 * 6740 * @return {String} 6741 */ 6742 toString : function () { 6743 return "Polyline" + (this._htOption.name ? " " + this._htOption.name : "")+ " #" + this.getId() + (this.getImage() ? "(image:" + this.getImage().src + ")" : ""); 6744 } 6745}, collie.DisplayObject); 6746/** 6747 * Text 6748 * - ë§ì¤ìì Canvasì¼ ëë§ ëë¤. DOMì 미구í 6749 * TODO Textë ë§ì¤ìê³¼ ìë ì¤ë°ê¿ ë문ì 모ë°ì¼ìì ì¬ì©íë©´ êµì¥í ë리ë¤. WebWorker를 ì¸ ì ìëì§ íì¸í´ ë´ì¼ í ê² 6750 * 6751 * @class collie.Text 6752 * @extends collie.DisplayObject 6753 * @param {Object} [htOption] 6754 * @param {Object} [htOption.fontFamily='Arial'] ê¸ê¼´ 6755 * @param {Object} [htOption.fontWeight=''] ì¤íì¼, bold ë©´ ì§íê² 6756 * @param {Object} [htOption.fontSize=12] í¬ê¸° (px) 6757 * @param {Object} [htOption.fontColor='#000000'] ê¸ê¼´ ìì 6758 * @param {Object} [htOption.lineHeight="auto"] ë¼ì¸ ê°ê²© (px), autoë©´ ìëì¼ë¡ ë§ì¶°ì§ 6759 * @param {Object} [htOption.textAlign='left'] í ì¤í¸ ì ë ¬ left, center, right 6760 * @param {Object} [htOption.padding="0 0 0 0"] í ì¤í¸ í¨ë© (px) top right bottom left 6761 * @param {Object} [htOption.ellipsisMaxLine=0] ìµë ë¼ì¸ ì. ë¼ì¸ ì를 ëì ê²½ì° ë§ì¤ì í¨. (0ì´ë©´ ì¬ì© ìí¨) 6762 * @param {Object} [htOption.ellipsisString='...'] ë§ì¤ì í ë ëì²´í í ì¤í¸ 6763 * @param {Object} [htOption.useEllipsis=false] ë§ì¤ì ì¬ì© ì¬ë¶ 6764 * @example 6765 * 기본ì ì¸ ì¬ì©ë² 6766 * <code> 6767 * var oText = new collie.Text({ 6768 * width : 100, // ëë¹ì ëì´ë¥¼ ë°ëì ì§ì í´ì¼ í©ëë¤. 6769 * height : 100, 6770 * x : 0, 6771 * y : 0, 6772 * fontColor : "#000000" 6773 * }).text("í ì¤í¸ ì ëë¤"); 6774 * </code> 6775 */ 6776collie.Text = collie.Class(/** @lends collie.Text.prototype */{ 6777 /** 6778 * @constructs 6779 */ 6780 $init : function (htOption) { 6781 this._sText = ""; 6782 this.option({ 6783 fontFamily : 'Arial', // ê¸ê¼´ ì¤íì¼ 6784 fontWeight : '', // bold 6785 fontSize : 12, // px 6786 fontColor : '#000000', // ê¸ê¼´ ìì 6787 lineHeight : "auto", // ë¼ì¸ ê°ê²©, px nullì´ë©´ autoë©´ ìë 6788 textAlign : 'left', // í ì¤í¸ ì ë ¬ left, center, right 6789 padding : "0 0 0 0", // í ì¤í¸ í¨ë© 6790 ellipsisMaxLine : 0, // ìµë ë¼ì¸ ì. ì§ì íë©´ ë§ì¤ì í¨ 6791 ellipsisString : '...', // ë§ì¤ì í ì¤í¸ 6792 useEllipsis : false, // ë§ì¤ì ì¬ì© ì¬ë¶ 6793 useCache : true // useCache ê¸°ë³¸ê° true 6794 }, null, true /* Don't overwrite options */); 6795 6796 this._elText = null; 6797 this._nTextWidth = 0; 6798 this._nRatio = 1; 6799 this._aCallbackTextWidth = []; 6800 }, 6801 6802 _initElement : function () { 6803 if (this._elText === null) { 6804 this._elText = document.createElement("div"); 6805 this._elText.style.display = "inline"; 6806 this.getDrawing().getItemElement().appendChild(this._elText); 6807 } 6808 }, 6809 6810 /** 6811 * Delegate 6812 * @private 6813 */ 6814 onCanvasDraw : function (oEvent) { 6815 this._nRatio = this._sRenderingMode === "canvas" && this._bRetinaDisplay ? 2 : 1; 6816 this._oContext = oEvent.context; 6817 var nMaxWidth = this._getMaxWidth(); 6818 this._oContext.font = this._getFontText(); 6819 this._oContext.fillStyle = this._htOption.fontColor; 6820 this._oContext.textBaseline = "top"; 6821 this._fillTextMultiline(this._wordWrap(nMaxWidth).split("\n"), oEvent.x, oEvent.y); 6822 this._triggerGetTextWidth(); 6823 }, 6824 6825 /** 6826 * Delegate 6827 * @private 6828 */ 6829 onDOMDraw : function (oEvent) { 6830 this._initElement(); 6831 var oDrawing = this.getDrawing(); 6832 var el = oEvent.element; 6833 var sText = this._sText.replace(/\n/g, "<br />"); 6834 var elStyle = el.style; 6835 elStyle.font = this._getFontText(); 6836 elStyle.color = this._htOption.fontColor; 6837 elStyle.padding = this._getPadding().replace(/ /g, "px ") + "px"; 6838 elStyle.width = this._getMaxWidth() + "px"; 6839 elStyle.height = this._getMaxHeight() + "px"; 6840 elStyle.lineHeight = this._getLineHeight() + "px"; 6841 elStyle.textAlign = this._htOption.textAlign; 6842 6843 if (this._elText.innerHTML != sText) { 6844 this._elText.innerHTML = sText; 6845 } 6846 6847 this.unsetChanged(); 6848 this._getDOMTextWidth(); 6849 this._triggerGetTextWidth(); 6850 }, 6851 6852 _getDOMTextWidth : function () { 6853 if (this._elText !== null) { 6854 this._nTextWidth = this._elText.offsetWidth; 6855 } 6856 }, 6857 6858 _getFontText : function () { 6859 return this._htOption.fontWeight + " " + (this._htOption.fontSize * this._nRatio) + "px " + this._htOption.fontFamily; 6860 }, 6861 6862 _getLineHeight : function () { 6863 return this._htOption.lineHeight === "auto" ? (this._htOption.fontSize * this._nRatio) : this._htOption.lineHeight * this._nRatio; 6864 }, 6865 6866 /** 6867 * ì¬ë¬ ì¤ì í ì¤í¸ë¥¼ ì°ë¬ì ì´ë¤ 6868 * 6869 * @private 6870 * @param {Array} aText í ë°°ì´ ë¹ í ì¤ 6871 */ 6872 _fillTextMultiline : function (aText, nX, nY) { 6873 var nLeft = this._getPadding("left"); 6874 var nMaxLine = this._htOption.ellipsisMaxLine; 6875 this._nTextWidth = 0; 6876 6877 for (var i = 0; i < aText.length; i++) { 6878 if (nMaxLine && i >
6878= nMaxLine - 1) { 6879 // ë§ì¤ìì´ íìíë©´ 6880 if (aText.length > nMaxLine) { 6881 aText[i] = this._insertEllipsisText(aText[i]); 6882 aText.splice(i + 1, aText.length - (i + 1)); // ë©ì¶¤ 6883 } 6884 } 6885 6886 var nTextWidth = this._oContext.measureText(aText[i]).width; 6887 6888 if (this._htOption.textAlign === "center") { 6889 nLeft = this._getMaxWidth() / 2 - nTextWidth / 2 + this._getPadding("left"); 6890 } else if (this._htOption.textAlign === "right") { 6891 nLeft = ((this._htOption.width * this._nRatio) - this._getPadding("right")) - nTextWidth; 6892 } 6893 6894 this._oContext.fillText(aText[i], nX + nLeft, nY + this._getTopPosition(i + 1)); 6895 this._nTextWidth = Math.max(this._nTextWidth, nTextWidth); 6896 } 6897 }, 6898 6899 _getMaxWidth : function () { 6900 return (this._htOption.width * this._nRatio) - (this._getPadding("left") + this._getPadding("right")); 6901 }, 6902 6903 _getMaxHeight : function () { 6904 return (this._htOption.height * this._nRatio) - (this._getPadding("top") + this._getPadding("bottom")); 6905 }, 6906 6907 /** 6908 * ìì top ìì¹ë¥¼ ë°í 6909 * 6910 * @private 6911 * @param {Number} nLine ë¼ì¸ë²í¸, 1ë¶í° ìì 6912 */ 6913 _getTopPosition : function (nLine) { 6914 return this._getLineHeight() * (nLine - 1) + this._getPadding("top"); 6915 }, 6916 6917 /** 6918 * í´ë¹ í¬ì§ì ì í¨ë© ê°ì ë°ííë¤ 6919 * 6920 * @param {String} sPositionName top, right, bottom, left, ê°ì´ ìì¼ë©´ ì ì²´ 문ìì´ì ë°í, ë¨ìë ì°ì§ ìëë¤. px 6921 * @return {Number|String} 6922 * @private 6923 */ 6924 _getPadding : function (sPositionName) { 6925 var sPadding = this._htOption.padding || "0 0 0 0"; 6926 var aPadding = sPadding.split(" "); 6927 6928 for (var i = 0, len = aPadding.length; i < len; i++) { 6929 aPadding[i] = parseInt(aPadding[i], 10) * this._nRatio; 6930 } 6931 6932 switch (sPositionName) { 6933 case "top" : 6934 return aPadding[0]; 6935 6936 case "right" : 6937 return aPadding[1]; 6938 6939 case "bottom" : 6940 return aPadding[2]; 6941 6942 case "left" : 6943 return aPadding[3]; 6944 6945 default : 6946 return aPadding.join(" "); 6947 } 6948 }, 6949 6950 /** 6951 * ë§ì¤ìë í ì¤í¸ë¥¼ ë°í 6952 * @private 6953 */ 6954 _insertEllipsisText : function (sText) { 6955 var nWidth = this._getMaxWidth(); 6956 var sEllipsizedText = ''; 6957 6958 for (var i = sText.length; i > 0; i--) { 6959 sEllipsizedText = sText.substr(0, i) + this._htOption.ellipsisString; 6960 6961 if (this._oContext.measureText(sEllipsizedText).width <= nWidth) { 6962 return sEllipsizedText; 6963 } 6964 } 6965 6966 return sText; 6967 }, 6968 6969 /** 6970 * ìë ì¤ë°ê¿ 6971 * - ì¬ê· í¸ì¶ 6972 * 6973 * @ignore 6974 * @param {Number} nWidth ì¤ë°ê¿ ë ëë¹ 6975 * @param {String} sText í ì¤í¸, ì¬ê·í¸ì¶ ëë©´ì ëë¨¸ì§ ê¸¸ì´ì í ì¤í¸ê° ë¤ì´ê°ë¤ 6976 * @return {String} ì¤ë°ê¿ë í ì¤í¸ 6977 */ 6978 _wordWrap : function (nWidth, sText) { 6979 var sOriginalText = sText || this._sText; 6980 var nCount = 1; 6981 6982 // ì본 문ìê° ìì¼ë©´
6983 if (!sOriginalText) { 6984 return ''; 6985 } 6986 6987 sText = sOriginalText.substr(0, 1); 6988 6989 // 첫ìë¶í° ììí´ì í´ë¹ ëë¹ê¹ì§ ëë¬íë©´ ì르기 6990 while (this._oContext.measureText(sText).width <= nWidth) { 6991 nCount++; 6992 6993 // ëì´ì 못ì르면 ë°í 6994 if (nCount > sOriginalText.length) { 6995 return sText; 6996 } 6997 6998 // ì르기 6999 sText = sOriginalText.substr(0, nCount); 7000 7001 // ì¤ë°ê¿ 문ìë©´ ì§ëê° 7002 if (sOriginalText.substr(nCount - 1, 1) === "\n") { 7003 break; 7004 } 7005 } 7006 7007 nCount = Math.max(1, nCount - 1); 7008 sText = sOriginalText.substr(0, nCount); 7009 7010 // ë¤ì 문ìê° ì¤ë°ê¿ë¬¸ìë©´ ì§ëê° 7011 if (sOriginalText.substr(nCount, 1) === "\n") { 7012 nCount++; 7013 } 7014 7015 // ë¤ì ë ë¨ììë¤ë©´ ì¬ê· í¸ì¶ 7016 if (sOriginalText.length > nCount) { 7017 sText += "\n" + (this._wordWrap(nWidth, sOriginalText.substr(nCount))); 7018 } 7019 7020 return sText; 7021 }, 7022 7023 /** 7024 * í ì¤í¸ë¥¼ ì´ë¤ 7025 * Write text 7026 * 7027 * @param {String} sText ì¶ë ¥í ë°ì´í° text data 7028 * @return {collie.Text} ë©ìë ì²´ì´ëì ìí´ ì기 ìì ì ë°í. return self instance for method chaining 7029 */ 7030 text : function (sText) { 7031 this._nTextWidth = 0; 7032 this._aCallbackTextWidth = []; 7033 this._sText = sText.toString(); 7034 this.setChanged(); 7035 return this; 7036 }, 7037 7038 /** 7039 * í ì¤í¸ ìµë ëë¹ë¥¼ ë°í, ê·¸ë ¤ì§ê¸° ì ìë ë°íì´ ëì§ ì기 ë문ì callback í¨ì를 ë£ì´ ê·¸ë ¤ì§ íì ê°ì ë°ìì¬ ì ìë¤ 7040 * ì½ë°± í¨ì 첫ë²ì§¸ ì¸ìê° ëë¹ ê° 7041 * @param {Function} fCallback 7042 * @return {Number} í ì¤í¸ ìµë ëë¹ 7043 */ 7044 getTextWidth : function (fCallback) { 7045 if (fCallback) { 7046 this._aCallbackTextWidth.push(fCallback); 7047 } 7048 7049 if (this._nTextWidth) { 7050 this._triggerGetTextWidth(); 7051 return this._nTextWidth / this._nRatio; 7052 } 7053 }, 7054 7055 _triggerGetTextWidth : function () { 7056 if (this._aCallbackTextWidth.length > 0) { 7057 for (var i = 0, len = this._aCallbackTextWidth.length; i < len; i++) { 7058 this._aCallbackTextWidth[i](this._nTextWidth / this._nRatio); 7059 } 7060 7061 this._aCallbackTextWidth = []; 7062 } 7063 }, 7064 7065 /** 7066 * 문ìì´ë¡ í´ëì¤ ì ë³´ ë°í 7067 * 7068 * @return {String} 7069 */ 7070 toString : function () { 7071 return "Text" + (this._htOption.name ? " " + this._htOption.name : "")+ " #" + this.getId() + (this.getImage() ? "(image:" + this.getImage().src + ")" : ""); 7072 } 7073}, collie.DisplayObject); 7074/** 7075 * ì ëë©ì´ì ë¶ëª¨ í´ëì¤ 7076 * 7077 * @class collie.Animation 7078 * @extends collie.Component 7079 * @param {Function} fCallback íì´ë¨¸ ì½ë°± í¨ì 7080 * @param {Number} nDuration íì´ë¨¸ ì¤í ìê°, ì§ì° ìê° (ms) 7081 * @param {Object} htOption ì¤ì 7082 * @param {Boolean} htOption.useAutoStart TimerListì ì¶ê°ë ë ìëì¼ë¡ ìì ëë¤ 7083 * @param {Function} [htOption.onì´ë²¤í¸ëª ] onCompleteì ê°ì´ ì´ë²¤í¸ëª ì ì¬ì©í´ì attach를 ì§ì íì§ ìê³ ìµì ì¼ë¡ í ì ìë¤ 7084 */ 7085collie.Animation = collie.Class(/** @lends collie.Animation.prototype */{ 7086 /** 7087 * @constructs 7088 */ 7089 $init : function (fCallback, nDuration, htOption) { 7090 this._nId = ++collie.Animation._idx; 7091 this._bIsPlaying = false; 7092 this._fCallback = fCallback; 7093 this._oTimerList = null; 7094 7095 // AnimationQueueì ê²½ì° nDurationì리ì htOptionì´ ë¤ì´ê°ë¤ 7096 this.option("useAutoStart", true); 7097 this.option((typeof nDuration === "object" ? nDuration : htOption) || {}); 7098 this.setDuration(nDuration); 7099 7100 // ì´ë²¤í¸ í¸ë¤ë¬ í ë¹ 7101 this.setOptionEvent(htOption); 7102 }, 7103 7104 /** 7105 * Option ì¤ì ì eventë¡ ë§ë¦ 7106 * @private 7107 */ 7108 setOptionEvent : function (htOption) { 7109 if (htOption) { 7110 for (var i in htOption) { 7111 if (i.toString().indexOf("on") === 0) { 7112 this.attach(i.toString().replace(/^on/, '').toLowerCase(), htOption[i]); 7113 } 7114 } 7115 } 7116 }, 7117 7118 /** 7119 * Callbackì ííì ë§ê² ì¤í 7120 * 7121 * @private 7122 * @param {Object} htParam 7123 */ 7124 triggerCallback : function (htParam) { 7125 // callbackì DisplayObject ê°ì²´ë¥¼ ë길 ê²½ì° 7126 if (typeof this._fCallback !== "function" && this._htOption.set) { 7127 var htOption = {}; 7128 7129 // ë°°ì´ ê° ì²ë¦¬ 7130 if (this._htOption.set instanceof Array) { 7131 for (var i = 0, len = this._htOption.set.length; i < len; i++) { 7132 htOption[this._htOption.set[i]] = (htParam.value instanceof Array) ? htParam.value[i] : htParam.value; 7133 } 7134 } else { 7135 htOption[this._htOption.set] = htParam.value; 7136 } 7137 7138 // ì¤í 7139 if (this._fCallback instanceof Array) { 7140 for (var j = 0, len = this._fCallback.length; j < len; j++) { 7141 this._fCallback[j].set(htOption); 7142 } 7143 } else { 7144 this._fCallback.set(htOption); 7145 } 7146 } else if (this._fCallback) { 7147 this._fCallback(htParam); 7148 } 7149 }, 7150 7151 /** 7152 * Durationì ì¤ì 7153 * 7154 * @param {Number|String} nDuration ì¤í ìê°, ì§ì° ìê° ì¤ì (ms) 7155 */ 7156 setDuration : function (nDuration) { 7157 this._nDuration = parseInt(nDuration, 10); 7158 }, 7159 7160 /** 7161 * Durationì ë°í 7162 * 7163 * @return {Number} (ms) 7164 */ 7165 getDuration : function () { 7166 return this._nDuration; 7167 }, 7168 7169 /** 7170 * TimerListì ì¶ê°ë ë ìë ¤ ì¤. stopí ë 목ë¡ìì 빼기 ìí¨ 7171 * 7172 * @param {collie.TimerList} 7173 * @private 7174 */ 7175 setTimerList : function (oTimerList) { 7176 this._oTimerList = oTimerList; 7177 7178 if (this._htOption.useAutoStart) { 7179 this.start(); 7180 } 7181 }, 7182 7183 /** 7184 * ì ëë©ì´ì ì¸ì¤í´ì¤ë¥¼ ìë³íë ìì´ë를 ë°í 7185 * 7186 * @private 7187 * @return {Number} ìì´ë (1...) 7188 */ 7189 getId : function () { 7190 return this._nId; 7191 }, 7192 7193 /** 7194 * ì ëë©ì´ì ì ì¤í 7195 * 7196 * @abstract 7197 * @param {Number} [nCurrentFrame] íì¬ ë ëë¬ íë ì, ê°ì´ ìì¼ë©´ ìëì¼ë¡ íì¬ ë ëë¬ íë ìì ê°ì ¸ ì¨ë¤ 7198 * @param {Number} [nDrameDuration] ì§íë íë ì ìê°(ms) 7199 */ 7200 run : function (nCurrentFrame, nFrameDuration) { 7201 throw new Error('abstract method'); 7202 }, 7203 7204 /** 7205 * ì¤ì ê°ì ì´ê¸°í í ë ì¬ì© 7206 * 7207 * @abstract 7208 */ 7209 reset : function () { 7210 throw new Error('abstract method'); 7211 }, 7212 7213 /** 7214 * ì ëë©ì´ì ì ì ì§ 7215 * @example 7216 * // stop/start 7217 * var timer = collie.Timer.repeat(function () {}, 1000); 7218 * timer.stop(); 7219 * timer.start(); 7220 * 7221 * @param {Boolean}
7221 bSkipEvent ì´ë²¤í¸ë¥¼ ë°ìíì§ ìëë¤ 7222 */ 7223 stop : function (bSkipEvent) { 7224 if (this.isPlaying()) { 7225 if (this._oTimerList !== null) { 7226 this._oTimerList.remove(this); 7227 } 7228 7229 this._bIsPlaying = false; 7230 this.reset(); 7231 7232 /** 7233 * íì´ë¨¸ë¥¼ ì ì§í ë ë°ì. ì ìì ì¼ë¡ completeë ê²½ì°ìë ë°ìíì§ ìëë¤ 7234 * @name collie.Animation#stop 7235 * @event 7236 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 7237 */ 7238 if (!bSkipEvent) { 7239 this.fireEvent("stop"); 7240 } 7241 } 7242 }, 7243 7244 /** 7245 * ì ëë©ì´ì ì ì¼ìì ì§ 7246 * @example 7247 * // pause/start 7248 * var timer = collie.Timer.repeat(function () {}, 1000); 7249 * timer.pause(); 7250 * timer.start(); 7251 */ 7252 pause : function () { 7253 if (this.isPlaying()) { 7254 this._bIsPlaying = false; 7255 7256 /** 7257 * íì´ë¨¸ë¥¼ ì¼ì ì ì§í ë ë°ì 7258 * @name collie.Animation#pause 7259 * @event 7260 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 7261 */ 7262 this.fireEvent("pause"); 7263 7264 if (this._oTimerList !== null) { 7265 this._oTimerList.remove(this); 7266 } 7267 } 7268 }, 7269 7270 /** 7271 * ì ì§ ìíì¸ íì´ë¨¸ë¥¼ ë¤ì ì¤í 7272 */ 7273 start : function () { 7274 if (!this.isPlaying()) { 7275 this._bIsPlaying = true; 7276 7277 if (this._oTimerList !== null) { 7278 this._oTimerList.add(this); 7279 } 7280 7281 /** 7282 * íì´ë¨¸ë¥¼ ì¤íí ë ë°ì. Timer를 ì´ì©í´ì ìì±í ëë ìì±íë ìê° ìì ìíì´ë¤. 7283 * @name collie.Animation#start 7284 * @event 7285 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 7286 */ 7287 this.fireEvent("start"); 7288 } 7289 }, 7290 7291 /** 7292 * íì´ë¨¸ê° ì§í ì¤ì¸ì§ ì¬ë¶ë¥¼ ë°í 7293 * 7294 * @return {Boolean} trueë©´ ì¤í ì¤ 7295 */ 7296 isPlaying : function () { 7297 return this._bIsPlaying; 7298 }, 7299 7300 /** 7301 * ì ëë©ì´ì ì´ ìë£ ëì ë ì¤í 7302 */ 7303 complete : function () { 7304 if (this.isPlaying()) { 7305 if (this._fCallbackComplete) { 7306 this._fCallbackComplete(); 7307 } 7308 7309 // complete ì´ë²¤í¸ ë°ì ì ì ë©ì¶¤ 7310 this.stop(true); 7311 7312 /** 7313 * íì´ë¨¸ê° ì ìì ì¼ë¡ ì¢ ë£ëë©´ ë°ì, repeatë cycleì loopê° 0ê³¼ ê°ì´ ì§ìì ì¼ë¡ ë°ë³µëë íì´ë¨¸ììë ì¼ì´ëì§ ìëë¤ 7314 * @name collie.Animation#complete 7315 * @event 7316 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 7317 */ 7318 this.fireEvent("complete"); 7319 } 7320 } 7321 7322 /** 7323 * íì¬ íì´ë¨¸ë¥¼ ì ê±°íë¤ 7324 * 7325 * @name collie.Animation#remove 7326 * @deprecated start, stopí ë Listì ì¶ê°ëê³ ì ê±°ë기 ë문ì ë³ëë¡ remove를 í íìê° ìì´ì¡ë¤. 7327 */ 7328}, collie.Component); 7329 7330/** 7331 * @private 7332 */ 7333collie.Animation._idx = 0; 7334/** 7335 * collie.Effect를 ì¬ì©í Transition íì´ë¨¸ 7336 * <a href="../tutorial/timer_transition.html" target="_blank">íí ë¦¬ì¼ ë³´ê¸°</a> 7337 * 7338 * @example 7339 * <code> 7340 * ì¬ë¬ ê°ì ê°ì¼ë¡ í¸ëì§ì 7341 * collie.Timer.transition(function (oEvent) { 7342 * oDisplayObject.set("opacity", oEvent.value[0]); 7343 * oDisplayObject.set("x", oEvent.value[1]); 7344 * }, 1000, { 7345 * from : [1, 100], 7346 * to : [0, 300] 7347 * }); 7348 * </code> 7349 * 7350 * @example 7351 * DisplayObject를 callbackì¼ë¡ ì¬ì©í´ì ì¬ë¬ ìì±ì ë³ê²½íë ë°©ë² 7352 * <code> 7353 * collie.Timer.transition(oDisplayObject, 1000, { 7354 * from : [10, 10], // from ì ìëµ ê°ë¥, ìëµíë©´ íì¬ ê°ì´ ìëì¼ë¡ ì ë ¥ ë¨ 7355 * to : [100, 200], 7356 * set : ["x", "y"] 7357 * }); 7358 * </code> 7359 * íì§ë§ ì´ ëìë DisplayObjectì move ë©ìë를 ì¬ì©íë ê²ì´ ì¢ì 7360 * 7361 * @example 7362 * ì¬ë¬ ê°ì DisplayObject를 í꺼ë²ì ì¤íí ìë ìì 7363 * <code> 7364 * collie.Timer.transition([oDisplayObjectA, oDisplayObjectB], 1000, { 7365 * from : 0, // ì´ ëìë from ìëµ ë¶ê°ë¥ 7366 * to : 1, 7367 * set : "opacity" 7368 * }); 7369 * </code> 7370 * 7371 * @see collie.Timer 7372 * @class collie.AnimationTransition 7373 * @extends collie.Animation 7374 * @param {Function|collie.DisplayObject|Array} fCallback ì¤íë ì½ë°± í¨ì, DisplayObject를 ë£ê² ëë©´ í´ë¹ ê°ì²´ì ê´í ë´ì©ë§ ë³ê²½í¨. htOptionì set 참조. 7375 * @param {collie.AnimationCycle} fCallback.timer íì¬ íì´ë¨¸ ì¸ì¤í´ì¤ 7376 * @param {Number} fCallback.frame íì¬ íë ì 7377 * @param {Number} fCallback.duration íì´ë¨¸ì ì¤ì ë duraiton ê° 7378 * @param {Number} fCallback.cycle ë°ë³µ íì 7379 * @param {Number} fCallback.runningTime íì´ë¨¸ ìì í ì¤íë ìê° (ms) 7380 * @param {Number|Array} fCallback.value ì ì©í ê°. from, to ê°ì´ ë°°ì´ì¼ ê²½ì° ì´ ê°ë ë°°ì´ë¡ ë°í 7381 * @param {Number|Array} fCallback.from ìì ê°, ìì ê°ì ì ë ¥íì§ ìê³ fCallbackì DisplayObject를 ë£ì¼ë©´ í´ë¹ ê°ì²´ì íì¬ ê°ì´ ìëì¼ë¡ ì ë ¥ë¨ 7382 * @param {Number|Array} fCallback.to ë ê° 7383 * @param {Number} nDuration ì¤í ìê° 7384 * @param {Object} htOption ì¤ì 7385 * @param {Number|Array} htOption.from ìì ê°(ë°°ì´ë¡ ë£ì ì ìì) 7386 * @param {Number|Array} htOption.to ë ê°(ë°°ì´ë¡ ë£ì ì ìì) 7387 * @param {Number} [htOption.loop=1] ë°ë³µ íì 7388 * @param {collie.Effect} [htOption.effect=collie.Effect.linear] í¨ê³¼ í¨ì 7389 * @param {String|Array} [htOption.set] fCallbackì DisplayObject를 ë£ì ê²½ì° setì ì´ì©í´ì í¹ì ê°ì ë³ê²½íë
7389¤. ë°°ì´ë¡ ë£ì ê²½ì° ì¬ë¬ ìì±ì ë³ê²½í ì ìë¤ 7390 * @see collie.Effect 7391 */ 7392collie.AnimationTransition = collie.Class(/** @lends collie.AnimationTransition.prototype */{ 7393 /** 7394 * @constructs 7395 */ 7396 $init : function (fCallback, nDuration, htOption) { 7397 this.option({ 7398 from : null, // ìì ê°(ë°°ì´ë¡ ë£ì ì ìì) 7399 to : null, // ë ê°(ë°°ì´ë¡ ë£ì ì ìì) 7400 set : "", 7401 loop : 1, 7402 effect : collie.Effect.linear // ì´íí¸ í¨ì 7403 }); 7404 this._htCallback = {}; 7405 this.option(htOption || {}); 7406 var fReset = this.reset.bind(this); 7407 this.optionSetter("from", fReset); 7408 this.optionSetter("to", fReset); 7409 this._nCount = 0; 7410 this._nCountCycle = 0; 7411 this._nFrameAtRunLastest = null; 7412 this._nRunningTime = null; 7413 this._bIsArrayValue = false; 7414 }, 7415 7416 /** 7417 * ììí ë ì¤íëë ë©ìë 7418 * @override 7419 */ 7420 start : function () { 7421 // ìì ê°ì´ ìì ë ê°ì²´ì íì¬ ê°ì ì ë ¥ 7422 if (this._htOption.from === null && typeof this._fCallback !== "function") { 7423 this._setDefaultFromValues(); 7424 } 7425 7426 if (this._nFrameAtRunLastest === null) { 7427 this.reset(); 7428 } 7429 7430 this.constructor.$super.start.call(this); 7431 }, 7432 7433 /** 7434 * @private 7435 */ 7436 _setDefaultFromValues : function () { 7437 var vFrom = null; 7438 7439 if (this._htOption.set) { 7440 if (this._htOption.set instanceof Array) { 7441 vFrom = []; 7442 for (var i = 0, len = this._htOption.set.length; i < len; i++) { 7443 vFrom.push(this._fCallback.get(this._htOption.set[i])); 7444 } 7445 } else { 7446 vFrom = this._fCallback.get(this._htOption.set) 7447 } 7448 7449 this.option("from", vFrom); 7450 } 7451 }, 7452 7453 /** 7454 * ê°ì ì´ê¸°í 7455 */ 7456 reset : function () { 7457 this._nFrameAtRunLastest = null; 7458 this._nRunningTime = null; 7459 this._nValue = this._htOption.from; 7460 this._bIsArrayValue = this._htOption.from instanceof Array; 7461 this._nCount = 0; 7462 this._nCountCycle = 0; 7463 7464 // ê°ì´ ë°°ì´ì¼ ê²½ì° ì²ë¦¬ 7465 if (this._bIsArrayValue) { 7466 this._fEffect = []; 7467 var fEffect = null; 7468 7469 for (var i = 0, len = this._htOption.from.length; i < len; i++) { 7470 fEffect = (this._htOption.effect instanceof Array) ? this._htOption.effect[i] : this._htOption.effect; 7471 this._fEffect[i] = fEffect(this._htOption.from[i], this._htOption.to[i]); 7472 } 7473 } else { 7474 this._fEffect = this._htOption.effect(this._htOption.from, this._htOption.to); 7475 } 7476 }, 7477 7478 /** 7479 * íì¬ ê°ì ì¤ì 7480 * 7481 * @param {Variables} vValue 7482 */ 7483 setValue : function (vValue) { 7484 this._nValue = vValue; 7485 }, 7486 7487 /** 7488 * íì¬ ê°ì ë°í 7489 * 7490 * @return {Variables} 7491 */ 7492 getValue : function () { 7493 return this._nValue; 7494 }, 7495 7496 /** 7497 * ì ëë©ì´ì ì ì¤í 7498 * 7499 * @param {Number} [nCurrentFrame] íì¬ ë ëë¬ íë ì, ê°ì´ ìì¼ë©´ ìëì¼ë¡ íì¬ ë ëë¬ íë ìì ê°ì ¸ ì¨ë¤ 7500 * @param {Number} [nFrameDuration] ì§íë íë ì ìê°(ms) 7501 */ 7502 run : function (nCurrentFrame, nFrameDuration) { 7503 if (nCurrentFrame === undefined) { 7504 nCurrentFrame = collie.Renderer.getInfo().frame; 7505 } 7506 7507 // ë ëë¬ê° stop ë ê²½ì° 7508 if (this._nFrameAtRunLastest > nCurrentFrame) { 7509 this.reset(); 7510 return; 7511 } 7512 7513 // ìì íë ì ì ì¥ 7514 if (this._nFrameAtRunLastest === null) { 7515 this._nFrameAtRunLastest = nCurrentFrame; 7516 this._nRunningTime = 0; 7517 nFrameDuration = 0; 7518 } 7519 7520 this._nRunningTime += nFrameDuration; 7521 this._nCount++; 7522 7523 // ìê°ì´ ì§ë¬ì¼ë©´ ë©ì¶¤ 7524 if (this._nRunningTime >= this._nDuration) { 7525 this._nCountCycle++; 7526 7527 // ëëë ê°ì´ ìëë©´ ëëë ê°ì¼ë¡ ë§ë¦(íë² ë ì¤í), 루íì ë§ì§ë§ì¼ ëë§ ë³´ì í¨. 7528 if (!this._isEndValue() && this._htOption.loop && this._htOption.loop <= this._nCountCycle) { 7529 this._setEndValue(); 7530 } else if (!this._htOption.loop || this._htOption.loop > this._nCountCycle) { 7531 /** 7532 * loopê° ìì ê²½ì° í¸ëì§ì ì´ íë² ëë¬ì ë ë°ì 7533 * @name collie.AnimationTransition#end 7534 * @event 7535 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 7536 */ 7537 this.fireEvent("end"); 7538 this._nFrameAtRunLastest = nCurrentFrame; 7539 this._nRunningTime = this._nRunningTime - this._nDuration; // loopë©´ ì²ìë¶í° ë¤ì ììì´ ìëë¼ ì´ì´ì ìì 7540 this._nValue = this._htOption.from; 7541 this._transitionValue(this._nRunningTime); 7542 } else { 7543 /** 7544 * í¸ëì§ì ì´ ëë í ë°ì 7545 * @name collie.AnimationTransition#complete 7546 * @event 7547 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 7548 */ 7549 this.complete(); 7550 return; 7551 } 7552 } else if (this._nRunningTime > 0) { 7553 this._transitionValue(this._nRunningTime); 7554 } 7555 7556 // ê°ì²´ ì¬íì© 7557 this._htCallback.timer = this; 7558 this._htCallback.frame = nCurrentFrame; 7559 this._htCallback.duration = this._nDuration; 7560 this._htCallback.cycle = this._nCountCycle; 7561 this._htCallback.runningTime = this._nRunningTime; 7562 this._htCallback.from = this._htOption.from; 7563 this._htCallback.to = this._htOption.to; 7564 this._htCallback.value = this._nValue; // ê°ì´ ë°°ì´ì´ë©´ ì´ê²ë ë°°ì´ë¡ ë°íë¨ 7565 this.triggerCallback(this._htCallback); 7566 7567 if (this._nRunningTime > 0) { 7568 this._nFrameAtRunLastest = nCurrentFrame; 7569 } 7570 }, 7571 7572 /** 7573 * íì¬ íë ì ê°ì ë°ì íì¬ ê°ì transitionë ê°ì¼ë¡ ë³ê²½ íë¤ 7574 * @private 7575 * @param {Number} nCurrentRunningTime íì¬ ì§íë ìê°(ms) 7576 */ 7577 _transitionValue : function (nCurrentRunningTime) { 7578 if (this._bIsArrayValue) { 7579 this._nValue = []; 7580 7581 for (var i = 0, len = this._htOption.from.length; i < len; i++) { 7582 this._nValue[i] = parseFloat(this._fEffect[i](Math.max(0, Math.min(1, nCurrentRunningTime / this._nDuration)))); 7583 } 7584 } else { 7585 this._nValue = parseFloat(this._fEffect(Math.max(0, Math.min(1, nCurrentRunningTime / this._nDuration)))); 7586 } 7587 }, 7588 7589 /** 7590 * ë ê°ì¸ì§ ì¬ë¶ë¥¼ ë°í 7591 * @private 7592 * @return {Boolean} trueë©´ ë ê° 7593 */ 7594 _isEndValue : function () { 7595 if (this._bIsArrayValue) { 7596 for (var i = 0, len = this._htOption.to.length; i < len; i++) { 7597 if (this._nValue[i] !== parseFloat(this._fEffect[i](1))) { 7598 return false;
7599 } 7600 } 7601 7602 return true; 7603 } else { 7604 return this._nValue === parseFloat(this._fEffect(1)); 7605 } 7606 }, 7607 7608 /** 7609 * íì¬ ê°ì ë ê°ì¼ë¡ ì¤ì íë¤ 7610 * @private 7611 * @param {Number} nValue 7612 */ 7613 _setEndValue : function () { 7614 if (this._bIsArrayValue) { 7615 for (var i = 0, len = this._htOption.to.length; i < len; i++) { 7616 this._nValue[i] = parseFloat(this._fEffect[i](1)); 7617 } 7618 } else { 7619 this._nValue = parseFloat(this._fEffect(1)); 7620 } 7621 } 7622}, collie.Animation); 7623 7624/** 7625 * ì´ë²¤í¸ í¨ê³¼ í¨ì 7626 * @namespace 7627 * @name collie.Effect 7628 */ 7629/** 7630 * í¹ì ìê° ê°ê²©ì¼ë¡ ê³ì ë°ë³µëë íì´ë¨¸ 7631 * <a href="../tutorial/timer_repeat.html" target="_blank">íí ë¦¬ì¼ ë³´ê¸°</a> 7632 * 7633 * timeline ---------------------------------> 7634 * action * duration * duration * duration * 7635 * @see collie.Timer 7636 * @class collie.AnimationRepeat 7637 * @extends collie.Animation 7638 * @param {Function} fCallback ì¤íë ì½ë°± í¨ì 7639 * @param {collie.AnimationCycle} fCallback.timer íì¬ íì´ë¨¸ ì¸ì¤í´ì¤ 7640 * @param {Number} fCallback.frame íì¬ íë ì 7641 * @param {Number} fCallback.duration íì´ë¨¸ì ì¤ì ë duraiton ê° 7642 * @param {Number} fCallback.count ì¤í íì 7643 * @param {Number} fCallback.skippedCount ì§ëê° ì¤í íì 7644 * @param {Number} fCallback.runningTime íì´ë¨¸ ìì í ì¤íë ìê° (ms) 7645 * @param {Number} nDuration ìê° ê°ê²© ms 7646 * @param {Object} [htOption] 7647 * @param {Number} [htOption.beforeDelay=0] ììë기 ì ì ì§ì°ìê°(ms) 7648 * @param {Number} [htOption.loop=0] ë°ë³µ íì(0ì´ë©´ 무í ë°ë³µ, complete ì´ë²¤í¸ê° ì¼ì´ëì§ ìëë¤) 7649 * @param {Number} [htOption.useRealTime=true] SkippedFrameì ì ì©í´ì count ê°ì ë³´ì íë¤ 7650 */ 7651collie.AnimationRepeat = collie.Class(/** @lends collie.AnimationRepeat.prototype */{ 7652 /** 7653 * @constructs 7654 */ 7655 $init : function (fCallback, nDuration, htOption) { 7656 this.option({ 7657 beforeDelay : 0, 7658 afterDelay : 0, 7659 loop : 0, 7660 useRealTime : true 7661 }); 7662 this.option(htOption || {}); 7663 this.reset(); 7664 this.setDuration(nDuration); 7665 this._nFrameAtRunLastest = null; 7666 }, 7667 7668 /** 7669 * Durationì ì¤ì 7670 * Repeatë Rendererì Durationë³´ë¤ ì§§ê² ì¤íí ì ì기 ë문ì ê°ì ë³´ì íë¤ 7671 * 7672 * @param {Number} nDuration ì¤í ìê°, ì§ì° ìê° ì¤ì (ms) 7673 */ 7674 setDuration : function (nDuration) { 7675 nDuration = parseInt(nDuration, 10); 7676 7677 if (nDuration < collie.Renderer.getDuration()) { 7678 nDuration = collie.Renderer.getDuration(); 7679 } 7680 7681 this._nDuration = nDuration; 7682 }, 7683 7684 /** 7685 * ê°ì ì´ê¸°í 7686 */ 7687 reset : function () { 7688 this._nCount = 0; 7689 this._nFrameAtRunLastest = null; 7690 this._nRunningTime = null; 7691 this._nRunLastestTime = null; 7692 this._nBeforeDelay = this._htOption.beforeDelay; 7693 }, 7694 7695 /** 7696 * ì ëë©ì´ì ì ì¤í 7697 * 7698 * @param {Number} [nCurrentFrame] íì¬ ë ëë¬ íë ì, ê°ì´ ìì¼ë©´ ìëì¼ë¡ íì¬ ë ëë¬ íë ìì ê°ì ¸ ì¨ë¤ 7699 * @param {Number} [nFrameDuration] ì§íë íë ì ìê°(ms) 7700 */ 7701 run : function (nCurrentFrame, nFrameDuration) { 7702 if (nCurrentFrame === undefined) { 7703 nCurrentFrame = collie.Renderer.getInfo().frame; 7704 } 7705 7706 // stop ë ê²½ì° 7707 if (this._nFrameAtRunLastest > nCurrentFrame) { 7708 this.reset(); 7709 return; 7710 } 7711 7712 // ììëì§ ììì ë ìì ìì ê¸°ë¡ 7713 if (this._nFrameAtRunLastest === null) { 7714 this._nFrameAtRunLastest = nCurrentFrame; 7715 this._nRunningTime = 0; 7716 this._nRunLastestTime = 0; 7717 nFrameDuration = 0; 7718 } 7719 7720 this._nRunningTime += nFrameDuration; 7721 var nSkippedCount = Math.max(1, Math.floor((this._nRunningTime - this._nRunLastestTime) / this._nDuration)) - 1; 7722 7723 // ìì ì§ì°ìê° 7724 if (this._nCount === 0 && this._nBeforeDelay) { 7725 // ëë ë ëë©´ ì²ë¦¬ 7726 if (this._nRunLastestTime + this._nBeforeDelay <= this._nRunningTime) { 7727 this.reset(); 7728 this._nBeforeDelay = 0; 7729 } 7730 return; 7731 } 7732 7733 // ì¤íëì´ì¼ í ìê°ì´ ì§ë¬ë¤ë©´ ì¤í 7734 if (this._nRunningTime === 0 || this._nRunLastestTime + this._nDuration <= this._nRunningTime) { 7735 this._nCount += this._htOption.useRealTime ? 1 + nSkippedCount : 1; 7736 this._fCallback({ 7737 timer : this, 7738 frame : nCurrentFrame, 7739 duration : this._nDuration, 7740 count : this._nCount, 7741 skippedCount : nSkippedCount, 7742 runningTime : this._nRunningTime 7743 }); 7744 7745 if (this._htOption.loop && this._htOption.loop <= this._nCount) { 7746 /** 7747 * ê³íë 모ë ì ëë©ì´ì ê³¼ ë°ë³µ íìê° ëëë©´ ë°ì. loop=0ì¼ë¡ ì¤ì íë©´ ë°ìíì§ ìëë¤. 7748 * @name collie.AnimationRepeat#complete 7749 * @event 7750 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 7751 */ 7752 this.complete(); 7753 return; 7754 } 7755 7756 this._nFrameAtRunLastest = nCurrentFrame; 7757 this._nRunLastestTime = this._nRunningTime; 7758 } 7759 } 7760}, collie.Animation); 7761/** 7762 * í¹ì ìê° ëì ì¤íë í ë기 ìê° ì´íì ë¤ì ì¤íëë ì¸ì´í´ ì ëë©ì´ì 7763 * ì£¼ë¡ Sprite ì ëë©ì´ì ì ì¬ì© ëë¤. 7764 * <a href="../tutorial/timer_cycle.html" target="_blank">íí ë¦¬ì¼ ë³´ê¸°</a> 7765 * 7766 * timeline ------------------------------------> 7767 * action *-duration-* delay *-duration-* delay 7768 * 7769 * @see collie.Timer 7770 * @class collie.AnimationCycle 7771 * @extends collie.Animation 7772 * @param {Function|collie.DisplayObject|Array} fCallback ì¤íë ì½ë°± í¨ì, DisplayObject를 ë£ê² ëë©´ í´ë¹ ê°ì²´ì ê´í ë´ì©ë§ ë³ê²½í¨. htOptionì set 참조. 7773 * @param {collie.AnimationCycle} fCallback.timer íì¬ íì´ë¨¸ ì¸ì¤í´ì¤ 7774 * @param {Number} fCallback.frame íì¬ íë ì 7775 * @param {Number} fCallback.duration íì´ë¨¸ì ì¤ì ë duraiton ê° 7776 * @param {Number} fCallback.count ì¤í íì 7777 * @param {Number} fCallback.skippedCount ì§ëê° ì¤í íì 7778 * @param {Number} fCallback.runningTime íì´ë¨¸ ìì í ì¤íë ìê° (ms) 7779 * @param {Variables} fCallback.value ì¸ì´í´ ê° 7780 * @param {Number} fCallback.cycle ì¸ì´í´ ë°ë³µ íì 7781 * @param {Number} fCallback.step ë¨ê³ ê° 7782 * @param {Number} fCallback.from ìì ê° 7783 * @param {Number} fCallback.to ë ê° 7784 * @param {Number|String} nDuration ìê° ê°ê²© (ms), fps ë¨ì를 ì¬ì©í ì ìë¤. 7785 * @param {Number} htOption ì¤ì 7786 * @param {Number} htOption.from=0 ì¸ì´í´ ìì ê° 7787 * @param {Number} htOption.to=0 ì¸ì´í´ ë ê° 7788 * @param {Number} [htOption.step=1] ì¦ê° ê° 7789 * @param {Number} [htOption.loop=0] 0ì´ ìëë©´ í´ë¹ íìë§í¼ ë°ë³µ 7790 * @param {Number} [htOption.useRealTime=true] SkippedFrameì ì ì©í´ì ì¸ì´í´ì íì¬ ìê°ê³¼ ì¼ì¹ 7791 * @param {Array} [htOption.valueSet] ë¹ ê·ì¹ì cycleì ì¬ì©í ë valueSetì ë°°ì´ì ë£ê³ ììëë¡ ê°ì êº¼ë´ ì¸ ì ìë¤ 7792 * @param {String|Array} [htOption.set="spriteX"] fCallbackì DisplayObject를 ë£ì ê²½ì° setì ì´ì©í´ì í¹ì ê°ì ë³ê²½íë
7792¤. ë°°ì´ë¡ ë£ì ê²½ì° ì¬ë¬ ìì±ì ë³ê²½í ì ìë¤ 7793 * @param {Number} [htOption.start] from ê°ì´ ìë ê°ë¶í° ììí ê²½ì° ê°ì ì¤ì . ex) from:0, to:3 ì¼ ë 2, 3, 0, 1, 2, 3... ì¼ë¡ ì§íí ê²½ì° start:2 ê°ì ì¤ì 7794 * @example 7795 * valueSet ì¬ì© ë°©ë², step, from, to ìµì ì ìëì¼ë¡ ì¤ì ëë¤ 7796 * <code> 7797 * collie.Timer.cycle(function () { 7798 * // 0, 1, 2, 1, 0 ìì¼ë¡ íë ì´ 7799 * }, 1000, { 7800 * valueSet : [0, 1, 2, 1, 0] 7801 * }); 7802 * </code> 7803 * 7804 * DisplayObject를 callbackì¼ë¡ ì¬ì©í´ì ì¤íë¼ì´í¸ ì ëë©ì´ì ì 구ííë ë°©ë² 7805 * <code> 7806 * collie.Timer.cycle(oDisplayObject, 1000, { 7807 * valueSet : [0, 1, 2, 1, 0] 7808 * }); 7809 * </code> 7810 * 7811 * fps ë¨ì를 ì°ë©´ íë ì ë¹ ì¬ì ìë를 ì¤ì í ì ìë¤. 8íë ìì´ë ì´ ê²½ì°ì 24fpsë (1000 / 24 * 8)msê° ëë¤. 7812 * <code> 7813 * collie.Timer.cycle(oDisplayObject, "24fps", { 7814 * from : 0, 7815 * to : 7 7816 * }); 7817 * </code> 7818 */ 7819collie.AnimationCycle = collie.Class(/** @lends collie.AnimationCycle.prototype */{ 7820 /** 7821 * @constructs 7822 */ 7823 $init : function (fCallback, nDuration, htOption) { 7824 this._nFPS = null; 7825 this._htCallback = {}; 7826 var fSetterFPS = this._setterFPS.bind(this); 7827 this.optionSetter("valueSet", this._setterValueSet.bind(this)); 7828 this.optionSetter("to", fSetterFPS); 7829 this.optionSetter("from", fSetterFPS); 7830 this.option({ 7831 delay : 0, // ë¤ì ì¸ì´í´ ê¹ì§ì ë기 ìê° ms 7832 from : 0, // ìì ê° 7833 to : 0, // ë ê° 7834 step : 1, // ë¨ê³ ê° 7835 loop : 0, // 0ì´ ìëë©´ ë°ë³µíì ì í 7836 set : "spriteX", 7837 useRealTime : true, 7838 valueSet : null, 7839 start : null // ììê°ì´ ìë ê°ë¶í° ììí ê²½ì° ì§ì 7840 }); 7841 this.option(htOption || {}); 7842 this._nFrameAtRunLastest = null; 7843 this._nRunLastestTime = null; 7844 this._nRunningTime = null; 7845 this._nCountCycle = 0; 7846 this._nCountCycleBefore = 0; 7847 this.setDuration(nDuration); 7848 this.reset(); 7849 }, 7850 7851 /** 7852 * ê°ì ì´ê¸°í 7853 */ 7854 reset : function () { 7855 this._nCount = 0; 7856 this._nCountCycle = 0; 7857 this._nCountCycleBefore = 0; 7858 this._nFrameAtRunLastest = null; 7859 this._nRunningTime = null; 7860 this._nRunLastestTime = null; 7861 this._nValue = (this._htOption.start !== null ? this._htOption.start : this._htOption.from) - this._htOption.step; 7862 }, 7863 7864 /** 7865 * valueSetì setter 7866 * @private 7867 */ 7868 _setterValueSet : function () { 7869 var aValueSet = this._htOption.valueSet; 7870 7871 // valueSetì ë§ì¶°ì ëë¨¸ì§ ìµì ì ë³ê²½ íë¤ 7872 if (aValueSet && aValueSet instanceof Array) { 7873 this.option({ 7874 from : 0, 7875 to : aValueSet.length - 1, 7876 step : 1 7877 }); 7878 } 7879 }, 7880 7881 /** 7882 * @private 7883 */ 7884 _setterFPS : function () { 7885 if (this._nFPS !== null && typeof this._htOption.to !== "undefined" && typeof this._htOption.from !== "undefined") { 7886 var nCount = (this._htOption.to - this._htOption.from) + 1; 7887 this._nDuration = Math.round(1000 / this._nFPS * nCount); 7888 } 7889 }, 7890 7891 /** 7892 * fps ì²ë¦¬ 7893 * 7894 * @param {Number|String} nDuration 7895 * @private 7896 */ 7897 setDuration : function (nDuration) { 7898 this._nDuration = parseInt(nDuration, 10); 7899 7900 if (/fps/i.test(nDuration) && typeof this._htOption.to !== "undefined" && typeof this._htOption.from !== "undefined") { 7901 this._nFPS = parseInt(nDuration, 10); 7902 this._setterFPS(); 7903 } else { 7904 this._nFPS = null; 7905 } 7906 }, 7907 7908 /** 7909 * íì¬ ê°ì ì¤ì 7910 * 7911 * @param {Variables} vValue 7912 */ 7913 setValue : function (vValue) { 7914 this._nValue = vValue; 7915 }, 7916 7917 /** 7918 * íì¬ ê°ì ë°í 7919 * 7920 * @return {Variables} 7921 */ 7922 getValue : function () { 7923 return this._htOption.valueSet ? this._htOption.valueSet[this._nValue] : this._nValue; 7924 }, 7925 7926 /** 7927 * ì ëë©ì´ì ì ì¤í 7928 * 7929 * @param {Number} [nCurrentFrame] íì¬ ë ëë¬ íë ì, ê°ì´ ìì¼ë©´ ìëì¼ë¡ íì¬ ë ëë¬ íë ìì ê°ì ¸ ì¨ë¤ 7930 * @param {Number} [nFrameDuration] ì§íë íë ì ìê°(ms) 7931 */ 7932 run : function (nCurrentFrame, nFrameDuration) { 7933 if (typeof nCurrentFrame === "undefined") { 7934 nCurrentFrame = collie.Renderer.getInfo().frame; 7935 } 7936 7937 // stop ë ê²½ì° 7938 if (this._nFrameAtRunLastest > nCurrentFrame) { 7939 this.reset(); 7940 return; 7941 } 7942 7943 // ììëì§ ììì ë ìì ìì ê¸°ë¡ 7944 if (this._nFrameAtRunLastest === null) { 7945 this._nFrameAtRunLastest = nCurrentFrame; 7946 this._nRunLastestTime = 0; // ë§ì§ë§ì¼ë¡ ì¤íëë ìê° 7947 this._nRunningTime = 0; 7948 nFrameDuration = 0; // ìì ìì ìë FrameDurationì ê³ì°íì§ ìëë¤ 7949 } 7950 7951 if (!nFrameDuration) { 7952 nFrameDuration = 0; 7953 } 7954 7955 var htOption = this._htOption; 7956 var nDiff = htOption.to - htOption.from; 7957 this._nTotalCount = nDiff / htOption.step; // ì´ íì 7958 this._nTerm = this._nDuration / this._nTotalCount; // ìê° ê°ê²© 7959 this._nRunningTime += nFrameDuration; // ìì ìì ë¶í° ì´ ì§íë ìê° 7960 var nSkippedCount = (!htOption.useRealTime) ? 0 : Math.max(1, Math.floor((this._nRunningTime - this._nRunLastestTime) / this._nTerm)) - 1; 7961 7962 // ì¤íëì´ì¼ í ìê°ì´ ì§ë¬ë¤ë©´ ì¤í 7963 if (this._nRunningTime === 0 || this._nRunLastestTime + this._nTerm <= this._nRunningTime) { 7964 // ì¬ì´í´ì´ ëëë©´ end ë°ì 7965 if (this._nCountCycleBefore !== this._nCountCycle) { 7966 /** 7967 * í ì¸ì´í´ì´ ëëë©´ ë°ìí¨ 7968 * @name collie.AnimationCycle#end 7969 * @event 7970 * @param {Object} oEvent ì»´í¬ëí¸ ê¸°ë³¸ ì´ë²¤í¸ ê°ì²´ 7971 */ 7972 this.fireEvent("end"); 7973 } 7974 7975 // ë°ë³µ íì를 ëìë¤ë©´ ì¢ ë£ 7976 if (htOption.loop && this._nCountCycle >= htOption.loop) { 7977 this.complete(); 7978 return; 7979 } 7980 7981 // ë ê°ì´ë©´ ìì ê°ì¼ë¡ ëë림 7982 if (this._nValue === htOption.to) { 7983 this._nValue = htOption.from - htOption.step; 7984 } 7985 7986 this._nValue += (htOption.step * (1 + nSkippedCount)); 7987 this._nCount += (1 + nSkippedCount); 7988 this._nCountCycleBefore = this._nCountCycle; 7989 7990 // ê°ì ë²ì´ë¬ì ë ì²ë¦¬ 7991 if (htOption.from <= htOption.to ? this._nValue >= htOption.to : this._nValue <= htOption.to) { 7992 var nOverCount = (this._nValue - htOption.to) / htOption.step;
7993 var nOverCountCycle = Math.ceil(nOverCount / (this._nTotalCount + 1)); // ì ì²´ ì«ì ì¹´ì´í¸ 7994 nOverCount = nOverCount % (this._nTotalCount + 1); 7995 7996 if (nOverCount) { // ì§ëê° ê² 7997 this._nCountCycle += nOverCountCycle; 7998 this._nValue = htOption.from + (nOverCount - 1) * htOption.step; 7999 } else { // ì íí ëë ê² 8000 this._nCountCycle += 1; 8001 this._nValue = htOption.to; 8002 } 8003 } 8004 8005 // ê°ì²´ ì¬íì© 8006 this._htCallback.timer = this; 8007 this._htCallback.frame = nCurrentFrame; 8008 this._htCallback.duration = this._nDuration; 8009 this._htCallback.count = this._nCount; 8010 this._htCallback.skippedCount = nSkippedCount; 8011 this._htCallback.runningTime = this._nRunningTime; 8012 this._htCallback.value = this.getValue(); 8013 this._htCallback.cycle = this._nCountCycle; 8014 this._htCallback.step = htOption.step; 8015 this._htCallback.from = htOption.from; 8016 this._htCallback.to = htOption.to; 8017 this.triggerCallback(this._htCallback); 8018 8019 // ìê° ì§í 8020 this._nFrameAtRunLastest = nCurrentFrame; 8021 this._nRunLastestTime = this._nRunningTime; 8022 } 8023 } 8024}, collie.Animation); 8025/** 8026 * ì¤ì ë ìê°ëì ì§ì° íì ì¤íëë íì´ë¨¸ 8027 * <a href="../tutorial/timer_delay.html" target="_blank">íí ë¦¬ì¼ ë³´ê¸°</a> 8028 * 8029 * timeline ----------> 8030 * action duration * 8031 * @see collie.Timer 8032 * @class collie.AnimationDelay 8033 * @extends collie.Animation 8034 * @param {Function} fCallback ì¤íë ì½ë°± í¨ì 8035 * @param {collie.AnimationDelay} fCallback.timer íì¬ íì´ë¨¸ ì¸ì¤í´ì¤ 8036 * @param {Number} fCallback.frame íì¬ íë ì 8037 * @param {Number} fCallback.duration íì´ë¨¸ì ì¤ì ë duraiton ê° 8038 * @param {Number} fCallback.runningTime íì´ë¨¸ ìì í ì¤íë ìê° (ms) 8039 * @param {Number} nDuration ìê° ê°ê²© ms 8040 */ 8041collie.AnimationDelay = collie.Class(/** @lends collie.AnimationDelay.prototype */{ 8042 /** 8043 * @constructs 8044 */ 8045 $init : function (fCallback, nDuration) { 8046 this.reset(); 8047 }, 8048 8049 /** 8050 * ê°ì ì´ê¸°í 8051 */ 8052 reset : function () { 8053 this._nFrameAtRunLastest = null; 8054 this._nRunningTime = null; 8055 this._nRunLastestTime = null; 8056 }, 8057 8058 /** 8059 * ì ëë©ì´ì ì ì¤í 8060 * 8061 * @param {Number} [nCurrentFrame] íì¬ ë ëë¬ íë ì, ê°ì´ ìì¼ë©´ ìëì¼ë¡ íì¬ ë ëë¬ íë ìì ê°ì ¸ ì¨ë¤ 8062 * @param {Number} [nFrameDuration] ì§íë íë ì ìê°(ms) 8063 */ 8064 run : function (nCurrentFrame, nFrameDuration) { 8065 if (nCurrentFrame === undefined) { 8066 nCurrentFrame = collie.Renderer.getInfo().frame; 8067 } 8068 8069 // stop ë ê²½ì° 8070 if (this._nFrameAtRunLastest > nCurrentFrame) { 8071 this.reset(); 8072 return; 8073 } 8074 8075 if (this._nFrameAtRunLastest === null) { 8076 this._nFrameAtRunLastest = nCurrentFrame; 8077 this._nRunLastestTime = 0; 8078 this._nRunningTime = 0; 8079 nFrameDuration = 0; 8080 } 8081 8082 this._nRunningTime += nFrameDuration; 8083 8084 // ì²ì ì¤íëë©´ ê¸°ë¡ 8085 if (this._nRunLastestTime + this._nDuration <= this._nRunningTime) { 8086 if (this._fCallback) { 8087 this._fCallback({ 8088 timer : this, 8089 frame : nCurrentFrame, 8090 duration : this._nDuration, 8091 runningTime : this._nRunningTime 8092 }); 8093 } 8094 8095 /** 8096 * ì ëë©ì´ì ì´ ëë¬ì ë ë°ì 8097 * @name collie.AnimationDelay#complete 8098 * @event 8099 */ 8100 this.complete(); 8101 } 8102 } 8103}, collie.Animation); 8104/** 8105 * íìë¼ì¸ 기ë°ì¼ë¡ ì ëë©ì´ì ì ì¤íìí´ 8106 * <a href="../tutorial/timer_timeline.html" target="_blank">íí ë¦¬ì¼ ë³´ê¸°</a> 8107 * 8108 * @see collie.Timer 8109 * @class collie.AnimationTimeline 8110 * @extends collie.Animation 8111 * @param {Array} aTimeline íìë¼ì¸ ë°°ì´ 8112 * @param {Object} [htOption] 8113 * @param {Object} [htOption.loop=1] ë°ë³µ íì, 0ì¼ ê²½ì° ë¬´í ë°ë³µ íë¤ 8114 * @example 8115 * // ìì±ê³¼ ëìì íìë¼ì¸ì ì ì 8116 * collie.Timer.timeline([ 8117 * [0, "delay", function () {}, 1000], 8118 * [10, "transition", function () {}, 1000, { from:1, to:1 }], 8119 * ]); 8120 * 8121 * @example 8122 * // ìì± í íìë¼ì¸ì ì ì 8123 * var timeline = collie.Timer.timeline(); 8124 * timeline.add(0, "delay", function () {}, 1000); 8125 * timeline.add(10, "transition", function () {}, 1000, { from:1, to:1 }); 8126 * 8127 * @example 8128 * // íìë¼ì¸ ì¡ì ì ìì 8129 * var timeline = collie.Timer.timeline(); 8130 * var action = timeline.add(0, "delay", function () {}, 1000); 8131 * timeline.remove(10); // 10msì ì¤íëë 모ë ì¡ì ì ìì 8132 * timeline.remove(10, action); // actionë§ ìì 8133 */
8134collie.AnimationTimeline = collie.Class(/** @lends collie.AnimationTimeline.prototype */{ 8135 /** 8136 * @constructs 8137 */ 8138 $init : function (aTimeline, htOption) { 8139 this.option("loop", 1); 8140 this.option(htOption || {}); 8141 this.setOptionEvent(htOption); 8142 this._htAnimations = {}; 8143 this._aTimeline = null; 8144 this._aRunningAnimation = null; 8145 this._nRunningTime = null; 8146 this._nCountCycle = 0; 8147 8148 if (aTimeline) { 8149 for (var i = 0, l = aTimeline.length; i < l; i++) { 8150 this.addTimeline.apply(this, aTimeline[i]); 8151 } 8152 } 8153 8154 this.reset(); 8155 }, 8156 8157 /** 8158 * íìë¼ì¸ì ì ëë©ì´ì ì ì¶ê° 8159 * 8160 * @param {Number} nStartTime ìì ìê°(ms) 8161 * @param {String|collie.Animation} ì ëë©ì´ì ì´ë¦ì´ë ì ëë©ì´ì ê°ì²´ë¥¼ ì§ì íë¤. 8162 * @param {Function|Object} fCallback ê° ì ëë©ì´ì ì ì°ì´ë ì¸ì, queue ì ëë©ì´ì ì¼ ê²½ì° ì²« ë²ì§¸ ììê° htOptionì´ ëë¤ 8163 * @param {Number} nDuration ê° ì ëë©ì´ì ì ì°ì´ë ì¸ì 8164 * @param {Object} htOption ê° ì ëë©ì´ì ì ì°ì´ë ì¸ì 8165 * @return {collie.Animation} ë§ë¤ì´ì§ ì ëë©ì´ì 8166 * @example 8167 * var timeline = collie.Timer.timeline(); 8168 * 8169 * // queue를 ì¬ì©íë ë°©ë² 8170 * var queue = timeline.add(0, "queue"); 8171 * queue.cycle(item, 1000, { from:0, to:9 }); 8172 * 8173 * // ì§ì Animation ê°ì²´ë¥¼ ìì± 8174 * timeline.add(100, new collie.AnimationCycle(item, 1000, { from:0, to:9 })); 8175 */ 8176 add : function (nStartTime, vType, fCallback, nDuration, htOption) { 8177 var oAnimation; 8178 8179 // ì ëë©ì´ì ì¸ì¤í´ì¤ ìì± 8180 switch (vType) { 8181 case "delay" : 8182 oAnimation = new collie.AnimationDelay(fCallback, nDuration, htOption); 8183 break; 8184 8185 case "repeat" : 8186 oAnimation = new collie.AnimationRepeat(fCallback, nDuration, htOption); 8187 break; 8188 8189 case "transition" : 8190 oAnimation = new collie.AnimationTransition(fCallback, nDuration, htOption); 8191 break; 8192 8193 case "cycle" : 8194 oAnimation = new collie.AnimationCycle(fCallback, nDuration, htOption); 8195 break; 8196 8197 case "queue" : 8198 oAnimation = new collie.AnimationQueue(fCallback /* htOptionì */); 8199 break; 8200 8201 default : 8202 if (vType instanceof collie.Animation) { 8203 oAnimation = vType; 8204 } else { 8205 throw new Error(vType + ' timer is not defined'); 8206 } 8207 } 8208 8209 this._addTimeline(nStartTime, oAnimation); 8210 return oAnimation; 8211 }, 8212 8213 /** 8214 * ì ëë©ì´ì ì¸ì¤í´ì¤ë¥¼ ì¶ê° 8215 * 8216 * @private 8217 * @param {Number} nStartTime ìì ìê°(ms) 8218 * @param {collie.Animation} oAnimation ì¶ê°ë ì ëë©ì´ì 8219 */ 8220 _addTimeline : function (nStartTime, oAnimation) { 8221 nStartTime = parseInt(nStartTime, 10); // ì ìë¡ ë³í 8222 this._htAnimations[nStartTime] = this._htAnimations[nStartTime] || []; 8223 this._htAnimations[nStartTime].push(oAnimation); 8224 8225 // ì´ë¯¸ ì´ê¸°í ëë¤ë©´ ë¤ì ì´ê¸°í 8226 if (this._aTimeline !== null) { 8227 this.reset(); 8228 } 8229 }, 8230 8231 /** 8232 * ë±ë¡ë íìë¼ì¸ì ì ê±°íë¤ 8233 * 8234 * @param {Number} nStartTime ìì ìê°(ms) 8235 * @param {collie.Animation} oTimer ì§ì¸ íì´ë¨¸, ê°ì´ ìì¼ë©´ í´ë¹ ìê°ë ì ë¶ë¥¼ ì§ì 8236 */ 8237 remove : function (nStartTime, oTimer) { 8238 nStartTime = parseInt(nStartTime, 10); // ì ìë¡ ë³í 8239 8240 if (this._htAnimations && this._htAnimations[nStartTime]) { 8241 for (var i = 0; i < this._htAnimations[nStartTime].length; i++) { 8242 if (typeof oTimer === "undefined" || oTimer === this._htAnimations[nStartTime][i]) { 8243 this._htAnimations[nStartTime][i].stop(); 8244 this._htAnimations[nStartTime].splice(i, 1); 8245 i--; 8246 8247 if (typeof oTimer !== "undefined") { 8248 break; 8249 } 8250 } 8251 } 8252 8253 // ì§ì ëë° ë ì´ì ê·¸ ìê°ëì íì´ë¨¸ê° ìì ê²½ì° ìì±ë Timelineë ì§ì 8254 if (this._htAnimations[nStartTime].length < 1) { 8255 delete this._htAnimations[nStartTime]; 8256 this._removeTimelineStartTime(nStartTime); 8257 } 8258 } 8259 }, 8260 8261 _removeTimelineStartTime : function (nStartTime) { 8262 if (this._aTimeline) { 8263 for (var i = 0, l = this._aTimeline.length; i < l; i++) { 8264 if (this._aTimeline[i] === nStartTime) { 8265 this._aTimeline.splice(i, 1); 8266 break; 8267 } 8268 } 8269 } 8270 }, 8271 8272 /** 8273 * íìë¼ì¸ì ì´ê¸°í 8274 * @private 8275 */ 8276 _initTimeline : function () { 8277 this._aTimeline = []; 8278 this._aRunningAnimation = []; 8279 8280 // ìì ìê°ì ë£ì 8281 for (var i in this._htAnimations) { 8282 this._aTimeline.push(parseInt(i, 10)); 8283 } 8284
8285 // ì ë ¬ 8286 this._aTimeline.sort(function (a, b) { 8287 return a - b; 8288 }); 8289 }, 8290 8291 /** 8292 * ë±ë¡ë ì ëë©ì´ì ì¸ì¤í´ì¤ë¥¼ ë°ííë¤ 8293 * 8294 * @param {Number} nStartTime ìì ìê°(ms) 8295 * @return {Array|Boolean} ë±ë¡ë ì ëë©ì´ì ì´ ìì¼ë©´ false를 ë°í, ë°í íìì íì ë°°ì´ì 8296 */ 8297 getAnimation : function (nStartTime) { 8298 nStartTime = parseInt(nStartTime, 10); // ì ìë¡ ë³í 8299 return (this._htAnimations && this._htAnimations[nStartTime]) ? this._htAnimations[nStartTime] : false; 8300 }, 8301 8302 /** 8303 * íì¬ê¹ì§ ì§íë ìê°ì ë°í 8304 * @return {Number} ms ì§íì´ ìë ìíë©´ 0ì ë°í 8305 */ 8306 getRunningTime : function () { 8307 return this._nRunningTime || 0; 8308 }, 8309 8310 /** 8311 * íì¬ê¹ì§ ë°ë³µë íì 8312 * @return {Number} 8313 */ 8314 getCycle : function () { 8315 return this._nCountCycle || 0; 8316 }, 8317 8318 /** 8319 * ê°ì ì´ê¸°í 8320 */ 8321 reset : function () { 8322 this._nFrameAtRunLastest = null; 8323 this._nRunningTime = null; 8324 this._aTimeline = null; 8325 this._aRunningAnimation = null; 8326 this._nCountCycle = 0; 8327 this._initTimeline(); 8328 }, 8329 8330 /** 8331 * ì ëë©ì´ì ì ì¤í 8332 * 8333 * @param {Number} [nCurrentFrame] íì¬ ë ëë¬ íë ì, ê°ì´ ìì¼ë©´ ìëì¼ë¡ íì¬ ë ëë¬ íë ìì ê°ì ¸ ì¨ë¤ 8334 * @param {Number} [nFrameDuration] ì§íë íë ì ìê°(ms) 8335 */ 8336 run : function (nCurrentFrame, nFrameDuration) { 8337 if (nCurrentFrame === undefined) { 8338 nCurrentFrame = collie.Renderer.getInfo().frame; 8339 } 8340 8341 // ë ëë¬ê° stop ë ê²½ì° 8342 if (this._nFrameAtRunLastest > nCurrentFrame) { 8343 this.reset(); 8344 return; 8345 } 8346 8347 // ìì íë ì ì ì¥ 8348 if (this._nFrameAtRunLastest === null) { 8349 this._nFrameAtRunLastest = nCurrentFrame; 8350 this._nRunningTime = 0; 8351 nFrameDuration = 0; 8352 } 8353 8354 this._nRunningTime += nFrameDuration; 8355 8356 // ì§íë ì¡ì ì´ ìì ê²½ì° ì¶ê° 8357 if (this._aTimeline.length > 0) { 8358 while (this._aTimeline[0] <= this._nRunningTime) { 8359 var nStartTime = this._aTimeline.shift(); 8360 8361 for (var i = 0, l = this._htAnimations[nStartTime].length; i < l; i++) { 8362 this._aRunningAnimation.push(this._htAnimations[nStartTime][i]); 8363 this._htAnimations[nStartTime][i].start(); 8364 } 8365 } 8366 } 8367 8368 // ì§íì¤ì¸ ì¡ì ì´ ìì ê²½ì° run ì ë¬ 8369 if (this._aRunningAnimation.length > 0) { 8370 for (var i = 0; i < this._aRunningAnimation.length; i++) { 8371 if (this._aRunningAnimation[i]) { 8372 this._aRunningAnimation[i].run(nCurrentFrame, nFrameDuration); 8373 } 8374 8375 if (!this._aRunningAnimation[i] || !this._aRunningAnimation[i].isPlaying()) { 8376 if (this._aRunningAnimation[i]) { 8377 this._aRunningAnimation[i].reset(); 8378 } 8379 8380 this._aRunningAnimation.splice(i, 1); 8381 i--; 8382 this._checkComplete(); 8383 } 8384 } 8385 } 8386 }, 8387 8388 _checkComplete : function () { 8389 // ëë¬ì¼ë©´ 8390 if (this._aRunningAnimation.length < 1 && this._aTimeline.length < 1) { 8391 this._nCountCycle++; 8392 8393 if (this._htOption.loop && this._htOption.loop <= this._nCountCycle) { 8394 /** 8395 * ê³íë 모ë ì ëë©ì´ì ê³¼ ë°ë³µ íìê° ëëë©´ ë°ì. loop=0ì¼ë¡ ì¤ì íë©´ ë°ìíì§ ìëë¤. 8396 * @name collie.AnimationTimeline#complete 8397 * @event 8398 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 8399 */ 8400 this.complete(); 8401 } else { 8402 /** 8403 * loopê° ìì ê²½ì° ëª¨ë íìë¼ì¸ ì¡ì ì´ í ë² ëë¬ì ë ë°ì 8404 * @name collie.AnimationTimeline#end 8405 * @event 8406 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 8407 */ 8408 this.fireEvent("end"); 8409 this._nFrameAtRunLastest = null; 8410 this._nRunningTime = null; 8411 this._aTimeline = null; 8412 this._aRunningAnimation = null; 8413 this._initTimeline(); 8414 } 8415 } 8416 } 8417}, collie.Animation); 8418/** 8419 * ê³íë ì¬ë¬ ì ëë©ì´ì ì ë¤ë£° ì ìë Queue 8420 * <a href="../tutorial/timer_queue.html" target="_blank">íí ë¦¬ì¼ ë³´ê¸°</a> 8421 * 8422 * @see collie.Timer 8423 * @class collie.AnimationQueue 8424 * @extends collie.Animation 8425 * @param {Object} [htOption] 8426 * @param {Object} [htOption.loop=1] í ë°ë³µ íì, 0ì¼ ê²½ì° ë¬´í ë°ë³µ íë¤ 8427 * @example 8428 * collie.Timer.queue({ loop : 1 }). 8429 * delay(function () {}, 1000). 8430 * transition(function () {}, 1000, { from : 1, to : 1 }); 8431 */
8432collie.AnimationQueue = collie.Class(/** @lends collie.AnimationQueue.prototype */{ 8433 /** 8434 * @constructs 8435 */ 8436 $init : function (htOption) { 8437 this.option("loop", 1); 8438 this.option(htOption || {}); 8439 this.setOptionEvent(htOption); 8440 this._aAnimations = []; 8441 this._fOnCompleteAnimation = this._onCompleteAnimation.bind(this); 8442 this.reset(); 8443 }, 8444 8445 /** 8446 * queueì delay ì ëë©ì´ì ì ì¶ê°íë¤ 8447 * @see collie.AnimationDelay 8448 * @return {collie.AnimationQueue} ë©ìë ì²´ì´ë ì¬ì© ê°ë¥ 8449 */ 8450 delay : function (fCallback, nDuration, htOption) { 8451 this._add(new collie.AnimationDelay(fCallback, nDuration, htOption)); 8452 return this; 8453 }, 8454 8455 /** 8456 * queueì repeat ì ëë©ì´ì ì ì¶ê°íë¤ 8457 * @see collie.AnimationRepeat 8458 * @return {collie.AnimationQueue} ë©ìë ì²´ì´ë ì¬ì© ê°ë¥ 8459 */ 8460 repeat : function (fCallback, nDuration, htOption) { 8461 this._add(new collie.AnimationRepeat(fCallback, nDuration, htOption)); 8462 return this; 8463 }, 8464 8465 /** 8466 * queueì transition ì ëë©ì´ì ì ì¶ê°íë¤ 8467 * @see collie.AnimationTransition 8468 * @return {collie.AnimationQueue} ë©ìë ì²´ì´ë ì¬ì© ê°ë¥ 8469 */ 8470 transition : function (fCallback, nDuration, htOption) { 8471 this._add(new collie.AnimationTransition(fCallback, nDuration, htOption)); 8472 return this; 8473 }, 8474 8475 /** 8476 * queueì cycle ì ëë©ì´ì ì ì¶ê°íë¤ 8477 * @see collie.AnimationCycle 8478 * @return {collie.AnimationQueue} ë©ìë ì²´ì´ë ì¬ì© ê°ë¥ 8479 */ 8480 cycle : function (fCallback, nDuration, htOption) { 8481 this._add(new collie.AnimationCycle(fCallback, nDuration, htOption)); 8482 return this; 8483 }, 8484 8485 /** 8486 * ë±ë¡ë ì ëë©ì´ì ì¸ì¤í´ì¤ë¥¼ ë°ííë¤ 8487 * 8488 * @param {Number} nIdx ë±ë¡ ìì (0~) 8489 * @return {collie.Animation} 8490 */ 8491 getAnimation : function (nIdx) { 8492 return this._aAnimations[nIdx] || false; 8493 }, 8494 8495 /** 8496 * ì ëë©ì´ì ì¸ì¤í´ì¤ë¥¼ ì¶ê° 8497 * 8498 * @private 8499 * @param {collie.Animation} oAnimation ì¶ê°ë ì ëë©ì´ì 8500 */ 8501 _add : function (oAnimation) { 8502 oAnimation.attach("complete", this._fOnCompleteAnimation); 8503 this._aAnimations.push(oAnimation); 8504 }, 8505 8506 /** 8507 * ê° ì ëë©ì´ì ì´ ì¢ ë£ëìì ë ì²ë¦¬íë ì´ë²¤í¸ í¸ë¤ë¬ 8508 * @private 8509 */ 8510 _onCompleteAnimation : function () { 8511 this.next(); 8512 }, 8513 8514 /** 8515 * ë¤ì ì ëë©ì´ì ì¼ë¡ ëê¸´ë¤ 8516 */ 8517 next : function () { 8518 if (this._nAnimationIdx === null) { 8519 this._nAnimationIdx = 0; 8520 } else { 8521 this._nAnimationIdx++; 8522 } 8523 8524 // ì¢ ë£ëë©´ 8525 if (this._nAnimationIdx >= this._aAnimations.length) { 8526 this._nCount++; 8527 8528 /** 8529 * ê³íë 모ë ì ëë©ì´ì ì´ ëë ë ë§ë¤ ë°ì, loop ì¤ì ê³¼ ê´ê³ ìì´ ë§¤ë² ì¼ì´ëë¤ 8530 * @name collie.AnimationQueue#end 8531 * @event 8532 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 8533 * @param {Object} oEvent.count íì¬ê¹ì§ ë°ë³µë íì 8534 */ 8535 this.fireEvent("end", { 8536 count : this._nCount 8537 }); 8538 8539 // loop ì¤ì ì´ ìì¼ë©´ ëë림 8540 if (!this._htOption.loop || this._htOption.loop > this._nCount) { 8541 this._nAnimationIdx = 0; 8542 } else { 8543 /** 8544 * ê³íë 모ë ì ëë©ì´ì ê³¼ ë°ë³µ íìê° ëëë©´ ë°ì. loop=0ì¼ë¡ ì¤ì íë©´ ë°ìíì§ ìëë¤. 8545 * @name collie.AnimationQueue#complete 8546 * @event 8547 * @param {Object} oEvent 기본 ì»´í¬ëí¸ ì´ë²¤í¸ ê°ì²´ 8548 */ 8549 this.complete(); 8550 return; 8551 } 8552 } 8553 8554 this._aAnimations[this._nAnimationIdx].stop(); 8555 this._aAnimations[this._nAnimationIdx].start(); 8556 }, 8557 8558 /** 8559 * ê°ì ì´ê¸°í 8560 */ 8561 reset : function () { 8562 this._nFrameAtRunLastest = null; 8563 this._nAnimationIdx = null; 8564 this._nCount = 0; 8565 }, 8566 8567 /** 8568 * ë±ë¡ë 모ë ì ëë©ì´ì ì ì ê±° 8569 */ 8570 removeAll : function () { 8571 this._aAnimations = []; 8572 this.reset(); 8573 }, 8574 8575 /** 8576 * íì¬ ì§í ì¤ì¸ ì ëë©ì´ì ê¹ì§ ë¨ê¸°ê³ ë머ì§ë¥¼ ì§ì 8577 */ 8578 removeAfter : function () { 8579 if (this._nAnimationIdx + 1 <= this._aAnimations.length - 1) { 8580 var count = this._aAnimations.length - (this._nAnimationIdx + 1); 8581 this._aAnimations.splice(this._nAnimationIdx + 1, count); 8582 } 8583 }, 8584 8585 /** 8586 * ì ëë©ì´ì ì ì¤í 8587 * 8588 * @param {Number} [nCurrentFrame] íì¬ ë ëë¬ íë ì, ê°ì´ ìì¼ë©´ ìëì¼ë¡ íì¬ ë ëë¬ íë ìì ê°ì ¸ ì¨ë¤ 8589 * @param {Number} [nFrameDuration] ì§íë íë ì ìê°(ms) 8590 */ 8591 run : function (nCurrentFrame, nFrameDuration) { 8592 // ë±ë¡ë ì ëë©ì´ì ì´ ìë ê²½ì°ìë ì§ëê° 8593 if (this._aAnimations.length < 1) { 8594 return; 8595 } 8596 8597 if (nCurrentFrame === undefined) { 8598 nCurrentFrame = collie.Renderer.getInfo().frame; 8599 } 8600 8601 // ë ëë¬ê° stop ë ê²½ì° 8602 if (this._nFrameAtRunLastest > nCurrentFrame) { 8603 this.reset(); 8604 return; 8605 } 8606 8607 // ììëì§ ììì ë ìì ìì ê¸°ë¡ 8608 if (this._nFrameAtRunLastest === null) { 8609 this._nFrameAtRunLastest = nCurrentFrame; 8610 } 8611 8612 if (this._nAnimationIdx === null) { 8613 this.next(); 8614 } 8615
8616 this._aAnimations[this._nAnimationIdx].run(nCurrentFrame, nFrameDuration); 8617 } 8618}, collie.Animation); 8619/** 8620 * Timer ëª©ë¡ 8621 * 8622 * @private 8623 * @class collie.TimerList 8624 */ 8625collie.TimerList = collie.Class(/** @lends collie.TimerList.prototype */{ 8626 /** 8627 * @constructs 8628 * @private 8629 */ 8630 $init : function () { 8631 this._aList = []; 8632 }, 8633 8634 /** 8635 * ì ëë©ì´ì ì¶ê° 8636 * 8637 * @param {collie.Animation} oAnimation 8638 */ 8639 add : function (oAnimation) { 8640 this._aList.unshift(oAnimation); // for문ì ê±°ê¾¸ë¡ ë리기 ìí´ ìììë¶í° ì½ì 8641 }, 8642 8643 /** 8644 * ì ëë©ì´ì ì ê±°(ë©ì¶¤ì´ë¼ê³ ë³´ë©´ ë¨) 8645 * 8646 * @param {collie.Animation} oAnimation ì ê±°í ì ëë©ì´ì ì¸ì¤í´ì¤ 8647 */ 8648 remove : function (oAnimation) { 8649 for (var i = 0, len = this._aList.length; i < len; i++) { 8650 if (this._aList[i] === oAnimation) { 8651 this._aList.splice(i, 1); 8652 break; 8653 } 8654 } 8655 }, 8656 8657 /** 8658 * ì ëë©ì´ì ì 모ë ì ê±° 8659 */ 8660 removeAll : function () { 8661 this._aList = []; 8662 }, 8663 8664 /** 8665 * ì ëë©ì´ì ì 모ë ë©ì¶¤ 8666 */ 8667 stopAll : function () { 8668 for (var i = 0, len = this._aList.length; i < len; i++) { 8669 this._aList[i].stop(); 8670 } 8671 }, 8672 8673 /** 8674 * ì ëë©ì´ì ì ì¤í 8675 * 8676 * @param {Number} nCurrentFrame íì¬ íë ìì Animation ì¸ì¤í´ì¤ì ì ë¬í¨ 8677 * @param {Number} nFrameDuration ì§íë íë ì ìê°(ms) 8678 */ 8679 run : function (nCurrentFrame, nFrameDuration) { 8680 // ë¤ìì ë¶í° ì¤íí´ì ì¤ê°ì ìì ëë forë¬¸ì´ ëìíëë¡ í¨ 8681 for (var i = this._aList.length - 1; i >= 0; i--) { 8682 if (this._aList[i]) { 8683 if (this._aList[i].isPlaying()) { 8684 this._aList[i].run(nCurrentFrame, nFrameDuration); 8685 } else { 8686 // ì ëë©ì´ì ì´ ì¤í ì¤ì´ ìëë°ë 리ì¤í¸ì ìë¤ë©´ ì ê±° 8687 this._aList.splice(i, 1); 8688 } 8689 } 8690 } 8691 } 8692}); 8693/** 8694 * íì´ë¨¸ë¥¼ ìì± / ê´ë¦¬. 모ë íì´ë¨¸ë collie.Timerìì ìì±íë¤ 8695 * @namespace 8696 */ 8697collie.Timer = collie.Timer || new (collie.Class(/** @lends collie.Timer */{ 8698 $init : function () { 8699 this._oList = new collie.TimerList(); 8700 }, 8701 8702 /** 8703 * ë ëë¬ìì ë ëë§ í기 ì ì íì´ë¨¸ë¥¼ ì¤í íë¤. 8704 * 8705 * @param {Number} nCurrentFrame íì¬ íë ì 8706 * @param {Number} nFrameDuration ì§íë íë ì ìê°(ms) 8707 */ 8708 run : function (nCurrentFrame, nFrameDuration) { 8709 this._oList.run(nCurrentFrame, nFrameDuration); 8710 }, 8711 8712 /** 8713 * ì 체를 ë©ì¶ë¤ 8714 * - ê°ë³ì ì¼ë¡ ë©ì¶ëê±´ ê°ê° íì´ë¨¸ ì¸ì¤í´ì¤ìì stopì í¸ì¶ 8715 */ 8716 stopAll : function () { 8717 this._oList.stopAll(); 8718 }, 8719 8720 /** 8721 * ì ì²´ íì´ë¨¸ë¥¼ ì ê±° íë¤ 8722 */ 8723 removeAll : function () { 8724 this._oList.removeAll(); 8725 }, 8726 8727 /** 8728 * @see collie.AnimationQueue 8729 * @arguments collie.AnimationQueue 8730 * @return {collie.AnimationQueue} 8731 */ 8732 queue : function (htOption) { 8733 var oAnimation = new collie.AnimationQueue(htOption); 8734 oAnimation.setTimerList(this._oList); 8735 return oAnimation; 8736 }, 8737 8738 /** 8739 * @see collie.AnimationRepeat 8740 * @arguments collie.AnimationRepeat 8741 * @return {collie.AnimationRepeat} 8742 */ 8743 repeat : function (fCallback, nDuration, htOption) { 8744 var oAnimation = new collie.AnimationRepeat(fCallback, nDuration, htOption); 8745 oAnimation.setTimerList(this._oList); 8746 return oAnimation; 8747 }, 8748 8749 /** 8750 * @see collie.AnimationTransition 8751 * @arguments collie.AnimationTransition 8752 * @return {collie.AnimationTransition} 8753 */ 8754 transition : function (fCallback, nDuration, htOption) { 8755 var oAnimation = new collie.AnimationTransition(fCallback, nDuration, htOption); 8756 oAnimation.setTimerList(this._oList); 8757 return oAnimation; 8758 }, 8759 8760 /** 8761 * @see collie.AnimationCycle 8762 * @arguments collie.AnimationCycle 8763 * @return {collie.AnimationCycle} 8764 */ 8765 cycle : function (fCallback, nDuration, htOption) { 8766 var oAnimation = new collie.AnimationCycle(fCallback, nDuration, htOption); 8767 oAnimation.setTimerList(this._oList); 8768 return oAnimation; 8769 }, 8770 8771 /** 8772 * @see collie.AnimationDelay 8773 * @arguments collie.AnimationDelay 8774 * @return {collie.AnimationDelay} 8775 */ 8776 delay : function (fCallback, nDuration, htOption) { 8777 var oAnimation = new collie.AnimationDelay(fCallback, nDuration, htOption); 8778 oAnimation.setTimerList(this._oList); 8779 return oAnimation; 8780 }, 8781 8782 /** 8783 * @see collie.AnimationTimeline 8784 * @arguments collie.AnimationTimeline 8785 * @return {collie.AnimationTimeline} 8786 */ 8787 timeline : function (aTimeline, htOption) { 8788 var oAnimation = new collie.AnimationTimeline(aTimeline, htOption); 8789 oAnimation.setTimerList(this._oList); 8790 return oAnimation; 8791 } 8792}))(); 8793/**
8794 * Layer를 ë±ë¡í´ì 그리ë ë ëë§ íì´íë¼ì¸ 8795 * @namespace 8796 * @TODO frameì 기ë¡íë í´ëì¤ì ê²½ì° stopëê³ ë¤ì ììëë©´ 0ë¶í° ììíë¯ë¡ 8797ìê¸°ê° ê¸°ë¡í frameì´ íì¬ frameë³´ë¤ í´ ë ë³´ì ì²ë¦¬ë¥¼ ë°ëì í´ì¤ì¼ íë¤. 8798ì´ë ëì¤ì frameì´ int íì¹´ì´í¸ê° ëìì ë ì²ë¦¬ê° ììì§ë 모르ë¯ë¡ íì 8799 */ 8800collie.Renderer = collie.Renderer || new (collie.Class(/** @lends collie.Renderer */{ 8801 /** 8802 * 기본 ë ëë§ FPS 8803 * @type {String} 8804 */ 8805 DEFAULT_FPS : "60fps", 8806 8807 /** 8808 * ë í°ë ëì¤íë ì´ ì¬ë¶ auto ê°ì¼ ê²½ì° ìë íë¨, true/false ê°ì ìë 8809 * @type {String|Boolean} auto ì¼ ë ìë íë¨ ë¨ 8810 */ 8811 RETINA_DISPLAY : false, 8812 8813 /** 8814 * ì´ ê°ì trueë¡ ë³ê²½íë©´ ê°ì ëë ì´ë¥¼ ë°ìí ì ìë¤. 8815 * ê°ì ëë ì´ ë°ì ìíììë requestAnimationFrameì´ ëìíì§ ìì¼ë©° 8816 * íì´ë¨¸ ë±ì´ ì¤íµë ë ì´ë»ê² ëìíëì§ íì¸í ì ìë¤. 8817 * 8818 * @type {Boolean} 8819 * @example 8820 * collie.Renderer.DEBUG_USE_DELAY = true; 8821 * collie.Renderer.DEBUG_MAX_DELAY = 200; 8822 * collie.Renderer.start(); 8823 */ 8824 DEBUG_USE_DELAY : false, 8825 8826 /** 8827 * ê°ì ëë ì´ ìµëê°(ëë¤íê² ë°ì, ms) 8828 * @type {Number} 8829 */ 8830 DEBUG_MAX_DELAY : 200, 8831 8832 /** 8833 * ë ëë§ ëª¨ë [auto|canvas|dom] 8834 * @type {String} 8835 */ 8836 DEBUG_RENDERING_MODE : "auto", 8837 8838 $init : function () { 8839 this._sVisibilityChange = this._getNamePageVisibility(); 8840 this._bPlaying = false; 8841 this._bPause = false; 8842 this._nFPS = 0; 8843 this._nDuration = 0; // ms 8844 this._nCurrentFrame = 0; 8845 this._nSkippedFrame = 0; 8846 this._nBeforeFrameTime = null; // ms 8847 this._nBeforeRenderingTime = 0; // ms 8848 this._aLayerList = []; 8849 this._fRender = this._render.bind(this); 8850 this._fCallback = null; 8851 this._htCallback = {}; 8852 this._elContainer = document.createElement("div"); 8853 this._elContainer.className = "_collie_container"; 8854 this._elContainer.style.position = "relative"; 8855 this._elContainer.style.overflow = "hidden"; 8856 this._elParent = null; 8857 this._nDebugDelayedTime = 0; 8858 this._oRenderingTimer = null; 8859 this._bLoaded = false; 8860 this._sRenderingMode = null; 8861 this._bUseRetinaDisplay = null; 8862 this._htEventStatus = {}; 8863 this._htPosition = {}; 8864 this._bIsPreventDefault = true; 8865 this._htDeviceInfo = collie.util.getDeviceInfo(); 8866 8867 // PageVisibility API를 ì¬ì©í ì ìë¤ë©´ ì¬ì© 8868 if (this._sVisibilityChange) { 8869 collie.util.addEventListener(document, this._sVisibilityChange, this._onChangeVisibility.bind(this)); 8870 // 모ë°ì¼ì´ë¼ë©´ pageshow/pagehide를 ì¬ì© 8871 // In-App Browserì¼ ë pageshow/pagehideê° ì ìì ì¼ë¡ í¸ì¶ ìëë 문ì ì ì´ ìì 8872 } else if (!this._htDeviceInfo.desktop) { 8873 collie.util.addEventListener(window, "pageshow", this._onPageShow.bind(this)); 8874 collie.util.addEventListener(window, "pagehide", this._onPageHide.bind(this)); 8875 } 8876 8877 // ë ëë¬ ì리먼í¸ì ìì¹ë¥¼ ì ì¥í´ ëëë¤ 8878 collie.util.addEventListener(window, "resize", this.refresh.bind(this)); 8879 }, 8880 8881 /** 8882 * íì´ì§ë¥¼ ì§ì í ë ë ëë¬ ì²ë¦¬ 8883 * @private 8884 */ 8885 _onPageShow : function () { 8886 if (!this.isPlaying() && this._bPause) { 8887 this.resume(); 8888 } 8889 }, 8890 8891 /** 8892 * íì´ì§ë¥¼ ì´íí ë ë ëë¬ ì²ë¦¬ 8893 * @private 8894 */ 8895 _onPageHide : function () { 8896 if (this.isPlaying()) { 8897 this.pause(); 8898 } 8899 }, 8900 8901 /** 8902 * @private 8903 */ 8904 _onChangeVisibility : function () { 8905 var state = document.visibilityState || document.webkitVisibilityState || document.mozVisibilityState; 8906 8907 if (state === "hidden") { 8908 this.pause(); 8909 } else if (state === "visible") { 8910 this.resume(); 8911 } 8912 }, 8913 8914 /** 8915 * ë ëë§ ì리먼í¸ì ìì¹ë¥¼ ê°±ì íë¤ 8916 * ë§ì¼ ë ëë§ ì리먼í¸ì ìì¹ê° load íì ë³ê²½ë ê²½ì° refresh ë©ìë를 ì¤íìì¼ì¤ì¼ íë¤ 8917 */ 8918 refresh : function () { 8919 if (this._elParent !== null) { 8920 this._htPosition = collie.util.getPosition(this._elParent); 8921 } 8922 }, 8923 8924 /** 8925 * ë ëë¬ ì리먼í¸ì íì¬ ìì¹ë¥¼ ë°í 8926 * ë ëë¬ê° loadëì§ ììë¤ë©´ false를 ë°í 8927 * 8928 * @private 8929 * @return {Object|Boolean} htResult 8930 * @return {Number} htResult.x íì´ì§ ì²ìë¶í°ì xì¢í 8931 * @return {Number} htResult.y íì´ì§ ì²ìë¶í°ì yì¢í 8932 * @return {Number} htResult.width ëë¹ 8933 * @return {Number} htResult.height ëì´ 8934 */ 8935 getPosition : function () { 8936 return this._bLoaded ? this._htPosition : false;
8937 }, 8938 8939 /** 8940 * ë ëë¬ì ì ì©í ë ì´ì´ë¥¼ ì¶ê° íë¤ 8941 * 8942 * @param {collie.Layer} oLayer 8943 */ 8944 addLayer : function (oLayer) { 8945 if (!oLayer || !("type" in oLayer) || oLayer.type !== "layer") { 8946 throw new Error('oLayer is not Layer instnace'); 8947 } 8948 8949 // ì´ë¯¸ ì¶ê°ë ë ì´ì´ë¼ë©´ 무ì 8950 for (var i = 0, len = this._aLayerList.length; i < len; i++) { 8951 if (this._aLayerList[i] === oLayer) { 8952 return; 8953 } 8954 } 8955 8956 this._aLayerList.push(oLayer); 8957 8958 // ë¡ëë ìíììë ìëì¼ë¡ ë¶ê¸° 8959 if (this._bLoaded) { 8960 oLayer.load(this._elContainer, this._aLayerList.length); 8961 this.resetLayerEvent(); 8962 } 8963 }, 8964 8965 /** 8966 * ë ëë¬ì ì ì©í ë ì´ì´ë¥¼ ì ê±° íë¤ 8967 * 8968 * @param {collie.Layer} oLayer 8969 */ 8970 removeLayer : function (oLayer) { 8971 for (var i = 0, len = this._aLayerList.length; i < len; i++) { 8972 if (this._aLayerList[i] === oLayer) { 8973 this._aLayerList[i].unload(); // ë¡ë©ëì´ ìì¼ë©´ í´ì ìí´ 8974 this._aLayerList.splice(i, 1); 8975 return; 8976 } 8977 } 8978 }, 8979 8980 /** 8981 * ë±ë¡ë 모ë ë ì´ì´ë¥¼ ì ê±° íë¤ 8982 */ 8983 removeAllLayer : function () { 8984 for (var i = this._aLayerList.length - 1; i >= 0; i--) { 8985 this._aLayerList[i].unload(); 8986 } 8987 8988 this._aLayerList = []; 8989 }, 8990 8991 /** 8992 * ë±ë¡ë ë ì´ì´ë¥¼ 모ë ë°í 8993 * 8994 * @return {Array} 8995 */ 8996 getLayers : function () { 8997 return this._aLayerList; 8998 }, 8999 9000 /** 9001 * ì´ë²¤í¸ë¥¼ 모ë í´ì íê³ ë¤ì ê±´ë¤ 9002 * @private 9003 */ 9004 resetLayerEvent : function () { 9005 for (var i = 0, len = this._aLayerList.length; i < len; i++) { 9006 this._aLayerList[i].detachEvent(); 9007 } 9008 9009 // ë ì´ì´ ììì¼ë¡ ì´ë²¤í¸ê° ëìí´ì¼ í기 ë문ì ì´ë²¤í¸ë ììì¼ë¡ ê±´ë¤ 9010 for (var i = this._aLayerList.length - 1; i >= 0; i--) { 9011 this._aLayerList[i].attachEvent(); 9012 } 9013 }, 9014 9015 /** 9016 * ë ëë¬ì 컨í ì´ë ì리먼í¸ë¥¼ ë°í 9017 * @return {HTMLElement} 9018 */ 9019 getElement : function () { 9020 return this._elContainer; 9021 }, 9022 9023 /** 9024 * ë ëë¬ì ì ì©ë ìê°ì ë°í 9025 * 9026 * @return {Number} ms 9027 */ 9028 getDuration : function () { 9029 return this._nDuration; 9030 }, 9031 9032 /** 9033 * ë ëë¬ ì 보를 ë°í 9034 * 9035 * @return {Object} htInfo 9036 * @return {Number} htInfo.frame íì¬ íë ì ì 9037 * @return {Number} htInfo.skippedFrame ì§ëê° ëì íë ì ì 9038 * @return {Number} htInfo.fps 9039 * @return {Number} htInfo.duration ì§ì°ìê°(ms) 9040 * @return {Number} htInfo.renderingTime ì´ì ì ë°ìíë ë ëë§ ìê°(ms) 9041 * @return {Number} htInfo.beforeFrameTime ì´ì ì ë ëë¬ê° ì¤íëë ìê°(timestamp) 9042 */ 9043 getInfo : function () { 9044 // ê°ì²´ ì¬íì© 9045 this._htCallback.frame = this._nCurrentFrame; 9046 this._htCallback.skippedFrame = this._nSkippedFrame; 9047 this._htCallback.fps = this._nFPS; 9048 this._htCallback.duration = this._nDuration; 9049 this._htCallback.renderingTime = this._nBeforeRenderingTime; 9050 this._htCallback.beforeFrameTime = this._nBeforeFrameTime; 9051 return this._htCallback; 9052 }, 9053 9054 /** 9055 * ë ëë§ ëª¨ë를 ë°í 9056 * - ëê°ì ë°©ìì ìì´ ì°ë ê²ì ìëê° ëë ¤ì 1ê°ì§ ë°©ìì ì¬ì©íë ê²ì´ ë«ë¤ 9057 * @return {String} [dom|canvas] 9058 */ 9059 getRenderingMode : function () { 9060 if (this._sRenderingMode === null) { 9061 var htDeviceInfo = collie.util.getDeviceInfo(); 9062 this._sRenderingMode = this.DEBUG_RENDERING_MODE; 9063 9064 if (!this._sRenderingMode || this._sRenderingMode === "auto") { 9065 // ìëë¡ì´ë 2.2 미ë§, ìºë²ì¤ë¥¼ ì§ìíì§ ìê±°ë ios 5 미ë§ì¸ ê²½ì° 9066 // ìëë¡ì´ë 4 ë²ì ëìì DOM ë¶ìì ì±ì´ ë°ê²¬ë¨ 9067 // ìëë¡ì´ë 4.2.2 galaxy S4 ë¶í° canvasê° ë 빨ë¼ì§ 9068 if ( 9069 ( 9070 htDeviceInfo.android && !htDeviceInfo.chrome && ( 9071 (htDeviceInfo.android < 4.2 && htDeviceInfo.android >= 3) || 9072 htDeviceInfo.android < 2.2 9073 ) 9074 ) || 9075 !htDeviceInfo.supportCanvas || 9076 (htDeviceInfo.ios && htDeviceInfo.ios < 5) 9077 ) { 9078 this._sRenderingMode = "dom"; 9079 } else { 9080 this._sRenderingMode = "canvas"; 9081 } 9082 } 9083 9084 // ìºë²ì¤ë¥¼ ì§ìíì§ ìì¼ë©´ 무조건 DOM 모ëë¡ 9085 if (!htDeviceInfo.supportCanvas) { 9086 this._sRenderingMode = "dom"; 9087 } 9088 } 9089 9090 return this._sRenderingMode; 9091 }, 9092 9093 /** 9094 * ë ëë§ ëª¨ë를 ë³ê²½ íë¤ 9095 * 9096 * @param {String} sMode [auto|dom|canvas] 9097 * @example collie를 ì¬ì©í기 ì ì ì¬ì©í´ì¼ íë¤. 9098 * collie.Renderer.setRenderingMode("dom"); 9099 * collie.ImageManager.add({ 9100 * ... 9101 * }, function () { 9102 * ... 9103 * }); 9104 */ 9105 setRenderingMode : function (sMode) { 9106 this.DEBUG_RENDERING_MODE = sMode.toString().toLowerCase(); 9107 this._sRenderingMode = null; 9108 }, 9109 9110 /** 9111 * ë í°ë ëì¤íë ì´ë¥¼ ì¬ì©íê³ ìëì§ ì¬ë¶ 9112 * IE9 미ë§ììë 무조건 false를 ë°í 9113 * 9114 * @return {Boolean} 9115 */ 9116 isRetinaDisplay : function () { 9117 if (this._bUseRetinaDisplay === null) { 9118 // android 4.0 ì´ìë retina ì§ì ì¶ê° 9119 this._bUseRetinaDisplay = this.RETINA_DISPLAY !== "auto" ? this.RETINA_DISPLAY : window.devicePixelRatio >= 2 && (!collie.util.getDeviceInfo().android || collie.util.getDeviceInfo().android >= 4); 9120 var htDeviceInfo = collie.util.getDeviceInfo(); 9121 9122 // background-size를 ì§ìíì§ ìë ìíìì ê³ í´ìë ëì¤íë ì´ ëª¨ë ì¬ì©í ì ìì 9123 if (htDeviceInfo.ie && htDeviceInfo.ie < 9) { 9124 this._bUseRetinaDisplay = false;
9125 } 9126 } 9127 9128 return this._bUseRetinaDisplay; 9129 }, 9130 9131 /** 9132 * ë í°ë ëì¤íë ì´ ë°©ìì ë³ê²½ íë¤ 9133 * @param {Boolean|String} vMode [false|true|"auto"] 9134 * @example collie를 ì¬ì©í기 ì ì ì¬ì©í´ì¼ íë¤. 9135 * collie.Renderer.setRetinaDisplay(true); 9136 * collie.ImageManager.add({ 9137 * ... 9138 * }, function () { 9139 * ... 9140 * }); 9141 */ 9142 setRetinaDisplay : function (vMode) { 9143 this.RETINA_DISPLAY = vMode; 9144 this._bUseRetinaDisplay = null; 9145 }, 9146 9147 /** 9148 * requestAnimationFrame ì¬ì© ì¬ë¶ ë°í 9149 * 9150 * @private 9151 * @param {Boolean} bCancelName trueë©´ CancelAnimationFrame ì´ë¦ì ë°í 9152 * @return {bool|String} ì¬ì© ê°ë¥íë©´ í¨ìëª ì ë°í 9153 */ 9154 _getNameAnimationFrame : function (bCancelName) { 9155 if (typeof window.requestAnimationFrame !== "undefined") { 9156 return bCancelName ? "cancelAnimationFrame" : "requestAnimationFrame"; 9157 } else if (typeof window.webkitRequestAnimationFrame !== "undefined") { 9158 return bCancelName ? "webkitCancelAnimationFrame" : "webkitRequestAnimationFrame"; 9159 } else if (typeof window.msRequestAnimationFrame !== "undefined") { 9160 return bCancelName ? "msCancelAnimationFrame" : "msRequestAnimationFrame"; 9161 } else if (typeof window.mozRequestAnimationFrame !== "undefined") { 9162 return bCancelName ? "mozCancelAnimationFrame" : "mozRequestAnimationFrame"; 9163 } else if (typeof window.oRequestAnimationFrame !== "undefined") { 9164 return bCancelName ? "oCancelAnimationFrame" : "oRequestAnimationFrame"; 9165 } else { 9166 return false; 9167 } 9168 }, 9169 9170 /** 9171 * Page Visibility Event ì´ë¦ì ë°í 9172 * @private 9173 * @return {String|Boolean} 9174 */ 9175 _getNamePageVisibility : function () { 9176 if ("hidden" in document) { 9177 return "visibilitychange"; 9178 } else if ("webkitHidden" in document) { 9179 return "webkitvisibilitychange"; 9180 } else if ("mozHidden" in document) { 9181 return "mozvisibilitychange"; 9182 } else { 9183 return false; 9184 } 9185 }, 9186 9187 /** 9188 * ííí ë ì´ì´ë¥¼ elParentì ë¶ì¸ë¤ ììì ì ë°ëì í´ì¼í¨ 9189 * 9190 * @param {HTMLElement} elParent 9191 */ 9192 load : function (elParent) { 9193 this.unload(); 9194 this._bLoaded = true; 9195 this._elParent = elParent; 9196 this._elParent.appendChild(this._elContainer); 9197 this.refresh(); 9198 9199 if (this._aLayerList.length) { 9200 for (var i = 0, len = this._aLayerList.length; i < len; i++) { 9201 this._aLayerList[i].load(this._elContainer, i); 9202 } 9203 9204 // ë ì´ì´ ììì¼ë¡ ì´ë²¤í¸ê° ëìí´ì¼ í기 ë문ì ì´ë²¤í¸ë ììì¼ë¡ ê±´ë¤ 9205 for (var i = this._aLayerList.length - 1; i >= 0; i--) { 9206 this._aLayerList[i].attachEvent(); 9207 } 9208 } 9209 9210 }, 9211 9212 /** 9213 * ë¶ëª¨ ì리먼í¸ì ë¶ì¸ ë ì´ì´ë¥¼ ì§ì 9214 */ 9215 unload : function () { 9216 if (this._bLoaded) { 9217 for (var i = 0, len = this._aLayerList.length; i < len; i++) { 9218 this._aLayerList[i].unload(); 9219 } 9220 9221 this._elParent.removeChild(this._elContainer); 9222 this._elParent = null; 9223 this._bLoaded = false; 9224 } 9225 }, 9226 9227 /** 9228 * ë ëë§ ìì 9229 * - callback ììì false를 ë°ííë©´ renderingì ë©ì¶ë¤ 9230 * 9231 * @param {Number|String} vDuration ë ëë¬ì ìê° ê°ê²©(ms), fps를 ë¶ì´ë©´ fps ë¨ìë¡ ì ë ¥ëë¤. 9232 * @param {Function} fCallback íë ìë§ë¤ ì¤íí í¨ì, ìì´ë ëê³ process ì´ë²¤í¸ë¥¼ ë°ìì ì²ë¦¬í´ë ëë¤. 9233 * @param {Number} fCallback.frame íì¬ íë ì 9234 * @param {Number} fCallback.skippedFrame ìê°ì´ ë°ë ¤ì ì§ëê° íë ì ì 9235 * @param {Number} fCallback.fps FPS 9236 * @param {Number} fCallback.duration ì§ì° ìê° (ms) 9237 * @example 9238 * fps를 ë¶ì´ë©´ FPSë¨ìë¡ ì ë ¥í ì ìë¤. 9239 * <code> 9240 * collie.Renderer.start("30fps"); 9241 * collie.Renderer.start(1000 / 30); 9242 * </code> 9243 */ 9244 start : function (vDuration, fCallback) { 9245 if (!this._bPlaying) { 9246 // this.stop(); 9247 vDuration = vDuration || this.DEFAULT_FPS; 9248 this._nDuration = (/fps$/i.test(vDuration)) ? 1000 / parseInt(vDuration, 10) : Math.max(16, vDuration); 9249 this._fCallback = fCallback || null; 9250 this._bPlaying = true; 9251 9252 // FPSê° 60ì¼ ëë§ requestAnimationFrameì ì¬ì©íë¤ 9253 if (this._nDuration < 17) { 9254 this._sRequestAnimationFrameName = this._getNameAnimationFrame(); 9255 this._sCancelAnimationFrameName = this._getNameAnimationFrame(true); 9256 } else { 9257 this._sRequestAnimationFrameName = false;
9258 this._sCancelAnimationFrameName = false; 9259 } 9260 9261 /** 9262 * ë ëë§ ìì 9263 * @name collie.Renderer#start 9264 * @event 9265 * @param {Object} oEvent 9266 */ 9267 this.fireEvent("start"); 9268 this._trigger(0); 9269 } 9270 9271 }, 9272 9273 _trigger : function (nDelay) { 9274 if (!this._sVisibilityChange) { 9275 if (window.screenTop < -30000) { 9276 this.pause(); 9277 } 9278 } 9279 9280 if (typeof nDelay === "undefined") { 9281 nDelay = 0; 9282 } else { 9283 nDelay = parseInt(nDelay, 10); 9284 } 9285 9286 // ê°ì ëë ì´ë¥¼ ì ì©íë ¤ë©´ requestAnimationFrameì ì ê±° 9287 if (this._sRequestAnimationFrameName !== false && !this.DEBUG_USE_DELAY) { 9288 this._oRenderingTimer = window[this._sRequestAnimationFrameName](this._fRender); 9289 } else { 9290 this._oRenderingTimer = setTimeout(this._fRender, nDelay); 9291 } 9292 }, 9293 9294 /** 9295 * ì¤ì íë©´ì ë ëë§ 9296 * 9297 * @private 9298 * @param {Number} nSkippedFrame collie.Renderer#draw ìì ëì´ì¨ ì¸ì 9299 * @param {Boolean} ì¤íì¤ ì¬ë¶ì ê´ê³ ìì´ ê·¸ë¦¼ 9300 */ 9301 _render : function (nSkippedFrame, bForcePlay) { 9302 // stop ìì ì´ ë¹ë기ë¼ì ìì ì´ ìë§ì ìë ìì. ë ëë§ì´ ë°ë¡ ì¤ë¨ëì¼ í¨ 9303 if (!this._bPlaying && !bForcePlay) { 9304 return; 9305 } 9306 9307 var nTime = this._getDate(); 9308 var nRealDuration = 0; 9309 var nFrameStep = 1; // ì§íí íë ì ë¨ê³ 9310 9311 // ì§íë íë ìì´ë©´ ìê° ê³ì° 9312 if (this._nBeforeFrameTime !== null) { 9313 nRealDuration = nTime - this._nBeforeFrameTime; // ì¤ì 걸린 ìê° 9314 nFrameStep = nSkippedFrame || Math.max(1, Math.round(nRealDuration / this._nDuration)); // 60fps 미ë§ì¼ë¡ë ë²ë¦°ë¤ 9315 9316 // requestAnimationFrame ì¸ìê° ë¤ì´ì´ 9317 if (this._sRequestAnimationFrameName !== false) { 9318 nSkippedFrame = 0; 9319 nFrameStep = 1; 9320 } 9321 9322 this._nSkippedFrame += Math.max(0, nFrameStep - 1); 9323 this._nFPS = Math.round(1000 / (nTime - this._nBeforeFrameTime)); 9324 } 9325 9326 this._nCurrentFrame += nFrameStep; 9327 var htInfo = this.getInfo(); 9328 9329 // callbackì´ ìê±°ë callback ì¤í ê²°ê³¼ê° falseê° ìëê±°ë process ì´ë²¤í¸ stopì´ ë°ì ìí ê²½ì°ìë§ ì§í 9330 /** 9331 * ë ëë§ ì§í 9332 * @name collie.Renderer#process 9333 * @event 9334 * @param {Object} oEvent 9335 * @param {Function} oEvent.stop stop íë©´ ë ëë§ì´ ë©ì¶ë¤ 9336 */ 9337 if ((this._fCallback === null || this._fCallback(htInfo) !== false) && this.fireEvent("process", htInfo) !== false) { 9338 collie.Timer.run(this._nCurrentFrame, nRealDuration); 9339 this._update(nRealDuration); 9340 var nDebugDelayedTime = 0; 9341 9342 // ê°ì ëë ì´ ì ì© 9343 if (this.DEBUG_USE_DELAY) { 9344 nDebugDelayedTime = Math.round(Math.random() * this.DEBUG_MAX_DELAY); 9345 this._nDebugDelayedTime += nDebugDelayedTime; 9346 } 9347 9348 this._nBeforeRenderingTime = this._getDate() - nTime; 9349 this._nBeforeFrameTime = nTime; 9350 9351 if (this._bPlaying) { 9352 this._trigger(Math.max(0, this._nDuration - this._nBeforeRenderingTime + nDebugDelayedTime * 2)); 9353 } 9354 } else { 9355 this.stop(); 9356 } 9357 }, 9358 9359 /** 9360 * ìíë íë ìì¼ë¡ ì¤íµí´ì ê·¸ë¦°ë¤ 9361 * 9362 * @param {Number} nSkippedFrame ê°ì´ ìì¼ë©´ ì¤íµ ìì´, ê°ì´ ìì¼ë©´ ê·¸ ê°ë§í¼ íë ìì ì¤íµí´ì ê·¸ë¦°ë¤ 9363 */ 9364 draw : function (nSkippedFrame) { 9365 this._fRender(nSkippedFrame, true); 9366 }, 9367 9368 /** 9369 * íì¬ ìê°ì ê°ì ¸ ì¨ë¤ 9370 * @private 9371 * @return {Number} timestamp 9372 */ 9373 _getDate : function () { 9374 return (+new Date()) + (this.DEBUG_USE_DELAY ? this._nDebugDelayedTime : 0); 9375 }, 9376 9377 /** 9378 * ë ëë§ì ë©ì¶ë¤ 9379 */ 9380 stop : function () { 9381 if (this._bPlaying) { 9382 this._bPlaying = false; 9383 this._resetTimer(); 9384 9385 /** 9386 * ë ëë§ ë©ì¶¤ 9387 * @name collie.Renderer#stop 9388 * @event 9389 * @param {Object} oEvent 9390 */ 9391 this.fireEvent("stop", this.getInfo()); 9392 9393 this._sRenderingMode = null; 9394 this._bUseRetinaDisplay = null; 9395 this._fCallback = null; 9396 this._nCurrentFrame = 0; 9397 this._nBeforeRenderingTime = 0; 9398 this._nSkippedFrame = 0; 9399 this._nBeforeFrameTime = null; 9400 } 9401 }, 9402 9403 _resetTimer : function () { 9404 if (this._oRenderingTimer !== null) { 9405 if (this._sCancelAnimationFrameName !== false) { 9406 window[this._sCancelAnimationFrameName](this._oRenderingTimer); 9407 } else { 9408 clearTimeout(this._oRenderingTimer); 9409 } 9410 9411 //TODO debug 9412 window.tempTimer = window.tempTimer || []; 9413 window.tempTimer.push(this._oRenderingTimer); 9414 this._oRenderingTimer = null; 9415 } 9416 }, 9417 9418 /** 9419 * ì ì ë©ì¶ë¤ 9420 */ 9421 pause : function () { 9422 if (this._bPlaying) { 9423 this._bPlaying = false;
9424 this._bPause = true; 9425 9426 /** 9427 * ë ëë¬ê° ì¼ì ì ì§ ë ë°ì. getInfo ê°ì´ ì´ë²¤í¸ ì¸ìë¡ ëì´ê°ë¤ 9428 * @name collie.Renderer#pause 9429 * @event 9430 * @see collie.Renderer.getInfo 9431 */ 9432 this.fireEvent("pause", this.getInfo()); 9433 9434 // ì§íëê³ ìë íì´ë¨¸ë¥¼ í´ì 9435 this._resetTimer(); 9436 } 9437 }, 9438 9439 /** 9440 * ì ì ë©ì¶ê²ì ë¤ì ì¤í íë¤ 9441 */ 9442 resume : function () { 9443 if (this._bPause) { 9444 this._nBeforeFrameTime = this._getDate(); 9445 this._nBeforeRenderingTime = 0; 9446 this._bPlaying = true; 9447 this._bPause = false; 9448 9449 /** 9450 * ë ëë¬ê° ì¼ì ì ì§ìì í´ì ë ë ë°ì. getInfo ê°ì´ ì´ë²¤í¸ ì¸ìë¡ ëì´ê°ë¤ 9451 * @name collie.Renderer#resume 9452 * @event 9453 * @see collie.Renderer.getInfo 9454 */ 9455 this.fireEvent("resume", this.getInfo()); 9456 this._trigger(0); 9457 } 9458 }, 9459 9460 /** 9461 * íì¬ ì¤í ì¤ì¸ì§ ì¬ë¶ë¥¼ ë°í 9462 * 9463 * @return {Boolean} 9464 */ 9465 isPlaying : function () { 9466 return this._bPlaying; 9467 }, 9468 9469 /** 9470 * ë ì´ì´ ì ë°ì´í¸, ì£¼ë¡ ë¤ì 그리거ë ëì ë±ì ì ë°ì´í¸ íë¤ 9471 * 9472 * @param {Number} nFrameDuration ì¤ì ì§íë ìê° 9473 * @private 9474 */ 9475 _update : function (nFrameDuration) { 9476 for (var i = 0, len = this._aLayerList.length; i < len; i++) { 9477 this._aLayerList[i].update(nFrameDuration); 9478 } 9479 }, 9480 9481 /** 9482 * ì´ë²¤í¸ì ë ì´ì´ê° ì ë¬ì ë§ê¸° ìí ì´ë²¤í¸ ìí를 ì¤ì íë¤ 9483 * 9484 * @private 9485 * @param {String} sEventType ì´ë²¤í¸ íì 9486 * @param {Boolean} bFiredOnTarget ì´ë²¤í¸ê° ëìì ë°ìíëì§ ì¬ë¶ 9487 */ 9488 setEventStatus : function (sEventType, bFiredOnTarget) { 9489 this._htEventStatus = { 9490 type : sEventType, 9491 firedOnTarget : bFiredOnTarget 9492 }; 9493 }, 9494 9495 /** 9496 * ê°ì²´ ì´ë²¤í¸ë¥¼ ë©ì¶°ì¼ íëì§ ì¬ë¶ 9497 * @private 9498 * @param {String} sEventType ì´ë²¤í¸ íì 9499 * @return {Boolean} ì´ë²¤í¸ë¥¼ ë©ì¶°ì¼ íëì§ ì¬ë¶ 9500 */ 9501 isStopEvent : function (sEventType) { 9502 // click ì´ë²¤í¸ë ììë¡ ë°ììí¤ê¸° ë문ì mouseup ì¼ë¡ ê°ì£¼ 9503 if (sEventType === "click") { 9504 sEventType = "mouseup"; 9505 } 9506 9507 return sEventType === this._htEventStatus.type && this._htEventStatus.firedOnTarget; 9508 }, 9509 9510 /** 9511 * ì´ë²¤í¸ì ë ì´ì´ê° ì ë¬ì ë§ê¸° ìí ì´ë²¤í¸ ìí를 ê°ì ¸ ì¨ë¤ 9512 * 9513 * @private 9514 * @return {Object} htEventStatus 9515 * @return {String} htEventStatus.type ì´ë²¤í¸ íì 9516 * @return {Boolean} htEventStatus.firedOnTarget ì´ë²¤í¸ê° ëìì ë°ìíëì§ ì¬ë¶ 9517 */ 9518 getEventStatus : function () { 9519 return this._htEventStatus; 9520 }, 9521 9522 /** 9523 * ë ì´ì´ ììì 기본 ì´ë²¤í¸(mousemove, mousedown) ëìì ë§ìì§ ì¬ë¶ë¥¼ ì¤ì íë¤. 9524 * 9525 * @param {Boolean} bPreventDefault trueë©´ 기본 ëìì ë§ëë¤. 9526 */ 9527 setPreventDefault : function (bPreventDefault) { 9528 this._bIsPreventDefault = !!bPreventDefault; 9529 }, 9530 9531 /** 9532 * 기본 ëìì ë§ëì§ ì¬ë¶ë¥¼ ë°í 9533 * 9534 * @return {Boolean} trueì¼ ë ë§ëë¤, 기본ê°ì´ true 9535 */ 9536 isPreventDefault : function () { 9537 return this._bIsPreventDefault; 9538 }, 9539 9540 /** 9541 * ë ëë¬ì ë±ë¡ë 모ë ë ì´ì´ì í¬ê¸°ë¥¼ ë³ê²½ íë¤ 9542 * 9543 * @param {Number} nWidth 9544 * @param {Number} nHeight 9545 * @param {Boolean} bExpand íì¥í ì§ í¬ê¸°ë§ ë³ê²½í ì§ ì¬ë¶ 9546 */ 9547 resize : function (nWidth, nHeight, bExpand) { 9548 for (var i = 0, len = this._aLayerList.length; i < len; i++) { 9549 this._aLayerList[i].resize(nWidth, nHeight, bExpand); 9550 } 9551 } 9552}, collie.Component))();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.