HanSolo / SteelSeries-Canvas

The HTML5 Canvas port of the SteelSeries component library. Mainly contains gauges.
120 stars 76 forks source link

Possibly converting to jQuery #1

Open freman opened 12 years ago

freman commented 12 years ago

Hi there.

I'm loving your library, however I'm a little unhappy with it's size, I'd like to suggest a conversion to using jQuery to help with some of the repetitiveness.

A very short example I've prepared... I liked the idea of really gutting the codebase but it's huuuuge man!

var radialGaugeDefaults = {
    gaugeType: steelseries.GaugeType.TYPE4,
    size: 200,
    minValue: 0,
    maxValue: undefined,
    niceScale: true,
    threshold: undefined,
    section: null,
    titleString: "",
    frameDesign: steelseries.FrameDesign.METAL,
    frameVisible: true,
    backgroundColor: steelseries.BackgroundColor.DARK_GRAY,
    backgroundVisible: true,
    lcdColor: steelseries.LcdColor.STANDARD,
    lcdVisible: true,
    lcdDeicmals: 2,
    digitalFont: false,
    fractionalScaleDecimals: 1,
    ledColor: steelseries.LedColor.RED_LED,
    ledVisible: true,
    customLayer: null,
    forgroundType: steelseries.ForegroundType.TYPE1,
    foregroundVisible: true,
    playAlarm: false,
    alarmSound: false,
    tickLabelOrientation: undefined,
    trendVisible: false,
    trendColors: [steelseries.LedColor.RED_LED,steelseries.LedColor.GREEN_LED,steelseries.LedColor.CYAN_LED]
}

