Saturday 14 July 2018

Getting Unstuck: Day 10

As a result of signing up for Scratch Getting Unstuck I got a little carried away building a binary clock like this one in Scratch, but got really, really annoyed about not being able to place the elements just where I wanted. I remembered reading something a little while ago about the sb2 file format being an archive so I unzipped it and clocked that sprites have a scratchX and scratchY coordinate within the project.json file. That and figuring out that it uses SVG as the Vector format (why wouldn't you?) meant that I could replace the dodgy path with a circle element. This is the result and I'm quite pleased with it. Now, if only I could automagically use dynamic variable names I wouldn't have to have so many functions. Ah well.

Wednesday 11 July 2018

Getting IE11 to play nicely with grid-area

I've been playing with CSS Grid layout lately within a Vue Component and I'm needing to place specific blocks within a grid, they are of an arbitrary position width and height and that all worked a treat within FireFox and Chrome... just not in, you guessed it, IE11.

So after banging my head against the issue for a few hours and trying everything I could think of I went to StackOverflow and asked. It seems I was being too helpful and adding the browser prefix rather than letting Vue do it for me. So far so good and StackOverflow provided the answer (thanks zero298), but it only went so far.

After looking at the issue some more I came up with the following script:

getStyle: function(x, y, a, b, c, d){
    var style = [];
    style.push("grid-row: " + x + ";");
    style.push("grid-row-span: " + d + ";");
    style.push("grid-column: " + y + ";");
    style.push("grid-column-span: " + c + ";");
    style.push("grid-area: " + x + " / " + y + " / " + a + " / " + b + ";");
    style.push("border: 1px solid white;");
    return style.join(" ");
}

I know that I'm using CSS for the border on the elements but IE11 doesn't support the grid-gap property for some reason, and rather than use browser detection, I figured it would be better to just do it this way for all elements. It's an interesting way of doing things as some of the properties are incompatible, which is why the decent bits of grid-area are left to the end and the IE11 specific bits get added first. IE11 doesn't support grid-area anyway so we're golden.

A little bit of extra work but should you examine the result in the bound style of an element you only see the appropriate CSS for the appropriate browser, which is nice. As I replied added in my original question on SO I just needed to trust Vue!

EDIT

I got to thinking about the variables I was passing to the function above and realised that the c and d variables could be derived from subtracting the width from the x coordinate and the depth of the block from the y coordinate. Not only does this meant that the number of variables I was passing was reduced (something of an issue as the functions I was calling this from were making the calculations on the fly) but it also makes it much clearer. This is the new function:

getStyle: function(x, y, width, depth){
    /***
     * X=Row , Y=Column
     * https://answers.yahoo.com/question/index?qid=20090609205915AASR51m&guccounter=1
     * IE11 has issues with grid-area as well as the syntax of grid-row and grid-column.
     * As such we need a polyfill for that that uses "-span" to indicate the "length" of the element
     * @param {number} x The "line" where the element should start on the horizontal grid (column) from the top
     * @param {number} y The "line" where the element should start on the vertical grid (row) from the left
     * @param {number} width The "line" where the element should end on the horizontal grid (column) from the top
     * @param {number} depth The "line" where the element should end on the vertical grid (row) from the left
     */
    var style = [];
    style.push("grid-row: " + x);
    style.push("grid-row-span: " + (width - x));
    style.push("grid-column: " + y);
    style.push("grid-column-span: " + (depth - y));
    style.push("grid-area: " + x + " / " + y + " / " + width + " / " + depth);
    return style.join("; ");
}