How do you access a body by its label in MatterJS? - javascript

This question was asked here but no answer was given.
To clarify the question, once a body is created, it is stored in the World/Composite.
The question is, given a body created like so:
Bodies.rectangle(0, 1000, 0, 100, {
isStatic: true,
label: "floor",
friction: 0,
render: {
fillStyle: 'light blue'
},
})
How do you access the body using the label? (Assuming the body is added to the world)

The simple answer is no, there is no built in function that allows you to retrieve a body by its label. The reason is because labels aren't unique and retrieving a body by label can take really long. Imagine if there were thousands of bodies...
In any case, if you still want to retrieve a body by its label you can do this to search for the body in linear time:
// retrieve all bodies in the world and filter on label
// returns an array containing all bodies that have that label
function getBodiesByLabel(label, world) {
return Composite.allBodies(world).filter(body => body.label === label)
}
const floorBodies = getBodiesByLabel('floor')
floorBodies.forEach(floorBody => console.log(floorBody))
If you only have a couple of bodies to look through, it's not that bad.
Source: MatterJS GitHub Question
Credit: grantjenkins on GitHub

The answer by gfdb works, but it involves a linear search over all bodies for each label lookup, O(n). As I mentioned in a couple of comments, MJS does offer a label property for convenience, but doesn't purport to be a holistic entity management solution; it's just a physics engine library. There doesn't seem to be any backing data structure for labels, and that's probably a good thing. Leaning heavily on this single property seems to be an antipattern, expecting MJS to handle entity management when it's not intended to.
So, the general approach when using MJS standalone is to roll your own application-specific entity management solution that meets your needs, or use an opinionated framework like Phaser that offers an off-the-shelf solution.
A couple of common approaches are:
Use a composition pattern: write your own classes and keep fields for MJS bodies as implementation details (probably OK to be tightly-coupled for most use cases), along with whatever other data you need for your app. Group in data structures as needed and optionally inherit from your base classes as in normal OOP.
class Enemy {
constructor(x, y, width, height, opts) {
this.body = Matter.Bodies.rectangle(x, y, width, height, opts);
this.kills = 0;
this.cooldown = 30;
// ... other important data that isn't necessarily MJS-related
}
update() {...}
draw() {...}
...
}
const entities = {
enemies: [new Enemy(...), ...],
walls: [...],
...
};
Use the bodies directly, but put them into an object of arrays organized by label:
const bodiesByType = {
walls: [Matter.Bodies.rectangle(), ...],
enemies: [Matter.Bodies.rectangle(), ...],
players: [Matter.Bodies.rectangle(), ...],
...
};
... or even skip the object and look them up by loose variable names player, walls, etc.
Use gfdb's approach for simple use cases where the above options might be premature optimization (although I don't think option 2 is much work).

Related

Dynamic formula evaluation in JavaScript: eval() or not eval()

