collusioni.st

CNNi Style Headlines

Saturday, September 09 2006

I got a bit obsessive tonight and set myself up with a challenge. After watching one of CNN’s international news broadcasts, I got interested in recreating their new on screen headline graphics with HTML and Javascript. Here’s what it looks like:

Effect.BlindLeft = function(element) {
element = $(element);
element.makeClipping();
return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false,
scaleY: false,
restoreAfterFinish: true,
afterFinishInternal: function(effect) {
effect.element.hide();
effect.element.undoClipping();
}
}, arguments1 || {})
);
}

Effect.BlindRight = function(element) {
element = $(element);
var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100,
Object.extend({ scaleContent: false,
scaleY: false,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
effect.element.makeClipping();
effect.element.setStyle({width: ’0px’});
effect.element.show();
},
afterFinishInternal: function(effect) {
effect.element.undoClipping();
}
}, arguments1 || {})
);
}

Effect.DelayedChain = Class.create();
Object.extend(Effect.DelayedChain.prototype, {
initialize: function(effect, elements, options, timeout){
this.elements = elements;
this.effect = effect;
this.timeout = timeout || 100;
this.options = Object.extend({}, options || {});

this.afterFinish = this.options.afterFinish || Prototype.emptyFunction;
this.options.afterFinish = Prototype.emptyFunction;
setTimeout(this.action.bind(this),1);
},
action: function() {
if(this.elements.length){
new Effect[this.effect](this.elements.shift(), this.options);
setTimeout(this.action.bind(this), this.timeout);
} else {
if(this.afterFinish) this.afterFinish();
}
}
});

Effect.Chain = Class.create();
Object.extend(Effect.Chain.prototype, {
initialize: function(effect, elements, options){
this.elements = elements || [];
this.effect = effect;
this.options = options || {};
this.afterFinish = this.options.afterFinish || Prototype.emptyFunction;
this.options.afterFinish = this.nextEffect.bind(this);
setTimeout(this.nextEffect.bind(this), 1);
},
nextEffect: function(){
if(this.elements.length)
new Effect[this.effect](this.elements.shift(), this.options);
else
this.afterFinish();
}
});

.headline_text {
font-family: helvetica;
font-size: 2em;
color: white;
background-color: black;
padding: 4px;
}
.headline_bg {
font-family: helvetica;
font-size: 2em;
color: grey;
background-color: grey;
padding: 4px;
}

Primates learn how
to make blueberry pancakes and blintzes
.
.

/*
elements all sit off in an hidden overflow area at top of -300px.
This is so we can get the rendered width of the text, which we use to build out the divs and such. if it were display:none it’d have no width at all.

headline_bg’s build out from left to right, with about 4 frames total
then the headline words themselves, with black, fill in at about the same speed
*/

// get the widths of our two lines
var widths = [$(‘word_one’).offsetWidth+4,$(‘word_two’).offsetWidth+4];
var heights = [($(‘word_one’).offsetHeight+8)2,($(‘word_two’).offsetHeight+8)2];

// hide, set positions and widths of grey bg
$(‘head_bg_one’).style.display = “none”;
$(‘head_bg_two’).style.display = “none”;
$(‘head_bg_one’).style.width = widths0 + “px”;
$(‘head_bg_two’).style.width = widths1 + “px”;
$(‘head_bg_one’).style.top = -heights0 + “px”;
$(‘head_bg_two’).style.top = -heights1 + “px”;

// hide, set positions and widths of words
$(‘bg_one’).style.display = “none”;
$(‘bg_two’).style.display = “none”;

$(‘bg_one’).style.width = widths0 + “px”;
$(‘bg_two’).style.width = widths1 + “px”;
$(‘bg_one’).style.top = “0px”;
$(‘bg_two’).style.top = “0px”;

$(‘word’).style.height = (heights0) + “px”;

function shakedown() {
new Effect.DelayedChain(‘BlindRight’, [‘head_bg_one’,‘head_bg_two’, ‘bg_one’, ‘bg_two’], { duration: 0.25 }, 100);
}

setTimeout(‘shakedown()’, 100);

See it again.

It’s not perfect, but its fun. This can be dropped into Rails apps pretty easily or adapated to a non rails app. Check out more code after the jump.