dimanche 12 mai 2019

Trigger a computed property when element is inserted

i have an ember project with a service that gets the correct font size for an element based on its width. For responsive scaling.

Here is my code.

Element:

screenSizeService: service('screen-size'),
utilsService:      service('utils'),

portrait:  computed.readOnly('screenSizeService.portrait'),
landscape: computed.readOnly('screenSizeService.landscape'),

style: computed('screenSizeService.{width,height}', 'landscape', 'portrait', function()
{
    console.log('calculating');
    //Since the properties have to be consumed, get their values
    this.get('screenSizeService.width');
    this.get('screenSizeService.height');

    //Params = scale if it's landscape, scale if it's portrait, min font size, max and the parent to watch the width of
    return this.getFontSize(1.2, 1.2, 30, 60, this.$();
}),

getFontSize(landscapeScale, portraitScale, min, max, parent)
{
    const scale = (this.get('landscape')) ? landscapeScale : portraitScale;
    const fontSize = this.get('utilsService').scaleFontSize(parent, scale, min, max);
    return htmlSafe('font-size: ' + fontSize + 'px');
}

So this listens to the resize event and calculates every time it changes. This works really well except for when it initally loads.

On the initial load, The parent that im passing through doesnt have a width therfore cannot calculate its font size until the page is resized.

Here is my screen size service:

init()
{
    this._super(...arguments);
    this.get('resizeService').on('resize', this, this.screenSizeChange);
    this.screenSizeChange();
},

willDestroyElement()
{
    this._super(...arguments);
    this.get('resizeService').off('resize', this, this.screenSizeChange);
},

screenSizeChange()
{
    const width  = window.innerWidth;
    const height = window.innerHeight;

    this.set('width',  width);
    this.set('height', height);

    if (width >= height && !this.get('landscape'))
    {
        this.set('landscape', true);
        this.set('portrait',  false);
    }

    if (height > width && !this.get('portrait'))
    {
        this.set('landscape', false);
        this.set('portrait',  true);
    }
}

Lastly, My utils function that calculates the font size:

scaleFontSize(parent, scale, min, max)
{
    const parentWidth = (parent && parent.width()) ? parent.width() : null;
    if (!parentWidth) {return;}

    scale = scale || 1;
    min   = min   || 1;
    max   = max   || 1000;

    return Math.max(Math.min(parentWidth / (scale * 10), parseFloat(max)), parseFloat(min));
}

Would anyone know a possible way around this so it calculates on didInsertElement?

I have tried setting the style on didInsertElement, but then it doesnt change on resize. I think because im setting it twice.

Any help is appriciated




Aucun commentaire:

Enregistrer un commentaire