Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
document.canvasSequence = function (options) {
var _fontColor = options.fontColor ? options.fontColor : "#ffffff";
var _fontFamily = options.fontFamily ? options.fontFamily : "Arial,Helvetica,sans-serif";
var _fontSize = options.fontSize ? options.fontSize : 30;
var _fontWeight = options.fontWeight ? options.fontWeight : "200";
var wrapCanvasText = function(t, canvas, maxW, maxH) {
if (typeof maxH === "undefined") {
maxH = 0;
}
// var words = t.text.split(" ");
var words = t.split(" ");
var formatted = '';
// clear newlines
// var sansBreaks = t.text.replace(/(\r\n|\n|\r)/gm, "");
var sansBreaks = t.replace(/(\r\n|\n|\r)/gm, "");
// calc line height
var lineHeight = new fabric.Text(sansBreaks, {
fontFamily: t.fontFamily,
fontSize: 25 //t.fontSize
}).height;
// adjust for vertical offset
var maxHAdjusted = maxH > 0 ? maxH - lineHeight : 0;
var context = canvas.getContext("2d");
context.font = t.fontSize + "px " + t.fontFamily;
var currentLine = "";
var breakLineCount = 0;
for (var n = 0; n < words.length; n++) {
var isNewLine = currentLine == "";
var testOverlap = currentLine + ' ' + words[n];
// are we over width?
var w = context.measureText(testOverlap).width;
if (w < maxW) { // if not, keep adding words
currentLine += words[n] + ' ';
formatted += words[n] += ' ';
} else {
// if this hits, we got a word that need to be hypenated
if (isNewLine) {
var wordOverlap = "";
// test word length until its over maxW
for (var i = 0; i < words[n].length; ++i) {
wordOverlap += words[n].charAt(i);
var withHypeh = wordOverlap + "-";
if (context.measureText(withHypeh).width >= maxW) {
// add hyphen when splitting a word
withHypeh = wordOverlap.substr(0, wordOverlap.length - 2) + "-";
// update current word with remainder
words[n] = words[n].substr(wordOverlap.length - 1, words[n].length);
formatted += withHypeh; // add hypenated word
break;
}
}
}
n--; // restart cycle
formatted += '\n';
breakLineCount++;
currentLine = "";
}
if (maxHAdjusted > 0 && (breakLineCount * lineHeight) > maxHAdjusted) {
// add ... at the end indicating text was cutoff
formatted = formatted.substr(0, formatted.length - 3) + "...\n";
break;
}
}
// get rid of empy newline at the end
formatted = formatted.substr(0, formatted.length - 1);
return formatted;
};
var showFirstFrame = function(canvas, content) {
fabric.Image.fromURL(content.bgImage, function(oImg) {
oImg.setLeft(canvas.width / 2);
oImg.scaleToWidth(canvas.width);
oImg.scaleToHeight(canvas.height);
oImg.top = 0;
oImg.originX = 'center';
oImg.opacity = 0.4;
canvas.add(oImg);
oImg.sendToBack();
_objectsOnCanvas.push(oImg);
var text = new fabric.Text(wrapCanvasText(content.text, canvas, canvas.width / 3, canvas.height - 100), {
top: 0,
left: -canvas.width,
fontFamily: content.fontFamily ? content.fontFamily : _fontFamily,
fontSize: content.fontSize ? content.fontSize : _fontSize,
fill: content.fontColor ? content.fontColor : _fontColor,
fontWeight: content.fontWeight ? content.fontWeight : _fontWeight
});
text.setTop(canvas.height - (text.height + 20));
text.setLeft(canvas.width / 2);
text.originX = 'center';
canvas.add(text);
_objectsOnCanvas.push(text);
canvas.renderAll();
});
};
var _objectsOnCanvas = [];
var removeObjects = function(canvas) {
for (var i = 0; i < _objectsOnCanvas.length; i++) {
canvas.remove(_objectsOnCanvas[i]);
}
_objectsOnCanvas = [];
canvas.renderAll();
};
var renderContent = function(content, isLast, callback) {
removeObjects(canvas, _objectsOnCanvas);
var duration = content.text == null ? 500 : content.text.split(' ').length * 500;
if (!isLast) {
fabric.Image.fromURL(content.bgImage, function(oImg) {
oImg.setLeft(-canvas.width);
oImg.scaleToWidth(canvas.width);
oImg.scaleToHeight(canvas.height);
oImg.top = 0;
oImg.originX = 'center';
canvas.add(oImg);
_objectsOnCanvas.push(oImg);
oImg.animate('left', canvas.width / 2, {
onChange: canvas.renderAll.bind(canvas),
onComplete: function() {
oImg.animate('height', oImg.height + 100, {
onChange: canvas.renderAll.bind(canvas),
duration: duration,
onComplete: function() {
if (callback) callback();
}
});
oImg.animate('width', oImg.width + 100, {
onChange: canvas.renderAll.bind(canvas),
duration: duration
});
}
});
var text = new fabric.Text(wrapCanvasText(content.text, canvas, canvas.width / 3, canvas.height - 100), {
top: 0,
left: -canvas.width,
fontFamily: content.fontFamily ? content.fontFamily : _fontFamily,
fontSize: content.fontSize ? content.fontSize : _fontSize,
fill: content.fontColor ? content.fontColor : _fontColor,
fontWeight: content.fontWeight ? content.fontWeight : _fontWeight
});
text.setTop(canvas.height - (text.height + 20));
text.originX = 'center';
canvas.add(text);
_objectsOnCanvas.push(text);
text.animate('left', canvas.width / 2, {
onChange: canvas.renderAll.bind(canvas)
});
canvas.renderAll();
});
} else {
fabric.Image.fromURL(content.bgImage, function(oImg) {
oImg.setLeft(-canvas.width);
oImg.scaleToWidth(canvas.width);
oImg.scaleToHeight(canvas.height);
oImg.top = 0;
oImg.originX = 'center';
canvas.add(oImg);
_objectsOnCanvas.push(oImg);
oImg.animate('left', canvas.width / 2, {
onChange: canvas.renderAll.bind(canvas),
onComplete: function() {
oImg.animate('height', oImg.height + 100, {
onChange: canvas.renderAll.bind(canvas),
duration: duration,
onComplete: function() {
if (callback) callback();
}
});
oImg.animate('width', oImg.width + 100, {
onChange: canvas.renderAll.bind(canvas),
duration: duration
});
}
});
canvas.renderAll();
});
}
};
var canvasPlay = function(canvas, playButton) {
canvas.on('mouse:over', function(e) {
canvas.defaultCursor = 'auto';
});
canvas.remove(playButton);
canvas.renderAll();
if (options.onPlay) {
options.onPlay();
}
start();
audio.play();
};
var playButton = function() {
var play = new fabric.Triangle({
fill: '#f7f7f7',
angle: 90
});
canvas.add(play);
play.center();
canvas.renderAll();
play.bringToFront();
canvas.on('mouse:over', function(e) {
canvas.defaultCursor = 'pointer';
});
canvas.on('mouse:down', function() {
canvasPlay(canvas, play);
});
};
var canvas = new fabric.Canvas(options.canvasId);
fabric.Object.prototype.selectable = false;
var audio = null;
if (options.audio) {
audio = new Audio(options.audio);
}
var init = function(){
showFirstFrame(canvas, options.data[0]);
playButton();
};
var i = 0, isLast = false;
var start = function() {
if (i == (options.data.length - 1)) {
isLast = true;
if (options.onComplete) {
options.onComplete();
}
}
renderContent(options.data[i++], isLast, function() {
if (!isLast) {
start();
} else if (audio) {
var _iId = setInterval(function(){
if (audio.volume > 0) {
try {
audio.volume = audio.volume - 0.09;
} catch(e){
clearInterval(_iId);
audio.pause();
}
} else {
clearInterval(_iId);
audio.pause();
}
}, 150);
}
});
};
init();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment