|
function animateText(group, ms, play, props, cv, id) { |
|
var starttime = p_keyframes.find((x) => x.id == id).start; |
|
ms -= starttime; |
|
var length = group._objects.length; |
|
var globaldelay = 0; |
|
for (var i = 0; i < length; i++) { |
|
var index = i; |
|
if (props.order == 'backward') { |
|
index = length - i - 1; |
|
} |
|
let left = group.item(index).defaultLeft; |
|
let top = group.item(index).defaultTop; |
|
let scaleX = group.item(index).defaultScaleX; |
|
let scaleY = group.item(index).defaultScaleY; |
|
var delay = i * duration; |
|
var duration = props.duration / length; |
|
var animation = { |
|
opacity: 0, |
|
top: top, |
|
left: left, |
|
scaleX: scaleX, |
|
scaleY: scaleY, |
|
}; |
|
if (props.typeAnim == 'letter') { |
|
delay = i * duration - 100; |
|
} else if (props.typeAnim == 'word') { |
|
if (group.item(index).text == ' ') { |
|
globaldelay += 500; |
|
} |
|
delay = globaldelay; |
|
} |
|
if (props.preset == 'typewriter') { |
|
delay = i * duration; |
|
duration = 20; |
|
} else if (props.preset == 'fade in') { |
|
} else if (props.preset == 'slide top') { |
|
animation.top += 20; |
|
} else if (props.preset == 'slide bottom') { |
|
animation.top -= 20; |
|
} else if (props.preset == 'slide left') { |
|
animation.left += 20; |
|
} else if (props.preset == 'slide right') { |
|
animation.left -= 20; |
|
} else if (props.preset == 'scale') { |
|
animation.scaleX = 0; |
|
animation.scaleY = 0; |
|
} else if (props.preset == 'shrink') { |
|
animation.scaleX = 1.5; |
|
animation.scaleY = 1.5; |
|
} |
|
if (delay < 0) { |
|
delay = 0; |
|
} |
|
if (duration < 20) { |
|
duration = 20; |
|
} |
|
var start = false; |
|
var instance = anime({ |
|
targets: animation, |
|
delay: delay, |
|
opacity: 1, |
|
left: left, |
|
top: top, |
|
scaleX: scaleX, |
|
scaleY: scaleY, |
|
duration: duration, |
|
easing: props.easing, |
|
autoplay: play, |
|
update: function () { |
|
if (start && play) { |
|
group.item(index).set({ |
|
opacity: animation.opacity, |
|
left: animation.left, |
|
top: animation.top, |
|
scaleX: animation.scaleX, |
|
scaleY: animation.scaleY, |
|
}); |
|
cv.renderAll(); |
|
} |
|
}, |
|
changeBegin: function () { |
|
start = true; |
|
}, |
|
}); |
|
instance.seek(ms); |
|
if (!play) { |
|
group.item(index).set({ |
|
opacity: animation.opacity, |
|
left: animation.left, |
|
top: animation.top, |
|
scaleX: animation.scaleX, |
|
scaleY: animation.scaleY, |
|
}); |
|
cv.renderAll(); |
|
} |
|
} |
|
} |
|
|
|
function setText(group, props, cv) { |
|
var length = group._objects.length; |
|
for (var i = 0; i < length; i++) { |
|
group.item(i).set({ |
|
fill: props.fill, |
|
fontFamily: props.fontFamily, |
|
}); |
|
cv.renderAll(); |
|
} |
|
} |
|
|
|
function renderText(string, props, x, y, cv, id, isnew, start) { |
|
var textOffset = 0; |
|
var group = []; |
|
function renderLetter(letter) { |
|
var text = new fabric.Text(letter, { |
|
left: textOffset, |
|
top: 0, |
|
fill: props.fill, |
|
fontFamily: props.fontFamily, |
|
opacity: 1, |
|
}); |
|
text.set({ |
|
defaultLeft: text.left, |
|
defaultTop: text.top, |
|
defaultScaleX: 1, |
|
defaultScaleY: 1, |
|
}); |
|
textOffset += text.get('width'); |
|
return text; |
|
} |
|
for (var i = 0; i < string.length; i++) { |
|
group.push(renderLetter(string.charAt(i))); |
|
} |
|
var result = new fabric.Group(group, { |
|
cursorWidth: 1, |
|
stroke: '#000', |
|
strokeUniform: true, |
|
paintFirst: 'stroke', |
|
strokeWidth: 0, |
|
originX: 'center', |
|
originY: 'center', |
|
left: x - artboard.left, |
|
top: y - artboard.top, |
|
cursorDuration: 1, |
|
cursorDelay: 250, |
|
assetType: 'animatedText', |
|
id: id, |
|
strokeDashArray: false, |
|
inGroup: false, |
|
}); |
|
if (isnew) { |
|
result.set({ |
|
notnew: true, |
|
starttime: start, |
|
}); |
|
} |
|
result.objectCaching = false; |
|
cv.add(result); |
|
cv.renderAll(); |
|
newLayer(result); |
|
result._objects.forEach(function (object, index) { |
|
result.item(index).set({ |
|
defaultLeft: result.item(index).defaultLeft - result.width / 2, |
|
defaultTop: result.item(index).defaultTop - result.height / 2, |
|
}); |
|
}); |
|
cv.setActiveObject(result); |
|
cv.bringToFront(result); |
|
return result.id; |
|
} |
|
|
|
class AnimatedText { |
|
constructor(text, props) { |
|
this.text = text; |
|
this.props = props; |
|
this.id = 'Text' + layer_count; |
|
} |
|
render(cv) { |
|
this.id = renderText( |
|
this.text, |
|
this.props, |
|
this.props.left, |
|
this.props.top, |
|
cv, |
|
this.id, |
|
false, |
|
0 |
|
); |
|
animateText( |
|
cv.getItemById(this.id), |
|
currenttime, |
|
false, |
|
this.props, |
|
cv, |
|
this.id |
|
); |
|
} |
|
seek(ms, cv) { |
|
animateText( |
|
cv.getItemById(this.id), |
|
ms, |
|
false, |
|
this.props, |
|
cv, |
|
this.id |
|
); |
|
} |
|
play(cv) { |
|
animateText( |
|
cv.getItemById(this.id), |
|
0, |
|
true, |
|
this.props, |
|
cv, |
|
this.id |
|
); |
|
} |
|
getObject(cv) { |
|
return cv.getItemById(this.id); |
|
} |
|
setProps(newprops, cv) { |
|
this.props = $.extend(this.props, newprops); |
|
setText(cv.getItemById(this.id), this.props, cv); |
|
} |
|
setProp(newprop) { |
|
$.extend(this.props, newprop); |
|
} |
|
reset(text, newprops, cv) { |
|
var obj = cv.getItemById(this.id); |
|
var left = obj.left; |
|
var top = obj.top; |
|
var scaleX = obj, |
|
scaleX; |
|
var scaleY = obj.scaleY; |
|
var angle = obj.angle; |
|
var start = p_keyframes.find((x) => x.id == this.id).start; |
|
deleteObject(obj, false); |
|
this.text = text; |
|
this.props = newprops; |
|
this.inst = renderText( |
|
text, |
|
this.props, |
|
left, |
|
top, |
|
cv, |
|
this.id, |
|
true, |
|
start |
|
); |
|
cv.getItemById(this.id).set({ |
|
angle: angle, |
|
scaleX: scaleX, |
|
scaleY: scaleY, |
|
}); |
|
cv.renderAll(); |
|
animateText( |
|
cv.getItemById(this.id), |
|
currenttime, |
|
false, |
|
this.props, |
|
cv, |
|
this.id |
|
); |
|
animate(currenttime, false); |
|
save(); |
|
} |
|
assignTo(id, text, props) { |
|
this.id = id; |
|
} |
|
} |
|
|