Ver a proveniência

refactored to use requirejs

tags/v0.2.0^2
big bad waffle há 6 anos
ascendente
cometimento
e586f4e303
13 ficheiros alterados com 601 adições e 431 eliminações
  1. +0
    -139
      helpers/passives/generator.js
  2. +0
    -65
      helpers/passives/helpers.js
  3. +3
    -15
      helpers/passives/index.html
  4. +24
    -0
      helpers/passives/js/app.js
  5. +15
    -0
      helpers/passives/js/constants.js
  6. +47
    -0
      helpers/passives/js/events.js
  7. +105
    -0
      helpers/passives/js/generator.js
  8. +156
    -0
      helpers/passives/js/input.js
  9. +60
    -0
      helpers/passives/js/main.js
  10. +163
    -0
      helpers/passives/js/renderer.js
  11. +28
    -0
      helpers/passives/js/tplNode.js
  12. +0
    -175
      helpers/passives/renderer.js
  13. +0
    -37
      helpers/passives/ui.js

+ 0
- 139
helpers/passives/generator.js Ver ficheiro

@@ -1,139 +0,0 @@
var generator = {
links: [],
nodes: [],

selected: null,

init: function () {
this.actions.addNode.call(this, null, {
x: 23,
y: 14
});

renderer.center(this.nodes[0]);
},

onClick: function (button, x, y) {
if (button == 0) {
if (ui.shiftDown)
this.actions.moveNode.call(this, x, y);
else {
this.actions.addNode.call(this, null, {
x: x,
y: y
});
}
} else if (button == 1) {
var node = this.findNode(x, y);
if (node)
this.actions.selectNode.call(this, node);
} else if (button == 2) {
var node = this.findNode(x, y);
if (node)
this.actions.connectNode.call(this, node);
}

renderer.makeDirty();
},

findNode: function (x, y) {
return this.nodes.find(n => ((n.pos.x == x) && (n.pos.y == y)));
},

actions: {
selectNode: function (node) {
if (this.selected)
this.selected.selected = false;
node.selected = true;
this.selected = node;

ui.setActive(node);
},

addNode: function (parent, options = {}) {
var node = tplNode.build({
id: this.nodes.length,
x: options.x,
y: options.y
});

this.nodes.push(node);
},

connectNode: function (node) {
if (this.selected) {
if (ui.shiftDown) {
this.links.spliceWhere(l => (
(
(l.from == node) ||
(l.to == node)
) &&
(
(l.from == this.selected) ||
(l.to == this.selected)
) &&
(node != this.selected)
));
} else {
this.links.push({
from: this.selected,
to: node
});
}
this.selected = null;
} else
this.selected = node;
},

moveNode: function (x, y) {
if (!this.selected)
return;

this.selected.pos.x = x;
this.selected.pos.y = y;
},

recolorNode: function () {
if (!this.selected)
return;

this.selected.color = (this.selected.color + 1) % 4;
},

resizeNode: function () {
if (!this.selected)
return;

this.selected.size = (this.selected.size + 1) % 3;
}
}
};

var tplNode = {
id: 0,
color: 0,
size: 0,
pos: {
x: 0,
y: 0
},

build: function (options) {
var res = $.extend(true, {}, this, {
id: this.id++,
pos: {
x: options.x,
y: options.y
}
});
delete res.build;

return res;
}
};

$(function () {
ui.init();
renderer.init();
generator.init();
})

+ 0
- 65
helpers/passives/helpers.js Ver ficheiro

@@ -1,65 +0,0 @@
Array.prototype.firstIndex = function (callback, thisArg) {
var T = thisArg;
var O = Object(this);
var len = O.length >>> 0;

var k = 0;

while (k < len) {
var kValue;

if (k in O) {
kValue = O[k];

if (callback.call(T, kValue, k, O))
return k;
}
k++;
}

return -1;
};

