jquery.pureCanvas.js 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453
  1. +function($){
  2. 'use strict';
  3. /**
  4. * Pure Canvas - Class Definition.
  5. */
  6. // 申明一个全局变量监控是否按下空格键
  7. var move_flag = false;
  8. var this_recWidth = null;
  9. var this_recHeight = null;
  10. // document.onkeydown=function(event){
  11. // var e = event || window.event || arguments.callee.caller.arguments[0];
  12. // alert(111);
  13. // if(e.keyCode==32){
  14. // move_flag = true;
  15. // }
  16. // }
  17. // document.onkeyup=function(event){
  18. // var e = event || window.event || arguments.callee.caller.arguments[0];
  19. // move_flag = false;
  20. // }
  21. var PureCanvas = function(element, options){
  22. // PureCanvas Div element 정보(createCanvas에서 추가됨)
  23. this.$element = $(element);
  24. this.$main = null;
  25. this.$container = null;
  26. // 설정 정보
  27. this.options = options;
  28. // Canvas ID 지정
  29. if(!this.options.setting.id) this.options.setting.id = this.createUUID.call(this);
  30. // Canvas 정보
  31. this.canvasInfo = {};
  32. // background image 정보
  33. this.imageInfo = {};
  34. // Draw 히스터리 정보
  35. this.historyInfo = {
  36. index: -1,
  37. drawData: []
  38. }
  39. // Canvas 생성
  40. this.createCanvas.call(this);
  41. // Event 생성
  42. this.makeCanvasEvent.call(this);
  43. //
  44. // 监控按键
  45. //document.onkeydown=function(event){
  46. //var e = event || window.event || arguments.callee.caller.arguments[0];
  47. // if(e.shiftKey){
  48. // move_flag = true;
  49. // }
  50. //}
  51. //document.onkeyup=function(event){
  52. // var e = event || window.event || arguments.callee.caller.arguments[0];
  53. // move_flag = false;
  54. //}
  55. document.addEventListener("keydown",function(event){
  56. var e = event || window.event || arguments.callee.caller.arguments[0];
  57. //e.preventDefault();
  58. if(e.shiftKey){
  59. //if(e.keyCode==32){
  60. move_flag = true;
  61. }
  62. });
  63. document.addEventListener("keyup",function(event){
  64. var e = event || window.event || arguments.callee.caller.arguments[0];
  65. if(e.shiftKey){
  66. //if(e.keyCode==32){
  67. move_flag = false;
  68. }
  69. move_flag = false;
  70. this_recWidth = null;
  71. this_recHeight = null;
  72. });
  73. }
  74. PureCanvas.VERSION = '0.1';
  75. PureCanvas.DEFIN = {
  76. // 사용자 옵션으로 호출 가능한 prototype
  77. optionName: {
  78. // Toolkit 정보 설정
  79. toolkit: 'toolkit',
  80. // setting 정보 설정
  81. setting: 'setting',
  82. // Canvas resizing 작업 호출
  83. resize: 'resize',
  84. // draw undo, redo event
  85. history: 'history',
  86. }
  87. }
  88. // 사용자에 의해 설정 변경 가능한 항목
  89. PureCanvas.DEFAULTS = {
  90. // Canvas의 설정 정보
  91. setting: {
  92. // 그리기 권한
  93. authForDraw: true,
  94. // 그리기 권한이 없는 경우, 마우스 커스 모양
  95. notAuthForDrawCursor: 'not-allowed',
  96. // 마우스포인터 사용 권한
  97. pointerForDraw: true,
  98. // 마우스포인터 클릭 시 전송 여부
  99. pointerDownSend: true,
  100. // 화면 사이즈 설정 정보(page:쪽맞춤, rate:비율)
  101. resizeType: 'rate',
  102. // 화면 비율 정보(page일 경우 size에 맞게 계산, rate일 경우 입력 값) 1 = 100%
  103. rateVal: 1,
  104. // 마우스포인터 전송 지연 시간(ms)
  105. delayMousePoint: 3,
  106. containerStyle: {},
  107. // point 비율 계산에 따른 소수점 자리수
  108. pointFixed: 1,
  109. //autoWindowResize
  110. windowResizeEvent: true,
  111. },
  112. // Toolkit 정보
  113. toolkit: {
  114. // Toolkit Type, '$.pureCanvas.toolkit.type'에 정의된 것에 한함.
  115. type: 'Cursor',
  116. // context style 설정
  117. style: {
  118. lineCap: 'round',
  119. lineJoin: 'round',
  120. // 선 색, 선택으로 채움색까지 사용함.
  121. strokeStyle: "rgba(0,0,0,100)",
  122. // 채움 색
  123. fillStyle: "rgba(0,0,0,100)",
  124. // 선 굴기
  125. lineWidth: 1,
  126. },
  127. },
  128. }
  129. $.extend(PureCanvas.prototype, {
  130. /**
  131. * Create UUID
  132. */
  133. createUUID: function(){
  134. var uuid = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  135. var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
  136. return v.toString(16);
  137. });
  138. return uuid;
  139. },
  140. /**
  141. * Create Canvas Element & Info
  142. */
  143. createCanvas: function(){
  144. // Canvas 정보
  145. this.canvasInfo = {
  146. // Background Canvas 생성
  147. bg: {domView: true, resize: true, clearView: false}, //true, true, false
  148. // Main Canvas 생성 - view을 비율에 맞게 조정한 Canvas
  149. main: {domView: true, resize: true, clearView: false}, //true, true, true
  150. // View Canvas 생성 - recvDraw+drawTemp+mView를 합친 Canvas
  151. view: {domView: false, resize: false, clearView: true}, // false, false, true
  152. // recvDraw Canvas 생성 - 외부 수신 데이터를 임시 Draw하는 Canvas
  153. recvDraw: {domView: false, resize: false, clearView: false}, //false, false, false
  154. // mView Canvas 생성 - 중요 포인트를 Draw하는 Canvas
  155. mView: {domView: false, resize: false, clearView: true}, //false, false, true
  156. // Pointer Canvas 생성 - 마우스포인트를 Draw하는 Canvas
  157. pointer: {domView: true, resize: true, clearView: false}, //true, true, false
  158. // DrawTemp Canvas 생성 - 원본 크기로 Draw에서 그린 데이터를 원본 크기로 임시로 다시 그리는 Canvas
  159. drawTemp: {domView: false, resize: false, clearView: false}, //false, false, false
  160. // Draw Canvas 생성 - 비율에 따른 변경되는 사용자가 임시로 그리고 있는 Canvas
  161. draw: {domView: true, resize: true, clearView: false}, //true, true, false
  162. }
  163. // Style & Attribute setting, append element
  164. this.$element.css({'display': 'table'}).attr('data-pure-canvas', 'element');
  165. var $main = $('<div></div>').attr('data-pure-canvas', 'main')
  166. .css({'display': 'block', 'position': 'absolute', 'overflow': 'auto', 'width': 'inherit', 'height': 'inherit'})
  167. .appendTo(this.$element);
  168. var $container = $('<div></div>').attr('data-pure-canvas', 'container')
  169. //.css({'border': '1px solid'})
  170. .css(this.options.setting.containerStyle)
  171. .appendTo($main);
  172. this.$main = $main;
  173. this.$container = $container;
  174. // Canvas 정보 목록에 존재하는 Canvas 생성
  175. for(var key in this.canvasInfo){
  176. var data = this.canvasInfo[key];
  177. // Canvas 생성 및 설정
  178. var $canvas = $('<canvas></canvas>').attr('data-pure-canvas-type', key);
  179. this.settingDefaultStyle($canvas);
  180. if(data.domView) this.$container.append($canvas);
  181. //if(!data.domView) $canvas.css({'display': 'none'});
  182. //$container.append($canvas);
  183. // Canvas 추가 정보 설정
  184. data.type = key;
  185. data.$canvas = $canvas;
  186. data.canvas = $canvas.get(0);
  187. data.context = $canvas.get(0).getContext('2d');
  188. }
  189. console.debug(this.canvasInfo);
  190. },
  191. /**
  192. * Canvas 기본 스타일 설정
  193. */
  194. settingDefaultStyle: function($canvas){
  195. var $element = this.$element;
  196. console.log($element);
  197. //var divWidth = $element.width();
  198. //var divHeight = $element.height();
  199. //var divWidth = 1295;
  200. //var divHeight = 950;
  201. var divWidth = $element.attr("data-width");
  202. var divHeight = $element.attr("data-height");
  203. $canvas.get(0).width = parseInt(divWidth);
  204. $canvas.get(0).height = parseInt(divHeight);
  205. $canvas.css({'position': 'absolute'});
  206. },
  207. /**
  208. * Mouse, Touch Event 생성
  209. */
  210. makeCanvasEvent: function(){
  211. var THIS = this;
  212. var setting = this.options.setting;
  213. var toolkit = this.options.toolkit;
  214. var $drawCanvas = this.canvasInfo.draw.$canvas;
  215. $drawCanvas.on('mousedown mousemove mouseup mouseover mouseout touchstart touchmove touchend', function(e){
  216. // 그리기 권한이 없는 경우 이벤트를 수행하지 않음.
  217. if(!setting.authForDraw){
  218. return;
  219. }
  220. // Touch Event인 경우 처리
  221. if(e.type.indexOf('touch') >= 0){
  222. e.preventDefault();
  223. e.isTouch = true;
  224. }
  225. // 이벤트 분류
  226. var type = e.type;
  227. var callMethod = null;
  228. switch (type) {
  229. case 'mousedown':
  230. case 'touchstart':
  231. callMethod = 'drawStart';
  232. // Touch가 아닌 경우(Mouse 인 경우) 왼쪽 클릭 만 허용함.
  233. if(!e.isTouch && e.button !== 0){
  234. return;
  235. }
  236. break;
  237. case 'mousemove':
  238. //case 'mouseover':
  239. case 'touchmove':
  240. callMethod = 'drawing';
  241. break;
  242. case 'mouseup':
  243. case 'touchend':
  244. callMethod = 'drawEnd';
  245. break;
  246. case 'mouseout':
  247. callMethod = 'drawOut';
  248. break;
  249. }
  250. // 추가 이벤트 정보 설정
  251. $.extend(e, {
  252. type: 'drawEvent-' + toolkit.type,
  253. callMethod: callMethod,
  254. eventType: type,
  255. toolkitType: toolkit.type
  256. });
  257. //console.log(e.eventType, e.type, e.callMethod, e.timeStamp, e);
  258. // PureCanvas Event 호출
  259. try{
  260. $drawCanvas.trigger(e);
  261. }catch(ex){
  262. console.warn('drawEvent-%s event error. [%s]', toolkit.type, ex);
  263. }
  264. })
  265. },
  266. /**
  267. * Loading Bar 설정
  268. */
  269. loadingBar: function(option, message){
  270. // Create & Show
  271. if(!option || option === 'show'){
  272. // loading bar 생성
  273. if(!this.loadingBarDiv){
  274. this.loadingBarDiv = $('<div></div>')
  275. .attr('data-pure-canvas', 'loadingBar')
  276. .css({'background-color': 'rgba(0,0,0, 0.5)', position: 'absolute', 'text-align': 'center', 'display': 'none'})
  277. .appendTo(this.$element);
  278. var messageBox = $('<div></div>')
  279. .css({padding: '10px', 'background-color': 'rgb(0,0,0)', color: '#fff', height: '21px'})
  280. .appendTo(this.loadingBarDiv);
  281. this.loadingBarDiv.data('messageBox', messageBox);
  282. }
  283. var messageBox = this.loadingBarDiv.data('messageBox');
  284. // 내용 변경
  285. this.loadingBarDiv.css({width: this.$element.width(), height: this.$element.height()});
  286. var top = (this.$element.height() / 2) - messageBox.height();
  287. messageBox.css({'margin-top': top}).html(message);
  288. // fade show
  289. this.loadingBarDiv.fadeIn(500);
  290. }
  291. // Hide
  292. else if(option === 'hide'){
  293. // fade hide
  294. this.loadingBarDiv.fadeOut(500);
  295. }
  296. },
  297. });
  298. /**
  299. * Pure Canvas - Context Style Setting - 'toolkit' options
  300. */
  301. PureCanvas.prototype.toolkit = function(targetName, value){
  302. // getter
  303. if(!targetName && value == undefined) return this.options.toolkit;
  304. if(targetName && value == undefined) return this.options.toolkit[targetName];
  305. // setter
  306. return this.toolkit[targetName] ? this.toolkit[targetName].call(this, value) : undefined;
  307. }
  308. $.extend(PureCanvas.prototype.toolkit, {
  309. type: function(value){
  310. var toolkit = this.options.toolkit;
  311. var toolkitType = $.pureCanvas.toolkit.type[value];
  312. if(toolkitType == undefined){
  313. console.warn('not match toolkit type. ', value);
  314. return;
  315. }
  316. // 즉시 처리 로직 수행
  317. if(toolkitType.instantProcess){
  318. console.debug('setting value instantProcess.: ' + value);
  319. toolkitType.instantProcess();
  320. return;
  321. }
  322. toolkit.type = value;
  323. console.debug('setting toolkit.type : ' + value, toolkit);
  324. // 커서 모양 변경
  325. this.canvasInfo.draw.canvas.style.cursor = toolkitType.getCursor();
  326. },
  327. lineWidth: function(value){
  328. // Use : BallPen, highlighter, StraightLine, Rectangle
  329. this.toolkit.contextStyle.call(this, 'lineWidth', value);
  330. },
  331. lineCap: function(value){
  332. // Use : BallPen, highlighter, StraightLine
  333. // Style : butt, round, square
  334. this.toolkit.contextStyle.call(this, 'lineCap', value);
  335. },
  336. lineJoin: function(value){
  337. // Use : BallPen, highlighter
  338. // Style : miter, round, bevel
  339. this.toolkit.contextStyle.call(this, 'lineJoin', value);
  340. },
  341. strokeStyle: function(value){
  342. if(typeof value == 'string') value = {color: value, opacity: 100};
  343. // Use : BallPen, highlighter, StraightLine, Circle, Triangle, Rectangle
  344. this.toolkit.contextStyle.call(this, 'strokeStyle', this.pureCanvasToolkit.hexToRgba(value.color, value.opacity));
  345. },
  346. fillStyle: function(value){
  347. if(typeof value == 'string') value = {color: value, opacity: 100};
  348. // Use : BallPen, highlighter, StraightLine, Circle, Triangle, Rectangle
  349. this.toolkit.contextStyle.call(this, 'fillStyle', this.pureCanvasToolkit.hexToRgba(value.color, value.opacity));
  350. },
  351. contextStyle: function(styleName, value){
  352. var toolkit = this.options.toolkit;
  353. toolkit.style[styleName] = value;
  354. console.debug('setting style [' + styleName + '] apply:' + toolkit.style[styleName] + ' , input:' + value);
  355. },
  356. draw: function(toolkitData){
  357. if(typeof toolkitData != 'object') return;
  358. // 이벤트 생성 및 추가 정보 설정
  359. var event = $.Event('drawEvent-' + toolkitData.type, {
  360. callMethod: 'draw',
  361. eventType: 'draw.pureCanvas',
  362. toolkitData: toolkitData,
  363. toolkitType: toolkitData.type,
  364. });
  365. // draw canvas에 Event 호출
  366. try{
  367. this.canvasInfo.draw.$canvas.trigger(event);
  368. }catch(ex){
  369. console.warn('drawEvent-%s event error. [%s]', toolkitData.type, ex);
  370. }
  371. },
  372. });
  373. /**
  374. * Pure Canvas - Canvas Setting - 'setting' options
  375. */
  376. PureCanvas.prototype.setting = function(targetName, value){
  377. // getter
  378. if(!targetName && value == undefined) return this.options.toolkit;
  379. if(targetName && value == undefined) return this.options.setting[targetName];
  380. // setter
  381. return this.setting[targetName] ? this.setting[targetName].call(this, value) : undefined;
  382. }
  383. $.extend(PureCanvas.prototype.setting, {
  384. authForDraw: function(value){
  385. this.options.setting.authForDraw = value;
  386. if(value){
  387. var cursor = $.pureCanvas.toolkit.type[this.options.toolkit.type].getCursor();
  388. this.canvasInfo.draw.canvas.style.cursor = cursor;
  389. }else{
  390. this.canvasInfo.draw.canvas.style.cursor = this.options.setting.notAuthForDrawCursor;
  391. }
  392. console.debug('setting setting.authForDraw : ' + value);
  393. },
  394. pointerForDraw: function(value){
  395. this.options.setting.pointerForDraw = value;
  396. console.debug('setting setting.pointerForDraw : ' + value);
  397. },
  398. pointerDownSend: function(value){
  399. this.options.setting.pointerDownSend = value;
  400. console.debug('setting setting.pointerDownSend : ' + value);
  401. },
  402. backgroundImage: function(value){
  403. var THIS = this;
  404. var callbackFunction;
  405. var _width = value.width;
  406. var _height = value.height;
  407. if(typeof value == 'object'){
  408. callbackFunction = value.callback;
  409. value = value.imageSrc;
  410. }
  411. if(THIS.imageInfo && THIS.imageInfo.imgSrc === value){
  412. console.debug('duplication. image. ' + value);
  413. return;
  414. }
  415. var image = new Image();
  416. var sDate = new Date();
  417. this.loadingBar.call(this, 'show', 'Loading...');
  418. var $element = this.$element;
  419. image.onload = function(){
  420. //var imageWidth = image.width;
  421. //var imageHeight = image.height;
  422. //var imageWidth = 1295;
  423. //var imageHeight = 950;
  424. var imageWidth = $element.attr("data-width");
  425. var imageHeight = $element.attr("data-height");
  426. var imageWidth = _width;
  427. var imageHeight = _height;
  428. //alert(imageHeight);
  429. // 이미지 원본 크기와 동일해야 되는 Canvas 크기 조정, cavnasInfo: resize = false
  430. $.each(THIS.canvasInfo, function(key, canvas){
  431. if(!canvas.resize){
  432. canvas.canvas.width = imageWidth;
  433. canvas.canvas.height = imageHeight;
  434. }
  435. });
  436. // 이미지 정보 저장
  437. THIS.imageInfo = {
  438. // 이미지 객체
  439. image: image,
  440. // 이미지 주소
  441. imgSrc: value,
  442. // 이미지 원본 가로 크기
  443. orgImageWidth: imageWidth,
  444. // 이미지 원본 세로 크기
  445. orgImageHeight: imageHeight,
  446. // re draw 여부
  447. isSetting: true
  448. }
  449. THIS.historyInfo = {
  450. index: -1,
  451. drawData: []
  452. }
  453. // canvas resize 호출
  454. THIS.resize();
  455. var eDate = new Date();
  456. console.debug("image loading time: %dms", eDate - sDate);
  457. try{
  458. // 백그라운드 이미지 출력 완료 이벤트 발생
  459. if(callbackFunction && typeof callbackFunction == 'function'){
  460. callbackFunction({id: THIS.options.setting.id, imageSrc: value});
  461. }
  462. }catch(ex){
  463. console.warn('callbackFunction event error. [%s]', ex);
  464. }
  465. // try{
  466. // THIS.$element.trigger({
  467. // type: 'show.bg.pureCanvas',
  468. // imageData: {imageSrc: value}
  469. // });
  470. // }catch(ex){
  471. // console.warn('show.bg.pureCanvas event error. [%s]', ex);
  472. // }
  473. THIS.loadingBar.call(THIS, 'hide');
  474. }
  475. image.onerror = function(){
  476. console.error("["+value+"] image loading Error.");
  477. }
  478. image.src = value;
  479. },
  480. resizeType: function(value){
  481. // page(쪽맞춤), rate(비율)
  482. if(typeof value == 'string'){
  483. if(value.indexOf('rate') >= 0){
  484. var split = value.split("_");
  485. this.options.setting.resizeType = split[0];
  486. this.options.setting.rateVal = split[1] / 100;
  487. }else{
  488. this.options.setting.resizeType = value;
  489. this.options.setting.rateVal = 1;
  490. }
  491. }else{
  492. this.options.setting.resizeType = value.type;
  493. this.options.setting.rateVal = value.rateVal ? value.rateVal / 100 : 1;
  494. }
  495. // canvas resize 호출
  496. this.imageInfo.isSetting = true;
  497. this.resize();
  498. console.debug('setting resizeType: ' + this.options.setting.resizeType, this.options.setting.rateVal);
  499. },
  500. scroll: function(value){
  501. this.pureCanvasToolkit.recvScrollData(value);
  502. }
  503. });
  504. /**
  505. * Canvas 크기 변경
  506. */
  507. PureCanvas.prototype.resize = function(){
  508. if(this.resize[this.options.setting.resizeType]){
  509. var data = this.resize[this.options.setting.resizeType].call(this)
  510. this.resize.canvasResizeNDraw.call(this, data);
  511. }
  512. try{
  513. this.$element.trigger({
  514. type: 'canvas-resize.pureCanvas'
  515. });
  516. }catch(ex){
  517. console.warn('canvas-resize.pureCanvas event error. [%s]', ex);
  518. }
  519. }
  520. $.extend(PureCanvas.prototype.resize, {
  521. // 비율(%)
  522. rate: function(){
  523. var imageInfo = this.imageInfo;
  524. var rateVal = this.options.setting.rateVal;
  525. // 이미지 원본 크기 * 비율 = 비율에 맞는 이미지 크기
  526. var width = imageInfo.orgImageWidth * rateVal;
  527. var height = imageInfo.orgImageHeight * rateVal;
  528. return {width: width, height: height};
  529. },
  530. //쪽맞춤
  531. page: function(){
  532. var imageInfo = this.imageInfo;
  533. // main div의 크기와 원본 이미지 크기로 비율 정보 계산
  534. var rateWidth = this.$main.width() / imageInfo.orgImageWidth;
  535. var rateHeight = this.$main.height() / imageInfo.orgImageHeight;
  536. // 가로, 세로 중 비율 정보가 작은 값 사용
  537. var rateVal = (rateWidth > rateHeight) ? rateHeight : rateWidth;
  538. this.options.setting.rateVal = rateVal;
  539. // 이미지 원본 크기 * 비율 = 비율에 맞는 이미지 크기
  540. var width = imageInfo.orgImageWidth * rateVal;
  541. var height = imageInfo.orgImageHeight * rateVal;
  542. // 쪽맞춤일 경우 window.resize에 따라 이미지 크기가 변경됨으로 true 값 설정
  543. imageInfo.isSetting = true;
  544. return {width: width, height: height};
  545. },
  546. canvasResizeNDraw: function(data){
  547. var width = data.width;
  548. var height = data.height;
  549. var imageInfo = this.imageInfo;
  550. var rateVal = this.options.setting.rateVal;
  551. // 왼쪽, 위 마진 정보 계산,
  552. var marginLeft = this.$main.width() / 2 - (width / 2);
  553. var marginTop = this.$main.height() / 2 - (height / 2)
  554. // border, padding size를 고려하여 가로, 세로 크기를 변경한다.
  555. width -= (this.$container.outerWidth() - this.$container.width());
  556. height -= (this.$container.outerHeight() - this.$container.height());
  557. this.$container.css({width: width, height: height, 'margin-left': marginLeft < 0 ? 0 : marginLeft, 'margin-top': marginTop < 0 ? 0 : marginTop});
  558. if(imageInfo.isSetting){
  559. // 이미지 원본 크기와 동일해야 되는 Canvas 크기 조정, cavnasInfo: resize = false
  560. $.each(this.canvasInfo, function(key, canvas){
  561. if(canvas.resize){
  562. canvas.canvas.width = width;
  563. canvas.canvas.height = height;
  564. }
  565. });
  566. var mainCtx = this.canvasInfo.main.context;
  567. var bgCtx = this.canvasInfo.bg.context;
  568. // 메인의 draw data가 비율에 맞게 변경하여 다시 출력한다.
  569. mainCtx.clearCanvas();
  570. mainCtx.save();
  571. mainCtx.setTransform(rateVal, 0, 0, rateVal, 0, 0);
  572. mainCtx.drawImage(this.canvasInfo.view.canvas, 0, 0);
  573. mainCtx.drawImage(this.canvasInfo.mView.canvas, 0, 0);
  574. mainCtx.restore();
  575. bgCtx.drawImage(imageInfo.image, 0, 0, width, height);
  576. imageInfo.isSetting = false;
  577. }
  578. }
  579. });
  580. /**
  581. * History
  582. */
  583. PureCanvas.prototype.history = function(targetName){
  584. var isSend = true;
  585. if(typeof targetName == 'object'){
  586. targetName = targetName.action;
  587. isSend = false;
  588. }
  589. this.history[targetName] ? this.history[targetName].call(this, isSend) : undefined;
  590. }
  591. $.extend(PureCanvas.prototype, {
  592. historyAdd: function(){
  593. var ctx = this.canvasInfo.view.context;
  594. //此处注释掉解决out of memory
  595. //var snapshot = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
  596. var snapshot = null;
  597. this.historyInfo.drawData[++this.historyInfo.index] = snapshot;
  598. while (this.historyInfo.index < this.historyInfo.drawData.length -1) {
  599. this.historyInfo.drawData.pop();
  600. }
  601. },
  602. changeImage: function(){
  603. var ctx = this.canvasInfo.view.context;
  604. // 초기 화면(clear)
  605. if(this.historyInfo.index < 0){
  606. ctx.clearCanvas();
  607. }else{
  608. // 저장된 index 정보의 이미지로 그린다.
  609. var snapshot = this.historyInfo.drawData[this.historyInfo.index];
  610. ctx.putImageData(snapshot, 0, 0);
  611. }
  612. this.pureCanvasToolkit.mainCanvasChange(true);
  613. }
  614. });
  615. $.extend(PureCanvas.prototype.history, {
  616. next: function(isSend){
  617. if(this.history.hasNext.call(this)){
  618. this.historyInfo.index++;
  619. this.changeImage();
  620. if(isSend){
  621. try{
  622. this.$element.trigger({
  623. type: 'history.pureCanvas',
  624. historyData: {id: this.options.setting.id, action: 'next', index: this.historyInfo.index}
  625. });
  626. }catch (ex) {
  627. console.warn('history.pureCanvas event error. [%s]', ex);
  628. }
  629. }
  630. }
  631. },
  632. prev: function(isSend){
  633. if(this.history.hasPrev.call(this)){
  634. --this.historyInfo.index;
  635. this.changeImage();
  636. if(isSend){
  637. try{
  638. this.$element.trigger({
  639. type: 'history.pureCanvas',
  640. historyData: {id: this.options.setting.id, action: 'prev', index: this.historyInfo.index}
  641. });
  642. }catch(ex){
  643. console.warn('history.pureCanvas event error. [%s]', ex);
  644. }
  645. }
  646. }
  647. },
  648. hasNext: function(){
  649. return this.historyInfo.index < this.historyInfo.drawData.length - 1;
  650. },
  651. hasPrev: function(){
  652. return this.historyInfo.index >= 0;
  653. }
  654. });
  655. /**
  656. * Pure Canvas - Plug-in Definition.
  657. */
  658. function Plugin(option, _relatedTarget, _relatedValue){
  659. var $this = $(this);
  660. var data = $this.data('pure.pureCanvas');
  661. var options = $.extend(true, {}, PureCanvas.DEFAULTS, $this.data, typeof option == 'object' && option);
  662. if(!data){
  663. $this.data('pure.pureCanvas', (data = new PureCanvas(this, options)));
  664. data.pureCanvasToolkit = new $.pureCanvas.toolkit(this);
  665. }
  666. if(typeof option == 'string' && PureCanvas.DEFIN.optionName[option]){
  667. var returnValue = data[option](_relatedTarget, _relatedValue);
  668. return returnValue == undefined ? $this : returnValue;
  669. }
  670. return $this;
  671. }
  672. $.fn.pureCanvas = Plugin;
  673. $.fn.pureCanvas.Constructor = PureCanvas;
  674. /**
  675. * Pure Canvas - Event
  676. */
  677. $(window).on('load', function(){
  678. $(window).on('resize', function(){
  679. $('[data-pure-canvas="element"]').each(function(index, element){
  680. if($(element).pureCanvas('setting', 'windowResizeEvent')){
  681. $(element).pureCanvas('resize');
  682. }
  683. });
  684. });
  685. });
  686. /*******************************************************************************************************************************/
  687. $.pureCanvas = {};
  688. $.pureCanvas.toolkit = function(element){
  689. // Element 정보
  690. this.$element = element;
  691. this.$main = this.$element.find('[data-pure-canvas="main"]');
  692. // 설정 정보
  693. this.options = this.$element.data('pure.pureCanvas').options;
  694. this.setting = this.options.setting;
  695. this.toolkit = this.options.toolkit;
  696. // canvas 정보
  697. this.canvasInfo = this.$element.data('pure.pureCanvas').canvasInfo;
  698. this.drawCanvas = this.canvasInfo.draw.canvas;
  699. this.$drawCanvas = this.canvasInfo.draw.$canvas;
  700. this.drawCtx = this.canvasInfo.draw.context;
  701. //
  702. this.drawTempCtx = this.canvasInfo.drawTemp.context;
  703. this.recvDrawCtx = this.canvasInfo.recvDraw.context;
  704. this.viewCtx = this.canvasInfo.view.context;
  705. this.mViewCtx = this.canvasInfo.mView.context;
  706. this.mainCtx = this.canvasInfo.main.context;
  707. // Toolit Event 생성
  708. this.makeEvent();
  709. }
  710. $.extend($.pureCanvas.toolkit, {
  711. prototype: {
  712. makeEvent: function(){
  713. var THIS = this;
  714. // Toolkit 별 event 생성
  715. $.each($.pureCanvas.toolkit.type, function(toolkitType, toolkit){
  716. // $.pureCanvas.toolkit의 공통 function을 사용하기 위해 $.extend 함.
  717. $.extend(toolkit, THIS);
  718. // 초기 설정이 있는 경우
  719. if(toolkit.init) toolkit.init();
  720. THIS.$drawCanvas.on('drawEvent-' + toolkitType, function(e){
  721. // Canvas에 직접 Draw 하는 것만 좌표를 계산한다.
  722. if(e.eventType != 'draw.pureCanvas'){
  723. // 좌표 계산, touchend event는 값 없음.
  724. e.point = THIS.getPoint(e);
  725. }
  726. // Toolkit Type의 callMethod가 있는 경우 수행한다.
  727. var toolkitType = $.pureCanvas.toolkit.type[e.toolkitType];
  728. if(toolkitType[e.callMethod]) toolkitType[e.callMethod](e);
  729. });
  730. });
  731. },
  732. sendDrawData: function(points){
  733. var data = {
  734. id: this.setting.id,
  735. type: this.getType(),
  736. style: this.toolkit.style,
  737. points: points ? (Object.prototype.toString.call(points) === "[object Array]") ? points.join(',') : points : null
  738. }
  739. try{
  740. this.$element.trigger({
  741. type: 'complate.draw.pureCanvas',
  742. drawData: data,
  743. });
  744. }catch(ex){
  745. console.warn('complate.draw.pureCanvas event error. [%s]', ex);
  746. }
  747. },
  748. sendScrollData: function(){
  749. // Scroll bar의 크기를 구한다.
  750. var scrollBarWidth = this.$main.prop("scrollWidth") - this.$main.prop("clientWidth");
  751. var scrollBarHeight = this.$main.prop("scrollHeight") - this.$main.prop("clientHeight");
  752. // 현재 Scroll 위치를 구한다.
  753. var scrollLeft = this.$main.scrollLeft();
  754. var scrollTop = this.$main.scrollTop();
  755. // 이동한 위치의 비율을 계산한다.
  756. var leftRate = scrollLeft / scrollBarWidth;
  757. var topRate = scrollTop / scrollBarHeight;
  758. var data = {
  759. scrollBarWidth: scrollBarWidth,
  760. scrollBarHeight: scrollBarHeight,
  761. scrollLeft: scrollLeft,
  762. scrollTop: scrollTop,
  763. left: leftRate,
  764. top: topRate
  765. }
  766. try{
  767. this.$element.trigger({
  768. type: 'scroll-move.pureCanvas',
  769. scrollData: data
  770. });
  771. }catch (ex) {
  772. console.warn('scroll-move.pureCanvas event error. [%s]', ex);
  773. }
  774. },
  775. recvScrollData: function(data){
  776. // Scroll bar의 크기를 구한다.
  777. var scrollBarWidth = this.$main.prop("scrollWidth") - this.$main.prop("clientWidth");
  778. var scrollBarHeight = this.$main.prop("scrollHeight") - this.$main.prop("clientHeight");
  779. // 이동한 위치의 비율을 계산한다.
  780. var scrollLeft = scrollBarWidth * data.left;
  781. var scrollTop = scrollBarHeight * data.top;
  782. // event 중복 호출 방지, 수신으로 변경된 정보가 event를 타고 나가는것 방지
  783. this.$main.data('pureCanvas-scroll', {type: 'recv', isTrigger: false});
  784. this.$main.scrollLeft(scrollLeft);
  785. this.$main.scrollTop(scrollTop);
  786. },
  787. getPoint: function(e){
  788. var x, y;
  789. // Mouse Event일 경우
  790. if(e.eventType.indexOf("mouse") >= 0){
  791. //console.log(e.type, e.offsetX || e.pageX - $(e.target).offset().left, e.offsetY || e.pageY - $(e.target).offset().top);
  792. x = typeof e.offsetX !== 'undefined' ? e.offsetX : e.pageX - $(e.target).offset().left;
  793. y = typeof e.offsetY !== 'undefined' ? e.offsetY : e.pageY - $(e.target).offset().top;
  794. }
  795. // Touch Event일 경우
  796. else{
  797. // ThuchEnd인 경우 좌표가 없으므로 공백을 반환한다.
  798. if(!e.originalEvent.targetTouches[0]){
  799. return {org: '', rate: ''}
  800. }
  801. //console.log(e.type, e.targetTouches[0].pageX, e.targetTouches[0].pageY);
  802. var tx = e.originalEvent.targetTouches[0].pageX;
  803. var ty = e.originalEvent.targetTouches[0].pageY;
  804. var cx = this.$drawCanvas.offset().left;
  805. var cy = this.$drawCanvas.offset().top;
  806. x = tx - cx;
  807. y = ty - cy;
  808. }
  809. // 비율에 따른 좌표 계산
  810. var rateVal = this.setting.rateVal;
  811. var rx = Math.round(x / rateVal, this.setting.pointFixed);
  812. var ry = Math.round(y / rateVal, this.setting.pointFixed);
  813. //var rx = (x / rateVal).toFixed(this.setting.pointFixed);
  814. //var ry = (y / rateVal).toFixed(this.setting.pointFixed);
  815. return {org: x+" "+y, rate: rx+" "+ry}
  816. },
  817. /**
  818. * ","로 구분되어 있는 point 문자열을 배열로 변경한다.
  819. * @returns
  820. */
  821. getPointSplitList: function(points){
  822. if(!points){
  823. console.error("points is undifine");
  824. return;
  825. }
  826. var pointsSplit = points.split(",");
  827. return pointsSplit;
  828. },
  829. /**
  830. * " "으로 구분되어 있는 x,y 좌표를 변경하여 Object{x:x, y:y}로 변경한다.
  831. * @returns Object{x:x, y:y}
  832. */
  833. getPointSplit: function(point){
  834. if(!point){
  835. console.error("point is undifine");
  836. return;
  837. }
  838. var pointSplit = point.split(" ");
  839. if(pointSplit.length != 2){
  840. console.error("point is not length 2. " + pointSplit.length);
  841. return;
  842. }
  843. return {x:Number(pointSplit[0]), y:Number(pointSplit[1])};
  844. },
  845. /*
  846. * hex(#000000) 값을 rgba(xxx, xxx, xxx, x) 값으로 변환
  847. */
  848. hexToRgba: function(hex, opacity){
  849. if(!hex){
  850. return null;
  851. }
  852. hex = hex.replace("#","");
  853. var r = parseInt(hex.substring(0,2), 16);
  854. var g = parseInt(hex.substring(2,4), 16);
  855. var b = parseInt(hex.substring(4,6), 16);
  856. if(!opacity) opacity = 100;
  857. return "rgba("+r+","+g+","+b+","+opacity/100+")";
  858. },
  859. /*
  860. * rgba(xxx, xxx, xxx, x) 값을 hex(#000000) 값으로 변환
  861. */
  862. rgbaToHex: function(rgba){
  863. if(!rgba){
  864. return {hex:"#000000", opacity: 100};
  865. }
  866. rgba = rgba.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+(\.?\d*))[\s+]?/i);
  867. var hex, opacity;
  868. if(rgba && (rgba.length === 5 || rgba.length === 6)){
  869. hex = "#"
  870. + ("0" + parseInt(rgba[1], 10).toString(16)).slice(-2)
  871. + ("0" + parseInt(rgba[2], 10).toString(16)).slice(-2)
  872. + ("0" + parseInt(rgba[3], 10).toString(16)).slice(-2);
  873. opacity = parseFloat(rgba[4]) * 100;
  874. }
  875. return {hex:hex, opacity: opacity};
  876. },
  877. /**
  878. * bg 비율에 맞게 Style을 변경한다.
  879. */
  880. getDrawStyle: function(){
  881. var style = $.extend({}, this.toolkit.style);
  882. style.orgLineWidth = style.lineWidth;
  883. style.lineWidth = style.orgLineWidth * this.setting.rateVal;
  884. return style;
  885. },
  886. /**
  887. * Draw 완료 후 copy, clear의 작업을 수행한다
  888. */
  889. complateDraw: function(data){
  890. var src = data.copyFrom;
  891. var target = data.copyTo;
  892. if(data.copyToPreClear){
  893. target.context.clearCanvas();
  894. }
  895. target.context.save();
  896. // source-over : 새 도형은 기존 내용 위에 그려진다. 기본값
  897. target.context.globalCompositeOperation = 'source-over';
  898. // target canvas에 source canvas를 덥어 그린다.
  899. target.context.drawImage(src.canvas, 0, 0);
  900. target.context.restore();
  901. if(data.clear){
  902. if(typeof data.clear == 'object'){
  903. $.each(data.clear, function(index, element){
  904. element.context.clearCanvas();
  905. });
  906. }
  907. }
  908. this.mainCanvasChange();
  909. move_flag = false;
  910. },
  911. /**
  912. * view, mview의 Image를 비율에 맞게 main에 draw한다.
  913. */
  914. mainCanvasChange: function(flag){
  915. var mainCanvas = this.canvasInfo.main.canvas;
  916. var mainCtx = this.canvasInfo.main.context;
  917. var viewCanvas = this.canvasInfo.view.canvas;
  918. var mviewCanvas = this.canvasInfo.mView.canvas;
  919. var setting = this.$element.data('pure.pureCanvas').options.setting;
  920. if(!flag){
  921. this.$element.data('pure.pureCanvas').historyAdd();
  922. }
  923. mainCtx.save();
  924. mainCtx.clearCanvas();
  925. mainCtx.setTransform(setting.rateVal, 0, 0, setting.rateVal, 0, 0);
  926. // source-over : 새 도형은 기존 내용 위에 그려진다. 기본값
  927. mainCtx.globalCompositeOperation = 'source-over';
  928. // target canvas에 source canvas를 덥어 그린다.
  929. mainCtx.drawImage(viewCanvas, 0, 0);
  930. mainCtx.drawImage(mviewCanvas, 0, 0);
  931. mainCtx.restore();
  932. },
  933. },
  934. // $.pureCanvas.toolkit.addToolkit
  935. addToolkit: function(toolkit){
  936. var makeToolkit = new toolkit();
  937. $.pureCanvas.toolkit.type[makeToolkit.getType()] = makeToolkit;
  938. },
  939. // Toolkit Types
  940. type: {}
  941. });
  942. /*******************************************************************************************************************************/
  943. $.extend($.pureCanvas.toolkit.prototype, {
  944. isLastSameCurrentPoint: function(points, currentPoint){
  945. return points && points.length > 0 ? points[points.lenght-1] == currentPoint : false;
  946. },
  947. // 굵기, 색에 따라 그려질 정보를 출력한다.
  948. drawForPrePoint: function(ctx, drawStyle, drawPoint){
  949. var style = $.extend({}, drawStyle);
  950. if(!drawStyle.isNotChange){
  951. style.fillStyle = style.strokeStyle;
  952. style.strokeStyle = '#ffffff';
  953. }
  954. var point = this.getPointSplit(drawPoint);
  955. if(!this.isDrawing) ctx.clearCanvas();
  956. ctx.save();
  957. ctx.beginPath();
  958. ctx.arc(point.x, point.y, style.lineWidth / 2, 0, Math.PI * 2, false);
  959. ctx.lineWidth = 1;
  960. ctx.lineCap = 'round';
  961. ctx.lineJoin = 'round';
  962. if(style.fillStyle){
  963. ctx.fillStyle = style.fillStyle;
  964. ctx.fill();
  965. }
  966. if(style.strokeStyle){
  967. ctx.strokeStyle = style.strokeStyle;
  968. ctx.stroke();
  969. }
  970. ctx.restore();
  971. },
  972. drawForArc: function(ctx, style, drawPoints){
  973. var point0 = this.getPointSplit(drawPoints[0]);
  974. var point1 = this.getPointSplit(drawPoints[1]);
  975. ctx.clearCanvas();
  976. ctx.beginPath();
  977. // 원의 반지름 구하기
  978. // 중심점에서 마우스 위치가 X, Y에서 더 큰쪽으로 반지름을 구한다????
  979. var radius = point0.x - point1.x;
  980. if(radius < 0) radius = radius * -1;
  981. var radiusY = point0.y - point1.y;
  982. if(radiusY < 0) radiusY = radiusY * -1;
  983. if(radius < radiusY) radius = radiusY;
  984. ctx.arc(point0.x, point0.y, radius, 2 * Math.PI, false);
  985. ctx.lineWidth = style.lineWidth;
  986. ctx.lineCap = 'round';
  987. ctx.lineJoin = 'round';
  988. if(style.isStroke){
  989. ctx.strokeStyle = style.strokeStyle;
  990. ctx.stroke();
  991. }
  992. if(style.isFill){
  993. ctx.fillStyle = style.fillStyle;
  994. ctx.fill();
  995. }
  996. },
  997. drawForLine: function(ctx, style, drawPoints){
  998. // drawForStraightLine
  999. if(drawPoints.length <= 2){
  1000. ctx.beginPath();
  1001. if(!style.isNotClear){
  1002. ctx.clearCanvas();
  1003. }
  1004. var point0 = this.getPointSplit(drawPoints[0]);
  1005. var point1;
  1006. if(drawPoints.length == 2){
  1007. point1 = this.getPointSplit(drawPoints[1]);
  1008. }else{
  1009. point1 = {x: point0.x+0.5, y: point0.y+0.5};
  1010. }
  1011. ctx.moveTo(point0.x, point0.y);
  1012. ctx.lineTo(point1.x, point1.y);
  1013. ctx.lineWidth = style.lineWidth;
  1014. ctx.lineCap = 'round';
  1015. ctx.lineJoin = 'round';
  1016. ctx.strokeStyle = style.strokeStyle;
  1017. ctx.stroke();
  1018. return;
  1019. }
  1020. if(!style.isNotClear){
  1021. ctx.clearCanvas();
  1022. }
  1023. ctx.beginPath();
  1024. ctx.lineWidth = style.lineWidth;
  1025. ctx.lineCap = 'round';
  1026. ctx.lineJoin = 'round';
  1027. ctx.strokeStyle = style.strokeStyle;
  1028. var point0 = this.getPointSplit(drawPoints[0]);
  1029. var pointi, pointi1;
  1030. ctx.moveTo(point0.x, point0.y);
  1031. for(var i=1; i<drawPoints.length-2; i++) {
  1032. pointi = this.getPointSplit(drawPoints[i]);
  1033. pointi1 = this.getPointSplit(drawPoints[i+1]);
  1034. var c = (pointi.x + pointi1.x) / 2;
  1035. var d = (pointi.y + pointi1.y) / 2;
  1036. ctx.quadraticCurveTo(pointi.x, pointi.y, c, d);
  1037. }
  1038. pointi = this.getPointSplit(drawPoints[i]);
  1039. pointi1 = this.getPointSplit(drawPoints[i+1]);
  1040. ctx.quadraticCurveTo(pointi.x, pointi.y, pointi1.x, pointi1.y );
  1041. ctx.stroke();
  1042. },
  1043. drawForRect: function(ctx, style, drawPoints){
  1044. var point1 = this.getPointSplit(drawPoints[0]);
  1045. var point2 = this.getPointSplit(drawPoints[1]);
  1046. if(!style.isNotClear){
  1047. ctx.clearCanvas();
  1048. }
  1049. // ctx.beginPath();
  1050. ctx.lineWidth = style.lineWidth;
  1051. ctx.lineCap = 'round';
  1052. ctx.lineJoin = 'round';
  1053. ctx.strokeStyle = style.strokeStyle;
  1054. ctx.stroke();
  1055. ctx.fillStyle = style.fillStyle;
  1056. ctx.fill();
  1057. if(style.isStroke){
  1058. ctx.strokeRect(point1.x, point1.y, point2.x - point1.x, point2.y - point1.y);
  1059. }else if(style.isFill){
  1060. ctx.rect(point1.x, point1.y, point2.x - point1.x, point2.y - point1.y);
  1061. }
  1062. },
  1063. drawForTriangle: function(ctx, style, drawPoints){
  1064. var point0 = this.getPointSplit(drawPoints[0]);
  1065. var point1 = this.getPointSplit(drawPoints[1]);
  1066. ctx.clearCanvas();
  1067. ctx.beginPath();
  1068. ctx.moveTo(point1.x, point1.y);
  1069. ctx.lineTo(point0.x - (point1.x - point0.x), point1.y);
  1070. ctx.lineTo(point0.x, point0.y - (point1.y - point0.y));
  1071. ctx.lineTo(point1.x, point1.y);
  1072. ctx.lineWidth = style.lineWidth;
  1073. ctx.lineCap = 'round';
  1074. ctx.lineJoin = 'round';
  1075. if(style.isStroke){
  1076. ctx.strokeStyle = style.strokeStyle;
  1077. ctx.stroke();
  1078. }
  1079. if(style.isFill){
  1080. ctx.fillStyle = style.fillStyle;
  1081. ctx.fill();
  1082. }
  1083. }
  1084. });
  1085. /*******************************************************************************************************************************/
  1086. /*******************************************************************************
  1087. * Cursor
  1088. *******************************************************************************/
  1089. var Cursor = function(){
  1090. }
  1091. Cursor.prototype = {
  1092. getType: function(){
  1093. return 'Cursor';
  1094. },
  1095. getCursor: function(){
  1096. return 'auto';
  1097. },
  1098. }
  1099. $.pureCanvas.toolkit.addToolkit(Cursor);
  1100. /*******************************************************************************
  1101. * HandCursor
  1102. *******************************************************************************/
  1103. var HandCursor = function(){
  1104. this.isDrawing = false;
  1105. this.downPoint = null;
  1106. this.eventCaller = null;
  1107. }
  1108. HandCursor.prototype = {
  1109. getType: function(){
  1110. return 'HandCursor';
  1111. },
  1112. getCursor: function(){
  1113. return 'all-scroll';
  1114. },
  1115. init: function(){
  1116. var THIS = this;
  1117. // scroll Event 추가
  1118. this.$main.on('scroll', function(e){
  1119. if(!THIS.isDrawing){
  1120. // Scroll Event의 과다 호출을 줄이기 위해 300ms 중지된 상태에서 이벤트를 호출한다.
  1121. clearTimeout(THIS.eventCaller);
  1122. //{type: 'recv', isTrigger: false}
  1123. // scroll 수신 시 trigger 호출 방지
  1124. var data = THIS.$main.data('pureCanvas-scroll');
  1125. if(data && !data.isTrigger){
  1126. THIS.$main.removeData('pureCanvas-scroll');
  1127. return;
  1128. }
  1129. THIS.eventCaller = setTimeout(function(){
  1130. THIS.sendScrollData(e);
  1131. }, 300);
  1132. }
  1133. });
  1134. },
  1135. drawStart: function(e){
  1136. //console.log(this.getType() + ' drawStart');
  1137. this.isDrawing = true;
  1138. this.downPoint = this.getPointSplit(e.point.org);
  1139. },
  1140. drawing: function(e){
  1141. //console.log(this.getType() + ' drawing');
  1142. if(this.isDrawing){
  1143. var movePoint = this.getPointSplit(e.point.org);
  1144. // 마우스가 이동한 만큼 scroll의 위치를 변경한다.
  1145. var left = this.$main.scrollLeft() + (this.downPoint.x - movePoint.x);
  1146. var top = this.$main.scrollTop() + (this.downPoint.y - movePoint.y);
  1147. this.$main.scrollLeft(left);
  1148. this.$main.scrollTop(top);
  1149. }
  1150. },
  1151. drawEnd: function(e){
  1152. //console.log(this.getType() + ' drawEnd');
  1153. if(this.isDrawing){
  1154. this.sendScrollData();
  1155. }
  1156. this.isDrawing = false;
  1157. },
  1158. draw: function(e){
  1159. //console.log(this.getType() + ' draw');
  1160. var toolkitData = e.toolkitData;
  1161. this.$main.scrollLeft(toolkitData.left);
  1162. this.$main.scrollTop(toolkitData.top);
  1163. },
  1164. }
  1165. $.pureCanvas.toolkit.addToolkit(HandCursor);
  1166. /*******************************************************************************
  1167. * Eraser
  1168. *******************************************************************************/
  1169. var Eraser = function(){
  1170. this.isEraser = false;
  1171. this.points = [];
  1172. this.pointsRate = [];
  1173. }
  1174. Eraser.prototype = {
  1175. getType: function(){
  1176. return 'Eraser';
  1177. },
  1178. getCursor: function(){
  1179. return 'crosshair';
  1180. },
  1181. drawStart: function(e){
  1182. //console.log(this.getType() + ' drawStart');
  1183. this.isEraser = true;
  1184. this.viewCtx.globalCompositeOperation = "destination-out";
  1185. this.mainCtx.globalCompositeOperation = "destination-out";
  1186. this.drawing(e);
  1187. },
  1188. drawing: function(e){
  1189. //console.log(this.getType() + ' drawing');
  1190. var drawStyle = this.getCustomStyleLine(this.getDrawStyle());
  1191. var drawTempStyle = this.getCustomStyleLine(this.toolkit.style);
  1192. if(this.isEraser){
  1193. this.points.push(e.point.org);
  1194. this.pointsRate.push(e.point.rate);
  1195. this.drawForLine(this.mainCtx, drawStyle, this.points);
  1196. this.drawForLine(this.viewCtx, drawTempStyle, this.pointsRate);
  1197. }
  1198. this.drawForPrePoint(this.drawCtx, this.getCustomStyle(drawStyle), e.point.org);
  1199. },
  1200. drawEnd: function(e){
  1201. //console.log(this.getType() + ' drawEnd');
  1202. if(e.isTouch){
  1203. this.drawCtx.clearCanvas();
  1204. }
  1205. if(this.isEraser){
  1206. this.sendDrawData(this.pointsRate);
  1207. this.$element.data('pure.pureCanvas').historyAdd();
  1208. }
  1209. this.isEraser = false;
  1210. this.points = [];
  1211. this.pointsRate = [];
  1212. },
  1213. drawOut: function(e){
  1214. //console.log(this.getType() + ' drawOut');
  1215. this.drawCtx.clearCanvas();
  1216. },
  1217. getCustomStyleLine: function(style){
  1218. var custom = $.extend({}, style);
  1219. custom.isNotClear = true;
  1220. return custom;
  1221. },
  1222. getCustomStyle: function(style){
  1223. var custom = $.extend({}, style);
  1224. custom.fillStyle = 'rgba(255,255,250, 0.7)';
  1225. custom.strokeStyle = 'black';
  1226. custom.isNotChange = true;
  1227. return custom;
  1228. },
  1229. draw: function(e){
  1230. //console.log(this.getType() + ' draw');
  1231. var toolkitData = e.toolkitData;
  1232. this.viewCtx.globalCompositeOperation = "destination-out";
  1233. this.mViewCtx.globalCompositeOperation = "destination-out";
  1234. this.drawForLine(this.viewCtx, this.getCustomStyleLine(toolkitData.style), this.getPointSplitList(toolkitData.points));
  1235. this.drawForLine(this.mViewCtx, this.getCustomStyleLine(toolkitData.style), this.getPointSplitList(toolkitData.points));
  1236. this.mainCanvasChange();
  1237. },
  1238. }
  1239. $.pureCanvas.toolkit.addToolkit(Eraser);
  1240. /*******************************************************************************
  1241. * ClearAll
  1242. *******************************************************************************/
  1243. var ClearAll = function(){
  1244. }
  1245. ClearAll.prototype = {
  1246. getType: function(){
  1247. return 'ClearAll';
  1248. },
  1249. getCursor: function(){
  1250. return 'auto';
  1251. },
  1252. instantProcess: function(e){
  1253. this.clearCanvas();
  1254. this.sendDrawData(null);
  1255. },
  1256. clearCanvas: function(){
  1257. $.each(this.canvasInfo, function(key, canvas){
  1258. if(canvas.clearView){
  1259. canvas.context.clearCanvas();
  1260. }
  1261. });
  1262. this.mainCanvasChange();
  1263. },
  1264. draw: function(e){
  1265. //console.log(this.getType() + ' draw');
  1266. this.clearCanvas();
  1267. },
  1268. }
  1269. $.pureCanvas.toolkit.addToolkit(ClearAll);
  1270. /*******************************************************************************
  1271. * Pen Abstract
  1272. *******************************************************************************/
  1273. var PenAbstract = {
  1274. getCursor: function(){
  1275. return 'crosshair';
  1276. },
  1277. drawStart: function(e){
  1278. //console.log(this.getType() + ' drawStart');
  1279. this.isDrawing = true;
  1280. this.drawing(e);
  1281. },
  1282. drawing: function(e){
  1283. //console.log(this.getType() + ' drawing');
  1284. var drawStyle = this.getCustomStyle(this.getDrawStyle());
  1285. var drawTempStyle = this.getCustomStyle(this.toolkit.style);
  1286. if(this.isDrawing){
  1287. if(!this.isLastSameCurrentPoint(this.points, e.point.org)){
  1288. this.points.push(e.point.org);
  1289. this.pointsRate.push(e.point.rate);
  1290. this.drawForLine(this.drawCtx, drawStyle, this.points);
  1291. this.drawForLine(this.drawTempCtx, drawTempStyle, this.pointsRate);
  1292. }
  1293. }
  1294. this.drawForPrePoint(this.drawCtx, drawStyle, e.point.org);
  1295. },
  1296. drawEnd: function(e){
  1297. //console.log(this.getType() + ' drawEnd');
  1298. if(this.isDrawing){
  1299. this.complateDraw({
  1300. copyFrom: this.canvasInfo.drawTemp,
  1301. copyTo: this.canvasInfo.view,
  1302. clear: [this.canvasInfo.draw, this.canvasInfo.drawTemp]
  1303. });
  1304. this.sendDrawData(this.pointsRate);
  1305. }
  1306. this.isDrawing = false;
  1307. this.points = [];
  1308. this.pointsRate = [];
  1309. },
  1310. drawOut: function(e){
  1311. //console.log(this.getType() + ' drawOut');
  1312. if(!this.isDrawing){
  1313. this.drawCtx.clearCanvas();
  1314. }
  1315. },
  1316. draw: function(e){
  1317. //console.log(this.getType() + ' draw');
  1318. var toolkitData = e.toolkitData;
  1319. this.drawForLine(this.recvDrawCtx, this.getCustomStyle(toolkitData.style), this.getPointSplitList(toolkitData.points));
  1320. this.complateDraw({
  1321. copyFrom: this.canvasInfo.recvDraw,
  1322. copyTo: this.canvasInfo.view,
  1323. clear: [this.canvasInfo.recvDraw]
  1324. });
  1325. },
  1326. }
  1327. /*******************************************************************************
  1328. * BallPen
  1329. *******************************************************************************/
  1330. var BallPen = function(){
  1331. this.isDrawing = false;
  1332. this.points = [];
  1333. this.pointsRate = [];
  1334. }
  1335. BallPen.prototype = {
  1336. getType: function(){
  1337. return 'BallPen';
  1338. },
  1339. getCustomStyle: function(style){
  1340. var custom = $.extend({}, style);
  1341. custom.fillStyle = custom.strokeStyle;
  1342. return custom;
  1343. },
  1344. }
  1345. $.extend(BallPen.prototype, PenAbstract);
  1346. $.pureCanvas.toolkit.addToolkit(BallPen);
  1347. /*******************************************************************************
  1348. * Highlighter
  1349. *******************************************************************************/
  1350. var Highlighter = function(){
  1351. this.isDrawing = false;
  1352. this.points = [];
  1353. this.pointsRate = [];
  1354. }
  1355. Highlighter.prototype = {
  1356. getType: function(){
  1357. return 'Highlighter';
  1358. },
  1359. getCustomStyle: function(style){
  1360. var custom = $.extend({}, style);
  1361. var hexStyle = this.rgbaToHex(custom.strokeStyle);
  1362. custom.strokeStyle = this.hexToRgba(hexStyle.hex, 50);
  1363. custom.fillStyle = custom.strokeStyle;
  1364. return custom;
  1365. },
  1366. }
  1367. $.extend(Highlighter.prototype, PenAbstract);
  1368. $.pureCanvas.toolkit.addToolkit(Highlighter);
  1369. /*******************************************************************************
  1370. * StraightLine
  1371. *******************************************************************************/
  1372. var StraightLine = function(){
  1373. this.isDrawing = false;
  1374. this.points = [];
  1375. this.pointsRate = [];
  1376. }
  1377. StraightLine.prototype = {
  1378. getType: function(){
  1379. return 'StraightLine';
  1380. },
  1381. getCursor: function(){
  1382. return 'crosshair';
  1383. },
  1384. drawStart: function(e){
  1385. //console.log(this.getType() + ' drawStart');
  1386. this.isDrawing = true;
  1387. var point = e.point;
  1388. this.points[0] = point.org;
  1389. this.pointsRate[0] = point.rate;
  1390. },
  1391. drawing: function(e){
  1392. //console.log(this.getType() + ' drawing');
  1393. var drawStyle = this.getCustomStyle(this.getDrawStyle());
  1394. var drawTempStyle = this.toolkit.style;
  1395. if(this.isDrawing){
  1396. var point = e.point;
  1397. this.points[1] = point.org;
  1398. this.pointsRate[1] = point.rate;
  1399. this.drawForLine(this.drawCtx, drawStyle, this.points);
  1400. this.drawForLine(this.drawTempCtx, drawTempStyle, this.pointsRate);
  1401. }
  1402. this.drawForPrePoint(this.drawCtx, drawStyle, e.point.org);
  1403. },
  1404. drawEnd: function(e){
  1405. //console.log(this.getType() + ' drawEnd');
  1406. if(this.isDrawing){
  1407. this.complateDraw({
  1408. copyFrom: this.canvasInfo.drawTemp,
  1409. copyTo: this.canvasInfo.view,
  1410. clear: [this.canvasInfo.draw, this.canvasInfo.drawTemp]
  1411. });
  1412. this.sendDrawData(this.pointsRate);
  1413. }
  1414. this.isDrawing = false;
  1415. this.points = [];
  1416. this.pointsRate = [];
  1417. },
  1418. drawOut: function(e){
  1419. //console.log(this.getType() + ' drawOut');
  1420. if(!this.isDrawing){
  1421. this.drawCtx.clearCanvas();
  1422. }
  1423. },
  1424. getCustomStyle: function(style){
  1425. var custom = $.extend({}, style);
  1426. return custom;
  1427. },
  1428. draw: function(e){
  1429. //console.log(this.getType() + ' draw');
  1430. var toolkitData = e.toolkitData;
  1431. this.drawForLine(this.recvDrawCtx, this.getCustomStyle(toolkitData.style), this.getPointSplitList(toolkitData.points));
  1432. this.complateDraw({
  1433. copyFrom: this.canvasInfo.recvDraw,
  1434. copyTo: this.canvasInfo.view,
  1435. clear: [this.canvasInfo.recvDraw]
  1436. });
  1437. },
  1438. }
  1439. $.pureCanvas.toolkit.addToolkit(StraightLine);
  1440. /*******************************************************************************
  1441. * Rectangle - Stroke
  1442. *******************************************************************************/
  1443. var Rectangle = function(){
  1444. this.isDrawing = false;
  1445. this.points = [];
  1446. this.pointsRate = [];
  1447. //
  1448. this.startPoints =[];
  1449. this.recWidth = null;
  1450. this.recHeight = null;
  1451. }
  1452. Rectangle.prototype = {
  1453. getType: function(){
  1454. return 'Rectangle';
  1455. },
  1456. getCursor: function(){
  1457. return 'crosshair';
  1458. },
  1459. drawStart: function(e){
  1460. //console.log(this.getType() + ' drawStart');
  1461. this.isDrawing = true;
  1462. var point = e.point;
  1463. this.points[0] = point.org;
  1464. this.pointsRate[0] = point.rate;
  1465. //
  1466. this.startPoints = point;
  1467. this._tmp = this.pointsRate;
  1468. this.sfflag = false;
  1469. //alert(e.point);
  1470. },
  1471. drawing: function(e){
  1472. //var this_recWidth = null;
  1473. //var this_recHeight = null;
  1474. //console.log(this.getType() + ' drawing');
  1475. var drawStyle = this.getCustomStyle(this.getDrawStyle());
  1476. var drawTempStyle = this.getCustomStyle(this.toolkit.style);
  1477. if(this.isDrawing){
  1478. var point = e.point;
  1479. console.log("startpoint:");
  1480. console.log(this.startPoints);
  1481. this.points[1] = point.org;
  1482. this.pointsRate[1] = point.rate;
  1483. // 计算要移动的点位
  1484. //this._tmp = this.pointsRate;
  1485. // 画矩形
  1486. if(move_flag){
  1487. //if(!this.recWidth&&!this.recHeight){
  1488. // this.recWidth = point.rate.split(" ")[0]-this.startPoints.org.split(" ")[0];
  1489. // this.recHeight = point.rate.split(" ")[1]-this.startPoints.org.split(" ")[1];
  1490. //}
  1491. //this.points[0] = e.offsetX-this.recWidth + " " +(e.offsetY-this.recHeight);
  1492. //this.points[1] = e.offsetX + " " +(e.offsetY);
  1493. ////
  1494. //this.pointsRate[0] = e.offsetX-this.recWidth + " " +(e.offsetY-this.recHeight);
  1495. //this.pointsRate[1] = e.offsetX + " " +(e.offsetY);
  1496. if(!this_recWidth&&!this_recHeight){
  1497. this_recWidth = point.rate.split(" ")[0]-this.startPoints.org.split(" ")[0];
  1498. this_recHeight = point.rate.split(" ")[1]-this.startPoints.org.split(" ")[1];
  1499. this_recWidth = e.offsetX-this.startPoints.org.split(" ")[0];
  1500. this_recHeight = e.offsetY-this.startPoints.org.split(" ")[1];
  1501. this.sfflag = true;
  1502. }
  1503. this.points[0] = (e.offsetX-this_recWidth) + " " +(e.offsetY-this_recHeight);
  1504. this.points[1] = e.offsetX + " " +e.offsetY;
  1505. //
  1506. this.pointsRate[0] = (e.offsetX-this_recWidth) + " " +(e.offsetY-this_recHeight);
  1507. this.pointsRate[1] = e.offsetX + " " +e.offsetY;
  1508. this.drawForRect(this.drawCtx, drawStyle, this.points);
  1509. //新的starpoint
  1510. var spoint = e.point;
  1511. //
  1512. this.startPoints.org = this.pointsRate[0];
  1513. this.startPoints.rate = this.pointsRate[0];
  1514. console.log("999999999999999999999999999999");
  1515. console.log(this.startPoints);
  1516. var new_pointsRate = [];
  1517. var _rate = $("#rate").val()/100;
  1518. new_pointsRate[0] = this.pointsRate[0].split(" ")[0]/_rate +" "+ this.pointsRate[0].split(" ")[1]/_rate;
  1519. new_pointsRate[1] = this.pointsRate[1].split(" ")[0]/_rate +" "+ this.pointsRate[1].split(" ")[1]/_rate;
  1520. this.pointsRate = new_pointsRate;
  1521. }else{
  1522. console.log("e.offsetxy:")
  1523. console.log(e.offsetX);
  1524. console.log(e.offsetY);
  1525. this.drawForRect(this.drawCtx, drawStyle, this.points);
  1526. if(this_recWidth&&this_recHeight){
  1527. this_recWidth = null;
  1528. this_recHeight = null;
  1529. }
  1530. }
  1531. // this.drawForRect(this.drawTempCtx, drawTempStyle, this.pointsRate);
  1532. }
  1533. this.drawForPrePoint(this.drawCtx, drawStyle, e.point.org);
  1534. },
  1535. drawEnd: function(e){
  1536. //console.log(this.getType() + ' drawEnd');
  1537. if(this.isDrawing){
  1538. this.complateDraw({
  1539. copyFrom: this.canvasInfo.drawTemp,
  1540. copyTo: this.canvasInfo.view,
  1541. clear: [this.canvasInfo.draw, this.canvasInfo.drawTemp]
  1542. });
  1543. //this.sendDrawData(this.pointsRate);
  1544. var new_pointsRate = [];
  1545. var _rate = $("#rate").val()/100;
  1546. new_pointsRate[0] = this.pointsRate[0].split(" ")[0]/_rate +" "+ this.pointsRate[0].split(" ")[1]/_rate;
  1547. new_pointsRate[1] = this.pointsRate[1].split(" ")[0]/_rate +" "+ this.pointsRate[1].split(" ")[1]/_rate;
  1548. if(this.sfflag){
  1549. //this.sendDrawData(new_pointsRate);
  1550. this.sendDrawData(this.pointsRate);
  1551. }else{
  1552. this.sendDrawData(this.pointsRate);
  1553. }
  1554. this.sfflag = false;
  1555. }
  1556. if(this_recWidth&&this_recHeight){
  1557. this_recWidth = null;
  1558. this_recHeight = null;
  1559. }
  1560. this.isDrawing = false;
  1561. this.points = [];
  1562. this.pointsRate = [];
  1563. },
  1564. drawOut: function(e){
  1565. //console.log(this.getType() + ' drawOut');
  1566. if(!this.isDrawing){
  1567. this.drawCtx.clearCanvas();
  1568. }
  1569. if(this_recWidth&&this_recHeight){
  1570. this_recWidth = null;
  1571. this_recHeight = null;
  1572. }
  1573. },
  1574. getCustomStyle: function(style){
  1575. var custom = $.extend({}, style);
  1576. custom.isStroke = true;
  1577. return custom;
  1578. },
  1579. draw: function(e){
  1580. //console.log(this.getType() + ' draw');
  1581. var toolkitData = e.toolkitData;
  1582. this.drawForRect(this.recvDrawCtx, this.getCustomStyle(toolkitData.style), this.getPointSplitList(toolkitData.points));
  1583. this.complateDraw({
  1584. copyFrom: this.canvasInfo.recvDraw,
  1585. copyTo: this.canvasInfo.view,
  1586. clear: [this.canvasInfo.recvDraw]
  1587. });
  1588. },
  1589. }
  1590. $.pureCanvas.toolkit.addToolkit(Rectangle);
  1591. /*******************************************************************************
  1592. * Circle - Stroke
  1593. *******************************************************************************/
  1594. var Circle = function(){
  1595. this.isDrawing = false;
  1596. this.points = [];
  1597. this.pointsRate = [];
  1598. }
  1599. Circle.prototype = {
  1600. getType: function(){
  1601. return 'Circle';
  1602. },
  1603. getCursor: function(){
  1604. return 'crosshair';
  1605. },
  1606. drawStart: function(e){
  1607. //console.log(this.getType() + ' drawStart');
  1608. this.isDrawing = true;
  1609. var point = e.point;
  1610. this.points[0] = point.org;
  1611. this.pointsRate[0] = point.rate;
  1612. },
  1613. drawing: function(e){
  1614. //console.log(this.getType() + ' drawing');
  1615. var drawStyle = this.getCustomStyle(this.getDrawStyle());
  1616. var drawTempStyle = this.getCustomStyle(this.toolkit.style);
  1617. if(this.isDrawing){
  1618. var point = e.point;
  1619. this.points[1] = point.org;
  1620. this.pointsRate[1] = point.rate;
  1621. this.drawForArc(this.drawCtx, drawStyle, this.points);
  1622. this.drawForArc(this.drawTempCtx, drawTempStyle, this.pointsRate);
  1623. }
  1624. this.drawForPrePoint(this.drawCtx, drawStyle, e.point.org);
  1625. },
  1626. drawEnd: function(e){
  1627. //console.log(this.getType() + ' drawEnd');
  1628. if(this.isDrawing){
  1629. this.complateDraw({
  1630. copyFrom: this.canvasInfo.drawTemp,
  1631. copyTo: this.canvasInfo.view,
  1632. clear: [this.canvasInfo.draw, this.canvasInfo.drawTemp]
  1633. });
  1634. this.sendDrawData(this.pointsRate);
  1635. }
  1636. this.isDrawing = false;
  1637. this.points = [];
  1638. this.pointsRate = [];
  1639. },
  1640. drawOut: function(e){
  1641. //console.log(this.getType() + ' drawOut');
  1642. if(!this.isDrawing){
  1643. this.drawCtx.clearCanvas();
  1644. }
  1645. },
  1646. getCustomStyle: function(style){
  1647. var custom = $.extend({}, style);
  1648. custom.isStroke = true;
  1649. return custom;
  1650. },
  1651. draw: function(e){
  1652. //console.log(this.getType() + ' draw');
  1653. var toolkitData = e.toolkitData;
  1654. this.drawForArc(this.recvDrawCtx, this.getCustomStyle(toolkitData.style), this.getPointSplitList(toolkitData.points));
  1655. this.complateDraw({
  1656. copyFrom: this.canvasInfo.recvDraw,
  1657. copyTo: this.canvasInfo.view,
  1658. clear: [this.canvasInfo.recvDraw]
  1659. });
  1660. },
  1661. }
  1662. $.pureCanvas.toolkit.addToolkit(Circle);
  1663. /*******************************************************************************
  1664. * Triangle - Stroke
  1665. *******************************************************************************/
  1666. var Triangle = function(){
  1667. this.isDrawing = false;
  1668. this.points = [];
  1669. this.pointsRate = [];
  1670. }
  1671. Triangle.prototype = {
  1672. getType: function(){
  1673. return 'Triangle';
  1674. },
  1675. getCursor: function(){
  1676. return 'crosshair';
  1677. },
  1678. drawStart: function(e){
  1679. //console.log(this.getType() + ' drawStart');
  1680. this.isDrawing = true;
  1681. var point = e.point;
  1682. this.points[0] = point.org;
  1683. this.pointsRate[0] = point.rate;
  1684. },
  1685. drawing: function(e){
  1686. //console.log(this.getType() + ' drawing');
  1687. var drawStyle = this.getCustomStyle(this.getDrawStyle());
  1688. var drawTempStyle = this.getCustomStyle(this.toolkit.style);
  1689. if(this.isDrawing){
  1690. var point = e.point;
  1691. this.points[1] = point.org;
  1692. this.pointsRate[1] = point.rate;
  1693. this.drawForTriangle(this.drawCtx, drawStyle, this.points);
  1694. this.drawForTriangle(this.drawTempCtx, drawTempStyle, this.pointsRate);
  1695. }
  1696. this.drawForPrePoint(this.drawCtx, drawStyle, e.point.org);
  1697. },
  1698. drawEnd: function(e){
  1699. //console.log(this.getType() + ' drawEnd');
  1700. if(this.isDrawing){
  1701. this.complateDraw({
  1702. copyFrom: this.canvasInfo.drawTemp,
  1703. copyTo: this.canvasInfo.view,
  1704. clear: [this.canvasInfo.draw, this.canvasInfo.drawTemp]
  1705. });
  1706. this.sendDrawData(this.pointsRate);
  1707. }
  1708. this.isDrawing = false;
  1709. this.points = [];
  1710. this.pointsRate = [];
  1711. },
  1712. drawOut: function(e){
  1713. //console.log(this.getType() + ' drawOut');
  1714. if(!this.isDrawing){
  1715. this.drawCtx.clearCanvas();
  1716. }
  1717. },
  1718. getCustomStyle: function(style){
  1719. var custom = $.extend({}, style);
  1720. custom.isStroke = true;
  1721. return custom;
  1722. },
  1723. draw: function(e){
  1724. //console.log(this.getType() + ' draw');
  1725. var toolkitData = e.toolkitData;
  1726. this.drawForTriangle(this.recvDrawCtx, this.getCustomStyle(toolkitData.style), this.getPointSplitList(toolkitData.points));
  1727. this.complateDraw({
  1728. copyFrom: this.canvasInfo.recvDraw,
  1729. copyTo: this.canvasInfo.view,
  1730. clear: [this.canvasInfo.recvDraw]
  1731. });
  1732. },
  1733. }
  1734. $.pureCanvas.toolkit.addToolkit(Triangle);
  1735. /*******************************************************************************
  1736. * CheckPoint
  1737. *******************************************************************************/
  1738. var CheckPoint = function(){
  1739. this.isDrawing = false;
  1740. this.points = [];
  1741. this.pointsRate = [];
  1742. }
  1743. CheckPoint.prototype = {
  1744. getType: function(){
  1745. return 'CheckPoint';
  1746. },
  1747. getCursor: function(){
  1748. return 'pointer';
  1749. },
  1750. drawStart: function(e){
  1751. //console.log(this.getType() + ' drawStart');
  1752. this.isDrawing = true;
  1753. this.drawing(e);
  1754. },
  1755. drawing: function(e){
  1756. //console.log(this.getType() + ' drawing');
  1757. var point = e.point;
  1758. this.points[0] = point.org;
  1759. this.pointsRate[0] = point.rate;
  1760. this.drawForCheckPoint(this.drawCtx, this.points);
  1761. },
  1762. drawEnd: function(e){
  1763. //console.log(this.getType() + ' drawEnd');
  1764. if(this.isDrawing){
  1765. this.drawForCheckPoint(this.drawTempCtx, this.pointsRate);
  1766. this.complateDraw({
  1767. copyFrom: this.canvasInfo.drawTemp,
  1768. copyTo: this.canvasInfo.view,
  1769. clear: [this.canvasInfo.draw, this.canvasInfo.drawTemp]
  1770. });
  1771. this.sendDrawData(this.pointsRate);
  1772. }
  1773. this.isDrawing = false;
  1774. this.points = [];
  1775. this.pointsRate = [];
  1776. },
  1777. drawOut: function(e){
  1778. //console.log(this.getType() + ' drawOut');
  1779. this.isDrawing = false;
  1780. this.drawCtx.clearCanvas();
  1781. },
  1782. defaultStyle: {
  1783. lineCap: 'round',
  1784. lineJoin: 'bevel',
  1785. lineWidth: 2,
  1786. strokeStyle: 'black',
  1787. fillStyle: 'red',
  1788. },
  1789. drawForCheckPoint: function(ctx, drawPoints){
  1790. var point = this.getPointSplit(drawPoints[0]);
  1791. ctx.clearCanvas();
  1792. ctx.beginPath();
  1793. ctx.moveTo(point.x - 10, point.y - 10);
  1794. ctx.lineTo(point.x, point.y);
  1795. ctx.lineTo(point.x + 20, point.y - 15);
  1796. ctx.lineTo(point.x + 16, point.y - 15);
  1797. ctx.lineTo(point.x, point.y - 4);
  1798. ctx.lineTo(point.x - 6, point.y - 10);
  1799. ctx.lineTo(point.x - 10, point.y - 10);
  1800. ctx.lineCap = this.defaultStyle.lineCap;
  1801. ctx.lineJoin = this.defaultStyle.lineJoin;
  1802. ctx.lineWidth = this.defaultStyle.lineWidth;
  1803. ctx.strokeStyle = this.defaultStyle.strokeStyle;
  1804. ctx.stroke();
  1805. ctx.fillStyle = this.defaultStyle.fillStyle;
  1806. ctx.fill();
  1807. },
  1808. draw: function(e){
  1809. //console.log(this.getType() + ' draw');
  1810. var toolkitData = e.toolkitData;
  1811. this.drawForCheckPoint(this.recvDrawCtx, this.getPointSplitList(toolkitData.points));
  1812. this.complateDraw({
  1813. copyFrom: this.canvasInfo.recvDraw,
  1814. copyTo: this.canvasInfo.view,
  1815. clear: [this.canvasInfo.recvDraw]
  1816. });
  1817. },
  1818. }
  1819. $.pureCanvas.toolkit.addToolkit(CheckPoint);
  1820. /*******************************************************************************
  1821. * HighlightPoint
  1822. *******************************************************************************/
  1823. var HighlightPoint = function(){
  1824. this.isDrawing = false;
  1825. this.points = [];
  1826. this.pointsRate = [];
  1827. }
  1828. HighlightPoint.prototype = {
  1829. getType: function(){
  1830. return 'HighlightPoint';
  1831. },
  1832. getCursor: function(){
  1833. return 'pointer';
  1834. },
  1835. drawStart: function(e){
  1836. //console.log(this.getType() + ' drawStart');
  1837. this.isDrawing = true;
  1838. this.drawing(e);
  1839. },
  1840. drawing: function(e){
  1841. //console.log(this.getType() + ' drawing');
  1842. var point = e.point;
  1843. this.points[0] = point.org;
  1844. this.pointsRate[0] = point.rate;
  1845. this.drawForHighlightPoint(this.drawCtx, this.points);
  1846. },
  1847. drawEnd: function(e){
  1848. //console.log(this.getType() + ' drawEnd');
  1849. if(this.isDrawing){
  1850. this.drawForHighlightPoint(this.drawTempCtx, this.pointsRate);
  1851. this.complateDraw({
  1852. copyFrom: this.canvasInfo.drawTemp,
  1853. copyTo: this.canvasInfo.mView,
  1854. copyToPreClear: true,
  1855. clear: [this.canvasInfo.draw, this.canvasInfo.drawTemp]
  1856. });
  1857. this.sendDrawData(this.pointsRate);
  1858. }
  1859. this.isDrawing = false;
  1860. this.points = [];
  1861. this.pointsRate = [];
  1862. },
  1863. drawOut: function(e){
  1864. //console.log(this.getType() + ' drawOut');
  1865. this.isDrawing = false;
  1866. this.drawCtx.clearCanvas();
  1867. },
  1868. defaultStyle: {
  1869. lineCap: 'round',
  1870. lineJoin: 'round',
  1871. lineWidth: 3,
  1872. strokeStyle: 'black',
  1873. gradient0: 'rgba(250,120,120, 0.9)',
  1874. gradient1: '#FF0000'
  1875. },
  1876. drawForHighlightPoint: function(ctx, drawPoints){
  1877. ctx.clearCanvas();
  1878. var p = this.getPointSplit(drawPoints[0]);
  1879. ctx.beginPath();
  1880. ctx.moveTo(p.x - 30, p.y - 12);
  1881. ctx.lineTo(p.x, p.y);
  1882. ctx.lineTo(p.x - 30, p.y + 12);
  1883. ctx.lineTo(p.x - 23, p.y);
  1884. ctx.lineTo(p.x - 30, p.y - 12);
  1885. // add linear gradient
  1886. var grd = ctx.createLinearGradient(p.x - 20, p.y - 10, p.x, p.y + 10);
  1887. grd.addColorStop(0, this.defaultStyle.gradient0);
  1888. grd.addColorStop(1, this.defaultStyle.gradient1);
  1889. ctx.lineCap = this.defaultStyle.lineCap;
  1890. ctx.lineJoin = this.defaultStyle.lineJoin;
  1891. ctx.lineWidth = this.defaultStyle.lineWidth;
  1892. ctx.strokeStyle = this.defaultStyle.strokeStyle;
  1893. ctx.stroke();
  1894. ctx.stroke();
  1895. ctx.fillStyle = grd;
  1896. ctx.fill();
  1897. },
  1898. draw: function(e){
  1899. //console.log(this.getType() + ' draw');
  1900. var toolkitData = e.toolkitData;
  1901. this.drawForHighlightPoint(this.recvDrawCtx, this.getPointSplitList(toolkitData.points));
  1902. this.complateDraw({
  1903. copyFrom: this.canvasInfo.recvDraw,
  1904. copyTo: this.canvasInfo.mView,
  1905. copyToPreClear: true,
  1906. clear: [this.canvasInfo.recvDraw]
  1907. });
  1908. },
  1909. }
  1910. $.pureCanvas.toolkit.addToolkit(HighlightPoint);
  1911. /*******************************************************************************
  1912. * MousePointer
  1913. *******************************************************************************/
  1914. var MousePointer = function(){
  1915. this.isDrawing = false;
  1916. this.eventCaller = null;
  1917. this.pointerMap = {me: null}
  1918. }
  1919. MousePointer.prototype = {
  1920. getType: function(){
  1921. return 'MousePointer';
  1922. },
  1923. getCursor: function(){
  1924. return 'crosshair';
  1925. },
  1926. startDraw: function(){
  1927. var THIS = this;
  1928. clearTimeout(this.drawEvent);
  1929. this.drawEvent = setTimeout(function(){
  1930. THIS.drawForMousePointer();
  1931. clearTimeout(THIS.drawEvent);
  1932. });
  1933. },
  1934. drawStart: function(e){
  1935. //console.log(this.getType() + ' drawStart');
  1936. this.isDrawing = true;
  1937. this.drawing(e);
  1938. },
  1939. drawing: function(e){
  1940. //console.log(this.getType() + ' drawing');
  1941. if(e.callMethod != 'drawStart' && this.pointerMap.me && this.pointerMap.me.points == e.point.org){
  1942. return;
  1943. }
  1944. this.pointerMap.me = {style: this.toolkit.style, points: e.point.org}
  1945. //this.drawForMousePointer();
  1946. this.startDraw();
  1947. // over시 전송일 경우, 클릭시 전송일 경우 이벤트 호출
  1948. if((!this.setting.pointerDownSend) || (this.setting.pointerDownSend && this.isDrawing)){
  1949. this.sendEvent([e.point.rate]);
  1950. }
  1951. },
  1952. drawEnd: function(e){
  1953. //console.log(this.getType() + ' drawEnd');
  1954. if(e.isTouch) this.pointerMap.me = null;
  1955. //this.drawForMousePointer();
  1956. this.startDraw();
  1957. if(this.setting.pointerDownSend){
  1958. this.sendEvent(null);
  1959. }
  1960. this.isDrawing = false;
  1961. },
  1962. drawOut: function(e){
  1963. //console.log(this.getType() + ' drawOut');
  1964. this.pointerMap.me = null;
  1965. //this.drawForMousePointer();
  1966. this.startDraw();
  1967. if((!this.setting.pointerDownSend)|| (this.setting.pointerDownSend && this.isDrawing)){
  1968. this.sendEvent(null);
  1969. }
  1970. this.isDrawing = false;
  1971. },
  1972. sendTest: function(){
  1973. var points = ["667 533","667 533","665 533","660 533","653 534","644 536","631 541","618 543","603 548","589 552","575 555","559 560","542 563","520 569","498 572","464 576","431 582","396 584","360 584","336 584","309 584","286 584","258 583","237 575","212 569","198 561","184 553","173 548","164 540","161 534","156 526","155 518","151 507","150 498","150 488","148 477","145 464","145 452","145 438","145 425","145 414","145 405","145 396","145 387","145 378","149 368","154 355","159 340","165 326","166 316","169 303","171 292","171 286","173 277","174 272","175 267","176 256","178 249","180 243","180 237","181 229","181 224","181 217","183 210","186 201","187 194","192 186","195 178","202 166","210 157","221 144","221 144","233 133","246 126","258 119","269 116","285 112","296 111","306 111","315 111","321 111","332 115","341 119","347 122","357 127","363 132","370 138","378 144","384 152","392 163","398 172","407 186","414 198","421 210","422 218","422 227","422 232","422 235","421 239","421 239","421 241","421 242","421 241","425 233","433 224","440 215","446 204","452 194","460 184","467 174","476 162","481 153","484 143","486 132","486 126","482 118","476 112","465 107","457 106","448 103","439 102","431 102","423 102","413 102","403 102","393 102","379 105","365 109","349 114","332 119","317 126","305 134","299 139","296 143","296 147","296 151","296 156","298 161","307 169","318 176","335 184","353 192","374 198","386 200","401 205","411 206","423 207","433 208","438 208","440 210","443 210","445 211","449 212","452 213","456 216","458 217","461 221","464 224","465 226","469 233","470 240","470 249","470 258","470 268","470 280","470 290","475 300","475 310","475 317","475 329","475 336","468 347","461 358","456 368","451 378","447 384","446 391","445 396","443 403","440 408","437 415","432 421","426 427","419 433","408 440","397 446","390 449","379 454","372 455","364 459","352 462","339 464","321 464","303 464","303 464","280 464","261 464","243 464","228 464","216 464","206 462","200 458","199 458","199 456","199 453","199 449","200 443","210 436","224 431","244 427","280 424","320 424","354 425","371 427","384 430","396 432","408 433","415 434","421 438","427 438","428 438","429 438","430 438","435 438","441 435","449 424","458 412","468 394","475 379","480 362","485 342","488 327","490 309","490 294","490 280","490 267","490 258","486 248","480 238","472 231","459 221","449 214","440 209","431 203","425 197","417 192","413 187","408 184","400 179","390 174","379 171","369 166","361 163","354 158","345 154","336 149","330 145","325 142","319 137","308 132","298 129","283 124","271 121","259 117","250 114","240 111","231 108","223 106","218 105","209 102","200 102","189 102","177 102","164 102","155 102","146 102","143 102","136 104","135 105","135 106","135 108","132 110","132 114","132 120","132 130","132 137","132 147","130 157","126 169","126 181","126 188","126 201","126 215","135 229","151 246","165 257","181 266","204 280","217 287","232 296","248 304","263 311","279 320","296 330","304 337","316 345","324 352","329 357","331 365","334 373","335 380","335 387","335 396","335 408","335 418","335 431","335 441","334 450","329 458","322 469","322 469","316 475","307 482","299 487","291 490","285 494","280 495","273 496","266 499","255 499","250 499","242 499","237 499","225 494","218 489","208 483","201 476","199 473","198 469","198 462","198 455","198 446","198 433","199 422","204 409","208 396","215 383","222 371","231 359","237 347","247 337","256 326","263 318","269 308","277 298","282 290","291 280","295 272","298 267","303 257","306 250","310 246","313 240","319 234","325 226","331 220","336 213","340 207","343 203","344 198","346 196","350 193","353 192","362 189","368 187","375 187","384 186","390 186","400 186","411 186","421 186","433 186","446 186","459 186","472 186","482 186","494 185","504 181","513 178","515 177","520 174","521 174","524 171","526 169","527 165","530 160","531 154","533 147","533 140","533 134","533 129","531 125","529 119","526 114","520 108","516 102","514 100","511 97","507 93","502 90","500 89","495 87","486 83","479 82","472 81","464 77","455 76","446 72","436 71","427 70","417 68","406 68","393 68","378 68","361 68","347 68","335 68","323 69","312 69","307 71","300 72","293 73","283 73","278 74","270 78","263 79","256 83","252 85","248 88","246 89","243 93","243 96","239 103","237 109","237 114","237 121","237 126","237 132","237 132","237 138","237 142","238 148","240 155","247 164","253 173","261 181","267 190","278 200","283 204","287 212","295 219","299 224","309 230","319 235","328 237","338 243","349 248","360 252","371 256","380 261","387 265","396 270","403 274","409 281","415 286","419 290","423 296","427 300","433 309","436 313","441 321","445 328","446 331","451 337","453 341","458 347","463 355","468 362","471 372","476 382","478 391","482 403","483 412","484 421","484 427","484 434","484 439","484 444","484 449","482 457","479 461","475 465","467 473","462 476","456 480","451 481","440 486","436 487","427 489","421 490","410 492","399 493","385 495","372 495","358 495","343 495","329 495","310 495","298 495","281 495","261 489","247 487","231 481","219 476","209 470","203 467","199 463","195 454","193 445","193 435","193 427","193 417","195 409","202 399","210 390","215 384","218 378","223 371","227 364","231 356","234 349","238 345","243 341","249 336","255 335","263 330","267 329","273 328","276 325","280 323","285 319","289 316","293 311","301 305","307 299","315 290","321 282","328 272","333 264","336 255","341 247","345 239","347 232","353 224","353 219","357 214","360 206","364 202","366 197","369 193","373 185","374 181","375 175","375 169","375 164","375 156","375 156","375 150","375 144","375 138","374 132","374 126","372 121","372 116","371 111","368 105","368 102","367 97","367 95","367 91","369 89","371 87","374 84","377 84","380 84","384 84","390 84","395 84","402 84","410 84","421 85","435 89","447 92","458 95","468 98","479 102","487 103","494 108","498 110","500 113","500 114","501 117","501 118","502 122","503 126","504 132","507 136","510 143","513 149","517 156","520 160","524 168","525 171","526 175","529 184","531 187","532 193","532 200","532 208","535 217","537 229","538 237","539 249","542 261","544 269","548 281","550 292","553 303","556 311","556 323","556 332","556 343","556 350","556 360","556 368","556 378","556 383","556 390","556 393","556 397","554 400","552 404","549 407","546 411","543 417","538 423","534 427","527 431","521 435","509 440","501 445","490 448","482 452","470 458","463 458","452 463","445 466","434 468","424 471","415 471","403 473","390 473","377 473","364 473","350 473","341 473","327 470","313 465","302 460","291 451","281 441","274 431","268 421","263 409","261 403","261 391","261 379","261 368","261 355","261 342","261 329","261 314","264 301","269 286","274 272","279 260","286 248","293 236","300 226","306 218","313 210","317 202","324 195","324 195","330 189","336 181","341 174","348 169","354 165","359 163","367 157","375 155","384 151","396 145","404 144","418 138","431 135","441 132","453 130","467 125","477 122","490 118","506 117","520 111","532 108","547 104","561 101","577 99","596 96","614 95","637 90","663 87"];
  1974. var THIS = this;
  1975. var sendTimer = function(){
  1976. if(points.length <= 0){
  1977. THIS.sendEvent(null);
  1978. return;
  1979. }
  1980. var point = points.shift();
  1981. THIS.sendEvent([point]);
  1982. setTimeout(sendTimer, 6);
  1983. };
  1984. setTimeout(sendTimer, 0);
  1985. // $.each(points, function(index, point){
  1986. // THIS.sendEvent([point]);
  1987. // });
  1988. },
  1989. sendEvent: function(points){
  1990. var THIS = this;
  1991. // 지연 설정 이후에 이벤트를 발생한다. 과도한 이벤트 발생 방지
  1992. clearTimeout(this.eventCaller);
  1993. //this.eventCaller = setTimeout(function(){THIS.sendDrawData(points);}, this.setting.delayMousePoint);
  1994. },
  1995. drawForMousePointer: function(ctx){
  1996. if(!ctx) ctx = this.canvasInfo.pointer.context;
  1997. var THIS = this;
  1998. ctx.clearCanvas();
  1999. $.each(this.pointerMap, function(key, data){
  2000. if(!data){return;}
  2001. var style = data.style;
  2002. var points = data.points;
  2003. var nowTime = new Date().getTime();
  2004. if(key != 'me' && (nowTime - (10 * 1000) > data.timeStamp)){
  2005. points = null;
  2006. delete THIS.pointerMap[key];
  2007. }
  2008. // pointer의 위치가 canvas를 떠났을 경우 points가 null로 전송된다.
  2009. if(!points){
  2010. ctx.clearCanvas();
  2011. return;
  2012. }
  2013. var drawPoints = THIS.getPointSplitList(points);
  2014. var point = THIS.getPointSplit(drawPoints[0]);
  2015. if(key != 'me'){
  2016. point.x *= THIS.setting.rateVal;
  2017. point.y *= THIS.setting.rateVal;
  2018. }
  2019. ctx.save();
  2020. ctx.beginPath();
  2021. ctx.arc(point.x, point.y, 50, 2 * Math.PI, false);
  2022. // create radial gradient
  2023. var grd;
  2024. // down전송 시 mousedown event가 발생하지 않은 경우, mousepointer를 작게 표시
  2025. if(key == 'me' && THIS.setting.pointerDownSend && !THIS.isDrawing){
  2026. grd = ctx.createRadialGradient(point.x, point.y, 0, point.x, point.y, 13);
  2027. }
  2028. // mousepointer 일반적인 크기
  2029. else{
  2030. grd = ctx.createRadialGradient(point.x, point.y, 5, point.x, point.y, 15);
  2031. }
  2032. grd.addColorStop(0, style.strokeStyle);
  2033. grd.addColorStop(1, "rgba(255,255,255,0)");
  2034. ctx.fillStyle = grd;
  2035. ctx.fill();
  2036. ctx.closePath();
  2037. ctx.restore();
  2038. });
  2039. },
  2040. draw: function(e){
  2041. var toolkitData = e.toolkitData;
  2042. // 좌표정보가 있는 경우 마우스포인트 정보를 설정한다.
  2043. if(toolkitData.points){
  2044. this.pointerMap[toolkitData.id] = {style: toolkitData.style, points: toolkitData.points, timeStamp: e.timeStamp};
  2045. }
  2046. // 좌표정보가 없는 경우 마우스포인트 정보를 삭제한다.
  2047. else{
  2048. delete this.pointerMap[toolkitData.id];
  2049. }
  2050. //this.drawForMousePointer();
  2051. this.startDraw();
  2052. },
  2053. }
  2054. $.pureCanvas.toolkit.addToolkit(MousePointer);
  2055. /************************************************************************************/
  2056. /** add native function **/
  2057. // Canvas Context - Clear Canvas
  2058. CanvasRenderingContext2D.prototype.clearCanvas = function(){
  2059. this.clearRect(0, 0, this.canvas.width, this.canvas.height);
  2060. };
  2061. /************************************************************************************/
  2062. //
  2063. //去除多余的canvas
  2064. $("canvas:eq(1)").remove();
  2065. $("canvas:eq(1)").remove();
  2066. }(jQuery);