motion-graphics-webui / js /database.js
Sebastiankay's picture
Upload 20 files
52ae39e verified
// For debugging purposes
db.config.debug = false;
// Check if a project exists
function checkDB() {
db.collection('projects')
.get()
.then((project) => {
if (project.length == 0) {
canvas.clipPath = null;
const inst = canvas.toDatalessJSON([
'volume',
'audioSrc',
'defaultLeft',
'defaultTop',
'defaultScaleX',
'defaultScaleY',
'notnew',
'starttime',
'top',
'left',
'width',
'height',
'scaleX',
'scaleY',
'flipX',
'flipY',
'originX',
'originY',
'transformMatrix',
'stroke',
'strokeWidth',
'strokeDashArray',
'strokeLineCap',
'strokeDashOffset',
'strokeLineJoin',
'strokeMiterLimit',
'angle',
'opacity',
'fill',
'globalCompositeOperation',
'shadow',
'clipTo',
'visible',
'backgroundColor',
'skewX',
'skewY',
'fillRule',
'paintFirst',
'strokeUniform',
'rx',
'ry',
'selectable',
'hasControls',
'subTargetCheck',
'id',
'hoverCursor',
'defaultCursor',
'filesrc',
'isEditing',
'source',
'assetType',
'duration',
'inGroup',
'filters',
]);
canvas.clipPath = artboard;
db.collection('projects').add({
id: 1,
canvas: JSON.stringify(inst),
keyframes: JSON.stringify(keyframes.slice()),
p_keyframes: JSON.stringify(p_keyframes.slice()),
objects: JSON.stringify(objects.slice()),
colormode: colormode,
speed: speed,
duration: duration,
currenttime: currenttime,
layercount: layer_count,
width: artboard.width,
height: artboard.height,
animatedtext: JSON.stringify(animatedtext),
groups: JSON.stringify(groups),
files: JSON.stringify(files),
activepreset: activepreset,
});
checkstatus = true;
getAssets();
} else {
loadProject();
}
});
}
// Automatically save project (locally)
function autoSave() {
if (checkstatus) {
canvas.clipPath = null;
objects.forEach(async function (object) {
var obj = canvas.getItemById(object.id);
if (obj.filters) {
if (obj.filters.length > 0) {
object.filters = [];
obj.filters.forEach(function (filter) {
if (
filter.type == 'BlackWhite' ||
filter.type == 'Invert' ||
filter.type == 'Sepia' ||
filter.type == 'Kodachrome' ||
filter.type == 'Polaroid' ||
filter.type == 'Technicolor' ||
filter.type == 'Brownie' ||
filter.type == 'Vintage'
) {
object.filters.push({ type: filter.type });
} else if (filter.type == 'Brightness') {
object.filters.push({
type: filter.type,
value: filter.brightness,
});
} else if (filter.type == 'Contrast') {
object.filters.push({
type: filter.type,
value: filter.contrast,
});
} else if (filter.type == 'Vibrance') {
object.filters.push({
type: filter.type,
value: filter.vibrance,
});
} else if (filter.type == 'Saturation') {
object.filters.push({
type: filter.type,
value: filter.saturation,
});
} else if (filter.type == 'HueRotation') {
object.filters.push({
type: filter.type,
value: filter.rotation,
});
} else if (filter.type == 'Blur') {
object.filters.push({
type: filter.type,
value: filter.blur,
});
} else if (filter.type == 'Noise') {
object.filters.push({
type: filter.type,
value: filter.noise,
});
} else if (filter.type == 'RemoveColor') {
object.filters.push({
type: filter.type,
distance: filter.distance,
color: filter.color,
});
}
});
obj.filters = [];
obj.applyFilters();
var backend = fabric.filterBackend;
if (backend && backend.evictCachesForKey) {
backend.evictCachesForKey(obj.cacheKey);
backend.evictCachesForKey(obj.cacheKey + '_filtered');
}
if (
obj.filters.length > 0 &&
obj.get('id').indexOf('Video') >= 0
) {
await obj.setElement(obj.saveElem);
}
} else {
object.filters = [];
}
} else {
object.filters = [];
}
});
const inst = canvas.toDatalessJSON([
'volume',
'audioSrc',
'defaultLeft',
'defaultTop',
'defaultScaleX',
'defaultScaleY',
'notnew',
'starttime',
'top',
'left',
'width',
'height',
'scaleX',
'scaleY',
'flipX',
'flipY',
'originX',
'originY',
'transformMatrix',
'stroke',
'strokeWidth',
'strokeDashArray',
'strokeLineCap',
'strokeDashOffset',
'strokeLineJoin',
'strokeMiterLimit',
'angle',
'opacity',
'fill',
'globalCompositeOperation',
'shadow',
'clipTo',
'visible',
'backgroundColor',
'skewX',
'skewY',
'fillRule',
'paintFirst',
'strokeUniform',
'rx',
'ry',
'selectable',
'hasControls',
'subTargetCheck',
'id',
'hoverCursor',
'defaultCursor',
'filesrc',
'isEditing',
'source',
'assetType',
'duration',
'inGroup',
]);
canvas.clipPath = artboard;
db.collection('projects')
.doc({ id: 1 })
.update({
canvas: JSON.stringify(inst),
keyframes: JSON.stringify(keyframes.slice()),
p_keyframes: JSON.stringify(p_keyframes.slice()),
objects: JSON.stringify(objects.slice()),
colormode: colormode,
duration: duration,
currenttime: currenttime,
layercount: layer_count,
speed: speed,
audiosrc: background_key,
animatedtext: JSON.stringify(animatedtext),
files: JSON.stringify(files),
groups: JSON.stringify(groups),
activepreset: activepreset,
width: artboard.width,
height: artboard.height,
});
objects.forEach(function (object) {
replaceSource(canvas.getItemById(object.id), canvas);
});
}
}
var isSameSet = function (arr1, arr2) {
return (
$(arr1).not(arr2).length === 0 && $(arr2).not(arr1).length === 0
);
};
function loadProject() {
db.collection('projects')
.doc({ id: 1 })
.get()
.then((document) => {
var project = document;
keyframes = JSON.parse(project.keyframes);
p_keyframes = JSON.parse(project.p_keyframes);
objects = JSON.parse(project.objects);
files = JSON.parse(project.files);
colormode = project.colormode;
duration = project.duration;
layer_count = project.layercount;
speed = project.speed;
animatedtext = JSON.parse(project.animatedtext);
animatedtext.forEach(function (text, index) {
var temp = new AnimatedText(text.text, text.props);
temp.assignTo(text.id);
animatedtext[index] = temp;
});
$('#speed span').html(speed.toFixed(1) + 'x');
groups = JSON.parse(project.groups);
activepreset = project.activepreset;
currenttime = 0;
canvas.clipPath = null;
canvas.clear();
fabric.filterBackend = webglBackend;
f = fabric.Image.filters;
canvas.loadFromJSON(JSON.parse(project.canvas), function () {
canvas.clipPath = artboard;
canvas.getItemById('line_h').set({ opacity: 0 });
canvas.getItemById('line_v').set({ opacity: 0 });
canvas.renderAll();
$('.object-props').remove();
$('.layer').remove();
objects.forEach(function (object) {
var animatethis = false;
if (object.animate.length > 5) {
if (isSameSet(object.animate, props)) {
animatethis = true;
}
}
renderLayer(canvas.getItemById(object.id), animatethis);
if (
!canvas.getItemById(object.id).get('assetType') ||
canvas.getItemById(object.id).get('assetType') != 'audio'
) {
props.forEach(function (prop) {
if (
prop != 'top' &&
prop != 'scaleY' &&
prop != 'width' &&
prop != 'height' &&
prop != 'shadow.offsetX' &&
prop != 'shadow.offsetY' &&
prop != 'shadow.opacity' &&
prop != 'shadow.blur' &&
prop != 'lineHeight'
) {
renderProp(prop, canvas.getItemById(object.id));
}
});
replaceSource(canvas.getItemById(object.id), canvas);
} else {
renderProp('volume', canvas.getItemById(object.id));
}
});
keyframes.forEach(function (keyframe) {
if (
keyframe.name != 'top' &&
keyframe.name != 'scaleY' &&
keyframe.name != 'width' &&
keyframe.name != 'height' &&
keyframe.name != 'shadow.offsetX' &&
keyframe.name != 'shadow.offsetY' &&
keyframe.name != 'shadow.opacity' &&
keyframe.name != 'shadow.blur' &&
keyframe.name != 'lineHeight'
) {
renderKeyframe(
canvas.getItemById(keyframe.id),
keyframe.name,
keyframe.t
);
}
});
artboard.set({
width: project.width,
height: project.height,
});
canvas.renderAll();
resizeCanvas();
updatePanel();
animatedtext.forEach(function (text, index) {
text.reset(text.text, text.props, canvas);
canvas.renderAll();
});
// Set defaults
setDuration(duration);
setTimelineZoom(5);
checkstatus = true;
getAssets();
canvas.renderAll();
animate(false, 0);
//newLottieAnimation(100,100);
});
});
}
function blobToBase64(blob) {
return new Promise((resolve, _) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
}
async function saveFile(thumbnail, file, type, name, place, hidden) {
file = await blobToBase64(file);
thumbnail = await blobToBase64(thumbnail);
uploading = false;
var key = Math.random().toString(36).substr(2, 9);
db.collection('assets').add({
key: key,
src: file,
thumb: thumbnail,
name: name,
type: type,
hidden: hidden,
});
if (type === 'image') {
uploaded_images.push({
src: file,
thumb: thumbnail,
key: key,
type: 'image',
hidden: false,
});
populateGrid('images-tab');
} else if (type === 'video') {
uploaded_videos.push({
src: file,
thumb: thumbnail,
key: key,
type: 'video',
hidden: false,
});
populateGrid('videos-tab');
}
$('#upload-button').html(
"<img src='assets/upload.svg'> Upload media"
);
$('#upload-button').removeClass('uploading');
if (place) {
loadImage(
file,
artboard.get('left') + artboard.get('width') / 2,
artboard.get('top') + artboard.get('height') / 2,
200
);
}
save();
}
async function savePixabayImage(url, xpos, ypos, width) {
$('#load-image').addClass('loading-active');
fetch(url)
.then((res) => res.blob())
.then((blob) => {
url = blob;
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
url = reader.result;
var key = Math.random().toString(36).substr(2, 9);
db.collection('assets').add({
key: key,
src: url,
thumb: url,
name: 'test',
type: 'image',
hidden: true,
});
loadImage(url, xpos, ypos, width, false);
};
});
}
async function saveAudio(url) {
var reader = new FileReader();
reader.readAsDataURL(url);
reader.onloadend = function () {
var key = Math.random().toString(36).substr(2, 9);
db.collection('assets').add({
key: key,
src: reader.result,
name: 'test',
type: 'audio',
hidden: true,
});
newAudioLayer(reader.result);
};
}
async function savePixabayVideo(url, thumb, x, y) {
$('#load-video').addClass('loading-active');
fetch(url)
.then((res) => res.blob())
.then((blob) => {
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
fetch(thumb)
.then((res) => res.blob())
.then((blob2) => {
var reader2 = new FileReader();
reader2.readAsDataURL(blob2);
reader2.onloadend = function () {
url = reader.result;
thumb = reader2.result;
var key = Math.random().toString(36).substr(2, 9);
db.collection('assets').add({
key: key,
src: url,
thumb: thumb,
name: 'test',
type: 'video',
hidden: true,
});
loadVideo(url, x, y, false);
};
});
};
});
}
function deleteAsset(key) {
db.collection('assets')
.doc({ key: key })
.get()
.then((asset) => {
var temp = files.filter((x) => x.file == asset.src);
if (temp.length > 0) {
temp.forEach(function (file) {
deleteObject(canvas.getItemById(file.name));
files = $.grep(files, function (a) {
return a != file;
});
});
}
db.collection('assets').doc({ key: key }).delete();
if (asset.type == 'image') {
uploaded_images = uploaded_images.filter(function (obj) {
return obj.key !== key;
});
populateGrid('images-tab');
} else {
uploaded_videos = uploaded_videos.filter(function (obj) {
return obj.key !== key;
});
populateGrid('videos-tab');
}
});
}
function getAssets() {
db.collection('assets')
.get()
.then((assets) => {
// Sometimes the assets aren't ready when importing, really annoying
if (assets === undefined) {
getAssets();
} else if (assets.length > 0) {
assets.forEach(function (asset) {
if (asset.type == 'image') {
uploaded_images.push({
src: asset.src,
thumb: asset.thumb,
key: asset.key,
type: 'image',
hidden: asset.hidden,
});
} else if (asset.type == 'video') {
uploaded_videos.push({
src: asset.src,
thumb: asset.thumb,
key: asset.key,
type: 'video',
hidden: asset.hidden,
});
}
});
}
});
}
function readTextFile(file, callback) {
var rawFile = new XMLHttpRequest();
rawFile.overrideMimeType('application/json');
rawFile.open('GET', file, true);
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4 && rawFile.status == '200') {
callback(rawFile.responseText);
}
};
rawFile.send(null);
}
async function importProject(e) {
$('#import-project span').html('Importing...');
var file = e.target.files[0];
var path = (window.URL || window.webkitURL).createObjectURL(file);
readTextFile(path, function (text) {
var data = JSON.parse(text);
delete data.project[0].id;
if (data.project.length > 0) {
if (data.assets.length > 0) {
data.assets.forEach(function (asset) {
delete asset.id;
db.collection('assets').add(asset);
});
}
db.collection('projects')
.doc({ id: 1 })
.update(data.project[0])
.then((response) => {
$('#import-project span').html('Import');
hideModals();
loadProject();
});
} else {
alert('Wrong file type');
}
});
}
function importHandle() {
$('#import').click();
}
function exportProject() {
$('#export-project span').html('Exporting...');
db.collection('projects')
.get()
.then((project) => {
if (project.length > 0) {
db.collection('assets')
.get()
.then((assets) => {
var exportarr = { project: project, assets: assets };
$('<a />', {
download: 'data.json',
href:
'data:application/json,' +
encodeURIComponent(JSON.stringify(exportarr)),
})
.appendTo('body')
.click(function () {
$(this).remove();
$('#export-project span').html('Export');
})[0]
.click();
});
} else {
alert('Empty project');
$('#export-project span').html('Export');
}
});
}
$(document).on('click', '#import-project', importHandle);
$(document).on('click', '#export-project', exportProject);
$(document).on('change', '#import', importProject);
function clearProject() {
if (
window.confirm(
'Are you sure you want to clear this project? This action cannot be undone.'
)
) {
db.collection('projects').delete();
db.collection('assets').delete();
window.setTimeout(function () {
location.reload();
}, 1000);
}
hideMore();
}
$(document).on('click', '#clear-project', clearProject);