//*************************************   C O M P O N O N E N T S   *****************************2*******************
var radial = function(canvas, parameters) {
    var cfg = $.extend({}, radialGaugeDefaults, {
        area: null,
        unitString: "",
        pointerType: steelseries.PointerType.TYPE1,
        pointerColor: steelseries.ColorDef.RED,
        knobType: steelseries.KnobStyle.SILVER,
        knobStyle: steelseries.KnobStyle.SILVER,
        thresholdVisible: true,
        minMeasuredValueVisible: false,
        maxMeasuredValueVisible: false,
    }, parameters || {});

    if (cfg.maxValue === undefined)
        cfg.maxValue = cfg.minValue + 100;
    if (cfg.threshold === undefined)
        cfg.threshold = (cfg.maxValue - cfg.minValue) / 2
    if (cfg.tickLabelOrientation === undefined)

snip

var radialBargraph = function(canvas, parameters) {
    var cfg = $.extend({}, radialGaugeDefaults, {
        useSectionColors = false,
        valueColor = steelseries.ColorDef.RED,
        labelNumberFormat = steelseries.LabelNumberFormat.STANDARD,
        valueGradient = null,
        useValueGradient = false
    }, paramters || {});

    if (cfg.maxValue === undefined)
        cfg.maxValue = cfg.minValue + 100;
    if (cfg.threshold === undefined)
        cfg.threshold = (cfg.maxValue - cfg.minValue) / 2
    if (cfg.tickLabelOrientation === undefined)
        cfg.tickLabelOrientation = cfg.gaugeType === steelseries.GaugeType.TYPE1 ? steelseries.TickLabelOrientation.TANGENT : steelseries.TickLabelOrientation.NORMAL   

---- The above suggestion is based on the most cursory of looks, but realistically it seems you could use inheritance to reduce the codebase too.

I know a switch to jquery would mean you need to trim at least 30k from the library to make it worth the effort, but I'm sure this can be done, and more.

I'll even help :D

freman commented 12 years ago

Just thought I'd contribute my entire working javascript as an example of how beautiful this can be

var firstRun = true;

var g_defaults = {
        size                       : 201,
        gaugeType                  : steelseries.GaugeType.TYPE4,
        thresholdVisible           : false,
        minMeasuredValueVisible    : false,
        maxMeasuredValueVisible    : false,
        ledVisible                 : false,
        frameDesign                : steelseries.FrameDesign.TILTED_GRAY,
        backgroundColor            : steelseries.BackgroundColor.BEIGE,
        foregroundType             : steelseries.ForegroundType.TYPE1,
        pointerType                : steelseries.PointerType.TYPE8,
        pointerColor               : steelseries.ColorDef.BLUE,
        knobType                   : steelseries.KnobType.STANDARD_KNOB,
        knobStyle                  : steelseries.KnobStyle.SILVER,
        lcdColor                   : steelseries.LcdColor.STANDARD,
        valueColor                 : steelseries.ColorDef.BLUE,
        digitalFont                : true,
        tickLabelOrientation       : steelseries.TickLabelOrientation.HORIZONTAL,
        labelNumberFormat          : steelseries.LabelNumberFormat.STANDARD,
        lcdDecimals                : 1,
        area                       : [],
        section                    : [],
        value                      : 0
}
var g_tempDefaults = $.extend({}, g_defaults, {
        section      : [
                steelseries.Section(-10, -0, 'rgba(0, 0, 200, 0.3)'),
                steelseries.Section(-0, 5, 'rgba(20, 20, 200, 0.3)'),
                steelseries.Section(5, 15, 'rgba(50, 175, 125, 0.3)'),
                steelseries.Section(15, 25, 'rgba(0, 220, 0, 0.3)'),
                steelseries.Section(25, 35, 'rgba(255,255,0,0.3)'),
                steelseries.Section(35, 50, 'rgba(255,0,0,0.3)')
        ],
        minValue     : -10,
        maxValue     : 50,
        unitString   : '°C',
        trendVisible : false,
});
var g_humDefaults = $.extend({}, g_defaults, {
        section      : [
                steelseries.Section(0, 20, 'rgba(255,255,0,0.3)'),
                steelseries.Section(20, 80, 'rgba(0,255,0,0.3)'),
                steelseries.Section(80, 100, 'rgba(255,0,0,0.3)')
        ],
        minValue     : 0,
        maxValue     : 100,
        unitString   : '%',
});
var g_rainFallDefaults = $.extend({}, g_defaults, {
        maxValue     : 10,
        value        : 0.0001,
        scaleDecimals: 1,
        unitString   : 'mm'
});
var g_rainRateDefaults = $.extend({}, g_defaults, {
        maxValue     : 10,
        value        : 0.0001,
        scaleDecimals: 0,
        unitString   : 'mm/h'
});
var g_pressureDefaults = $.extend({}, g_defaults, {
        minValue     : 990,
        maxValue     : 1030,
        value        : 990,
        unitString   : 'hPa',
        scaleDecimals: 0
});
var g_windSpeedDefaults = $.extend({}, g_defaults, {
        maxValue     : 20,
        unitString   : 'kph',
        maxMeasuredValue: 0,
        maxMeasuredValueVisible : true,
});
var g_windDirDefaults = $.extend({}, g_defaults, {
        pointerTypeLatest: g_defaults.pointerType,
        pointerTypeAverage: steelseries.PointerType.TYPE8,
        pointerColorAverage: steelseries.ColorDef.RED,
        degreeScale : true,
        valueAverage: 0,
        valueLatest: 0
});

function createTempGauge(name, titleString) {
        return new steelseries.Radial(name, $.extend({}, g_tempDefaults, {
                titleString: titleString
        }));
};
function createHumGauge(name, titleString) {
        return new steelseries.Radial(name, $.extend({}, g_humDefaults, {
                titleString: titleString
        }));
};
function createRainFallGauge(name, titleString) {
        return new steelseries.RadialBargraph(name, $.extend({}, g_rainFallDefaults, {
                titleString: titleString
        }));
};
function createRainRateGauge(name, titleString) {
        return new steelseries.Radial(name, $.extend({}, g_rainRateDefaults, {
                titleString: titleString
        }));
};
function createPressureGauge(name, titleString) {
        return new steelseries.Radial(name, $.extend({}, g_pressureDefaults, {
                titleString: titleString
        }));
};
function createWindSpeedGauge(name, titleString) {
        return new steelseries.Radial(name, $.extend({}, g_windSpeedDefaults, {
                titleString: titleString
        }));
};
function createWindDirGauge(name, titleStringTop, titleStringBottom) {
        return new steelseries.WindDirection(name, $.extend({}, g_windDirDefaults, {
                lcdTitleStrings : [titleStringTop, titleStringBottom]
        }));
};
function createStatusDisplay(name, initialMessage) {
        return new steelseries.DisplaySingle(name, $.extend({}, g_defaults, {
                width: 400,
                height: 25,
                unitStringVisible: false,
                valuesNumeric : false,
                autoScroll : true,
                value: initialMessage
        }));
};

$(document).ready(function() {
        d_status = createStatusDisplay('c_status', 'Preparing...');
        g_temp = createTempGauge('c_temp', 'Temperature');
        g_dewpoint = createTempGauge('c_dewpoint', 'Dew Point');
        g_feelslike = createTempGauge('c_feelslike', 'Feels Like');
        g_humidity = createHumGauge('c_humidity', 'Humidity');
        g_rainfall = createRainFallGauge('c_rainfall', 'Rainfall');
        g_rainrate = createRainRateGauge('c_rainhour', 'Rain Rate');
        g_pressure = createPressureGauge('c_pressure', 'Pressure');
        g_windspeed = createWindSpeedGauge('c_windspeed', 'Wind Speed');
        g_winddir = createWindDirGauge('c_winddir', 'Latest', 'Average');

        d_status.setValue('Connecting to server');
        var socket = io.connect('http://some.domain');
        socket.on('data', function (data) {
                var method = firstRun ? 'setValue' : 'setValueAnimated';

                var temp = parseFloat(data.tempc);
                var humidity = parseFloat(data.humidity)
                g_temp[method](temp);
                g_dewpoint[method](parseFloat(data.dewptc));
                g_humidity[method](humidity);

                var rain = parseFloat(data.dailyrainmm);
                g_rainfall.setMaxValue(Math.max(Math.ceil(rain / 10) * 10, 10));
                g_rainfall[method](parseFloat(data.dailyrainmm));

                var rainRate = parseFloat(data.rainmm);
                g_rainrate.setMaxValue(Math.max(Math.ceil(rainRate / 10) * 10, 10));
                g_rainrate[method](rainRate);

                g_pressure[method](parseFloat(data.baromhpa));

                var gust = parseFloat(data.windgustms) * 3.6;
                var windspeedms = parseFloat(data.windspeedms);
                g_windspeed.setMaxValue(Math.max(Math.ceil(gust / 10) * 10, 20));
                g_windspeed[method](windspeedms * 3.6);
                g_windspeed.setMaxMeasuredValue(parseFloat(data.windgustms) * 3.6);

                var feels = temp + 0.33 * (humidity / 100 * 6.104 * Math.exp(17.27 * temp / (237.7 + temp))) - 0.7 * windspeedms - 4.0;
                g_feelslike[method](feels);

                g_winddir[method + 'Latest'](data.winddir);
                firstRun = false;

                d_status.setValue('Data received: ' + data.dateutc + ' UTC');
        });
});
HanSolo commented 12 years ago

Hi freman,

I totally agree to the fact that the size is a little bit of a problem (especially if used on mobile devices). My problem is that i do not have any time at the moment to do any work at the canvas port of the library. Maybe Mark Crossley will have time to work on this (i know that he is also thinking about splitting the lib into pieces).

Cheers,

Gerrit

freman commented 12 years ago

I don't know who's doing what, I found the library originally as part of something Cumulus was doing, then found the harmoniccode website, then found the google+ account, then found the github :D

mcrossley commented 12 years ago

Hi freman,

Sorry for the tardy reply, I've been a bit busy and the email from this issue slipped down my inbox :(

Yep, as Gerrit said I've already been looking at splitting the library into a 'core' and additional 'chunks' of similar functionality. I had it working fairly well, but it involved some compromises using pure js.

I'll have a look at what you have posted in a little more detail. As you know, at the moment the SteelSeries library has no dependencies on other libraries, we will have to think hard about the benefits of adding one.

There are probably lots of optimisations we can do without adding JQuery into the mix, starting along the lines of your first post which can be done quite easily in raw js.

The problem as ever is time, I have a number of other commitments at the moment - one I would like to start is to do with Cumulus, and radically changing how it works; which may involve some use of the steelseries code ;-)

Cheers Mark