Array.prototype.spliceWhere = function (callback, thisArg) {
var T = thisArg;
var O = Object(this);
var len = O.length >>> 0;

var k = 0;

while (k < len) {
var kValue;

if (k in O) {
kValue = O[k];

if (callback.call(T, kValue, k, O)) {
O.splice(k, 1);
k--;
}
}
k++;
}
};

Array.prototype.spliceFirstWhere = function (callback, thisArg) {
var T = thisArg;
var O = Object(this);
var len = O.length >>> 0;

var k = 0;

while (k < len) {
var kValue;

if (k in O) {
kValue = O[k];

if (callback.call(T, kValue, k, O)) {
O.splice(k, 1);
return kValue;
}
}
k++;
}
};

+ 3
- 15
helpers/passives/index.html Ver ficheiro

@@ -3,26 +3,14 @@
<head>
<title>test</title>
<link rel="stylesheet" href="styles.css">
<script src="../../src/client/plugins/jquery.min.js"></script>
<script src="renderer.js"></script>
<script src="generator.js"></script>
<script src="ui.js"></script>
<script src="helpers.js"></script>
<script src="../../src/client/plugins/require.js" data-main="js/app"></script>
</head>
<body>
<div class="left">
<canvas></canvas>
<canvas class="canvas"></canvas>
</div>
<div class="right">
<div class="id"></div>
<div class="commands">
<div class="command">a: add nodes</div>
<div class="command">e: extend nodes</div>
<div class="command">r: rotate nodes</div>
<div class="command">c: closen nodes</div>
<div class="command">f: furthen nodes</div>
<div class="command"></div>
</div>
</div>
</body>
</html>

+ 24
- 0
helpers/passives/js/app.js Ver ficheiro

@@ -0,0 +1,24 @@
require.config({
baseUrl: '',
waitSeconds: 120,
paths: {
'jquery': '../../src/client/plugins/jquery.min',
},
shim: {
'jquery': {
exports: '$'
}
}
});

require([
'../../src/client/js/misc/helpers',
'jquery',
'js/main'
], function (
helpers,
jQuery,
main
) {
main.init();
});

+ 15
- 0
helpers/passives/js/constants.js Ver ficheiro

@@ -0,0 +1,15 @@
define([

], function (

) {
return {
lineWidth: 5,
blockSize: 20,
defaultDistance: 50,
defaultDistanceInc: 60,
defaultAngle: Math.PI / 2,
defaultAngleInc: Math.PI / 8,
gridSize: 30
};
});

+ 47
- 0
helpers/passives/js/events.js Ver ficheiro

@@ -0,0 +1,47 @@
define([

], function (

) {
var events = {
events: {},

on: function (event, callback) {
var list = this.events[event] || (this.events[event] = []);
list.push(callback);

return callback;
},

off: function (event, callback) {
var list = this.events[event] || [];
var lLen = list.length;
for (var i = 0; i < lLen; i++) {
if (list[i] == callback) {
list.splice(i, 1);
i--;
lLen--;
}
}

if (lLen == 0)
delete this.events[event];
},

emit: function (event) {
var args = [].slice.call(arguments, 1);

var list = this.events[event];
if (!list)
return;

var len = list.length
for (var i = 0; i < len; i++) {
var l = list[i];
l.apply(null, args);
}
}
};

return events;
});

+ 105
- 0
helpers/passives/js/generator.js Ver ficheiro