I'm working on a web application where an admin can define and adapt formulas that would need to be evaluated based on the input values (numbers) provided by the end users.
For the sake of clarity, here is a reduced example of what I would except:
const obj = {
type: "External wall in contact with the ground",
layer: {
base: {
type: "Reinforced concrete (reinforcement 5 vol.%)",
thickness: 100, // <-- user value
lambda: 2.3, // <-- user value
_r: "{{thickness}}/{{lambda}}/1000", // <-- admin defined
r: 0
},
waterproofing: {
type: "Bitumen sheets (single layer)",
share: 1, // <-- user value
_r: "{{share}}", // <-- admin defined
r: 0,
},
insulation: {
type: "XPS",
thickness: 100, // <-- user value
share: 1, // <-- user value
lambda: 0.040, // <-- user value
_r: "{{thickness}}*{{share}}/{{lambda}}/1000", // <-- admin defined
r: 0
}
}
}
Object.entries(obj.layer).forEach(([key, object]) => {
var formula = object._r
Object.keys(object).forEach(k =>
formula = formula.replace(`{{${k}}}`, object[k])
)
obj.layer[key].r = eval(formula)
})
console.log(obj)
The _r is the formula defined by the admin. The {{value}} are the values provided by the end users.
The loop goes through the obj.layer properties to evaluate the formula and save the answer in r.
The resulting would be this object:
{
type: 'External wall in contact with the ground',
layer: {
base: {
type: 'Reinforced concrete (reinforcement 5 vol.%)',
thickness: 100,
lambda: 2.3,
_r: '{{thickness}}/{{lambda}}/1000',
r: 0.043478260869565216
},
waterproofing: {
type: 'Bitumen sheets (single layer)',
share: 1,
_r: '{{share}}',
r: 1
},
insulation: {
type: 'XPS',
thickness: 100,
share: 1,
lambda: 0.04,
_r: '{{thickness}}*{{share}}/{{lambda}}/1000',
r: 2.5
}
}
}
Let's skip the fact I don't validate the object structure and ensure all the values are available.
I know eval() is considered as "dangerous". A not-so good alternative would be Function(). Yet, not perfect.
So far, I see 3 possibilities:
Only the admin can alter the formulas. Therefore, the risk of executing evil code is very low. What I would need is to validate/sanitize the values (something like isFloat()), and that would be it.
Using the mathjs library, that offers a nice evaluate() function:
const node2 = math.parse('x^a')
const code2 = node2.compile()
let scope = {
x: 3,
a: 2
}
code2.evaluate(scope) // 9
Use a parser generator like http://zaa.ch/jison/, but it seems overkill for what I want to do..
To be honest, I feel the use of eval() in my specific case is justified: dynamic formulas with dynamic values. I could use an external library like mathjs but I feel I don't need it for such simple operations.
I would really like to get your idea on the subject, and hear your suggestion if any !
PS: Yes, the question has been asked already. Although, the most similar questions I found were asked (and responsed) several years ago. I would like to have a fresh input on that matter.
Based on #Sleavely answer, and further reading on the topic, mathjs seems the most reasonable solution to adopt ;-)
Based on #Sleavely answer (see comment quoted below), and further reading on the topic, mathjs seems the most reasonable solution:
Third-party admins may be the only ones who can edit the code, but
where will it actually run? In your backend? On visitors' computers? I
strongly recommend you avoid eval(), lest you be blamed for whatever
Bitcoin miner visitors end up contracting from your application. With
that in mind, I think that you're on the right track with your 2nd
option. Evaluating the formula against a set of predefined variables
strikes me as safe enough. Looks like mathjs actively avoids eval():
https://github.com/josdejong/mathjs/blob/master/docs/expressions/security.md

Creating Animations on the web in js, Tween, Spring, user interaction, interruptible and mixing it all in a carousel

