summaryrefslogtreecommitdiff
path: root/webcards/scripts/cards
diff options
context:
space:
mode:
Diffstat (limited to 'webcards/scripts/cards')
-rw-r--r--webcards/scripts/cards/card.js97
-rw-r--r--webcards/scripts/cards/deck.js106
-rw-r--r--webcards/scripts/cards/drag.js83
3 files changed, 286 insertions, 0 deletions
diff --git a/webcards/scripts/cards/card.js b/webcards/scripts/cards/card.js
new file mode 100644
index 0000000..015995d
--- /dev/null
+++ b/webcards/scripts/cards/card.js
@@ -0,0 +1,97 @@
+var CardPos = ["top", "topl", "topr", "mid", "midt", "midb", "bot", "botl", "botr", "all"];
+
+// Card class represents one card.
+// Every card should have a deck.
+// Use deck.appendCard or deck.prependCard to make a card visible
+function Card (data) {
+ this.e = this.generateElements(data);
+ this.e.style.left = "0px";
+ this.e.style.top = "0px";
+}
+
+// Internal
+Card.prototype = {
+ // Main generation func
+ generateElements: function (data) {
+ switch (typeof data) {
+ case "object":
+ return this.generateObjectCard(data);
+ case "string":
+ return this.generateBasicCard(data);
+ }
+ let e = document.createElement("card");
+ let t = document.createElement("carea");
+ t.className = "mid";
+ t.innerText = "Card Error: data";
+ e.append(t);
+ return e;
+ },
+
+ // Generate a card with basic text only
+ generateBasicCard: function (data) {
+ let e = document.createElement("card");
+ let t = document.createElement("carea");
+ t.className = "mid";
+ t.innerText = data;
+ e.appendChild(t);
+ return e;
+ },
+
+ // Generate a card with rich visuals
+ generateObjectCard: function (data) {
+ let e = document.createElement("card");
+
+ // Check for an asset URL
+ if (typeof data.assetURL != "string") {
+ data.assetURL = "";
+ }
+
+ // Set card styles
+ for (let i in data.style) {
+ e.style[i] = data.style[i];
+ }
+
+ // Generate card areas.
+ for (let i in CardPos) {
+ if (typeof data[CardPos[i]] == "object")
+ e.appendChild(this.generateCArea(data[CardPos[i]], CardPos[i], data.assetURL));
+ }
+
+ return e;
+ },
+
+ generateCArea: function (data, carea, assetURL) {
+ // Create and set area
+ let area = document.createElement("carea");
+ area.className = carea;
+
+ // Create inner area text and images
+ for (let i in data) {
+ if (i == "style")
+ for (j in data.style)
+ area.style[j] = data.style[j];
+
+ if (data[i].type == "text") {
+ let e = document.createElement("ctext");
+
+ e.innerText = data[i].text;
+
+ for (let j in data[i].style) {
+ e.style[j] = data[i].style[j];
+ }
+
+ area.appendChild(e);
+
+ } else if (data[i].type == "image") {
+ let e = document.createElement("cimage");
+
+ e.style.backgroundImage = "url(\"" + assetURL + data[i].image + "\")";
+
+ area.appendChild(e);
+ }
+ }
+
+ return area;
+ }
+
+}; \ No newline at end of file
diff --git a/webcards/scripts/cards/deck.js b/webcards/scripts/cards/deck.js
new file mode 100644
index 0000000..544a9ef
--- /dev/null
+++ b/webcards/scripts/cards/deck.js
@@ -0,0 +1,106 @@
+// Deck class represents multiple cards.
+// Can be arranged in multiple ways.
+function Deck (options = {}){
+ this.cards = [];
+
+ // View mode
+ // infdraw - infinite draw. always appears as if there are multiple cards
+ // stack - stack mode
+ // strip
+ // horizontal
+ // left (strip-hl)
+ // right (strip-hr)
+ // vertical
+ // top (strip-vt)
+ // bottom (strip-vb)
+ this.mode = options.mode;
+
+ // Select mode
+ // above
+ // below
+ // around
+ // one
+ // all
+ this.smode = options.smode;
+
+ // Select count (-1 = all available)
+ // above - controls number of cards above clicked are selected
+ // below - controls number of cards below clicked are selected
+ // around
+ // number - number above and below selected
+ // array - [first number: number above selected] [second number: number below selected]
+ // one - no effect
+ // all - no effect
+ this.sct = options.sct;
+
+ // Position
+ // array of where the deck is centered
+ this.x = options.pos[0];
+ this.y = options.pos[1];
+
+ this.e = document.createElement("deck");
+}
+
+Deck.prototype = {
+ // Add a card to the front of the deck
+ appendCard: function(card) {
+ this.cards.push(card);
+ this.e.appendChild(card.e);
+ },
+
+ // Add a card to the back of the deck
+ prependCard: function(card) {
+ this.cards.unshift(card);
+ this.e.prepend(card.e);
+ },
+
+ // Add a card at the index specified
+ addCardAt: function(card, index) {
+ if(index < 0 || index > this.cards.length)
+ return
+
+ if(index == 0) {
+ this.prependCard(card);
+ } else if (index == this.cards.length) {
+ this.appendCard(card);
+ } else {
+ let temp = this.cards.slice(0, index);
+ temp[temp.length - 1].e.after(card.e);
+ temp.push(card);
+ this.cards.unshift(...temp);
+ }
+ },
+
+ // Swap the cards at the specified indexes
+ swapCard: function(index1, index2) {
+ if(index1 < 0 || index1 >= this.cards.length || index2 < 0 || index2 >= this.cards.length)
+ return
+
+ var temp = this.cards[index1]
+ this.cards[index1] = this.cards[index2];
+ this.cards[index2] = temp;
+
+ this.cards[index1 - 1].e.after(this.cards[index1]);
+ this.cards[index2 - 1].e.after(this.cards[index2]);
+ },
+
+ // Remove the card at the front of the deck (index length - 1), returns the card removed (if any)
+ removeFront: function() {
+ return this.removeCard(this.cards.length - 1);
+ },
+
+ // Remove the card at the back of the deck (index 0), returns the card removed (if any)
+ removeBack: function() {
+ return this.removeCard(0);
+ },
+
+ // Remove a card from the deck, returning the card element
+ removeCard: function(index) {
+
+ if(index < 0 || index >= this.cards.length)
+ return
+
+ this.e.removeChild(this.cards[index].e);
+ return this.cards.splice(index, 1)[0];
+ }
+}; \ No newline at end of file
diff --git a/webcards/scripts/cards/drag.js b/webcards/scripts/cards/drag.js
new file mode 100644
index 0000000..cce1e72
--- /dev/null
+++ b/webcards/scripts/cards/drag.js
@@ -0,0 +1,83 @@
+function MultiDrag() {
+ this.del = false;
+ this.drag = [];
+ window.addEventListener("mousemove", this.update.bind(this));
+ document.body.addEventListener("mouseleave", this.stopDraggingAll.bind(this));
+}
+
+MultiDrag.prototype = {
+ addDragEl: function(el, ox, oy, px, py, pt) {
+ if(this.del)
+ return;
+
+ el.style.transitionDuration = "0.04s";
+
+ this.drag.push({
+ e: el,
+ osx: ox,
+ osy: oy,
+ prx: px,
+ pry: py,
+ ptd: pt
+ });
+
+ return this.drag.length - 1;
+ },
+
+ startDragging: function(mevent) {
+ if(this.del)
+ return;
+
+ console.log(mevent);
+
+ if(mevent.button != 0)
+ return;
+
+ let pos = mevent.target.getBoundingClientRect();
+
+ return this.addDragEl(
+ mevent.currentTarget,
+ mevent.clientX - pos.left,
+ mevent.clientY - pos.top,
+ mevent.currentTarget.style.left,
+ mevent.currentTarget.style.top,
+ mevent.currentTarget.style.transitionDuration
+ );
+ },
+
+ stopDragging: function(i) {
+ this.del = true;
+
+ if (i < 0 || i >= this.drag.length)
+ return;
+
+ this.drag[i].e.style.transitionDuration = this.drag[i].ptd;
+ this.drag[i].e.style.left = this.drag[i].prx;
+ this.drag[i].e.style.top = this.drag[i].pry;
+
+ this.drag.splice(i, 1);
+
+ this.del = false;
+ },
+
+ stopDraggingAll: function() {
+ this.del = true;
+
+ while (this.drag.length > 0) {
+ this.drag[0].e.style.transitionDuration = this.drag[0].ptd;
+ this.drag[0].e.style.left = this.drag[0].prx;
+ this.drag[0].e.style.top = this.drag[0].pry;
+
+ this.drag.shift();
+ }
+
+ this.del = false;
+ },
+
+ update: function(e) {
+ for (let i = 0; i < this.drag.length && !this.del; i++) {
+ this.drag[i].e.style.left = e.clientX - this.drag[i].osx + "px";
+ this.drag[i].e.style.top = e.clientY - this.drag[i].osy + "px";
+ }
+ }
+}; \ No newline at end of file