Sebastiankay/motion-graphics-webui
0
1var API_KEY = 'PIXABAY_API';2var GOOGLE_FONTS_API_KEY = 'GOOGLE_FONTS_API_KEY';3 4// for legacy browsers5const AudioContext = window.AudioContext || window.webkitAudioContext;6const audioContext = new AudioContext();7var oldsrc, oldobj;8var oldtimelinepos;9var speed = 1;10var page = 1;11var checkstatus = false;12let db = new Localbase('db');13var wip = false;14var paused = true;15var currenttime = 0;16var timelinetime = 5;17const offset_left = 20;18var duration = 30000;19var keyframes = [];20var p_keyframes = [];21var props = [22 'left',23 'top',24 'scaleX',25 'scaleY',26 'width',27 'height',28 'angle',29 'opacity',30 'fill',31 'strokeWidth',32 'stroke',33 'shadow.color',34 'shadow.opacity',35 'shadow.offsetX',36 'shadow.offsetY',37 'shadow.blur',38 'charSpacing',39 'lineHeight',40];41var objects = [];42var o_slider, o_letter_slider, o_line_slider;43var colormode = 'fill';44var spaceDown = false;45var selectedkeyframe;46var undo = [];47var undoarr = [];48var redo = [];49var groups = [];50var redoarr = [];51var state;52var statearr = [];53var recording = false;54var canvasrecord;55var clipboard;56var focus = false;57var editingpanel = false;58var files = [];59var re = /(?:\.([^.]+))?$/;60var filelist = [];61var timeout;62var spacehold = false;63var spacerelease = false;64var tempselection;65var line_h, line_v;66var tempgroup = [];67var editinggroup = false;68var tempgroupid;69var fontPicker;70var fonts = [];71var seeking = false;72var setting = false;73var handtool = false;74var canvasx = 0;75var canvasy = 0;76var overCanvas = false;77var draggingPanel = false;78var cropping = false;79var cropobj;80var cropscalex;81var cropscaley;82var croptop;83var cropleft;84var layer_count = 1;85var lockmovement = false;86var shiftx = 0;87var shifty = 0;88var editinglayer = false;89var editingproject = false;90var shiftkeys = [];91var shiftdown = false;92var cliptype = 'object';93var chromaslider, noiseslider, blurslider;94var isChrome =95 window.chrome && Object.values(window.chrome).length !== 0;96var eyeDropper;97if (isChrome) {98 eyeDropper = new EyeDropper();99}100var presets = [101 {102 name: 'Dribbble shot',103 id: 'dribbble',104 width: 1600,105 height: 1200,106 },107 { name: 'Facebook post', id: 'facebook', width: 1280, height: 720 },108 {109 name: 'Facebook ad',110 id: 'facebook-ad',111 width: 1080,112 height: 1080,113 },114 { name: 'Youtube video', id: 'youtube', width: 1920, height: 1080 },115 {116 name: 'Instagram video',117 id: 'instagram-id',118 width: 1080,119 height: 1920,120 },121 {122 name: 'Instagram stories',123 id: 'instagram-stories',124 width: 1080,125 height: 1920,126 },127 { name: 'Twitter video', id: 'twitter', width: 1280, height: 720 },128 { name: 'Snapchat ad', id: 'snapchat', width: 1080, height: 1920 },129 {130 name: 'LinkedIn video',131 id: 'linkedin',132 width: 1920,133 height: 1080,134 },135 {136 name: 'Product Hunt thumbnail',137 id: 'product-hunt',138 width: 600,139 height: 600,140 },141 {142 name: 'Pinterest ad',143 id: 'pinterest',144 width: 1080,145 height: 1920,146 },147];148var activepreset = 'custom';149var uploaded_images = [];150var uploaded_videos = [];151var uploading = false;152var background_audio = false;153var temp_audio = false;154var background_key;155var sliders = [];156var hovertime = 0;157var animatedtext = [];158 159// Get list of fonts160$.ajax({161 url:162 'https://www.googleapis.com/webfonts/v1/webfonts?key=' +163 GOOGLE_FONTS_API_KEY +164 '&sort=alpha',165 type: 'GET',166 dataType: 'json', // added data type167 success: function (response) {168 response.items.forEach(function (item) {169 fonts.push(item.family);170 });171 },172});173 174// Panel variants175const canvas_panel =176 '<div id="canvas-properties" class="panel-section"><p class="property-title">Canvas settings</p><table><tr><th class="name-col">Preset</th><th class="value-col"><select id="preset"></select></th></tr><tr><th class="name-col">Size</th><th class="value-col"><div id="canvas-w" class="property-input" data-label="W"><input type="number" min=1 value=1000></div><div id="canvas-h" class="property-input" data-label="H"><input type="number" value=1000 min=1></div></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="canvas-color" class="object-color"><div id="color-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="canvas-color-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Duration</th><th class="value-col" id="duration-cell"><div id="canvas-duration" class="property-input" data-label="s"><input type="number" value=15.00></div></th></tr></table></div>';177const object_panel =178 '<div id="layout-properties" class="panel-section"><p class="property-title">Layout</p><table><tr><th class="name-col">Position</th><th class="value-col"><div id="object-x" class="property-input" data-label="X"><input type="number" value=1000></div><div id="object-y" class="property-input" data-label="Y"><input value=1000 type="number"></div></th></tr><tr><th class="name-col">Size</th><th class="value-col"><div id="object-w" class="property-input" data-label="W"><input type="number" min=1 value=1000></div><div id="object-h" class="property-input" data-label="H"><input type="number" value=1000 min=1></div></th></tr><tr><th class="name-col">Rotation</th><th class="value-col" id="duration-cell"><div id="object-r" class="property-input" data-label="°"><input type="number" min=0 max=360 value=0></div></th></tr></table></div>';179const back_panel =180 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Mask</th><th class="value-col"><select id="masks"><option value="none">None</option></select></th></tr></table></div>';181const image_panel =182 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Mask</th><th class="value-col"><select id="masks"><option value="none">None</option></select></th></tr></table></div>';183const selection_panel =184 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Group</th><th class="value-col"><div id="group-objects">Group selection</div></th></tr></table></div>';185const group_panel =186 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Mask</th><th class="value-col"><select id="masks"><option value="none">None</option></select></th></tr><tr><th class="name-col">Group</th><th class="value-col"><div id="ungroup-objects">Ungroup selection</div></th></tr></table></div>';187const other_panel =188 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Mask</th><th class="value-col"><select id="masks"><option value="none">None</option></select></th></tr></table></div>';189const shape_panel =190 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Rectangle</p><table><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-fill" class="object-color"><div id="color-fill-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-fill-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Radius</th><th class="value-col" id="duration-cell"><div id="object-corners" class="property-input" data-label="px"><input type="number" value=0 min=0></div></th></tr></table></div>';191const path_panel =192 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Shape</p><table><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-fill" class="object-color"><div id="color-fill-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-fill-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr></table></div>';193const text_panel =194 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Text</p><table><tr><th class="name-col">Font</th><th class="value-col"><select id="font-picker"></select></th></tr><tr><th class="name-col">Align</th><th class="value-col"><div class="align-text" id="align-text-left"><img src="assets/align-text-left.svg"></div><div class="align-text" id="align-text-center"><img src="assets/align-text-center.svg"></div><div class="align-text" id="align-text-right"><img src="assets/align-text-right.svg"></div><div class="align-text" id="align-text-justify"><img src="assets/align-text-justify.svg"></div></th></tr><tr><th class="name-col">Format</th><th class="value-col"><div class="format-text" id="format-bold"><img src="assets/bold.svg"></div><div class="format-text" id="format-italic"><img src="assets/italic.svg"></div><div class="format-text" id="format-underline"><img src="assets/underline.svg"></div><div class="format-text" id="format-strike"><img src="assets/strike.svg"></div></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-fill" class="object-color"><div id="color-fill-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-fill-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Letter</th><th class="value-col"><div id="select-letter"></div><div id="text-h" class="property-input" data-label="%"><input type="number" value=1></div></th></tr><tr><th class="name-col">Line</th><th class="value-col"><div id="select-line"></div><div id="text-v" class="property-input" data-label="%"><input type="number" value=1></div></th></tr></table></div>';195const stroke_panel =196 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Stroke</p><table><tr><th class="name-col">Type</th><th class="value-col left-col"><div class="line-join" id="miter"><img src="assets/miter.svg"></div><div class="line-join" id="bevel"><img src="assets/bevel.svg"></div><div class="line-join" id="round"><img src="assets/round.svg"></div><div class="line-join" id="small-dash"><img src="assets/dash2.svg"></div></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-stroke" class="object-color"><div id="color-stroke-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-stroke-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Width</th><th class="value-col" id="duration-cell"><div id="object-stroke" class="property-input" data-label="px"><input type="number" min=0 value=0></div></th></tr></table></div>';197const shadow_panel =198 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Shadow</p><table><tr><th class="name-col">Offset</th><th class="value-col"><div id="object-shadow-x" class="property-input" data-label="X"><input type="number" value=0></div><div id="object-shadow-y" class="property-input" data-label="Y"><input value=0 type="number"></div></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-shadow" class="object-color"><div id="color-shadow-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-shadow-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Blur</th><th class="value-col" id="duration-cell"><div id="object-blur" class="property-input" data-label="px"><input type="number" value=0 min=0></div></th></tr></table></div>';199const image_more_panel =200 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Image</p><div id="image-buttons"><div id="filters-button"><img src="assets/filters.svg"> Edit filters</div><div id="crop-image"><img src="assets/crop-icon.svg">Crop image</div></div></div></hr>';201const video_more_panel =202 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Video</p><div id="image-buttons"><div id="filters-button" class="filters-video"><img src="assets/filters.svg"> Edit filters</div></div></div></hr>';203const animated_text_panel =204 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Text</p><table><tr><th class="name-col">Content</th><th class="value-col" id="duration-cell"><div id="animated-text" class="property-input" data-label=""><input id="animatedinput" type="text" value="text"><div id="animatedset">Set</div></div></th></tr><tr><th class="name-col">Font</th><th class="value-col"><select id="font-picker"></select></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="text-color" class="object-color"><div id="color-text-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="color-text-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr></table></div>';205const start_animation_panel =206 '<hr><div id="back-properties" class="panel-section"><p class="property-title">Start animation</p><table><tr><th class="name-col">Preset</th><th class="value-col"><select id="preset-picker"></select></th></tr><tr><th class="name-col">Easing</th><th class="value-col"><select id="easing-picker"><option value="linear">Linear</option><option value="easeInQuad">Ease in</option><option value="easeOutQuad">Ease out</option><option value="easeinOutQuad">Ease in-out</option><option value="easeOutInQuad">Ease out-in</option><option value="easeInBounce">Ease in bounce</option><option value="easeOutBounce">Ease out bounce</option><option value="easeinOutBounce">Ease in-out bounce</option><option value="easeOutInBouce">Ease out-in bounce</option><option value="easeOutInBouce">Ease out-in bounce</option><option value="easeInSine">Ease in sine</option><option value="easeOutSine">Ease out sine</option><option value="easeinOutSine">Ease in-out sine</option><option value="easeOutInSine">Ease out-in sine</option><option value="easeOutInSine">Ease out-in sine</option><option value="easeInCubic">Ease in cubic</option><option value="easeOutCubic">Ease out cubic</option><option value="easeinOutCubic">Ease in-out cubic</option><option value="easeOutInCubic">Ease out-in cubic</option><option value="easeOutInCubic">Ease out-in cubic</option></select></th></tr><tr><th class="name-col">Order</th><th class="value-col"><div id="order-toggle"><div id="order-backward" class="order-toggle-item">Backward</div><div id="order-forward" class="order-toggle-item order-toggle-item-active">Forward</div></div></th></tr><tr><th class="name-col">Order</th><th class="value-col"><div id="order-toggle"><div id="type-letters" class="order-toggle-item-2">Letters</div><div id="type-words" class="order-toggle-item-2 order-toggle-item-active-2">Words</div></div></th></tr><tr><th class="name-col">Duration</th><th class="value-col" id="duration-cell"><div id="animated-text-duration" class="property-input" data-label="s"><input id="durationinput" type="number" value="0"></div></th></tr></table></div>';207const audio_panel =208 '<div id="layout-properties" class="panel-section"><p class="property-title">Audio</p><table><tr><th class="name-col">Volume</th><th class="value-col" id="duration-cell"><div id="object-volume" class="property-input" data-label="%"><input type="number" value=0></div></th></tr></table></div>';209 210// Browser variants211const shape_browser =212 '<div id="search-fixed"><p class="property-title">Objects</p><img id="collapse" src="assets/collapse.svg"><div id="browser-search"><input placeholder="Search..."><img src="assets/search.svg" id="search-icon"><img src="assets/delete.svg" id="delete-search"><div id="search-button">Go</div></div></div><div id="shapes-cont"><p class="row-title">Shapes</p><div class="gallery-row" id="shapes-row"></div><p class="row-title">Emojis</p><div class="gallery-row" id="emojis-row"></div></div>';213const image_browser =214 '<div id="search-fixed"><p class="property-title">Images</p><img id="collapse" src="assets/collapse.svg"><div id="browser-search"><input placeholder="Search..."><a href="https://pixabay.com" target="_blank" id="pixabay"><img src="assets/pixabay.svg"></a><img src="assets/search.svg" id="search-icon"><img src="assets/delete.svg" id="delete-search"><div id="search-button">Go</div></div></div><div id="shapes-cont"><div id="landing"><div id="landing-text">Browse millions of high quality images from Pixabay. Use the search bar above or choose from popular categories below.</div><div id="categories"></div></div><div id="images-grid"></div></div>';215const text_browser =216 '<div id="search-fixed"><p class="property-title">Text</p><img id="collapse" src="assets/collapse.svg"><div id="browser-search"><input placeholder="Search..."><img src="assets/search.svg" id="search-icon"><img src="assets/delete.svg" id="delete-search"><div id="search-button">Go</div></div></div><div id="shapes-cont"><p class="row-title">Basic text</p><div id="heading-text" data-font="Inter" class="add-text noselect">Add a heading</div><div id="subheading-text" data-font="Inter" class="add-text noselect">Add a subheading</div><div id="body-text" data-font="Inter" class="add-text noselect">Add body text</div></div>';217const video_browser =218 '<div id="search-fixed"><p class="property-title">Videos</p><img id="collapse" src="assets/collapse.svg"><div id="browser-search"><input placeholder="Search..."><a href="https://pixabay.com" target="_blank" id="pixabay"><img src="assets/pixabay.svg"></a><img src="assets/search.svg" id="search-icon"><img src="assets/delete.svg" id="delete-search"><div id="search-button">Go</div></div></div><div id="shapes-cont"><div id="landing"><div id="landing-text">Browse millions of high quality images from Pixabay. Use the search bar above or choose from popular categories below.</div><div id="categories"></div></div><div id="images-grid"></div></div>';219const upload_browser =220 '<div id="search-fixed"><p class="property-title">Uploads</p><div id="upload-button"><img src="assets/upload.svg"> Upload media</div><img id="collapse" src="assets/collapse.svg"><div id="upload-tabs"><div id="images-tab" class="upload-tab upload-tab-active">Images</div><div id="videos-tab" class="upload-tab">Videos</div></div></div><div id="images-grid"></div>';221const audio_browser =222 '<div id="search-fixed" class="audio-browser"><p class="property-title">Audio</p><div id="audio-upload-button"><img src="assets/upload.svg"> Upload audio</div><img id="collapse" src="assets/collapse.svg"></div><div id="audio-list-parent"><div id="landing-text" class="audio-landing-text">Audio provided by Pixabay. Browse millions of assets from Pixabay by <a href="https://pixabay.com/music/" target="_blank">clicking here.</a></div><div id="audio-list"></div></div>';223 224// Text animation list225var text_animation_list = [226 { name: 'fade in', label: 'Fade in', src: 'assets/fade-in.svg' },227 {228 name: 'typewriter',229 label: 'Typewriter',230 src: 'assets/typewriter.svg',231 },232 {233 name: 'slide top',234 label: 'Slide top',235 src: 'assets/slide-top.svg',236 },237 {238 name: 'slide bottom',239 label: 'Slide bottom',240 src: 'assets/slide-bottom.svg',241 },242 {243 name: 'slide left',244 label: 'Slide left',245 src: 'assets/slide-left.svg',246 },247 {248 name: 'slide right',249 label: 'Slide right',250 src: 'assets/slide-right.svg',251 },252 { name: 'scale', label: 'Scale', src: 'assets/scale.svg' },253 { name: 'shrink', label: 'Shrink', src: 'assets/shrink.svg' },254];255 256// Shapes list257var shape_grid_items = [258 'assets/shapes/rectangle.svg',259 'assets/shapes/circle.svg',260 'assets/shapes/triangle.svg',261 'assets/shapes/polygon.svg',262 'assets/shapes/star.svg',263 'assets/thingy.svg',264 'assets/shapes/heart.svg',265 'assets/shapes/arrow.svg',266];267var emoji_items = [268 'assets/twemojis/laughing-emoji.png',269 'assets/twemojis/crying-emoji.png',270 'assets/twemojis/surprised-emoji.png',271 'assets/twemojis/smiling-emoji.png',272 'assets/twemojis/tongue-emoji.png',273 'assets/twemojis/heart-eyes-emoji.png',274 'assets/twemojis/heart-kiss-emoji.png',275 'assets/twemojis/sunglasses-cool-emoji.png',276 'assets/twemojis/ghost-emoji.png',277 'assets/twemojis/skull-emoji.png',278 'assets/twemojis/mindblown-emoji.png',279 'assets/twemojis/bomb-emoji.png',280 'assets/twemojis/hundred-100-points-emoji.png',281 'assets/twemojis/thought-balloon-emoji.png',282 'assets/twemojis/wave-emoji.png',283 'assets/twemojis/point-emoji.png',284 'assets/twemojis/thumbs-up-emoji.png',285 'assets/twemojis/clap-emoji.png',286 'assets/twemojis/raising-hands-emoji.png',287 'assets/twemojis/praying-hands-emoji.png',288 'assets/twemojis/nail-polish-emoji.png',289 'assets/twemojis/eyes-emoji.png',290 'assets/twemojis/cat-face-emoji.png',291 'assets/twemojis/dog-face-emoji.png',292 'assets/twemojis/rose-emoji.png',293 'assets/twemojis/tulip-emoji.png',294 'assets/twemojis/pizza-emoji.png',295 'assets/twemojis/construction-emoji.png',296 'assets/twemojis/plane-emoji.png',297 'assets/twemojis/rocket-emoji.png',298 'assets/twemojis/clock-emoji.png',299 'assets/twemojis/star-emoji.png',300 'assets/twemojis/sun-emoji.png',301 'assets/twemojis/moon-emoji.png',302 'assets/twemojis/fire-emoji.png',303 'assets/twemojis/sparkles-emoji.png',304 'assets/twemojis/party-popper-emoji.png',305 'assets/twemojis/gift-emoji.png',306 'assets/twemojis/trophy-emoji.png',307 'assets/twemojis/target-emoji.png',308 'assets/twemojis/gem-emoji.png',309 'assets/twemojis/money-emoji.png',310 'assets/twemojis/pencil-emoji.png',311 'assets/twemojis/graph-emoji.png',312 'assets/twemojis/wip-emoji.png',313 'assets/twemojis/winking-face-emoji.png',314 'assets/twemojis/pleading-face-emoji.png',315 'assets/twemojis/thinking-face-emoji.png',316];317 318// Image list319var image_grid_items = [320 'https://images.unsplash.com/photo-1609153259378-a8b23c766aec?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1866&q=80',321 'https://images.unsplash.com/photo-1614435082296-ef0cbdb16b70?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=934&q=80',322 'https://images.unsplash.com/photo-1614432254115-7e756705e910?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxMHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',323 'https://images.unsplash.com/photo-1614423234685-544477464e15?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHw4fHx8ZW58MHx8fA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',324 'https://images.unsplash.com/photo-1614357235247-99fabbee67f9?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxNHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',325 'https://images.unsplash.com/photo-1614373371549-c7d2e4885f17?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxOXx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',326];327var image_categories = [328 { name: 'background', image: 'assets/background.png' },329 { name: 'wallpaper', image: 'assets/wallpaper.png' },330 { name: 'nature', image: 'assets/nature.png' },331 { name: 'summer', image: 'assets/summer.png' },332 { name: 'beach', image: 'assets/beach.png' },333 { name: 'space', image: 'assets/space.png' },334 { name: 'office', image: 'assets/office.png' },335 { name: 'food', image: 'assets/food.png' },336];337 338// Video list339var video_categories = [340 { name: 'rain', image: 'assets/rain.png' },341 { name: 'cars', image: 'assets/cars.png' },342 { name: 'meditation', image: 'assets/meditation.png' },343 { name: 'forest', image: 'assets/forest.png' },344 { name: 'animals', image: 'assets/animals.png' },345 { name: 'street', image: 'assets/street.png' },346 { name: 'travel', image: 'assets/travel.png' },347 { name: 'work', image: 'assets/work.png' },348];349 350// Audio list351var audio_items = [352 {353 name: 'Lofi Study',354 desc: 'FASSounds',355 duration: '2:27',356 thumb: 'assets/audio/lofi-thumb.png',357 src: 'assets/audio/lofi.mp3',358 link: 'https://pixabay.com/users/fassounds-3433550/',359 },360 {361 name: 'Stomping Rock (Four Shots)',362 desc: 'AlexGrohl',363 duration: '1:59',364 thumb: 'assets/audio/stomping-rock-thumb.png',365 src: 'assets/audio/stomping-rock.mp3',366 link: 'https://pixabay.com/users/alexgrohl-25289918/',367 },368 {369 name: 'Everything Feels New',370 desc: 'EvgenyBardyuzha',371 duration: '1:06',372 thumb: 'assets/audio/everything-feels-new-thumb.png',373 src: 'assets/audio/everything-feels-new.mp3',374 link: 'https://pixabay.com/users/evgenybardyuzha-25235210/',375 },376 {377 name: 'Both of Us',378 desc: 'madiRFAN',379 duration: '2:48',380 thumb: 'assets/audio/both-of-us-thumb.png',381 src: 'assets/audio/both-of-us.mp3',382 link: 'https://pixabay.com/users/madirfan-50411/',383 },384 {385 name: 'The Podcast Intro',386 desc: 'Music Unlimited',387 duration: '1:51',388 thumb: 'assets/audio/the-podcast-intro-thumb.png',389 src: 'assets/audio/the-podcast-intro.mp3',390 link: 'https://pixabay.com/users/music_unlimited-27600023/',391 },392 {393 name: 'Epic Cinematic Trailer',394 desc: 'PavelYudin',395 duration: '2:27',396 thumb: 'assets/audio/epic-cinematic-trailer-thumb.png',397 src: 'assets/audio/epic-cinematic-trailer.mp3',398 link: 'https://pixabay.com/users/pavelyudin-27739282/',399 },400 {401 name: 'Inspirational Background',402 desc: 'AudioCoffee',403 duration: '2:19',404 thumb: 'assets/audio/inspirational-background-thumb.png',405 src: 'assets/audio/inspirational-background.mp3',406 link: 'https://pixabay.com/users/audiocoffee-27005420/',407 },408 {409 name: 'Tropical Summer Music',410 desc: 'Music Unlimited',411 duration: '2:35',412 thumb: 'assets/audio/tropical-summer-music-thumb.png',413 src: 'assets/audio/tropical-summer-music.mp3',414 link: 'https://pixabay.com/users/music_unlimited-27600023/',415 },416];417 418// Text list419var text_items = {420 sansserif: [421 { name: 'Roboto', fontname: 'Roboto' },422 { name: 'Montserrat', fontname: 'Montserrat' },423 { name: 'Poppins', fontname: 'Poppins' },424 ],425 serif: [426 { name: 'Playfair Display', fontname: 'Playfair Display' },427 { name: 'Merriweather', fontname: 'Merriweather' },428 { name: 'IBM Plex Serif', fontname: 'IBM Plex Serif' },429 ],430 monospace: [431 { name: 'Roboto Mono', fontname: 'Roboto Mono' },432 { name: 'Inconsolata', fontname: 'Inconsolata' },433 { name: 'Source Code Pro', fontname: 'Source Code Pro' },434 ],435 handwriting: [436 { name: 'Dancing Script', fontname: 'Dancing Script' },437 { name: 'Pacifico', fontname: 'Pacifico' },438 { name: 'Indie Flower', fontname: 'Indie Flower' },439 ],440 display: [441 { name: 'Lobster', fontname: 'Lobster' },442 { name: 'Bebas Neue', fontname: 'Bebas Neue' },443 { name: 'Titan One', fontname: 'Titan One' },444 ],445};446 447WebFont.load({448 google: {449 families: ['Syne'],450 },451 active: () => {},452});453 454var webglBackend;455try {456 webglBackend = new fabric.WebglFilterBackend();457} catch (e) {458 console.log(e);459}460var canvas2dBackend = new fabric.Canvas2dFilterBackend();461 462fabric.filterBackend = fabric.initFilterBackend();463fabric.filterBackend = webglBackend;464 465// Lottie support466fabric.Lottie = fabric.util.createClass(fabric.Image, {467 type: 'lottie',468 lockRotation: true,469 lockSkewingX: true,470 lockSkewingY: true,471 srcFromAttribute: false,472 473 initialize: function (path, options) {474 if (!options.width) options.width = 480;475 if (!options.height) options.height = 480;476 477 this.path = path;478 this.tmpCanvasEl = fabric.util.createCanvasElement();479 this.tmpCanvasEl.width = options.width;480 this.tmpCanvasEl.height = options.height;481 482 this.lottieItem = bodymovin.loadAnimation({483 renderer: 'canvas',484 loop: false,485 autoplay: false,486 path: path,487 rendererSettings: {488 context: this.tmpCanvasEl.getContext('2d'),489 preserveAspectRatio: 'xMidYMid meet',490 },491 });492 493 this.lottieItem.addEventListener('enterFrame', (e) => {494 this.canvas.requestRenderAll();495 });496 497 this.lottieItem.addEventListener('DOMLoaded', () => {498 this.lottieItem.goToAndStop(currenttime, false);499 this.lottieItem.duration =500 this.lottieItem.getDuration(false) * 1000;501 this.canvas.requestRenderAll();502 canvas.renderAll();503 canvas.fire('lottie:loaded', { any: 'payload' });504 });505 506 this.callSuper('initialize', this.tmpCanvasEl, options);507 },508 509 goToSeconds: function (seconds) {510 this.lottieItem.goToAndStop(seconds, false);511 this.canvas.requestRenderAll();512 },513 goToFrame: function (frame) {514 this.lottieItem.goToAndStop(frame, true);515 },516 getDuration: function () {517 return this.lottieItem.getDuration(false);518 },519 play: function () {520 this.lottieItem.play();521 },522 pause: function () {523 this.lottieItem.pause();524 },525 getSrc: function () {526 return this.path;527 },528});529 530fabric.Lottie.fromObject = function (_object, callback) {531 const object = fabric.util.object.clone(_object);532 fabric.Image.prototype._initFilters.call(533 object,534 object.filters,535 function (filters) {536 object.filters = filters || [];537 fabric.Image.prototype._initFilters.call(538 object,539 [object.resizeFilter],540 function (resizeFilters) {541 object.resizeFilter = resizeFilters[0];542 fabric.util.enlivenObjects(543 [object.clipPath],544 function (enlivedProps) {545 object.clipPath = enlivedProps[0];546 const fabricLottie = new fabric.Lottie(547 object.src,548 object549 );550 callback(fabricLottie, false);551 }552 );553 }554 );555 }556 );557};558 559// Initialize canvas560var canvas = new fabric.Canvas('canvas', {561 preserveObjectStacking: true,562 backgroundColor: '#FFF',563 stateful: true,564});565canvas.selection = false;566canvas.controlsAboveOverlay = true;567 568// Customize controls569fabric.Object.prototype.set({570 transparentCorners: false,571 borderColor: '#51B9F9',572 cornerColor: '#FFF',573 borderScaleFactor: 2.5,574 cornerStyle: 'circle',575 cornerStrokeColor: '#0E98FC',576 borderOpacityWhenMoving: 1,577});578 579canvas.selectionColor = 'rgba(46, 115, 252, 0.11)';580canvas.selectionBorderColor = 'rgba(98, 155, 255, 0.81)';581canvas.selectionLineWidth = 1.5;582 583var img = document.createElement('img');584img.src = 'assets/middlecontrol.svg';585 586var img2 = document.createElement('img');587img2.src = 'assets/middlecontrolhoz.svg';588 589var img3 = document.createElement('img');590img3.src = 'assets/edgecontrol.svg';591 592var img4 = document.createElement('img');593img4.src = 'assets/rotateicon.svg';594 595function renderIcon(ctx, left, top, styleOverride, fabricObject) {596 const wsize = 20;597 const hsize = 25;598 ctx.save();599 ctx.translate(left, top);600 ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));601 ctx.drawImage(img, -wsize / 2, -hsize / 2, wsize, hsize);602 ctx.restore();603}604function renderIconHoz(ctx, left, top, styleOverride, fabricObject) {605 const wsize = 25;606 const hsize = 20;607 ctx.save();608 ctx.translate(left, top);609 ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));610 ctx.drawImage(img2, -wsize / 2, -hsize / 2, wsize, hsize);611 ctx.restore();612}613function renderIconEdge(ctx, left, top, styleOverride, fabricObject) {614 const wsize = 25;615 const hsize = 25;616 ctx.save();617 ctx.translate(left, top);618 ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));619 ctx.drawImage(img3, -wsize / 2, -hsize / 2, wsize, hsize);620 ctx.restore();621}622 623function renderIconRotate(624 ctx,625 left,626 top,627 styleOverride,628 fabricObject629) {630 const wsize = 40;631 const hsize = 40;632 ctx.save();633 ctx.translate(left, top);634 ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));635 ctx.drawImage(img4, -wsize / 2, -hsize / 2, wsize, hsize);636 ctx.restore();637}638function resetControls() {639 fabric.Object.prototype.controls.ml = new fabric.Control({640 x: -0.5,641 y: 0,642 offsetX: -1,643 cursorStyleHandler:644 fabric.controlsUtils.scaleSkewCursorStyleHandler,645 actionHandler: fabric.controlsUtils.scalingXOrSkewingY,646 getActionName: fabric.controlsUtils.scaleOrSkewActionName,647 render: renderIcon,648 });649 650 fabric.Object.prototype.controls.mr = new fabric.Control({651 x: 0.5,652 y: 0,653 offsetX: 1,654 cursorStyleHandler:655 fabric.controlsUtils.scaleSkewCursorStyleHandler,656 actionHandler: fabric.controlsUtils.scalingXOrSkewingY,657 getActionName: fabric.controlsUtils.scaleOrSkewActionName,658 render: renderIcon,659 });660 661 fabric.Object.prototype.controls.mb = new fabric.Control({662 x: 0,663 y: 0.5,664 offsetY: 1,665 cursorStyleHandler:666 fabric.controlsUtils.scaleSkewCursorStyleHandler,667 actionHandler: fabric.controlsUtils.scalingYOrSkewingX,668 getActionName: fabric.controlsUtils.scaleOrSkewActionName,669 render: renderIconHoz,670 });671 672 fabric.Object.prototype.controls.mt = new fabric.Control({673 x: 0,674 y: -0.5,675 offsetY: -1,676 cursorStyleHandler:677 fabric.controlsUtils.scaleSkewCursorStyleHandler,678 actionHandler: fabric.controlsUtils.scalingYOrSkewingX,679 getActionName: fabric.controlsUtils.scaleOrSkewActionName,680 render: renderIconHoz,681 });682 683 fabric.Object.prototype.controls.tl = new fabric.Control({684 x: -0.5,685 y: -0.5,686 cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,687 actionHandler: fabric.controlsUtils.scalingEqually,688 render: renderIconEdge,689 });690 691 fabric.Object.prototype.controls.tr = new fabric.Control({692 x: 0.5,693 y: -0.5,694 cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,695 actionHandler: fabric.controlsUtils.scalingEqually,696 render: renderIconEdge,697 });698 699 fabric.Object.prototype.controls.bl = new fabric.Control({700 x: -0.5,701 y: 0.5,702 cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,703 actionHandler: fabric.controlsUtils.scalingEqually,704 render: renderIconEdge,705 });706 707 fabric.Object.prototype.controls.br = new fabric.Control({708 x: 0.5,709 y: 0.5,710 cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,711 actionHandler: fabric.controlsUtils.scalingEqually,712 render: renderIconEdge,713 });714 715 fabric.Object.prototype.controls.mtr = new fabric.Control({716 x: 0,717 y: 0.5,718 cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,719 actionHandler: fabric.controlsUtils.rotationWithSnapping,720 offsetY: 30,721 withConnecton: false,722 actionName: 'rotate',723 render: renderIconRotate,724 });725}726resetControls();727var textBoxControls = (fabric.Textbox.prototype.controls = {});728 729textBoxControls.mtr = fabric.Object.prototype.controls.mtr;730textBoxControls.tr = fabric.Object.prototype.controls.tr;731textBoxControls.br = fabric.Object.prototype.controls.br;732textBoxControls.tl = fabric.Object.prototype.controls.tl;733textBoxControls.bl = fabric.Object.prototype.controls.bl;734textBoxControls.mt = fabric.Object.prototype.controls.mt;735textBoxControls.mb = fabric.Object.prototype.controls.mb;736 737textBoxControls.ml = new fabric.Control({738 x: -0.5,739 y: 0,740 offsetX: -1,741 cursorStyleHandler:742 fabric.controlsUtils.scaleSkewCursorStyleHandler,743 actionHandler: fabric.controlsUtils.changeWidth,744 actionName: 'resizing',745 render: renderIcon,746});747 748textBoxControls.mr = new fabric.Control({749 x: 0.5,750 y: 0,751 offsetX: 1,752 cursorStyleHandler:753 fabric.controlsUtils.scaleSkewCursorStyleHandler,754 actionHandler: fabric.controlsUtils.changeWidth,755 actionName: 'resizing',756 render: renderIcon,757});758 759// Get any object by ID760fabric.Canvas.prototype.getItemById = function (name) {761 var object = null,762 objects = this.getObjects();763 for (var i = 0, len = this.size(); i < len; i++) {764 if (objects[i].get('type') == 'group') {765 if (objects[i].get('id') && objects[i].get('id') === name) {766 object = objects[i];767 break;768 }769 var wip = i;770 for (var o = 0; o < objects[i]._objects.length; o++) {771 if (772 objects[wip]._objects[o].id &&773 objects[wip]._objects[o].id === name774 ) {775 object = objects[wip]._objects[o];776 break;777 }778 }779 } else if (objects[i].id && objects[i].id === name) {780 object = objects[i];781 break;782 }783 }784 return object;785};786 787// Create the artboard788var a_width = 600;789var a_height = 500;790var artboard = new fabric.Rect({791 left: canvas.get('width') / 2 - a_width / 2,792 top: canvas.get('height') / 2 - a_height / 2,793 width: a_width,794 height: a_height,795 absolutePositioned: true,796 rx: 0,797 ry: 0,798 fill: '#FFF',799 hasControls: true,800 transparentCorners: false,801 borderColor: '#0E98FC',802 cornerColor: '#0E98FC',803 cursorWidth: 1,804 cursorDuration: 1,805 cursorDelay: 250,806 id: 'overlay',807});808canvas.renderAll();809 810// Clip canvas to the artboard811canvas.clipPath = artboard;812canvas.renderAll();813 814// Initialize color picker (fill)815var o_fill = Pickr.create({816 el: '#color-picker-fill',817 theme: 'nano',818 inline: true,819 useAsButton: true,820 swatches: null,821 default: '#FFFFFF',822 showAlways: true,823 components: {824 preview: true,825 opacity: true,826 hue: true,827 interaction: {828 hex: true,829 rgba: true,830 hsla: false,831 hsva: false,832 cmyk: false,833 input: true,834 clear: false,835 save: false,836 },837 },838});839 840// Color picker events841o_fill842 .on('init', (instance) => {843 o_fill.hide();844 })845 .on('change', (instance) => {846 if (canvas.getActiveObject()) {847 const object = canvas.getActiveObject();848 if (colormode == 'fill') {849 $('#object-color-fill input').val(850 o_fill.getColor().toHEXA().toString().substring(0, 7)851 );852 $('#object-color-fill-opacity input').val(853 Math.round(o_fill.getColor().toRGBA()[3] * 100 * 100) / 100854 );855 $('#color-fill-side').css(856 'background-color',857 o_fill.getColor().toHEXA().toString().substring(0, 7)858 );859 object.set('fill', o_fill.getColor().toRGBA().toString());860 if (!seeking && !setting) {861 newKeyframe(862 'fill',863 object,864 currenttime,865 object.get('fill'),866 true867 );868 }869 } else if (colormode == 'stroke') {870 $('#object-color-stroke input').val(871 o_fill.getColor().toHEXA().toString().substring(0, 7)872 );873 $('#object-color-stroke-opacity input').val(874 Math.round(o_fill.getColor().toRGBA()[3] * 100 * 100) / 100875 );876 $('#color-stroke-side').css(877 'background-color',878 o_fill.getColor().toHEXA().toString().substring(0, 7)879 );880 object.set('stroke', o_fill.getColor().toRGBA().toString());881 if (!seeking && !setting) {882 newKeyframe(883 'stroke',884 object,885 currenttime,886 object.get('stroke'),887 true888 );889 newKeyframe(890 'strokeWidth',891 object,892 currenttime,893 object.get('strokeWidth'),894 true895 );896 }897 } else if (colormode == 'shadow') {898 $('#object-color-shadow input').val(899 o_fill.getColor().toHEXA().toString().substring(0, 7)900 );901 $('#object-color-shadow-opacity input').val(902 Math.round(o_fill.getColor().toRGBA()[3] * 100 * 100) / 100903 );904 $('#color-shadow-side').css(905 'background-color',906 o_fill.getColor().toHEXA().toString().substring(0, 7)907 );908 object.set(909 'shadow',910 new fabric.Shadow({911 color: o_fill.getColor().toRGBA().toString(),912 offsetX: object.shadow.offsetX,913 offsetY: object.shadow.offsetY,914 blur: object.shadow.blur,915 opacity: object.shadow.opacity,916 })917 );918 if (!seeking && !setting) {919 newKeyframe(920 'shadow.color',921 object,922 currenttime,923 object.shadow.color,924 true925 );926 }927 } else if (colormode == 'chroma') {928 var obj = canvas.getActiveObject();929 $('#chroma-color input').val(930 o_fill.getColor().toHEXA().toString().substring(0, 7)931 );932 $('#color-chroma-side').css(933 'background-color',934 o_fill.getColor().toHEXA().toString().substring(0, 7)935 );936 if (obj.filters.find((x) => x.type == 'RemoveColor')) {937 obj.filters.find((x) => x.type == 'RemoveColor').color =938 o_fill.getColor().toRGBA().toString();939 }940 updateChromaValues();941 } else if (colormode == 'text') {942 var obj = canvas.getActiveObject();943 $('#text-color input').val(944 o_fill.getColor().toHEXA().toString().substring(0, 7)945 );946 $('#color-text-side').css(947 'background-color',948 o_fill.getColor().toHEXA().toString().substring(0, 7)949 );950 animatedtext951 .find((x) => x.id == obj.id)952 .setProps(953 { fill: o_fill.getColor().toRGBA().toString() },954 canvas955 );956 }957 canvas.renderAll();958 } else {959 if (colormode == 'back') {960 $('#canvas-color input').val(961 o_fill.getColor().toHEXA().toString().substring(0, 7)962 );963 $('#canvas-color-opacity input').val(964 Math.round(o_fill.getColor().toRGBA()[3] * 100 * 100) / 100965 );966 $('#color-side').css(967 'background-color',968 o_fill.getColor().toHEXA().toString().substring(0, 7)969 );970 canvas.setBackgroundColor(971 o_fill.getColor().toRGBA().toString()972 );973 canvas.renderAll();974 }975 }976 })977 .on('show', (instance) => {978 $('.pcr-current-color').html(979 "<img id='eyedropper' src='assets/eyedropper.svg'>"980 );981 });982 983var f = fabric.Image.filters;984 985// Canvas recorder initialization986var canvasrecord = new fabric.Canvas('canvasrecord', {987 preserveObjectStacking: true,988 backgroundColor: '#FFF',989 width: artboard.width,990 height: artboard.height,991});992 993var timelineslider = document.getElementById('timeline-zoom');994var t_slider = new RangeSlider(timelineslider, {995 design: '2d',996 theme: 'default',997 handle: 'round',998 popup: null,999 showMinMaxLabels: false,1000 unit: '%',1001 min: 5,1002 max: 47,1003 value: 47,1004 onmove: function (x) {1005 setTimelineZoom(-1 * (x - 51));1006 },1007 onfinish: function (x) {1008 setTimelineZoom(-1 * (x - 51));1009 },1010 onstart: function (x) {},1011});1012 1013const selectbox = new SelectionArea({1014 class: 'selection-area',1015 selectables: ['.keyframe'],1016 container: '#timeline',1017 // Query selectors for elements from where a selection can be started from.1018 startareas: ['html'],1019 1020 // Query selectors for elements which will be used as boundaries for the selection.1021 boundaries: ['#timeline'],1022 1023 startThreshold: 10,1024 1025 allowTouch: true,1026 1027 intersect: 'touch',1028 1029 overlap: 'invert',1030 1031 // Configuration in case a selectable gets just clicked.1032 singleTap: {1033 allow: false,1034 intersect: 'native',1035 },1036 1037 // Scroll configuration.1038 scrolling: {1039 speedDivider: 10,1040 manualSpeed: 750,1041 },1042});1043 1044selectbox1045 .on('beforestart', (evt) => {1046 if (1047 $(evt.event.target).hasClass('keyframe') ||1048 $(evt.event.target).attr('id') == 'seekbar' ||1049 $(evt.event.target).parent().hasClass('main-row') ||1050 $(evt.event.target).hasClass('main-row') ||1051 $(evt.event.target).hasClass('trim-row') ||1052 evt.event.which === 31053 ) {1054 return false;1055 }1056 })1057 .on('start', (evt) => {})1058 .on('move', (evt) => {})1059 .on('stop', (evt) => {1060 $('.keyframe-selected').removeClass('keyframe-selected');1061 shiftkeys = [];1062 if (evt.store.selected.length == 0) {1063 $('.keyframe-selected').removeClass('keyframe-selected');1064 } else {1065 canvas.discardActiveObject();1066 canvas.renderAll();1067 evt.store.selected.forEach(function (key) {1068 shiftkeys.push({1069 keyframe: key,1070 offset: $(key).offset().left,1071 });1072 $(key).addClass('keyframe-selected');1073 });1074 }1075 });1076 