@@ -0,0 +1,105 @@
define([
'js/tplNode'
], function (
tplNode
) {
return {
links: [],
nodes: [],

selected: null,

init: function () {
this.actions.addNode.call(this, {
x: 23,
y: 14
});
},

findNode: function (x, y) {
return this.nodes.find(n => ((n.pos.x == x) && (n.pos.y == y)));
},

callAction: function (action, options = {}) {
var node = options.node || this.findNode(options.x, options.y);
if ((action == 'addNode') && (options.shiftDown))
action = 'moveNode';

options.node = node;
this.actions[action].call(this, options);
},

actions: {
selectNode: function (options) {
if (this.selected)
this.selected.selected = false;

if (options.node)
options.node.selected = true;
this.selected = options.node;
},

addNode: function (options) {
this.nodes.push(tplNode.build({
id: this.nodes.length,
x: options.x,
y: options.y
}));
},

connectNode: function (options) {
var node = options.node;
if (!node)
return;

if (this.selected) {
if (options.shiftDown) {
this.links.spliceWhere(l => (
(
(l.from == node) ||
(l.to == node)
) &&
(
(l.from == this.selected) ||
(l.to == this.selected)
) &&
(node != this.selected)
));
} else {
this.links.push({
from: this.selected,
to: node
});
}
this.callAction('selectNode');
} else {
this.callAction('selectNode', {
node: node
})
}
},

moveNode: function (options) {
if (!this.selected)
return;

this.selected.pos.x = options.x;
this.selected.pos.y = options.y;
},

recolorNode: function () {
if (!this.selected)
return;

this.selected.color = (this.selected.color + 1) % 4;
},

resizeNode: function () {
if (!this.selected)
return;

this.selected.size = (this.selected.size + 1) % 3;
}
}
};
});

+ 156
- 0
helpers/passives/js/input.js Ver ficheiro

@@ -0,0 +1,156 @@
define([
'js/events',
'js/renderer',
'js/constants'
], function (
events,
renderer,
constants
) {
return {
mappings: {
'8': 'backspace',
'9': 'tab',
'13': 'enter',
'16': 'shift',
'17': 'ctrl',
'27': 'esc',
'37': 'left',
'38': 'up',
'39': 'right',
'40': 'down',
'46': 'del'
},

mouse: {
button: null,
x: 0,
y: 0
},
mouseRaw: null,

keys: {},

init: function () {
$(window).on('keydown', this.events.keyboard.onKeyDown.bind(this));
$(window).on('keyup', this.events.keyboard.onKeyUp.bind(this));

$('canvas')
.on('mousedown', this.events.mouse.onMouseDown.bind(this))
.on('mouseup', this.events.mouse.onMouseUp.bind(this))
.on('mousemove', this.events.mouse.onMouseMove.bind(this));
},

resetKeys: function () {
for (var k in this.keys) {
events.emit('onKeyUp', k);
}

this.keys = {};
},

getMapping: function (charCode) {
if (charCode >= 97)
return (charCode - 96).toString();

return (
this.mappings[charCode] ||
String.fromCharCode(charCode).toLowerCase()
);

},

isKeyDown: function (key, noConsume) {
var down = this.keys[key];
if (down != null) {
if (noConsume)
return true;
else {
this.keys[key] = 2;
return (down == 1);
}
} else
return false;
},

events: {
keyboard: {
onKeyDown: function (e) {
if (e.target != document.body)
return true;
if ((e.keyCode == 9) || (e.keyCode == 8) || (e.keyCode == 122))
e.preventDefault();

var key = this.getMapping(e.which);

if (this.keys[key] != null)
this.keys[key] = 2;
else {
this.keys[key] = 1;
events.emit('onKeyDown', key);
}

if (key == 'backspace')
return false;
},

onKeyUp: function (e) {
if (e.target != document.body)
return;

var key = this.getMapping(e.which);

delete this.keys[key];

events.emit('onKeyUp', key);
}
},

mouse: {
onMouseDown: function (e) {
var el = $(e.target);
if ((!el.hasClass('canvas')) || (el.hasClass('blocking')))
return;

var button = e.button;
this.mouse.button = button;
this.mouse.down = true;
this.mouse.event = e;

events.emit('onMouseDown', this.mouse);
},

onMouseUp: function (e) {
var el = $(e.target);
if ((!el.hasClass('canvas')) || (el.hasClass('blocking')))
return;

var button = e.button;
this.mouse.button = null;
this.mouse.down = false;

events.emit('onMouseUp', this.mouse);
},

onMouseMove: function (e) {
if (e)
this.mouseRaw = e;
else
e = this.mouseRaw;

if (!e)
return;

var el = $(e.target);
if ((!el.hasClass('canvas')) || (el.hasClass('blocking')))
return;

this.mouse.x = ~~((e.offsetX + renderer.pos.x + 40) / constants.gridSize)
this.mouse.y = ~~((e.offsetY + renderer.pos.y + 40) / constants.gridSize)

events.emit('onMouseMove', this.mouse);
}
}
}
};
});

