|
|
|
db.config.debug = false; |
|
|
|
|
|
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(); |
|
} |
|
}); |
|
} |
|
|
|
|
|
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(); |
|
}); |
|
|
|
|
|
setDuration(duration); |
|
setTimelineZoom(5); |
|
checkstatus = true; |
|
|
|
getAssets(); |
|
|
|
canvas.renderAll(); |
|
|
|
animate(false, 0); |
|
|
|
|
|
}); |
|
}); |
|
} |
|
|
|
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) => { |
|
|
|
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); |
|
|