TiledViz
Loading...
Searching...
No Matches
Tile.js
1
4
5$(document).ready( function (){
6
7Tile = function(Mesh) {
8
9
10 //***************************************************private variable***************************************************//
11
12 var nodeRef=this; // Reference to the node
13
14 var mesh=Mesh; // Each node has a reference to the mesh to which it belongs
15
16 var id = nodeIdProvider(); // Each node gets an unique id
17
18 var className = "node"; // Each node belongs to "node" class
19
20 var jsonData = jsDataTab[id]; // The data related to the node, url which contains simulations, visualisations, metadata etc.
21 //It is loaded from the js file : nodes.js
22
23 var loaded = false; /* state of url load */
24
25 var onoff = true; /* state of on/off toggle */
26
27 var nodeinviewport = false; /* This variable indicate if the node is visible in viewport */
28
29 var qrcoded = false;
30
31 if(useJsonDataLocation==false) { // Id of the place where the node is located on the mesh (the mesh is a grid)
32 var idLocation = id;
33 }
34 else if (useJsonDataLocation==true) {
35 var idLocation = parseInt(jsonData.IdLocation);
36 }
37 //For example, the id location on a grid with 3 columns ans 3 lines :
38 // | 1 | 2 | 3 |
39 // | 4 | 5 | 6 |
40 // | 7 | 8 | 9 |
41
42 var isMoving = true; // Is the node already moving (true at init) ?
43
44 var mlocation = mesh.me.mlocationProvider(idLocation); // The idLocation determines the node location on the mesh with the idLocation parameters
45 var location = mesh.me.locationProvider(idLocation); // The idLocation determines the node location on the screen with the idLocation parameters
46
47 var nodeHeight=mesh.me.getSpread().Y; // Height of a node, depends of the mesh parameters SPREAD
48 var nodeWidth=mesh.me.getSpread().X; // Width of a node, depends of the mesh parameters SPREAD
49
50 var init_tile = true; // save init state
51
52 var state = 0; // This variable is similar to the focus, just a way to know if the node is selected by users
53 //States :
54 // 0 = not clicked
55 // 1 = hovered
56 // 2 = clicked
57 // 3 = drag and drop achieved
58 // 4 = transparent
59
60 var isSelected=false; /* This variable is another way to specify if the node is selected
61 (we need a second variable to check selection because they are many options
62 which need a selection so we need many way to know if the node is selected) */
63
64 var nodeOpacity = configBehaviour.opacity;
65
66 var nodeAngle = 0; // Angle for rotation
67
68 // Html tag of the node
69 var htmlNode = ( function(){
70 htmlPrimaryParent.append('<div id='+id+' class='+className+'></div>');
71 $('#'+id).css({height : nodeHeight, width : nodeWidth, display: "block", margin: "auto" , backgroundColor : "none"});
72 $('#'+id).append('<div id=onoff'+id+' class=onoff>'+ id +'</div>');
73 $('#onoff'+id).hide();
74 $('#'+id).append('<div id=hitbox'+id+' class=hitbox></div>');
75 $('#hitbox'+id).hide();
76
77 var infoToDisplay = "";
78
79 // Handle to drag
80 $('#'+id).append('<div id=handle'+id+' class=handle></div>');
81 $('#handle'+id).addClass("drag-handle-on");
82
83 if (configJsonData.useTitle && jsonData.title != "") {
84 infoToDisplay = jsonData.title.replace(".png", "");
85 } else {
86 infoToDisplay = id;
87 }
88 $('#'+id).append('<div id=info'+id+' class=info>' + infoToDisplay +'</div>');
89 $('#'+id).append('<div id=rotate'+id+' class=rotate></div>');
90 $("#rotate"+id).hide();
91 return $('#'+id);
92 }());
93
94 this.sub=function(elt) {
95 return $("#"+elt+id);
96 }
97
98 this.init_htmlNode=function() {
99 $('#hitbox'+id).css('background-color', colorHBdefault);
100 $('#hitbox'+id).show();
101 $('#info'+id).css("font-family", configBehaviour.infoFonts[Math.min(configBehaviour.defaultFontIndex, configBehaviour.infoFonts.length)]);
102 $('#info'+id).css("color", configBehaviour.infoTextColor);
103 $('#info'+id).css("font-size", configBehaviour.defautInfoFontSize);
104
105 // Handle to rotate
106 $("#rotate"+id).css({
107 left : (parseInt($('#'+id).css("width"))/2-70)+'px',
108 top : (parseInt($('#'+id).css("height"))-15)+'px',
109 '-webkit-transform': "scale(0.5)",
110 '-moz-transform': "scale(0.5)",
111 '-transform': "scale(0.5)",
112 });
113
114 };
115
116 //this.init_htmlNode();
117 var jsNode = document.getElementById(id);
118
121 var nodeTagList = [];
122 var floatingTag = {};
123
124 this.initTag = function(thisjson) {
125 if (typeof thisjson.tags != 'undefined') {
126 var nodeTagListTmp = [];
127 var floatingTagTmp = {};
128 if (typeof thisjson.tags == "object") {
129 nodeTagListTmp = thisjson.tags;
130 }
131 else if (typeof thisjson.tags == "string" && thisjson.tags != "") {
132 nodeTagListTmp = thisjson.tags.split(",");
133 }
134
135
136 for (var item=0;item<nodeTagListTmp.length;item++) {
137 if ( nodeTagListTmp[item].search('{')==0 ) {
138 if ( nodeTagListTmp[item].search('{"') == -1 ) {
139 nodeTagListTmp[item]=nodeTagListTmp[item].replace(/{([^,]*),([^,]*),([^,]*),([^,]*)}/,
140 '{"name":"$1","m":$2,"val":$3,"M":$4}')
141 }
142 nodeTagListTmp[item]=JSON.parse(nodeTagListTmp[item]);
143 name=newTag_conformance(nodeTagListTmp[item].name);
144 floatingTagTmp[name]={"id": item, "m":nodeTagListTmp[item].m,"val":nodeTagListTmp[item].val, "M":nodeTagListTmp[item].M};
145 nodeTagListTmp[item]=name
146 } else {
147 nodeTagListTmp[item] = newTag_conformance(nodeTagListTmp[item]);
148 }
149 }
150 nodeTagList = nodeTagListTmp;
151 floatingTag = floatingTagTmp;
152 }
153 if (! nodeTagList.some(function(e) {return e=='Off'}) )
154 nodeTagList.push("Off");
155 nodeTagList.sort();
156 // Add On at the end to initialise its color and globalTagsList.
157 if ( nodeTagList.some(function(e) {return e=='On'}) )
158 nodeTagList.splice(nodeTagList.findIndex(function(e) {return e=='On'}),1);
159 nodeTagList.push("On");
160 }
161 this.initTag(jsonData);
162
166
167 var initialNote = "";
168 if(typeof jsonData.usersNotes != 'undefined') {
169 initialNote = jsonData.usersNotes;
170 }
171 //test
172 initialNote = jsonData.comment;
173 //"test" + id;
174 //#004
175 $.PostItAll.new({
176
177 id : "postit"+id, // The ID of the HTMLTag of the post it
178 content : initialNote, // prewritten on the post it
179 // Position and size
180 position : 'absolute',
181 width : mesh.me.getSpread().X, // At the moment, the post it takes the same space as the node on the mesh
182 height : mesh.me.getSpread().Y,
183 posX : location.getX(),
184 posY : location.getY() + mesh.me.getSpread().Y ,
185
186 style : { // GLOBAL ?
187 tresd : true, // General style in 3d format
188 backgroundcolor : "grey", // Background color in new postits when randomColor = false
189 textcolor : "white", // Text color
190 textshadow : true, // Shadow in the text
191 fontfamily : 'verdana', // Default font
192 fontsize : 80, // Default font size
193 arColumn : 'none', // Default arColumn : none, top, right, bottom, left
194 },
195
196 onDblClick: function (id) { return undefined; } // Triggered on double click
197
198 }, // Callback function, executed after postit creation
199 function(){
200 $('#postit'+id).css({display : "none"});
201 });
202
239 var menuTitleTab = new Array();
240 var menuEventTab = new Array();
241
242
246 var menuIconClassAttributesTab = new Array();
247
252 var MenuShareEvent = new Array();
253
254 // To make a node transparent and enable to overlap other nodes
255 menuTitleTab.push("Transparent mode to overlay")
256 menuEventTab.push( function(v, nodeId, optionNumber){
257 if (v==true) {
258 if (configBehaviour.onlyOneTransparentTile && me.getTransparent()!=-1) {
259 $('#menu'+me.getTransparent()+'>#option'+optionNumber).click();
260 }
261 me.setTransparent(nodeId, true);
262 nodeRef.setOpacityLocation();
263
264 $("#menu"+nodeId+">#option"+optionNumber).addClass("closeTransparentButtonIcon").removeClass("transparentButtonIcon");
265 } else {
266 me.setTransparent(nodeId, false);
267 $("#menu"+nodeId+">#option"+optionNumber).addClass("transparentButtonIcon").removeClass("closeTransparentButtonIcon");
268 }
269 }
270 );
271
272 menuIconClassAttributesTab.push("transparentButtonIcon");
273 MenuShareEvent.push(true);
274
275 // The options to display or not node's postIt
276 menuTitleTab.push("Display tile's postIt")
277 menuEventTab.push( function(v,nodeId,optionNumber){
278
279 if(v==true) {
280
281 nodeRef.updatePostItPositionandSize();
282 //$.PostItAll.show('postit'+nodeId);
283
284 // This part of code is to show off the postIt if the user resizes the screen or tries to move a node
285 var hidePostIt = function(event){
286
287 event.stopPropagation();
288 $("#menu"+nodeId+">#option"+optionNumber).click();
289 //$("#"+nodeId);
290 $( window ).off("resize",hidePostIt);
291 //$(".node").off("mousedown",hidePostIt);
292
293 };
294
295 $( window ).resize(hidePostIt) ;
296 //$('.node').mousedown(hidePostIt);
297
298 // Replace the "open option" icon with the "close option" icon
299 $("#menu"+nodeId+">#option"+optionNumber).addClass("closeWriteButtonIcon").removeClass("writeButtonIcon");
300 } else {
301 $( window ).off("resize",hidePostIt);
302 $.PostItAll.hide('postit'+nodeId);
303
304 // Replace the "close option" icon with the "open option" icon
305 $("#menu"+nodeId+">#option"+optionNumber).addClass("writeButtonIcon").removeClass("closeWriteButtonIcon");
306 }
307 });
308
309 menuIconClassAttributesTab.push("writeButtonIcon");
310 MenuShareEvent.push(true);
311
317
318 var zoomAndDrawOnNodes = ( function() {
319 var initialSpread = me.getSpread(); // or mesh.me.getSpread ?
320
321 return function (nodeId){
322
323 // First : zoom on the node $(#nodeId) with the function magnifyingGlass
324 // Compute arguments for magnifyingGlass
325 var ratio = me.getSpread().Y/me.getSpread().X;
326 //console.log("Ratio in zoomAndDrawOnNodes: " + ratio);
327 var nodeTab = new Array();
328 nodeTab.push(me.getNode(nodeId));
329
330 // Add unZoom button
331 $('body').append('<div id=buttonUnzoom class=unzoomButtonIcon></div>');
332 //$('#buttonUnzoom').hide();
333
334 // This function is defined on the mesh constructor and allow us to zoom on the selected node
335 me.magnifyingGlass(nodeTab,ratio,initialSpread, false, 0.5);
336
337 // Here we define the layer where the users will draw
338 var height = $('#zoomSupport > #Zoomed0').css('height');
339 var width = $('#zoomSupport > #Zoomed0').css('width');
340 var supportTop = parseInt($('#zoomSupport').css('top').replace('px',''));
341 var supportLeft = parseInt($('#zoomSupport').css('left').replace('px',''));
342
343 // NB: ("#zoomSupport") has been defined in the magnifyingGlass function (not to be confused with helpSupport)
344 // The Zoomed0 : is a div with the iframe scaled of the real node,
345 // so we no more need to delete some child of $('#zoomSupport > #'+nodeId): menu and hitbox
346
347
348 // Activate draw menu
349 menuDraw.css("visibility", "visible");
350 menuDraw.css("top", TagHeight+"px");
351
352 // // Deactivate other magnify menus
353 // me.disableOtherZoom("draw")
354
355 // Creation of the layer $("#drawCanvas") on the support if it doesn’t already exist
356 var supp = document.getElementById("drawCanvas"+nodeId);
357 if (supp==null) {
358 $('#zoomSupport').append('<canvas id="drawCanvas'+nodeId+'" class=drawing height='+height+' width='+width+'></canvas>');
359
360 $("#drawCanvas"+nodeId).css({// GLOBALCSS ?
361 position : "absolute",
362 top : 0,
363 left : 0,
364 width : $('#zoomSupport > #Zoomed0').css('width'),
365 height : $('#zoomSupport > #Zoomed0').css('height'),
366 zIndex : 300
367 });
368 } else {
369 $('#drawCanvas'+nodeId).show();
370 }
371
372
373 // Variables needed to draw on the iframe
374 // This tutorial http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/ can be helpful to understand the following code
375 var clickX = new Array();
376 var clickY = new Array();
377 var clickDrag = new Array();
378 var paint = false;
379 var p=0; // number of paths
380
381 var context = document.getElementById("drawCanvas"+nodeId).getContext("2d");
382 function addClick(x, y, dragging) {
383 clickX.push(x);
384 clickY.push(y);
385 clickDrag.push(dragging);
386 }
387
388
389 var mousedownDraw = function(e){
390 try {
391 context.strokeStyle = drawingColor;
392 }
393 catch(e) {
394 drawingColor = configBehaviour.draw.defaultColor;
395 context.strokeStyle = drawingColor;
396 }
397 context.lineJoin = configBehaviour.draw.style;
398 context.lineWidth = configBehaviour.draw.width;
399
400
401 var mouseX = e.pageX - supportLeft;
402 var mouseY = e.pageY - supportTop;
403
404 paint = true;
405 addClick(mouseX , mouseY);
406 redraw();
407 }
408
409 var mousemoveDraw = function(e){
410
411 if(paint) {
412 var mouseX = e.pageX - supportLeft;
413 var mouseY = e.pageY - supportTop;
414
415 addClick(mouseX , mouseY, true);
416 redraw();
417 }
418 }
419
420 var mouseupDraw = function(e){
421
422 paint = false;
423 }
424
425 $('#drawCanvas'+nodeId).on({
426 mousedown : mousedownDraw,
427 mousemove : mousemoveDraw,
428 mouseup : mouseupDraw,
429 });
430
431
432 function redraw(){
433
434 for(var i=p; i < clickX.length; i++) {
435
436 p++;
437 context.beginPath();
438
439 if(clickDrag[i] && i) {
440 context.moveTo(clickX[i-1]/* + supportTop */, clickY[i-1]);
441 } else {
442 context.moveTo(clickX[i]-1/* + supportTop */ , clickY[i]);
443 }
444
445 context.lineTo(clickX[i], clickY[i]);
446 context.closePath();
447 context.stroke();
448 }
449 }
450
451 var drawing = new Map(); // maps touch IDs to drag state objects
452 var p=0; // number of paths
453
454 context = document.getElementById("drawCanvas"+nodeId).getContext("2d");
455
456 var touchstartDraw = function (ev) {
457 var hastouched=false;
458 try {
459 context.strokeStyle = drawingColor;
460 }
461 catch(e) {
462 drawingColor = configBehaviour.draw.defaultColor;
463 context.strokeStyle = drawingColor;
464 }
465 context.lineJoin = configBehaviour.draw.style;
466 context.lineWidth = configBehaviour.draw.width;
467
468 for (var i = 0; i < ev.changedTouches.length; i++) {
469 var touch = ev.changedTouches[i];
470 var targetid=touch.target.id;
471 console.log("touchstartDraw targetid "+targetid+" point "+touch.pageX +" "+touch.pageY );
472 var mouseX = touch.pageX - supportLeft;
473 var mouseY = touch.pageY - supportTop;
474
475 drawing.set(touch.identifier, {
476 target: touch.target,
477 mouseX : mouseX,
478 mouseY : mouseY,
479 });
480
481 hastouched=true;
482 }
483 if (hastouched) {
484 hastouched=false;
485 ev.preventDefault();
486 //ev.stopPropagation()
487 }
488 }
489
490 var touchmoveDraw = function (ev) {
491 var hastouched=false;
492 for (var i = 0; i < ev.changedTouches.length; i++) {
493 var touch = ev.changedTouches[i];
494 var targetid=touch.target.id;
495 console.log("touchmoveDraw targetid "+targetid+" rect "+touch.pageX +" "+touch.pageY );
496 var mouseX = touch.pageX - supportLeft;
497 var mouseY = touch.pageY - supportTop;
498
499 var drawstate = drawing.get(touch.identifier);
500
501 context.beginPath();
502
503 context.moveTo(drawstate.mouseX, drawstate.mouseY);
504
505 context.lineTo(mouseX, mouseY);
506 context.closePath();
507 context.stroke();
508
509
510 drawstate.mouseX = mouseX;
511 drawstate.mouseY = mouseY;
512
513
514 hastouched=true;
515 }
516 if (hastouched) {
517 hastouched=false;
518 ev.preventDefault();
519 //ev.stopPropagation()
520 }
521 }
522
523 var touchendDraw = function (ev) {
524 var hastouched=false;
525 for (var i = 0; i < ev.changedTouches.length; i++) {
526 var touch = ev.changedTouches[i];
527 var targetid=touch.target.id;
528 console.log("touchendDraw targetid "+targetid+" rect "+touch.pageX +" "+touch.pageY );
529 drawing.delete(touch.identifier);
530
531 hastouched=true;
532 }
533 if (hastouched) {
534 hastouched=false;
535 ev.preventDefault();
536 //ev.stopPropagation()
537 }
538 }
539
540 $('#drawCanvas'+nodeId).on({
541 touchstart: touchstartDraw,
542 touchmove: touchmoveDraw,
543 touchend: touchendDraw
544 });
545 };
546 })()
547
550 menuTitleTab.push("Draw on tile")
551 menuEventTab.push( function(v,nodeId,optionNumber){
552
553 if(v==true) {
554 // Deactivate other magnify menus
555 me.disableOtherZoom("draw")
556 BlockDragAndDrop();
557
558 zoomAndDrawOnNodes(nodeId);
559 // Creation of a button to unzoom
560 $('#buttonUnzoom').on({
561 click : function(){
562 $(".node").off();
563 // Hide draw menu
564 menuDraw.css("visibility", "hidden");
565 // Activate other magnify menus
566 me.enableOtherZoom("draw")
567 EnableDragAndDrop();
568
569 $('#drawCanvas'+nodeId).hide();
570 $("#button").off();
571 //console.log("unzoom", $('#button'));
572 $("#button").remove();
573 //$('.hitbox').off("click");
574 me.meshEventReStart();
575 }
576 });
577 } else {
578
579 // Hide draw menu
580 menuDraw.css("visibility", "hidden");
581
582 //$('#buttonUnzoom') has been created on magnifyingGlass function himself called on zoomAndDrawOnNodes
583 $('#buttonUnzoom').on({
584
585 // Delete all tools created on magnifyingGlass and zoomAndDrawOnNodes
586 click : function(){
587 //console.log("click unzoom button");
588 $(".node").off();
589 // Hide draw menu
590 menuDraw.css("visibility", "hidden");
591 // Activate other magnify menus
592 me.enableOtherZoom("draw")
593 EnableDragAndDrop();
594
595 $('#drawCanvas'+nodeId).hide();
596 me.meshEventReStart();
597 }
598 });
599
600 }
601
602 }
603 );
604
605 menuIconClassAttributesTab.push("drawButtonIcon");
606 MenuShareEvent.push(false);
607
608 // To switch columns
609 menuTitleTab.push("To switch columns")
610 menuEventTab.push( function(v,nodeId,optionNumber){
611
612 if(v==true) {
613
614 if(mesh.me.getcolumnSelected() == -1 ) {
615
616 mesh.me.setcolumnSelected(mesh.me.mlocationProvider( mesh.me.getNode(nodeId).getIdLocation()).getnX());
617 //console.log("colonne : "+mesh.me.mlocationProvider( mesh.me.getNode(nodeId).getIdLocation()).getnX());
618
619 var allnodes=mesh.me.getNodes();
620 for(O in allnodes) {
621 if(mesh.me.getcolumnSelected() == mesh.me.mlocationProvider( allnodes[O].getIdLocation()).getnX() )
622 allnodes[O].getHtmlNode().css('boxShadow', configCSS.columnSwapBoxShadow);
623 }
624
625 }
626 else if(mesh.me.getcolumnSelected() != -1) {
627 var secondColumnSelected = mesh.me.mlocationProvider( mesh.me.getNode(nodeId).getIdLocation()).getnX();
628
629
630
631 var column1Tab = [];
632 var column2Tab = [];
633
634 var allnodes=mesh.me.getNodes();
635 for(O in allnodes) {
636
637 if(mesh.me.getcolumnSelected() == mesh.me.mlocationProvider( allnodes[O].getIdLocation()).getnX() ) {
638 column1Tab.push( allnodes[O]);
639 allnodes[O].getHtmlNode().css({
640 boxShadow: "none"});
641 }
642
643 if(secondColumnSelected == mesh.me.mlocationProvider( allnodes[O].getIdLocation()).getnX() ) {
644 column2Tab.push( allnodes[O]);
645 }
646
647 }
648
649 var i = 0 ;
650 for(i=0;i<column1Tab.length;i++) {
651 var tmpBoolBlockMove = i == 0 ? false : true;
652 if(typeof column1Tab[i]!= "undefined" && typeof column2Tab[i]!= "undefined" ) {
653 mesh.me.switchLocation(column1Tab[i],column2Tab[i],configBehaviour.showAnimationsLineColSwap,true, tmpBoolBlockMove);
654 }
655 }
656 mesh.me.setcolumnSelected(-1);
657 }
658
659
660
661 //console.log(column1Tab);
662 //console.log(column2Tab);
663
664 $("#menu"+nodeId+">#option"+optionNumber).click();
665 } else {
666
667
668
669
670 }
671 }
672 );
673
674 menuIconClassAttributesTab.push("columnButtonIcon");
675 MenuShareEvent.push(true);
676
677 // To switch lines
678 menuTitleTab.push("To switch lines")
679 menuEventTab.push( function(v,nodeId,optionNumber){
680
681 if(v==true) {
682
683 if(mesh.me.getlineSelected() == -1 ) {
684
685 mesh.me.setlineSelected(mesh.me.mlocationProvider( mesh.me.getNode(nodeId).getIdLocation()).getnY());
686 //console.log("line : "+mesh.me.mlocationProvider( mesh.me.getNode(nodeId).getIdLocation()).getnY());
687
688 var allnodes=mesh.me.getNodes();
689 for(O in allnodes) {
690 if(mesh.me.getlineSelected() == mesh.me.mlocationProvider( allnodes[O].getIdLocation()).getnY() )
691 allnodes[O].getHtmlNode().css('boxShadow', configCSS.lineSwapBoxShadow);
692 }
693 }
694 else if(mesh.me.getlineSelected() != -1) {
695 var secondLineSelected = mesh.me.mlocationProvider( mesh.me.getNode(nodeId).getIdLocation()).getnY();
696 //console.log(secondLineSelected);
697
698
699 var line1Tab = [];
700 var line2Tab = [];
701
702 var allnodes=mesh.me.getNodes();
703 for(O in allnodes) {
704 //console.log("aa",mesh.me.getlineSelected(),mesh.me.mlocationProvider( allnodes[O].getIdLocation()).getnY());
705 if(mesh.me.getlineSelected() == mesh.me.mlocationProvider( allnodes[O].getIdLocation()).getnY() ) {
706 line1Tab.push( allnodes[O]);
707 allnodes[O].getHtmlNode().css({boxShadow: "none"});
708 }
709
710 if(secondLineSelected == mesh.me.mlocationProvider( allnodes[O].getIdLocation()).getnY() ) {
711 line2Tab.push( allnodes[O]);
712 }
713
714 }
715
716 var i = 0 ;
717 for(i=0;i<line1Tab.length;i++) {
718 var tmpBoolBlockMove = i == 0 ? false : true;
719 if(typeof line1Tab[i]!= "undefined" && typeof line2Tab[i]!= "undefined" ) {
720 mesh.me.switchLocation(line1Tab[i],line2Tab[i],configBehaviour.showAnimationsLineColSwap, true, tmpBoolBlockMove);
721 }
722 }
723 mesh.me.setlineSelected(-1);
724 }
725
726
727
728 //console.log(line1Tab);
729 //console.log(line2Tab);
730
731 $("#menu"+nodeId+">#option"+optionNumber).click();
732 } else {
733
734
735
736
737 }
738 }
739 );
740
741 menuIconClassAttributesTab.push("lineButtonIcon");
742 MenuShareEvent.push(true);
743
744 var nodeMenu="";
745 this.setOpacityLocation = function () {};
746
747 this.buildmenu=function() {
748
749 // Don't build menu if not visible in start or if it already exists.
750 if ((init_tile && ! this.isInViewport()) || nodeMenu) {
751 init_tile=false
752 return
753 }
754
756 nodeMenu = new Menu(id,htmlNode,menuTitleTab,menuEventTab,menuIconClassAttributesTab,MenuShareEvent,{
757
758 // Position
759 position : "absolute",
760 top : -120, // GLOBAL ?
761 left : 0,
762 // Style
763 visible : "hidden",
764 //margin : "0px 5px 10px 15px", // Not useful, only for the menu and not the buttons
765
766 // Button default class
767 classN : "node",
768 // Button size
769 height : 100,
770 width : 100,
771 rightMargin : 30,
772 // Button style
773 //borderStyle : "solid", // GLOBAL
774 //borderWidth : "5px", // GLOBAL
775 //borderColor : "blue" //GLOBAL
776 menubox : false
777 });
778
779 var mymenu=$('#menu'+id);
780 $(OpacityZone).append("<div id=tile-opacity-"+id+" class=tile-opacity-menu-zone></div>");
781 // tileOpacitySlider is placed after the transparentButtonIcon (in first place)
782 var tile_opacity = $('#tile-opacity-'+id);
783 var buttonOpacity="";
784 var hbuttonOpacity="";
785 var tileOpacityLeft="";
786 var hmymenu=parseInt(mymenu.css("height"));
787 var wtile=parseInt($('#'+id).css("width"));
788 var locationTop="";
789 var locationLeft="";
790 function delayedOpacity() {
791 setTimeout(function() {
792 if (mymenu[0].childNodes.length < 1)
793 delayedOpacity();
794 else {
795 buttonOpacity=$(mymenu[0].childNodes[1]);
796 hbuttonOpacity=buttonOpacity[0];
797 tileOpacityLeft=parseInt(buttonOpacity.css("left"))+20;
798 locationTop=parseInt(buttonOpacity.css("top"));
799 locationLeft=tileOpacityLeft;
800 }
801 }, 100);
802 };
803 delayedOpacity();
804 this.setOpacityLocation = function () {
805 if (tile_opacity.css("visibility")=="visible") {
806 var rect = hbuttonOpacity.getBoundingClientRect();
807 var realposTop=rect.top;
808 var realposLeft=rect.left+20;
809 var absTop=realposTop+locationTop;
810 var absLeft=realposLeft+locationLeft;
811 tile_opacity.css({
812 position : "absolute",
813 top : absTop,
814 left : absLeft,
815 height : hmymenu,
816 width : wtile - tileOpacityLeft,
817 zIndex : 130
818 });
819 }
820 }
821 //this.setOpacityLocation();
822 tile_opacity.css("visibility","hidden")
823
824 //tile_opacity.append("<input id=tileOpacitySlider"+id+" class=tile-opacity-slider type='range' name=tileOpacitySlider"+id+" min=0 max=100 value="+nodeOpacity*100+">");
825 if ( this.isInViewport()) {
826 if (configBehaviour.alwaysShowInfo) {
827 $('#info'+id).show();
828 }
829 }
830 }
831
835 var stickers = new Stickers(id,htmlNode);
836
837 this.tileUpdateStickers = function () {
838 var newTags=[];
839 for(var k=0;k < nodeTagList.length;k++) {
840 var name=nodeTagList[k];
841 if ($.inArray(name, globalTagsList) == -1) {
842 newTags.push(name);
843 globalTagsList.push(name);
844 var l=globalTagsList.length-1;
845 if (name in floatingTag) {
846 globalFloatingTags[name]={"l":l,"m":floatingTag[name]["m"], "M":floatingTag[name]["M"]}
847 var outColors=ColorSticker(l,floatingTag[name]);
848 globalFloatingTags[name]["cm"]=outColors["cm"];
849 globalFloatingTags[name]["cM"]=outColors["cM"];
850 globalFloatingTags[name]["symb"]=outColors["symb"];
851 attributedTagsColorsArray[name] = globalFloatingTags[name]["cm"];
852 } else {
853 globalTagsColors[name]={"l":l};
854 attributedTagsColorsArray[name] = ColorSticker(l);
855 }
856 }
857 if (configTagsBehaviour.showAll) {
858 if (name in floatingTag) {
859 var outColors=ColorSticker(globalFloatingTags[name]["l"],floatingTag[name]);
860 stickers.addSticker(name,attributedTagsColorsArray[name],false,outColors,floatingTag[name]["val"]);
861 } else {
862 stickers.addSticker(name,attributedTagsColorsArray[name],false);
863 }
864 }
865 }
866 globalTagsList.sort();
867
868 return newTags;
869 }
870 var newTags=this.tileUpdateStickers();
871
872 // remove Off tag at the end of nodeTagList.
873 stickers.removeSticker('On',true);
874 nodeTagList.pop();
875 //console.log("nodeTagList",nodeTagList)
876
878 var thezoomnode = ""
879 this.init_zoomnode=function() {
880 thezoomnode = new zoomNodes(id);
881 }
882 //this.init_zoomnode();
883
886 var theqrcode = "";
887
888 //***************************************************methods***************************************************//
889
890
891 //*****loaded******//
892
893 this.getLoadedStatus = function() {
894 return loaded;
895 }
896
897 this.setLoadedStatus = function (bool) {
898 loaded = bool;
899 if (bool) {
900 if ( nodeTagList.some(function(e) {return e=='Off'}) ) {
901 nodeTagList[nodeTagList.findIndex(function(e) {return e=='Off'})] = "On";
902 stickers.removeSticker('Off',false);
903 stickers.addSticker("On",attributedTagsColorsArray["On"],true);
904 this.setQRcodeStatus()
905 this.setOnOffStatus(true)
906 }
907 } else {
908 if ( nodeTagList.some(function(e) {return e=='On'}) ) {
909 nodeTagList[nodeTagList.findIndex(function(e) {return e=='On'})] = "Off";
910 stickers.removeSticker('On',false);
911 stickers.addSticker("Off",attributedTagsColorsArray["Off"],true);
912 this.setOnOffStatus(false)
913 }
914 }
915 //console.log("nodeTagList setLoadedStatus",nodeTagList, bool)
916 }
917
918
919 //*****OnOff******//
920
921 this.getOnOffStatus = function() {
922 return onoff;
923 }
924
925 this.setOnOffStatus = function (bool) {
926 onoff = bool;
927 if (bool)
928 if (this.getNodeInViewportStatus()) {
929 var iframe = $('#iframe'+id);
930 iframe.css("display","inline")
931 } else {
932 this.isInViewport();
933 }
934 }
935
936 //*****NodeInViewport******//
937
938 this.getNodeInViewportStatus = function() {
939 return nodeinviewport;
940 }
941
942 this.setNodeInViewportStatus = function () {
943 this.isInViewport();
944 }
945
946 //*****QRcode******//
947 this.getQRcodeStatus = function() {
948 return qrcoded;
949 }
950
951 this.setQRcodeStatus = function() {
952 if (! qrcoded)
953 theqrcode = new QRcodes(id,jsonData);
954 qrcoded=true;
955 }
956 //******id & idLocation******//
957
958 //--getter
959 this.getId = function(){
960 return id;
961 };
962
963 //--getter
964 this.getIdLocation = function(){
965 return idLocation;
966 };
967
968 //--setter
969 this.setIdLocation = function(idloc){
970 idLocation=idloc;
971 };
972
973
974 //******Menu******//
975
976 this.getNodeMenu = function(){
977
978 return nodeMenu;
979 };
980
981 //******jsonData******//
982
983 //--getter
984 this.getJsonData = function(){
985 return jsonData;
986 };
987
988 //--setter
989 this.setJsonDataUrl = function(newurl){
990 jsonData.url=newurl;
991 };
992
993 //*****Comment******//
994
995 this.getComment = function() {
996 return $('#postit'+id).text().replace(/[0-9][0-9]\/[0-9][0-9]\/[0-9][0-9][0-9][0-9] \([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)Note config.*/,"")
997 }
998
999 //******nodeOpacity******//
1000
1001 //--getter
1002 this.getNodeOpacity = function(){
1003 //console.log("get no",nodeOpacity);
1004 return nodeOpacity;
1005 };
1006
1007 //--setter
1008 this.setNodeOpacity = function(newOpacValue){
1009 nodeOpacity = newOpacValue;
1010 //console.log("set no", nodeOpacity);
1011 };
1012
1013 //******nodeAngle******//
1014
1015 //--getter
1016 this.getNodeAngle = function(){
1017 //console.log("get no",nodeAngle);
1018 return nodeAngle;
1019 };
1020
1021 //--setter
1022 this.setNodeAngle = function(newAngleValue){
1023 nodeAngle = newAngleValue;
1024 //console.log("set no", nodeOpacity);
1025 };
1026
1027 //******nodeTagList*****//
1028 //--getter
1029 this.getNodeTagList = function(){
1030 return nodeTagList;
1031 };
1032 //--addElement
1033 this.addElementToNodeTagList = function(text_){
1034 if (nodeTagList.indexOf(text_)==-1) {
1035 nodeTagList.push(text_);
1036 nodeTagList.sort();
1037 }
1038 //console.log("after addition", nodeTagList);
1039 };
1040
1041 //--removeElement
1042 this.removeElementFromNodeTagList = function(text_){
1043 for(var i=0;i<nodeTagList.length;i++) {
1044 if (nodeTagList[i]==text_) {
1045 nodeTagList.splice(i,1);
1046 break;
1047 }
1048
1049 }
1050 stickers.removeSticker(text_,true);
1051 //console.log("after removing", nodeTagList);
1052 };
1053
1054
1055 //****** floatingTag *****//
1056 //--getter
1057 this.getFloatingTag = function(){
1058 return floatingTag;
1059 };
1060
1061 //--setter
1062 this.setFloatingTag = function(floatingT){
1063 floatingTag=floatingT;
1064 };
1065
1066 //******Stickers******//
1067
1068 //--getter
1069 this.getStickers = function(){
1070 return stickers;
1071 };
1072
1073 //******QRcode******//
1074
1075 //--getter
1076 this.getQRcode = function(){
1077 return theqrcode;
1078 };
1079
1080
1081 //******isMoving******//
1082
1083 //--getter
1084 this.getIsMoving = function(){
1085 return isMoving;
1086 }
1087
1088 //--setter
1089 this.setIsMoving = function(boolmoving){
1090
1091 isMoving=boolmoving;
1092 }
1093
1094
1095
1096
1097 //******htmlNode******//
1098
1099 //--getter
1100 this.getHtmlNode = function(){
1101
1102 return htmlNode;
1103 }
1104
1105 //--update
1119
1120 this.isInViewport = function() {
1121 var hnode=this.getHtmlNode();
1122 var pnode=hnode.position();
1123 var maxLeft=relativeLeft+pnode.left+parseInt(hnode.css("width"));
1124 var minRight=relativeLeft+pnode.left;
1125 var maxTop=pnode.top+parseInt(hnode.css("height"));
1126 var minDown=pnode.top;
1127 var window_test=my_window["left"] < maxLeft &&
1128 my_window["right"] > minRight &&
1129 my_window["top"] < maxTop &&
1130 my_window["down"] > minDown
1131 //console.log("window test :",window_test)
1132 nodeinviewport = window_test
1133 return window_test;
1134 };
1135
1136 this.updateUrl = function() {
1137 var id=this.getId();
1138 var iframe = $('#iframe'+id);
1139 if(this.getJsonData().url!='undefined' && this.getOnOffStatus()) {
1140 ifrdisp=iframe.css("display")
1141 if (ifrdisp != "inline" && ifrdisp != "block") {
1142 iframe.show();
1143 //this.setLoadedStatus(this.isInViewport());
1144 if (iframe.attr("src") == "") {
1145 iframe.attr("src",this.getJsonData().url);
1146 this.setLoadedStatus(true);
1147 }
1148 } else {
1149 // loadfunction = function () {
1150 if ( this.isInViewport() ) {
1151 if (iframe.attr("src") == "") {
1152 iframe.attr("src",this.getJsonData().url);
1153 this.setLoadedStatus(true);
1154 var ONst=iframe.css("display");
1155 if (ONst == "none")
1156 iframe.css("display","inline")
1157 }
1158 } else {
1159 iframe.attr("src","");
1160 //iframe.attr("src",this.getJsonData().url);
1161 iframe.css("display","none");
1162 this.setLoadedStatus(false);
1163 }
1164 // }
1165 // loadfunction()
1166 //setTimeout(loadfunction, id*100);
1167 }
1168 }
1169 };
1170 //this.updateUrl(); //already first call in next function updateHtmlNodeFromLoc
1171
1172 this.updateHtmlNodeFromLoc = function(loc){
1173 var position = {};
1174 position.left=loc.getX();
1175 position.top=loc.getY();
1176 // This line is the grid :
1177 htmlNode.offset(position);
1178 // jsNode.style.offsetLeft = position.left
1179 // jsNode.style.offsetTop = position.top;
1180 //jsNode.left = position.left
1181 //jsNode.top = position.top;
1182 // Update URL if tile becomes visible
1183 this.updateUrl();
1184 location.setX(position.left);
1185 location.setY(position.top);
1186 };
1187
1188 this.updateHtmlNodeFromHW = function(newHeight,newWidth){
1189 htmlNode.css({height : newHeight , width : newWidth});
1190 };
1191
1192 this.updateLocFromHtmlNode = function(booleanAnimation){
1193 location.setX(jsNode.offsetLeft);
1194 location.setY(jsNode.offsetTop);
1195 };
1196
1197 this.updatedata = function(tile2) {
1198 jsonData=tile2;
1199
1200 if ("usersNotes" in tile2) {
1201 NewNote = tile2.usersNotes;
1202 } else if ("comment" in tile2) {
1203 NewNote = tile2.comment;
1204 }
1205 $('#postit'+id).text(NewNote);
1206
1207 var infoToDisplay = "";
1208 if (configJsonData.useTitle && tile2.title != "") {
1209 infoToDisplay = tile2.title.replace(".png", "");
1210 } else {
1211 infoToDisplay = id;
1212 }
1213 $('#info'+id).html(infoToDisplay)
1214
1215 var oldNodeTagList=nodeTagList;
1216 var oldFloatingTag=floatingTag;
1217 stickers.resetStickerTab();
1218 this.initTag(tile2);
1219
1220 // Update Global Tag and Stickers :
1221 var newTags=this.tileUpdateStickers();
1222
1223 if (this.getOnOffStatus())
1224 stickers.removeSticker('Off');
1225 else
1226 stickers.removeSticker('On');
1227
1228 return newTags;
1229 };
1230
1231 //******State******//
1232 //remember state is a number and are just a way to distinguish different state of the node
1233 //States : 0 = not clicked
1234 // 1 = hovered
1235 // 2 = clicked
1236 // 3 = drag and drop achieved
1237 // 4 = transparent
1238
1239 //--update
1240 this.updateHtmlNodeState = function(newState){
1241 state=newState;
1242 }
1243
1244 //--getter
1245 this.getState = function(){
1246 return state;
1247 };
1248
1249
1250
1251 //******Selected******//
1252
1253 //--update node
1254 //remember state is a boolean and are just another way to distinguish if the node is selected or not
1255
1256 this.updateSelectedStatus = function(newStatus){
1257
1258 isSelected=newStatus;
1259
1260 if(isSelected==true) {
1261 mesh.addSelectedNode(this);
1262 //$('#'+id).css("color","red");
1263 var HB=$('#hitbox'+id);
1264 HB.css('background-color', colorHBselected);
1265 } else {
1266 mesh.removeSelectedNode(this);
1267 var HB=$('#hitbox'+id);
1268 HB.css('background-color', colorHBdefault);
1269 }
1270 }
1271
1272 //--getter node selected status
1273 this.getSelectedStatus = function(){
1274 return isSelected;
1275 };
1276
1277
1278
1279 //******height and width******//
1280
1281 this.updateHW= function (newHeight,newWidth){
1282 // minHeight and minWidth are yet to test !
1283 if(typeof newHeight == 'number' && newHeight > configBehaviour.minHeight) {
1284 height=newHeight;
1285 } else {
1286 height=configBehaviour.minHeight;
1287 }
1288
1289 if(typeof newWidth == 'number' && newWidth > configBehaviour.minWidth) {
1290 width=newWidth;
1291 } else {
1292 width=configBehaviour.minWidth;
1293 }
1294
1295 this.updateHtmlNodeFromHW(height, width);
1296 }
1297
1298
1299
1300
1301 //******location & mlocation******//
1302
1303 //--getter
1304 this.getLocation = function (){
1305
1306 return location;
1307 }
1308
1309 //--getter
1310 this.getmLocation = function (){
1311
1312 return mlocation;
1313 }
1314
1315 //--setter
1316
1317 this.setLocation = function(loc, boolAnimation, speed_){
1318
1319 if(boolAnimation==true && this.getIsMoving()==false ) {
1320
1321 this.setIsMoving(true);
1322
1323 //this.updateLocFromHtmlNode();
1324 var currentLoc = this.getLocation();
1325 loc.setX(loc.getX());
1326 loc.setY(loc.getY());
1327 var sx=loc.getX()-currentLoc.getX();
1328 var sy=loc.getY()-currentLoc.getY();
1329 var distInit = Math.sqrt(sx*sx+sy*sy);
1330
1331 if(typeof speed_ =='number' && speed_ > 0 ) {
1332 var speed = parseInt(speed_);
1333 } else {
1334 var speed=parseInt(configBehaviour.animationSpeed);
1335 //console.log(speed);
1336 }
1337
1338 var hnode=this;
1339 var u=0;
1340 var realmove = function() {
1341 hnode.updateLocFromHtmlNode();
1342 currentLoc = hnode.getLocation();
1343 u++;
1344
1345 var slocx=loc.getX()-currentLoc.getX();
1346 var slocy=loc.getY()-currentLoc.getY();
1347 var distLoc=Math.sqrt(slocx*slocx+slocy*slocy);
1348 if(distLoc>speed+1 && u<50) {
1349 // Do we really need that callback ?
1350 move();
1351 hnode.setOpacityLocation();
1352 } else {
1353 hnode.setLocation(me.locationProvider(hnode.getIdLocation()) );
1354 //return 0;
1355 }
1356 }
1357 var move = function(){
1358 $('#'+hnode.getId()).animate({ "left" : "+="+speed*sx/distInit, "top" : "+="+speed*sy/distInit}, 10, "linear",realmove)
1359
1360 return 0;
1361 };
1362
1363 move();
1364 } else {
1365 location = loc;
1366 this.updateHtmlNodeFromLoc(location, boolAnimation);
1367 }
1368 this.setIsMoving(false);
1369 this.setOpacityLocation();
1370
1371 if (!init_tile && !nodeMenu)
1372 this.buildmenu();
1373 if ( this.getNodeInViewportStatus() ) {
1374 if (configBehaviour.alwaysShowInfo) {
1375 $('#info'+id).show();
1376 }
1377 }
1378
1379 }
1380
1381
1382
1383 //******Post It All ******//
1384
1385 //--update position & size
1386 this.updatePostItPositionandSize = function(){
1387
1388 // for(var k=0;k < nodeTagList.length;k++) {
1389 // var name=nodeTagList[k];
1390 // if (name in floatingTag) {
1391 // $('#postit'+id).text($('#postit'+id).text()+'\n'
1392 // +floatingTag[name]["m"].toString()+" <= "+floatingTag[name]["val"].toString()+" <= "+floatingTag[name]["M"].toString());
1393 // }
1394 // }
1395
1396 var options = {id : "postit"+id,posX : this.getLocation().getX() , posY : this.getLocation().getY() + mesh.me.getSpread().Y };
1397 //, width : mesh.me.getSpread().X, height : mesh.me.getSpread().Y
1398 $('#postit'+id).postitall('options', options);
1399 //$('#postit'+id).remove();
1400
1401
1402 };
1403
1404
1405
1406 //******Special methods ******//
1407
1408
1409
1411 ( function(){
1412 nodeRef.setLocation(location,false);
1413 }());
1414
1415};
1416 })