+ 60
- 0
helpers/passives/js/main.js Ver ficheiro

@@ -0,0 +1,60 @@
define([
'js/events',
'js/generator',
'js/renderer',
'js/input'
], function (
events,
generator,
renderer,
input
) {
return {
init: function () {
generator.init();
renderer.init();
input.init();

events.on('onMouseDown', this.events.onMouseDown.bind(this));
events.on('onKeyDown', this.events.onKeyDown.bind(this));

this.render();
},

render: function () {
if (renderer.dirty)
renderer.render(generator.nodes, generator.links);

window.requestAnimationFrame(this.render.bind(this));
},

events: {
onMouseDown: function (e) {
var action = ([
'addNode',
'selectNode',
'connectNode'
])[e.button];

generator.callAction(action, {
x: e.x,
y: e.y,
shiftDown: input.isKeyDown('shift')
});

renderer.makeDirty();
},

onKeyDown: function (key) {
var action = ({
s: 'resizeNode',
c: 'recolorNode'
})[key];

generator.callAction(action, {});

renderer.makeDirty();
}
}
};
});

+ 163
- 0
helpers/passives/js/renderer.js Ver ficheiro

@@ -0,0 +1,163 @@
define([
'js/constants',
'js/events'
], function (
constants,
events
) {
return {
canvas: null,
ctx: null,

screen: {
w: 0,
h: 0
},

pos: {
x: 0,
y: 0
},

mouse: {
x: 0,
y: 0
},

dirty: true,

init: function () {
this.canvas = $('canvas')[0];
this.screen.w = this.canvas.width = $('.left').width();
this.screen.h = this.canvas.height = $('.left').height();
this.ctx = this.canvas.getContext('2d');

this.ctx.lineWidth = constants.lineWidth;

$(this.canvas)
.on('contextmenu', function () {
return false;
});

events.on('onMouseMove', this.events.onMouseMove.bind(this));
},

center: function (node) {
this.pos.x = ~~(node.pos.x * constants.gridSize) + (constants.blockSize / 2) - (this.screen.w / 2);
this.pos.y = ~~(node.pos.y * constants.gridSize) + (constants.blockSize / 2) - (this.screen.h / 2);

this.ctx.translate(-this.pos.x, -this.pos.y);
this.makeDirty();
},

makeDirty: function () {
this.dirty = true;
},

renderNodes: function (nodes, links) {
links.forEach(function (l) {
this.renderers.line.call(this, l.from, l.to);
}, this);

nodes.forEach(function (n) {
this.renderers.node.call(this, n, n.pos.x, n.pos.y);
}, this);
},

render: function (nodes, links) {
this.dirty = false;

this.renderers.clear.call(this);
this.renderers.grid.call(this);

this.renderNodes(nodes, links);
},

renderers: {
clear: function () {
this.ctx.clearRect(this.pos.x, this.pos.y, this.screen.w, this.screen.h);
},

grid: function () {
var gridSize = constants.gridSize;
var ctx = this.ctx;
var mouse = this.mouse;

var w = this.screen.w / gridSize;
var h = this.screen.h / gridSize;

ctx.fillStyle = '#3c3f4c';
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
if ((mouse.x == i) && (mouse.y == j)) {
ctx.fillStyle = '#ff6942';
ctx.fillRect((i * gridSize) - 25, (j * gridSize) - 25, 9, 9);
ctx.fillStyle = '#3c3f4c';
} else
ctx.fillRect((i * gridSize) - 23, (j * gridSize) - 23, 5, 5);
}
}
},

node: function (node) {
this.ctx.fillStyle = ([
'#c0c3cf',
'#3fa7dd',
'#4ac441',
'#d43346'
])[node.color];
var size = ([
constants.blockSize,
constants.blockSize * 2,
constants.blockSize * 3
])[node.size];
var x = (node.pos.x * constants.gridSize) - ((size - constants.blockSize) / 2);
var y = (node.pos.y * constants.gridSize) - ((size - constants.blockSize) / 2);

this.ctx.fillRect(x, y, size, size);

if (node.selected) {
this.ctx.strokeStyle = '#fafcfc';
this.ctx.strokeRect(x, y, size, size);
}
},

line: function (fromNode, toNode) {
var ctx = this.ctx;
var halfSize = constants.blockSize / 2;

var fromX = (fromNode.pos.x * constants.gridSize) + halfSize;
var fromY = (fromNode.pos.y * constants.gridSize) + halfSize;

var toX = (toNode.pos.x * constants.gridSize) + halfSize;
var toY = (toNode.pos.y * constants.gridSize) + halfSize;

ctx.strokeStyle = '#69696e';
ctx.beginPath();
ctx.moveTo(fromX, fromY);
ctx.lineTo(toX, toY);
ctx.closePath();
ctx.stroke();
}
},

events: {
onClick: function (e) {
generator.onClick(e.button, ~~((e.clientX + this.pos.x + 40) / constants.gridSize) - 1, ~~((e.clientY + this.pos.y + 40) / constants.gridSize) - 1);
e.preventDefault();
return false;
},

onMouseMove: function (pos) {
if ((this.mouse.x == pos.x) && (this.mouse.y == pos.y))
return;

this.mouse = {
x: pos.x,
y: pos.y
};
this.makeDirty();
}
}
};
});

