Sebastiankay/motion-graphics-webui
0
1// For debugging purposes2db.config.debug = false;3 4// Check if a project exists5function checkDB() {6 db.collection('projects')7 .get()8 .then((project) => {9 if (project.length == 0) {10 canvas.clipPath = null;11 const inst = canvas.toDatalessJSON([12 'volume',13 'audioSrc',14 'defaultLeft',15 'defaultTop',16 'defaultScaleX',17 'defaultScaleY',18 'notnew',19 'starttime',20 'top',21 'left',22 'width',23 'height',24 'scaleX',25 'scaleY',26 'flipX',27 'flipY',28 'originX',29 'originY',30 'transformMatrix',31 'stroke',32 'strokeWidth',33 'strokeDashArray',34 'strokeLineCap',35 'strokeDashOffset',36 'strokeLineJoin',37 'strokeMiterLimit',38 'angle',39 'opacity',40 'fill',41 'globalCompositeOperation',42 'shadow',43 'clipTo',44 'visible',45 'backgroundColor',46 'skewX',47 'skewY',48 'fillRule',49 'paintFirst',50 'strokeUniform',51 'rx',52 'ry',53 'selectable',54 'hasControls',55 'subTargetCheck',56 'id',57 'hoverCursor',58 'defaultCursor',59 'filesrc',60 'isEditing',61 'source',62 'assetType',63 'duration',64 'inGroup',65 'filters',66 ]);67 canvas.clipPath = artboard;68 db.collection('projects').add({69 id: 1,70 canvas: JSON.stringify(inst),71 keyframes: JSON.stringify(keyframes.slice()),72 p_keyframes: JSON.stringify(p_keyframes.slice()),73 objects: JSON.stringify(objects.slice()),74 colormode: colormode,75 speed: speed,76 duration: duration,77 currenttime: currenttime,78 layercount: layer_count,79 width: artboard.width,80 height: artboard.height,81 animatedtext: JSON.stringify(animatedtext),82 groups: JSON.stringify(groups),83 files: JSON.stringify(files),84 activepreset: activepreset,85 });86 checkstatus = true;87 getAssets();88 } else {89 loadProject();90 }91 });92}93 94// Automatically save project (locally)95function autoSave() {96 if (checkstatus) {97 canvas.clipPath = null;98 objects.forEach(async function (object) {99 var obj = canvas.getItemById(object.id);100 if (obj.filters) {101 if (obj.filters.length > 0) {102 object.filters = [];103 obj.filters.forEach(function (filter) {104 if (105 filter.type == 'BlackWhite' ||106 filter.type == 'Invert' ||107 filter.type == 'Sepia' ||108 filter.type == 'Kodachrome' ||109 filter.type == 'Polaroid' ||110 filter.type == 'Technicolor' ||111 filter.type == 'Brownie' ||112 filter.type == 'Vintage'113 ) {114 object.filters.push({ type: filter.type });115 } else if (filter.type == 'Brightness') {116 object.filters.push({117 type: filter.type,118 value: filter.brightness,119 });120 } else if (filter.type == 'Contrast') {121 object.filters.push({122 type: filter.type,123 value: filter.contrast,124 });125 } else if (filter.type == 'Vibrance') {126 object.filters.push({127 type: filter.type,128 value: filter.vibrance,129 });130 } else if (filter.type == 'Saturation') {131 object.filters.push({132 type: filter.type,133 value: filter.saturation,134 });135 } else if (filter.type == 'HueRotation') {136 object.filters.push({137 type: filter.type,138 value: filter.rotation,139 });140 } else if (filter.type == 'Blur') {141 object.filters.push({142 type: filter.type,143 value: filter.blur,144 });145 } else if (filter.type == 'Noise') {146 object.filters.push({147 type: filter.type,148 value: filter.noise,149 });150 } else if (filter.type == 'RemoveColor') {151 object.filters.push({152 type: filter.type,153 distance: filter.distance,154 color: filter.color,155 });156 }157 });158 obj.filters = [];159 obj.applyFilters();160 var backend = fabric.filterBackend;161 if (backend && backend.evictCachesForKey) {162 backend.evictCachesForKey(obj.cacheKey);163 backend.evictCachesForKey(obj.cacheKey + '_filtered');164 }165 if (166 obj.filters.length > 0 &&167 obj.get('id').indexOf('Video') >= 0168 ) {169 await obj.setElement(obj.saveElem);170 }171 } else {172 object.filters = [];173 }174 } else {175 object.filters = [];176 }177 });178 const inst = canvas.toDatalessJSON([179 'volume',180 'audioSrc',181 'defaultLeft',182 'defaultTop',183 'defaultScaleX',184 'defaultScaleY',185 'notnew',186 'starttime',187 'top',188 'left',189 'width',190 'height',191 'scaleX',192 'scaleY',193 'flipX',194 'flipY',195 'originX',196 'originY',197 'transformMatrix',198 'stroke',199 'strokeWidth',200 'strokeDashArray',201 'strokeLineCap',202 'strokeDashOffset',203 'strokeLineJoin',204 'strokeMiterLimit',205 'angle',206 'opacity',207 'fill',208 'globalCompositeOperation',209 'shadow',210 'clipTo',211 'visible',212 'backgroundColor',213 'skewX',214 'skewY',215 'fillRule',216 'paintFirst',217 'strokeUniform',218 'rx',219 'ry',220 'selectable',221 'hasControls',222 'subTargetCheck',223 'id',224 'hoverCursor',225 'defaultCursor',226 'filesrc',227 'isEditing',228 'source',229 'assetType',230 'duration',231 'inGroup',232 ]);233 canvas.clipPath = artboard;234 db.collection('projects')235 .doc({ id: 1 })236 .update({237 canvas: JSON.stringify(inst),238 keyframes: JSON.stringify(keyframes.slice()),239 p_keyframes: JSON.stringify(p_keyframes.slice()),240 objects: JSON.stringify(objects.slice()),241 colormode: colormode,242 duration: duration,243 currenttime: currenttime,244 layercount: layer_count,245 speed: speed,246 audiosrc: background_key,247 animatedtext: JSON.stringify(animatedtext),248 files: JSON.stringify(files),249 groups: JSON.stringify(groups),250 activepreset: activepreset,251 width: artboard.width,252 height: artboard.height,253 });254 objects.forEach(function (object) {255 replaceSource(canvas.getItemById(object.id), canvas);256 });257 }258}259 260var isSameSet = function (arr1, arr2) {261 return (262 $(arr1).not(arr2).length === 0 && $(arr2).not(arr1).length === 0263 );264};265 266function loadProject() {267 db.collection('projects')268 .doc({ id: 1 })269 .get()270 .then((document) => {271 var project = document;272 keyframes = JSON.parse(project.keyframes);273 p_keyframes = JSON.parse(project.p_keyframes);274 objects = JSON.parse(project.objects);275 files = JSON.parse(project.files);276 colormode = project.colormode;277 duration = project.duration;278 layer_count = project.layercount;279 speed = project.speed;280 animatedtext = JSON.parse(project.animatedtext);281 animatedtext.forEach(function (text, index) {282 var temp = new AnimatedText(text.text, text.props);283 temp.assignTo(text.id);284 animatedtext[index] = temp;285 });286 $('#speed span').html(speed.toFixed(1) + 'x');287 groups = JSON.parse(project.groups);288 activepreset = project.activepreset;289 currenttime = 0;290 canvas.clipPath = null;291 canvas.clear();292 fabric.filterBackend = webglBackend;293 f = fabric.Image.filters;294 canvas.loadFromJSON(JSON.parse(project.canvas), function () {295 canvas.clipPath = artboard;296 canvas.getItemById('line_h').set({ opacity: 0 });297 canvas.getItemById('line_v').set({ opacity: 0 });298 canvas.renderAll();299 $('.object-props').remove();300 $('.layer').remove();301 objects.forEach(function (object) {302 var animatethis = false;303 if (object.animate.length > 5) {304 if (isSameSet(object.animate, props)) {305 animatethis = true;306 }307 }308 renderLayer(canvas.getItemById(object.id), animatethis);309 if (310 !canvas.getItemById(object.id).get('assetType') ||311 canvas.getItemById(object.id).get('assetType') != 'audio'312 ) {313 props.forEach(function (prop) {314 if (315 prop != 'top' &&316 prop != 'scaleY' &&317 prop != 'width' &&318 prop != 'height' &&319 prop != 'shadow.offsetX' &&320 prop != 'shadow.offsetY' &&321 prop != 'shadow.opacity' &&322 prop != 'shadow.blur' &&323 prop != 'lineHeight'324 ) {325 renderProp(prop, canvas.getItemById(object.id));326 }327 });328 replaceSource(canvas.getItemById(object.id), canvas);329 } else {330 renderProp('volume', canvas.getItemById(object.id));331 }332 });333 keyframes.forEach(function (keyframe) {334 if (335 keyframe.name != 'top' &&336 keyframe.name != 'scaleY' &&337 keyframe.name != 'width' &&338 keyframe.name != 'height' &&339 keyframe.name != 'shadow.offsetX' &&340 keyframe.name != 'shadow.offsetY' &&341 keyframe.name != 'shadow.opacity' &&342 keyframe.name != 'shadow.blur' &&343 keyframe.name != 'lineHeight'344 ) {345 renderKeyframe(346 canvas.getItemById(keyframe.id),347 keyframe.name,348 keyframe.t349 );350 }351 });352 artboard.set({353 width: project.width,354 height: project.height,355 });356 canvas.renderAll();357 resizeCanvas();358 updatePanel();359 360 animatedtext.forEach(function (text, index) {361 text.reset(text.text, text.props, canvas);362 canvas.renderAll();363 });364 365 // Set defaults366 setDuration(duration);367 setTimelineZoom(5);368 checkstatus = true;369 370 getAssets();371 372 canvas.renderAll();373 374 animate(false, 0);375 376 //newLottieAnimation(100,100);377 });378 });379}380 381function blobToBase64(blob) {382 return new Promise((resolve, _) => {383 const reader = new FileReader();384 reader.onloadend = () => resolve(reader.result);385 reader.readAsDataURL(blob);386 });387}388 389async function saveFile(thumbnail, file, type, name, place, hidden) {390 file = await blobToBase64(file);391 thumbnail = await blobToBase64(thumbnail);392 uploading = false;393 var key = Math.random().toString(36).substr(2, 9);394 db.collection('assets').add({395 key: key,396 src: file,397 thumb: thumbnail,398 name: name,399 type: type,400 hidden: hidden,401 });402 if (type === 'image') {403 uploaded_images.push({404 src: file,405 thumb: thumbnail,406 key: key,407 type: 'image',408 hidden: false,409 });410 populateGrid('images-tab');411 } else if (type === 'video') {412 uploaded_videos.push({413 src: file,414 thumb: thumbnail,415 key: key,416 type: 'video',417 hidden: false,418 });419 populateGrid('videos-tab');420 }421 $('#upload-button').html(422 "<img src='assets/upload.svg'> Upload media"423 );424 $('#upload-button').removeClass('uploading');425 if (place) {426 loadImage(427 file,428 artboard.get('left') + artboard.get('width') / 2,429 artboard.get('top') + artboard.get('height') / 2,430 200431 );432 }433 save();434}435 436async function savePixabayImage(url, xpos, ypos, width) {437 $('#load-image').addClass('loading-active');438 fetch(url)439 .then((res) => res.blob())440 .then((blob) => {441 url = blob;442 var reader = new FileReader();443 reader.readAsDataURL(blob);444 reader.onloadend = function () {445 url = reader.result;446 var key = Math.random().toString(36).substr(2, 9);447 db.collection('assets').add({448 key: key,449 src: url,450 thumb: url,451 name: 'test',452 type: 'image',453 hidden: true,454 });455 loadImage(url, xpos, ypos, width, false);456 };457 });458}459 460async function saveAudio(url) {461 var reader = new FileReader();462 reader.readAsDataURL(url);463 reader.onloadend = function () {464 var key = Math.random().toString(36).substr(2, 9);465 db.collection('assets').add({466 key: key,467 src: reader.result,468 name: 'test',469 type: 'audio',470 hidden: true,471 });472 newAudioLayer(reader.result);473 };474}475 476async function savePixabayVideo(url, thumb, x, y) {477 $('#load-video').addClass('loading-active');478 fetch(url)479 .then((res) => res.blob())480 .then((blob) => {481 var reader = new FileReader();482 reader.readAsDataURL(blob);483 reader.onloadend = function () {484 fetch(thumb)485 .then((res) => res.blob())486 .then((blob2) => {487 var reader2 = new FileReader();488 reader2.readAsDataURL(blob2);489 reader2.onloadend = function () {490 url = reader.result;491 thumb = reader2.result;492 var key = Math.random().toString(36).substr(2, 9);493 db.collection('assets').add({494 key: key,495 src: url,496 thumb: thumb,497 name: 'test',498 type: 'video',499 hidden: true,500 });501 loadVideo(url, x, y, false);502 };503 });504 };505 });506}507 508function deleteAsset(key) {509 db.collection('assets')510 .doc({ key: key })511 .get()512 .then((asset) => {513 var temp = files.filter((x) => x.file == asset.src);514 if (temp.length > 0) {515 temp.forEach(function (file) {516 deleteObject(canvas.getItemById(file.name));517 files = $.grep(files, function (a) {518 return a != file;519 });520 });521 }522 db.collection('assets').doc({ key: key }).delete();523 if (asset.type == 'image') {524 uploaded_images = uploaded_images.filter(function (obj) {525 return obj.key !== key;526 });527 populateGrid('images-tab');528 } else {529 uploaded_videos = uploaded_videos.filter(function (obj) {530 return obj.key !== key;531 });532 populateGrid('videos-tab');533 }534 });535}536 537function getAssets() {538 db.collection('assets')539 .get()540 .then((assets) => {541 // Sometimes the assets aren't ready when importing, really annoying542 if (assets === undefined) {543 getAssets();544 } else if (assets.length > 0) {545 assets.forEach(function (asset) {546 if (asset.type == 'image') {547 uploaded_images.push({548 src: asset.src,549 thumb: asset.thumb,550 key: asset.key,551 type: 'image',552 hidden: asset.hidden,553 });554 } else if (asset.type == 'video') {555 uploaded_videos.push({556 src: asset.src,557 thumb: asset.thumb,558 key: asset.key,559 type: 'video',560 hidden: asset.hidden,561 });562 }563 });564 }565 });566}567 568function readTextFile(file, callback) {569 var rawFile = new XMLHttpRequest();570 rawFile.overrideMimeType('application/json');571 rawFile.open('GET', file, true);572 rawFile.onreadystatechange = function () {573 if (rawFile.readyState === 4 && rawFile.status == '200') {574 callback(rawFile.responseText);575 }576 };577 rawFile.send(null);578}579 580async function importProject(e) {581 $('#import-project span').html('Importing...');582 var file = e.target.files[0];583 var path = (window.URL || window.webkitURL).createObjectURL(file);584 readTextFile(path, function (text) {585 var data = JSON.parse(text);586 delete data.project[0].id;587 if (data.project.length > 0) {588 if (data.assets.length > 0) {589 data.assets.forEach(function (asset) {590 delete asset.id;591 db.collection('assets').add(asset);592 });593 }594 db.collection('projects')595 .doc({ id: 1 })596 .update(data.project[0])597 .then((response) => {598 $('#import-project span').html('Import');599 hideModals();600 loadProject();601 });602 } else {603 alert('Wrong file type');604 }605 });606}607 608function importHandle() {609 $('#import').click();610}611 612function exportProject() {613 $('#export-project span').html('Exporting...');614 db.collection('projects')615 .get()616 .then((project) => {617 if (project.length > 0) {618 db.collection('assets')619 .get()620 .then((assets) => {621 var exportarr = { project: project, assets: assets };622 $('<a />', {623 download: 'data.json',624 href:625 'data:application/json,' +626 encodeURIComponent(JSON.stringify(exportarr)),627 })628 .appendTo('body')629 .click(function () {630 $(this).remove();631 $('#export-project span').html('Export');632 })[0]633 .click();634 });635 } else {636 alert('Empty project');637 $('#export-project span').html('Export');638 }639 });640}641 642$(document).on('click', '#import-project', importHandle);643$(document).on('click', '#export-project', exportProject);644$(document).on('change', '#import', importProject);645 646function clearProject() {647 if (648 window.confirm(649 'Are you sure you want to clear this project? This action cannot be undone.'650 )651 ) {652 db.collection('projects').delete();653 db.collection('assets').delete();654 window.setTimeout(function () {655 location.reload();656 }, 1000);657 }658 hideMore();659}660$(document).on('click', '#clear-project', clearProject);661 