Wednesday 24 April 2019

JS Comma Operator

A mate at work asked me a question about checking things in JS. He had a case where if an object had a property he needed to check for 3 conditions, one of which was if the properties value matched a given value. If it didn't have the property then he needed just needed to check 2 conditions. He wasn't overly keen on wrapping the two conditions within a further if statement and asked if I knew of a way of combining them all into one if statement, I must admit I knew that there was one but I couldn't think of it for the life of me...

As in a particularly nasty case of athletes foot, it itched at me overnight, then I started to remember a rather obscure feature of JS which it seems it borrowed from C, the Comma Operator. In order to check that it would do what he needed to do, I wrote this simple JSFiddle:

let a;

if(true && true && a === 1, a){
  alert("First: a === 1");
}

a = 1;

if(true && true && a === 1, a){
  alert("Second: a === 1");
}

It's rather obscure though, so I'm a little concerned about using it with production code, as discussed on StackOverflow.

Saturday 6 April 2019

p5-INVADER

You might've seen previous posts on my conversion of Python to p5 from Wireframe magazine, and this has been by far the hardest one I've tried as it involved lots and lots of looping through arrays. Arrays not only of the elements which make up the characters, such as shots and shields but also through the matrix which I use to generate the images of the shots and shields. Using a matrix or multi-dimensional array in this way is an approach I'm thinking of adapting for the Digital Counter as it allows a visual representation of the character within an array and so makes tweaking the characters more accessible.

If you check through the history of the repo, you'll see that I went through many different methods of calculating whether or not a shot simply grazed a shield or whether it had a substantial impact, resulting in an explosion. I did this eventually by allowing the shot to have a hit point value which incremented each time it chewed a pixel from the shield; when that hit point reached a critical level, then the shot exploded and eroded a far greater chunk from the shield.

To save resources each shot is removed from an array when it drops too far beneath the stage, and each shield removed when it is empty. I guess I should also close the processing when there are no more shields, but this does pretty much what I wanted and seems to mimic the original Python implementation closely enough. If not you're welcome to branch and tweak it.

Monday 1 April 2019

grid-area in VueJS

As you can probably tell from recent posts, I'm making extensive use of CSS grid layouts... I'm also having to support IE11 while doing so, oh joy. The thing is I like the grid-area approach to defining where things should go within the layout, and I write it in the following way:

{
  ...
  grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end;
  ...
}

Which is cool, but it took me ages to figure out why it wasn't working... even though it was simple enough to get it working in IE11 too where I replaced it with four declarations:

{
  ...
  grid-row: grid-row-start;
  grid-row-span: (grid-row-end - grid-row-start);
  grid-column: grid-column-start;
  grid-column-span: (grid-column-end - grid-column-start);
  ...
}

I was left though with it still not working as expected until I clocked that Vue was replacing grid-row-end and grid-column-end with auto. I then clocked that the JS syntax is slightly different in that the final two values can also use spans like this:

{
  ...
  grid-area: grid-row-start / grid-column-start / span (grid-row-end - grid-row-start) / span (grid-column-end - grid-column-start);
  ...
}


Setting it as four integers was not working, setting it as integers prefixed with span was working in Vue where the final two integers were getting replaced with auto - so I replaced all instances with width and depth spans and updated my script accordingly, the required output is now:

{
  ...
  grid-area: grid-row-start / grid-column-start / span width / span depth;
  ...
}


Combined with the specificity required for IE11 we then have the following:

{
  ...
  grid-row: grid-row-start;
  grid-row-span: width;
  grid-column: grid-column-start;
  grid-column-span: depth;
  grid-area: grid-row-start / grid-column-start / span width / span depth;
  ...
}

Which, when converted to a method function, results in this:

placeElement: function (x, y, width, depth) {
    return {
        gridRow: x,
        gridRowSpan: width,
        gridColumn: y,
        gridColumnSpan: depth,
        gridArea: [x, y, "span " + width, "span " + depth].join(" / "),
    };
}

Not brilliant to look at but Vue will auto prefix the individual values so that gridRow becomes -ms-grid-row etc. for IE11 and won't bother outputting anything other than the grid-area for Chrome et al.

It also seems cleaner in that we have the four arguments and it looks more natural and logical somehow to define how many rows and columns the element should span.

Along with that, returning an object means we can then add to it in subsequent functions.