+ 28
- 0
helpers/passives/js/tplNode.js Ver ficheiro

@@ -0,0 +1,28 @@
define([

], function (

) {
return {
id: 0,
color: 0,
size: 0,
pos: {
x: 0,
y: 0
},

build: function (options) {
var res = $.extend(true, {}, this, {
id: this.id++,
pos: {
x: options.x,
y: options.y
}
});
delete res.build;

return res;
}
};
});

+ 0
- 175
helpers/passives/renderer.js Ver ficheiro

@@ -1,175 +0,0 @@
var renderer = {
canvas: null,
ctx: null,

screen: {
w: 0,
h: 0
},

pos: {
x: 0,
y: 0
},

mouse: {
x: 0,
y: 0
},

dirty: false,

init: function () {
this.canvas = $('canvas')[0];
this.screen.w = this.canvas.width = $('.left').width();
this.screen.h = this.canvas.height = $('.left').height();
this.ctx = this.canvas.getContext('2d');

this.ctx.lineWidth = constants.lineWidth;

$(this.canvas)
.on('mousedown', this.events.onClick.bind(this))
.on('mousemove', this.events.onMouseMove.bind(this))
.on('contextmenu', function () {
return false;
});

this.update();
},

center: function (node) {
this.pos.x = ~~(node.pos.x * constants.gridSize) + (constants.blockSize / 2) - (this.screen.w / 2);
this.pos.y = ~~(node.pos.y * constants.gridSize) + (constants.blockSize / 2) - (this.screen.h / 2);

this.ctx.translate(-this.pos.x, -this.pos.y);
this.makeDirty();
},

makeDirty: function () {
this.dirty = true;
},

render: function () {
var nodes = generator.nodes;
var links = generator.links;

links.forEach(function (l) {
this.renderers.line.call(this, l.from, l.to);
}, this);

nodes.forEach(function (n) {
this.renderers.node.call(this, n, n.pos.x, n.pos.y);
}, this);
},

update: function () {
if (this.dirty) {
this.dirty = false;
this.renderers.clear.call(this);
this.renderers.grid.call(this);
this.render();
}

window.requestAnimationFrame(this.update.bind(this));
},

renderers: {
clear: function () {
this.ctx.clearRect(this.pos.x, this.pos.y, this.screen.w, this.screen.h);
},

grid: function () {
var gridSize = constants.gridSize;
var ctx = this.ctx;
var mouse = this.mouse;

var w = this.screen.w / gridSize;
var h = this.screen.h / gridSize;

ctx.fillStyle = '#3c3f4c';
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
if ((mouse.x == i) && (mouse.y == j)) {
ctx.fillStyle = '#ff6942';
ctx.fillRect((i * gridSize) - 25, (j * gridSize) - 25, 9, 9);
ctx.fillStyle = '#3c3f4c';
} else
ctx.fillRect((i * gridSize) - 23, (j * gridSize) - 23, 5, 5);
}
}
},

