HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Retrocomputing scanline function

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
retrocomputingscanlinefunction

Problem

I need to refactor this code, targeted to Google Chrome (current+) to make it manageable going forward.

Here is a working JSBin of the idea.

The messiness comes from determining the accurate number of lines of text, and the real heights of elements. I know I am passing this information around too much, without enough structure, and recalculating too many things. I also know it is messy, especially inside scal_el and run_scan.

function scan_el(el_fin_callback,el,mask,sub_mask,real_height,real_width,push,lines,line) {
        line = line || 0;
        if(line >= lines) {
                el_fin_callback();
                return; // scan finished
        }
        var current_line = real_height*line;    
        var line_os = $(el).offset();
        line_os.top += current_line;
        if(lines > 1) {
                $(mask)[0].style.height = real_height+'px';
        }
        $(sub_mask).css( { 
                'height' : $(el).height()-real_height-current_line } );
        $(mask).offset(line_os);
        line_os.top += real_height;
        var length = Math.ceil($(el).text().length*real_width)+push;
        if(lines > 1) {
                length = $(el).width();
        }
        $(sub_mask).offset(line_os);
        function next_line() { // callback after scan complete
                scan_el(el_fin_callback,el,mask,sub_mask,real_height,real_width,push,lines,line+1);
        }
        run_line_scan(length,mask,next_line);
}

Solution

There are only two things I can think of.

Sometimes it's best to pass objects when there are more than 4 parameters for a method call.

Instead of this

function scan_el(el_fin_callback, el, mask, sub_mask, real_height, real_width, push, lines, line) {


Try this.

function scan_el(el_fin_callback, els, metrics, lines, line) {


els and metrics would look something like this.

els = {
    el : jQuery,
    mask : jQuery,
    submask : jQuery
};
metrics = {
    real_width : Number,
    real_height : Number,
    push : Number
}


Try to make functions no longer than 8-12 lines.

You could extract the real_* variables into a function and return a object instead of a list of variables.

function getRealMetrics(el){
      // doesn't work completely
    var real = {};
    real.box = window.getComputedStyle(el);
    real.width = parseFloat(real.box.width);
    real.height = parseFloat(real.box.height);
    real.el = el.getBoundingClientRect();
    real.el_style = window.getComputedStyle(el);
    real.el_padding = parseFloat(real.el_style.padding);
    real.el_padding_left = parseFloat(real.el_style.paddingLeft);
    real.el_margin_left = parseFloat(real.el_style.marginLeft);
    real.el_align = real.el_style.textAlign;

    if (!isNaN(real.el_padding)) {
        real.el_height -= real.el_padding * 2.0;
    }
    var lines = Math.ceil(real.el_height / real.height);
    if (lines > 1) {
        length = real.el.width;
    }
    real.el_push = real.el_margin_left + real.el_padding_left + (real.el.width - length) / 2.0;
    if (real.el_align !== 'center') {
        real.el_push = real.el_margin_left + real.el_padding;
    }
    return result;
}

Code Snippets

function scan_el(el_fin_callback, el, mask, sub_mask, real_height, real_width, push, lines, line) {
function scan_el(el_fin_callback, els, metrics, lines, line) {
els = {
    el : jQuery,
    mask : jQuery,
    submask : jQuery
};
metrics = {
    real_width : Number,
    real_height : Number,
    push : Number
}
function getRealMetrics(el){
      // doesn't work completely
    var real = {};
    real.box = window.getComputedStyle(el);
    real.width = parseFloat(real.box.width);
    real.height = parseFloat(real.box.height);
    real.el = el.getBoundingClientRect();
    real.el_style = window.getComputedStyle(el);
    real.el_padding = parseFloat(real.el_style.padding);
    real.el_padding_left = parseFloat(real.el_style.paddingLeft);
    real.el_margin_left = parseFloat(real.el_style.marginLeft);
    real.el_align = real.el_style.textAlign;

    if (!isNaN(real.el_padding)) {
        real.el_height -= real.el_padding * 2.0;
    }
    var lines = Math.ceil(real.el_height / real.height);
    if (lines > 1) {
        length = real.el.width;
    }
    real.el_push = real.el_margin_left + real.el_padding_left + (real.el.width - length) / 2.0;
    if (real.el_align !== 'center') {
        real.el_push = real.el_margin_left + real.el_padding;
    }
    return result;
}

Context

StackExchange Code Review Q#23735, answer score: 5

Revisions (0)

No revisions yet.