Text layout in MessageLayer is calculated by combining multiple TextCustomizer.
Texts are laid out with the following procedure.
- Initiate TextCustomizers instances, with array of TextProperties passed
- Loop through all TextCustomizers instances
- Assign time elapsed to the
timePassed
properties - Calls
perform()
on the instance - Check if the display is ended by looking at the
isEnded
property - If all text customizers are ended, stop
- Otherwise, continue the loop in the next animation frame
- Assign time elapsed to the
To customize the layout, you are suppose to create your own TextCustomizer subclass, then implement the perform()
method.
In the method, you can change the textProperties as you like, but you cannot change the length of the text array. For example a customizer for moving texts around might modify text.rect.x
and text.rect.y
.
Things to aware:
- Any time-aware changes should be based on the
timePassed
property, the message layer would set this property accordingly. - You should not modify texts outside of the
perform()
function, including delayed modification (e.g. viasetTimeout
).
This is a sample TextCustomizer that moves all texts 10px downward.
class MoveDown extends TextCustomizer {
constructor(messageLayer, oldTexts, newTexts) {
super(textLayer, oldTexts, newTexts);
this.newTexts = newTexts;
}
perform() {
this.newTexts.forEach(text => {
text.rect.y += 10;
});
}
}
Adding your own TextCustomizer
To add a TextCustomizer, you need to first register the class to MessageLayer.textCustomizers
// plugin/movedown.js
MessageLayer.textCustomizers.moveDown10px = MoveDown;
Next, you may enable the text customiser by appending the name to a message layer's textCustomizers
property.
layer.textCustomizers.push('moveDown10px');
Disabling is similar:
let index = layer.textCustomizers.indexOf('moveDown10px');
layer.textCustomizers.splice(index, 1);
Please be aware that it is the customiser's responsibility to make sure it is inserted into the correct index. For example you should not insert text customizer prior to the build-in baseTextCustomizer
.
This is how it is looks like in a tag that toggle the text customizer.
// plugin/movedown.js
Tag.actions.toggle_move_down = new TagAction({
rules: {
layer : {type: "MESSAGE_LAYER", required: true},
page : {type: /fore|back/, required: true}
},
action: (args)=> {
const layer = args.layer[args.page];
let index = layer.textCustomizers.indexOf('moveDown10px');
if (index >= 0) {
layer.textCustomizers.splice(index, 1);
} else {
layer.textCustomizers.push('moveDown10px');
}
return 0;
}
});
// first.ks
[o2_loadplugin module="movedown.js"]
before
[toggle_move_down]
after
Animation
A text customiser by default redraws screen with minimal FPS, depends on the setting of the [delay]
tag. If a text customizer needs to perform animation, it has to implement the following:
- It should return
true
for theisAnimation
property, message layer will then redraw every animation frame. - It should implement the
isEnded
property. Text presentation will end if all text customizers are ended. Therefore you should expectperform()
being called even afterisEnded
is true.
A simple TextCustomizer that shows characters one by one with an interval would looks like this:
class OneByOne extends TextCustomizer {
constructor(messageLayer, oldTexts, newTexts) {
super(textLayer, oldTexts, newTexts);
this.newTexts = newTexts;
}
perform() {
this.newTexts.forEach((text, i)=> {
if (this.timePassed / 1000 > i) {
text.styles.visible = true;
} else {
text.styles.visible = false;
}
});
}
get isEnded() {
return this.timePassed / 1000 >= this.newTexts.length;
}
get isAnimation() {
return true;
}
}