node: function (node) {
this.ctx.fillStyle = ([
'#c0c3cf',
'#3fa7dd',
'#4ac441',
'#d43346'
])[node.color];
var size = ([
constants.blockSize,
constants.blockSize * 2,
constants.blockSize * 3
])[node.size];
var x = (node.pos.x * constants.gridSize) - ((size - constants.blockSize) / 2);
var y = (node.pos.y * constants.gridSize) - ((size - constants.blockSize) / 2);

this.ctx.fillRect(x, y, size, size);

if (node == generator.selected) {
this.ctx.strokeStyle = '#fafcfc';
this.ctx.strokeRect(x, y, size, size);
}
},

line: function (fromNode, toNode) {
var ctx = this.ctx;
var halfSize = constants.blockSize / 2;

var fromX = (fromNode.pos.x * constants.gridSize) + halfSize;
var fromY = (fromNode.pos.y * constants.gridSize) + halfSize;

var toX = (toNode.pos.x * constants.gridSize) + halfSize;
var toY = (toNode.pos.y * constants.gridSize) + halfSize;

ctx.strokeStyle = '#69696e';
ctx.beginPath();
ctx.moveTo(fromX, fromY);
ctx.lineTo(toX, toY);
ctx.closePath();
ctx.stroke();
}
},

events: {
onClick: function (e) {
generator.onClick(e.button, ~~((e.clientX + this.pos.x + 40) / constants.gridSize) - 1, ~~((e.clientY + this.pos.y + 40) / constants.gridSize) - 1);
e.preventDefault();
return false;
},

onMouseMove: function (e) {
var mouseX = ~~((e.clientX + this.pos.x + 40) / constants.gridSize);
var mouseY = ~~((e.clientY + this.pos.y + 40) / constants.gridSize);

if ((this.mouse.x == mouseX) && (this.mouse.y == mouseY))
return;

this.mouse = {
x: mouseX,
y: mouseY
};
this.makeDirty();
}
}
};

var constants = {
lineWidth: 5,
blockSize: 20,
defaultDistance: 50,
defaultDistanceInc: 60,
defaultAngle: Math.PI / 2,
defaultAngleInc: Math.PI / 8,
gridSize: 30
};

+ 0
- 37
helpers/passives/ui.js Ver ficheiro

@@ -1,37 +0,0 @@
var ui = {
node: null,
shiftDown: false,

init: function () {
$(window)
.on('keydown', this.events.onKey.bind(this, true))
.on('keyup', this.events.onKey.bind(this, false));
},

find: function (selector) {
return $('.right').find('.' + selector).eq(0);
},

setActive: function (node) {
this.node = node;
this.find('id').html(node.id);
},

events: {
onKey: function (isDown, e) {
if (e.key == 'Shift')
this.shiftDown = isDown;

if (!isDown)
return;

if (e.key == 'c') {
generator.actions.recolorNode.call(generator);
renderer.makeDirty();
} else if (e.key == 's') {
generator.actions.resizeNode.call(generator);
renderer.makeDirty();
}
}
}
};

Carregando…
Cancelar
Guardar