Back story.
I am a web developer and i can pretty much do anything on the web. When i first started doing some programming it was in flash actionscript 3, and i was 14 and now i am 29 and still i haven't figure out this one thing. I have decided i am going to get to the bottom of it finally.
Goals.
To make the problem tangible.
Implement a carousel that can be swiped, autoplay, move with prev and next button, any of these animation should be interruptible and have velocity associated with it, except the mouse/finger tracking. I want it to feel natural, i want the elements moving to feel like they have weight and they are sliding into place. They need to feel real like they can be touched.
The animation needs to be additive, as i change directions and interact with it, it needs to be like how a human would expect it to be. Like they are sliding a piece of plastic on a smooth surface. It needs to snap into place when it is completed.
Now i know stack over flow it's all about show your work. I have done so many times and it all comes down to a mess. So a truce, please give comments and directions and i will update the question with the current progress and roadblocks. I will make and then i will keep it updated.
My Starting point
https://codesandbox.io/s/strange-darkness-3hmub
Concepts.
So here are things i think i need to be thinking about.
I believe there are really two types of animations i need to account for.
Tweens and Spring or animations with velocity (i don't know what i am doing).
interface {
type:"tween"|"velocity";
velocity:number; //unit per/second??? pixel
duration?:number;
from:number;
to:number;
start_time:number;
easing:(progress:number)=>number
}
Thought Process.
I think i need the animations to stack. So i need to know when the animation started and what type it is. I need to know if the new animation should completely remove all previous ones or if it should stack on top of it.
For example i could have stacks of all sorts of animations but if a use touches it then it needs to remove them.
I think i need the start time to do things such as easing functions. I want it to have weight and feel like it has inertia.
Contributing.
You may not be able to answer, but suggest, brain storm. I want to put this to bed!
I am committed!! Contribute however you can and i will do the work!!!
I think it can be accomplished using https://github.com/react-voodoo/react-voodoo ( beta, incomplete css interpolation support ),
Or directly using https://github.com/react-voodoo/tween-axis
tween-axis allow merging any numeric tween on a "tween-axis".
Once instantiated, we can use a classic goto function to update numeric props on a specified context object.
Even more, multiple tween-axis instance can update the same props.
let axis = new TweenAxis(
[
{
from : 0,
duration: 100,
target : "myTargetId",
easeFn:"easePolyOut", // https://github.com/d3/d3-ease or function
apply : {
value: 200
}
},
{
from : 0,
duration: 100,
target : "myTargetId",
apply : {
value: -100
}
}
]
),
context = {
myTargetId: {
value: 0
}
};
console.log(axis.go(.5, context));
//{ myTargetId: { value: 50 } }
console.log(axis.go(.25, context));
//{ myTargetId: { value: 25 } }
console.log(axis.go(.75, context));
//{ myTargetId: { value: 75 } }

Using plotly.js animation feature

Yesterday Plotly release the new feature animation!!! So I was very eager to test this out, and with the current lack of documentations (temporary I suppose) I'm struggling quite a bit on how to use it.
I did have a peek into the code on GitHub, but ... not working.
I define my div element in the template:
<div id="plotDiv"> </div>
I wanted to have the plot responsive to resize events, thus I followed the example on the plotly website:
const d3 = Plotly.d3;
const gd3 = d3.select("#plotDiv")
.style({width: "95%", "margin-left": "2.5%"});
const gd = gd3.node();
Then generate the data (bits of angular magic and other things) but in the end it looks like this:
data = {x: [array_ot_dates], y: [array_of_not_so_random_values], type:'bar'};
According to the jsdocs for the animation function, you need to pass a frame:
let plotlyFrame = {data:data, layout:{}};
Try to call animation!!!
Plotly.animate(gd, plotlyFrame);
And there it goes Kaboum!
First error is: This element is not a Plotly plot: [object HTMLDivElement]
But when I try this:
Plotly.newPlot(gd, data, {});
I have my plot...
So I tried to "predefine" gd by calling Plotly.plot with empty data and then the animate function...
Plotly.plot(gd, [], {});
// make my data not empty
Plotly.animate(gd, plotlyFrame);
And then I get the following error:
plotly.js:116922 Uncaught (in promise) TypeError: Cannot read property '_module' of undefined(…)
Possibly the second could come from the fact I'm using angular and thus calling the function at one point 3 times in a close row.
Any advices? Ideas?
I'm the person who worked on the animation feature! First of all, you can find the documentation here.
Regarding your specific question, it looks like the answer is that you need to initialize the plot before you animate it (I'll add this to the documentation!). For example:
var frame = [{
data: {
y: [...new values...]
}
}]
Plotly.plot(gd, [{x: [...], y: [...]}]).then(function() {
Plotly.animate(gd, frame)
});
If some sort of user input is triggering the animation, the promise probably isn't necessary (since the input event will handle things and is pretty unlikely to get fired before Plotly.plot has had a chance to initialize).
Additionally, at the very least I believe you'll need to actually initialize the plot with the trace you wish to animate. I think you can probably get away with empty data, but you'll still need to at least have a trace defined, e.g. Plotly.plot(gd, [{x: [], y: []}]). I think the issue with your attempted fix is that [] for a list of traces is still empty as far as Plotly is concerned since that tells it nothing about the type of trace that exists. Also FYI, one thing the feature is not really designed to do is to draw the initial plot in a fancy manner. That could likely be accomplished, but it's not automatic given animate on an empty plot.
I hope that's enough to clarify issues! It was a pretty large feature, so we'd love feedback and to hear about successes/failures with it!

Which is better for massive amounts of Variables

So after reading massively into JS the past few days (I'm just starting with it) I have come upon 3 viable options for my project, which is a game btw. There will be about 200 items in my game, with a total of about 30 stats/properties. But since the program has to know that a Sword doesn't give Spell damage than I have to give each item all those 30 properties even if 90% will be 0. So here is what I came up with, any advice is greatly appreciated:
var prop, obj = { Item1: "Boots", Item2: "Gloves", Item3: "Sword", Item4: "Cape" };
// Pretty sure I'd have to remake this somehow to put properties in there, this might not be as useable
function Item(hp, mp, dmg, spd, luk) {
this.hp = hp;
this.mp = mp;
this.dmg = dmg;
this.spd = spd;
this.luk = luk;
}
var BigSword = new Item(0, 0, 50, 20, 10)
//I think this might be my best option so there are as few variables as possible? or does that not matter as much? I figured with this option whenever I update totalHp and totalMp and totalDmg etc in the updating function I can create a local variable called theItem = BigSword and then just do theItem.hp, theItem.mp and that way it doesn't have to search much for the variable and should run relatively faster? Sorry for the newbie question but does JS even have local variables in functions? As in if I do var theItem = whatever, then theItem will be null outside the function?
itemNames = [ "Boots", "Gloves", "Sword", "Cape" ];
itemHp = [ 0, 0, 0, 50 ];
itemMp = [ 0, 30, 0, 0 ];
itemDmg = [ 0, 0, 50, 0 ];
itemSpd = [ 50, 0, 0, 0];
//This is the other option that I came up with, a little uglier but if it's faster or better to just use arrays I don't mind that much.
But please keep in mind, like I said, 200~ish total items, each item will have around 30 properties. What do you think?
Thanks a lot for reading and for any information provided, it's greatly appreciated! Thanks in advance
Your best bet is to have a constructor, as you have in your first example. However, I'd change a few things. First of all, for the constructor, you're simply passing in a lot of numbers. This is bad, because it's very easy to forget the order in which your numbers go. A better way to go would be to pass in an object to your constructor, so you can label each property:
function Item(props) {
this.hp = props.hp;
this.mp = props.mp;
this.dmg = props.dmg;
this.spd = props.spd;
this.luk = props.luk;
}
var BigSword = new Item({
hp: 0,
mp: 0, 5
dmg: 0,
spd: 20,
luk: 10
});
This is nice, but still a pain, because you have all sorts of different items, and as you said, you'd have to define 30 properties for each item, which gets both messy and time-consuming. At this point you get into the realm of more complex object oriented stuff. From here you have basically two options: inheritance and construction.
Inheritance
Using object inheritance to properly define objects is one probably the more common of the two, and is fairly straightforward. In essence, you have a "class" of object, and then sub-classes of each class. So you might have Magical Items and Non-Magical Items as two classes. If you had a magic belt, perhaps, you'd want to make it inherit the properties of the Magical Item class. On the other hand, if you had a basic un-charmed sword, you'd want to make it inherit from the Non-Magical Item class.
But say you have magical scrolls and magical potions. Those are both magical items, right? So you'd want to make a class called Potions and a class called Scrolls, which both inherit from the Magical Item class. Then you might have certain types of potions. Healing potions, maybe--"Magical Potion of Heal Allies" and "Magical Potion Of Heal Self". So you'd need different classes for those--and so on and so forth.
Inheritance in Javascript can be done a number of different ways and it's possible to get very in-depth, so I'm not going to discuss it in my post. Here are a few useful links to get you started with inheritance, though, if you want to go that route:
David Crockford on Inheritance
MDN on Inheritance and MDN Inheritance Revisted
Alex Sexton on Inheritance
Composition
Composition is a concept that borrows heavily from other loosely-typed languages, such as Python, which employs it quite extensively. The basic idea behind composition is that you have a base object class, and whenever you need a certain specific type of object, you add behaviors, or members, to that base class. This isn't quite as well-known as inheritance, but it's definitely the one I prefer.
In Javascript, it works by having a base constructor, Item, and then having other constructors which add the necessary behaviors to your Item. Let's take a look at the example I used for composition--creating a Magical Potion of Heal Allies. You have several distinct properties here: Magical Item, Potion, Healing. With inheritance you'd do something like Item -> Magical -> Potion -> Healing Potions -> Allies. However, with composition, you can add several behaviors to a base Item class, without having to set up a huge prototype chain: Affect Allies, Potion, Healing.
Since composition is a bit simpler than inheritance (and, I'll admit it, I'm biased) I'll set up a quick example in psuedo-code:
// base item class
function Item(props) {
this.someProperty = props.someProperty;
this.someOtherProperty = props.someOtherProperty;
}
// potion behavior
function Potion(props) {
this.amount = props.amount; // IDK what amount means, just some random potion property
this.color = "green";
}
// healing behavior
function Healing(props) {
this.amountToHeal = props.amountToHeal;
this.cooldown = props.cooldown;
}
// behavior to affect allies
function AffectAllies(props) {
this.allies = props.allies;
for(ally in this.allies) {
this.allies[ally].affect(props.affact);
}
}
// at this point we have the various behaviors set up and we can create the Magical Potion of Heal Allies constructor:
function MassHealingPotion(props) {
var self = this;
this.amount = props.amount;
this.potion = new Potion(props);
this.effect = new Healing(props);
this.AffectAllies = new AffectAllies({
affect: function(ally) {
self.potion.affect;
},
allies: player.allies;
});
}
// you can now create a mass healing potion:
var potion = new MassHealingPotion({
weight: 50,
someProp: "someValue",
someOtherProp: "someOtherValue"
// and so on and so forth with whatever properties you want the potion to have
});
Well, that turned out a bit longer than I expected and probably contains proportionally more errors than I'd like, but I hope that conveys the basic idea of composition.
Now, simpler object creation isn't even the best part of composition, which is that you can re-use different behaviors. Consider you have a magical sword that whenever you make an attack it heals your allies. All you have to do is give it the Healing member and the AffectAllies member and boom--magical sword of heal buddies. With inheritance, you'd have to create a Swords class in the Magical Items class (and then you'd have two different Swords classes-one for Non Magical Swords and the other for Magical Swords! Ew!), then extend that with Healing Swords, and so on and so forth.
You can go either way, inheritance or object composition. Both are equally effective for what you want to achieve.
But what about performance?
200 items with 30 properties a piece? Not a problem. Stick them all in one giant array/object, boil 'em, mash 'em, stick 'em in a stew. The browser don't care. Your best bet is probably an object, though:
var itemList = {
bigSword: new BigSword(...);
smallSword: new SmallSword(...);
}
I would prefer Objects. I would start with a simple, generic "Item" and then build specific items by "inherit" from the generic one with prototyping.
That probably may reduce code redundancy and increase maintainability dramatically.
Speedwise I don't have a clue but I think iterating through 200*30 array values isn't also that fast.
You need to do a serious design effort first. If you just start coding (as many developers do), you will only get so far and realise your design has a fundamental flaw and the application needs to be rewritten. That doesn't matter in the early stages, but once you've written a few hundred lines of code it gets quite tedious.
By all means write code to prototype things, but all you should expect to get from it are design hints, the code should be thrown away.
Your items list (or catalogue) should be an object with methods to add, remove and update items. Each player (character, avatar, whatever) then just needs a list of their items and their state. There should be a global update damage or health or whatever function that gets items of a specific type and applies them to players of a specific type (e.g. weapons damage enemies, food revives the player and friends, etc.).
Only once you know all the players and items and their attributes and actions, you can start to design the interfaces and methods, and finally write some code.
Keep your eye on the objective, which should be to develop an engaging game, not to just write a few thousand lines of code.

How can I reliably subsort arrays using DOM methods?

UP-FRONT NOTE: I am not using jQuery or another library here because I want to understand what I’ve written and why it works (or doesn’t), so please don’t answer this with libraries or plugins for libraries. I have nothing against libraries, but for this project they’re inimical to my programming goals.
That said…
Over at http://meyerweb.com/eric/css/colors/ I added some column sorting using DOM functions I wrote myself. The problem is that while it works great for, say, the simple case of alphabetizing strings, the results are inconsistent across browsers when I try to sort on multiple numeric terms—in effect, when I try to do a sort with two subsorts.
For example, if you click “Decimal RGB” a few times in Safari or Firefox on OS X, you get the results I intended. Do the same in Chrome or Opera (again, OS X) and you get very different results. Yes, Safari and Chrome diverge here.
Here’s a snippet of the JS I’m using for the RGB sort:
sorter.sort(function(a,b){
return a.blue - b.blue;
});
sorter.sort(function(a,b){
return a.green - b.green;
});
sorter.sort(function(a,b){
return a.red - b.red;
});
(sorter being the array I’m trying to sort.)
The sort is done in the tradition of another StackOverflow question “How does one sort a multi dimensional array by multiple columns in JavaScript?” and its top answer. Yet the results are not what I expected in two of the four browsers I initially tried out.
I sort (ha!) of get that this has to do with array sorts being “unstable”—no argument here!—but what I don’t know is how to overcome it in a consistent, reliable manner. I could really use some help both understanding the problem and seeing the solution, or at least a generic description of the solution.
I realize there are probably six million ways to optimize the rest of the JS (yes, I used a global). I’m still a JS novice and trying to correct that through practice. Right now, it’s array sorting that’s got me confused, and I could use some help with that piece of the script before moving on to cleaning up the code elsewhere. Thanks in advance!
UPDATE
In addition to the great explanations and suggestions below, I got a line on an even more compact solution:
function rgbSort(a,b) {
return (a.red - b.red || a.green - b.green || a.blue - b.blue);
}
Even though I don’t quite understand it yet, I think I’m beginning to grasp its outlines and it’s what I’m using now. Thanks to everyone for your help!
OK. So, as you've discovered, your problem is that the default JavaScript sort is not guaranteed to be stable. Specifically, I think that in your mind it works like this: I'll sort by blueness, and then when I sort by greenness the sorter will just move entries in my array up and down but keep them ordered by blueness. Sadly, the universe is not so conveniently arranged; the built-in JS sort is allowed to do the sort how it likes. In particular, it's allowed to just throw the contents of the array into a big bucket and then pull them out sorted by what you asked for, completely ignoring how it was arranged before, and it looks like at least some browsers do precisely that.
There are a couple of ways around this, for your particular example. Firstly, you could still do the sort in three separate calls, but make sure those calls do the sort stably: this would mean that after sorting by blueness, you'd stably sort by greenness and that would give you an array sorted by greenness and in blueness order within that (i.e., precisely what you're looking for). My sorttable library does this by implementing a "shaker sort" or "cocktail sort" method (http://en.wikipedia.org/wiki/Cocktail_sort); essentially, this style of sorting walks through the list a lot and moves items up and down. (In particular, what it does not do is just throw all the list items into a bucket and pull them back out in order.) There's a nice little graphic on the Wikipedia article. This means that "subsorts" stay sorted -- i.e., that the sort is stable, and that will give you what you want.
However, for this use case, I wouldn't worry about doing the sort in three different calls and ensuring that they're stable and all that; instead, I'd do all the sorting in one go. We can think of an rgb colour indicator (255, 192, 80) as actually being a big number in some strange base: to avoid too much math, imagine it's in base 1000 (if that phrase makes no sense, ignore it; just think of this as converting the whole rgb attribute into one number encompassing all of it, a bit like how CSS computes precedences in the cascade). So that number could be thought of as actually 255,192,080. If you compute this number for each of your rows and then sort by this number, it'll all work out, and you'll only have to do the sort once: so instead of doing three sorts, you could do one: sorter.sort(function(a,b) { return (a.red*1000000 + a.green*1000 + a.blue) - (b.red*1000000 + b.green*1000 + b.blue) } and it'll all work out.
Technically, this is slightly inefficient, because you have to compute that "base 1000 number" every time that your sort function is called, which may be (is very likely to be) more than once per row. If that's a big problem (which you can work out by benchmarking it), then you can use a Schwartzian transform (sorry for all the buzzwords here): basically, you work out the base-1000-number for each row once, put them all in a list, sort the list, and then go through the sorted list. So, create a list which looks like [ [255192080, <table row 1>], [255255255, <table row 2>], [192000000, <table row 3>] ], sort that list (with a function like mylist.sort(function(a,b) { return a[0]-b[0]; })), and then walk through that list and appendChild each of the s onto the table, which will sort the whole table in order. You probably don't need this last paragraph for the table you've got, but it may be useful and it certainly doesn't hurt to know about this trick, which sorttable.js also uses.
I would approach this problem in a different manner. It appears you're trying to reconstruct all the data by extracting it from the markup, which can be a perilous task; a more straightforward approach would be to represent all the data you want to render out to the page in a format your programs can understand from the start, and then simply regenerate the markup first on page load and then on each subsequent sort.
For instance:
var colorsData = [
{
keyword: 'mediumspringgreen',
decimalrgb: {
r: 0,
g: 250,
b: 154
},
percentrgb: {
r: 0,
g: 98,
b: 60.4
},
hsl: {
h: 157,
s: 100,
l: 49
}
hex: '00FA9A',
shorthex: undefined
},
{
//next color...
}
];
That way, you can run sorts on this array in whatever way you'd like, and you're not trying to rip data out from markup and split it and reassign it and all that.
But really, it seems you're maybe hung up on the sort functions. Running multiple sorts one after the other will get unintended results; you have to run a single sort function that compares the next 'column' in the case the previous one is found to be equal. An RGB sort could look like:
var decimalRgbForwards = function(a,b) {
var a = a.decimalrgb,
b = b.decimalrgb;
if ( a.r === b.r ) {
if ( a.g === b.g ) {
return a.b - b.b;
} else {
return a.g - b.g;
}
} else {
return a.r - b.r;
}
};
So two colors with matching r and g values would return for equality on the b value, which is just what you're looking for.
Then, you can apply the sort:
colorsData.sort(decimalRgbForwards);
..and finally iterate through that array to rebuild the markup inside the table.
Hope it helps, sir-

Categories