@andymcloid/trakk 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/dist/trakk.esm.js +1 -1
- package/dist/trakk.esm.js.map +1 -1
- package/dist/trakk.js +1 -1
- package/dist/trakk.js.map +1 -1
- package/package.json +1 -1
- package/src/trakk.js +213 -13
package/dist/trakk.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Trakk={})}(this,function(t){"use strict";class e{constructor(){this.events={}}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}off(t,e){this.events[t]&&(this.events[t]=this.events[t].filter(t=>t!==e))}emit(t,e){return!this.events[t]||(this.events[t].forEach(t=>t(e)),!0)}}class i extends e{constructor(){super(),this._timerId=null,this._playRate=1,this._currentTime=0,this._playState="paused",this._prev=0,this._effectMap={},this._actionMap={},this._actionSortIds=[],this._next=0,this._activeActionIds=[]}get isPlaying(){return"playing"===this._playState}get isPaused(){return"paused"===this._playState}set effects(t){this._effectMap=t}set data(t){this.isPlaying&&this.pause(),this._dealData(t),this._dealClear(),this._dealEnter(this._currentTime)}setPlayRate(t){return t<=0?(console.error("Error: rate cannot be less than 0!"),!1):(this._playRate=t,this.emit("afterSetPlayRate",{rate:t,engine:this}),!0)}getPlayRate(){return this._playRate}reRender(){this.isPlaying||this._tickAction(this._currentTime)}setTime(t,e=!1){return this._currentTime=t,this._next=0,this._dealLeave(t),this._dealEnter(t),e?this.emit("setTimeByTick",{time:t,engine:this}):this.emit("afterSetTime",{time:t,engine:this}),!0}getTime(){return this._currentTime}play({toTime:t,autoEnd:e}={}){const i=this.getTime();return!(this.isPlaying||t&&t<=i)&&(this._playState="playing",this._startOrStop("start"),this.emit("play",{engine:this}),this._timerId=requestAnimationFrame(i=>{this._prev=i,this._tick({now:i,autoEnd:e,to:t})}),!0)}pause(){this.isPlaying&&(this._playState="paused",this._startOrStop("stop"),this.emit("paused",{engine:this})),this._timerId&&cancelAnimationFrame(this._timerId)}_end(){this.pause(),this.emit("ended",{engine:this})}_startOrStop(t){for(let e=0;e<this._activeActionIds.length;e++){const i=this._activeActionIds[e],s=this._actionMap[i],n=this._effectMap[s?.effectId];"start"===t?n?.source?.start?.({action:s,effect:n,engine:this,isPlaying:this.isPlaying,time:this.getTime()}):"stop"===t&&n?.source?.stop?.({action:s,effect:n,engine:this,isPlaying:this.isPlaying,time:this.getTime()})}}_tick(t){if(this.isPaused)return;const{now:e,autoEnd:i,to:s}=t;let n=this.getTime()+Math.min(1e3,e-this._prev)/1e3*this._playRate;this._prev=e,s&&s<=n&&(n=s),this.setTime(n,!0),this._tickAction(n),!s&&i&&this._next>=this._actionSortIds.length&&0===this._activeActionIds.length||s&&s<=n?this._end():this.isPaused||(this._timerId=requestAnimationFrame(t=>{this._tick({now:t,autoEnd:i,to:s})}))}_tickAction(t){this._dealEnter(t),this._dealLeave(t);const e=this._activeActionIds.length;for(let i=0;i<e;i++){const e=this._activeActionIds[i],s=this._actionMap[e],n=this._effectMap[s.effectId];n?.source?.update&&n.source.update({time:t,action:s,isPlaying:this.isPlaying,effect:n,engine:this})}}_dealClear(){for(;this._activeActionIds.length;){const t=this._activeActionIds.shift(),e=this._actionMap[t],i=this._effectMap[e?.effectId];i?.source?.leave&&i.source.leave({action:e,effect:i,engine:this,isPlaying:this.isPlaying,time:this.getTime()})}this._next=0}_dealEnter(t){for(;this._actionSortIds[this._next];){const e=this._actionSortIds[this._next],i=this._actionMap[e];if(!i.disable){if(i.start>t)break;if(i.end>t&&!this._activeActionIds.includes(e)){const s=this._effectMap[i.effectId];s?.source?.enter&&s.source.enter({action:i,effect:s,isPlaying:this.isPlaying,time:t,engine:this}),this._activeActionIds.push(e)}}this._next++}}_dealLeave(t){let e=0;for(;this._activeActionIds[e];){const i=this._activeActionIds[e],s=this._actionMap[i];if(s.start>t||s.end<t){const i=this._effectMap[s.effectId];i?.source?.leave&&i.source.leave({action:s,effect:i,isPlaying:this.isPlaying,time:t,engine:this}),this._activeActionIds.splice(e,1);continue}e++}}_dealData(t){const e=[];t.forEach(t=>{const i=t.blocks||t.items||t.actions||[];e.push(...i)});const i=e.sort((t,e)=>t.start-e.start),s={},n=[];i.forEach(t=>{n.push(t.id),s[t.id]={...t}}),this._actionMap=s,this._actionSortIds=n}}const s=(t,{startLeft:e,scale:i,scaleWidth:s})=>t/i*s+e,n=(t,{startLeft:e,scale:i,scaleWidth:s})=>(t-e)/s*i;class a extends HTMLElement{constructor(){super(),this.config={scale:1,scaleWidth:160,scaleCount:20,scaleSplitCount:10,startLeft:120,contentPadding:0,minScaleCount:10,maxScaleCount:1/0,rowHeight:32,autoScroll:!0,hideCursor:!1,disableDrag:!1,gridSnap:!0,grid:1},this.callbacks={onActionMoveStart:null,onActionMoving:null,onActionMoveEnd:null,onActionResizeStart:null,onActionResizing:null,onActionResizeEnd:null,onClickRow:null,onClickAction:null,onDoubleClickRow:null,onDoubleClickAction:null,onContextMenuRow:null,onContextMenuAction:null,onCursorDragStart:null,onCursorDrag:null,onCursorDragEnd:null,onClickTimeArea:null,getActionRender:null,getScaleRender:null},this.tracks=[],this.cursorTime=0,this.isPlaying=!1,this._scrollX=0,this._scrollY=0,this.timeAreaEl=null,this.timeAreaWrapperEl=null,this.editAreaEl=null,this.labelColumnEl=null,this.labelInnerEl=null,this.cursorEl=null,this.engine=new i,this.dragState={isDragging:!1,isActuallyDragging:!1,type:null,action:null,row:null,rowIndex:null,startX:0,startY:0,currentLeft:0,currentWidth:0,deltaX:0,totalDeltaX:0}}connectedCallback(){this.className="timeline-editor",this.render(),this._setupEngineListeners(),this._setupResizeObserver()}disconnectedCallback(){this.engine.pause(),this._cleanup()}_cleanup(){document.removeEventListener("mousemove",this._boundHandleMouseMove),document.removeEventListener("mouseup",this._boundHandleMouseUp),this._resizeObserver&&this._resizeObserver.disconnect()}_setupResizeObserver(){this._resizeObserver=new ResizeObserver(t=>{for(let e of t)this.editAreaEl&&this._updateCursorPosition()}),this._resizeObserver.observe(this)}setData(t){this.tracks=t||[],this.engine.data=this.tracks,this.render()}setConfig(t){Object.assign(this.config,t),this.render()}setCallbacks(t){Object.assign(this.callbacks,t)}on(t,e){this.callbacks.hasOwnProperty(t)&&(this.callbacks[t]=e)}getData(){return{tracks:this.tracks}}exportJSON(){return JSON.stringify(this.getData(),null,2)}importJSON(t){try{const e=JSON.parse(t),i=e.tracks||e.editorData||[];return this.setData(i),!0}catch(t){return console.error("Failed to import timeline data:",t),!1}}saveToLocalStorage(t="timeline-data"){try{return localStorage.setItem(t,this.exportJSON()),!0}catch(t){return console.error("Failed to save to localStorage:",t),!1}}loadFromLocalStorage(t="timeline-data"){try{const e=localStorage.getItem(t);return!!e&&this.importJSON(e)}catch(t){return console.error("Failed to load from localStorage:",t),!1}}setTime(t){this.cursorTime=Math.max(0,t),this.engine.setTime(this.cursorTime),this._updateCursorPosition()}getTime(){return this.engine.getTime()}getTotalTime(){let t=0;for(const e of this.tracks){const i=e.blocks||e.items||e.actions||[];for(const e of i)e.end>t&&(t=e.end)}return t}play(t={}){return this.engine.play(t)}pause(){this.engine.pause()}_syncEngineData(){this.engine.data=this.tracks}_emitChange(){this._syncEngineData(),this.dispatchEvent(new CustomEvent("change",{detail:{tracks:this.tracks}}))}_expandTimelineIfNeeded(t){const e=Math.ceil(t/this.config.scale)+2;if(e>this.config.scaleCount){const t=Math.min(e,this.config.maxScaleCount);if(t>this.config.scaleCount)return this.config.scaleCount=t,this._updateTimelineWidth(),!0}return!1}_updateTimelineWidth(){const t=this.config.contentPadding,e=this.config.scaleCount*this.config.scaleWidth+t,i=this.editAreaEl?.querySelector(".timeline-editor-rows");i&&(i.style.width=`${e}px`,i.style.minWidth=`${e}px`);const s=this.editAreaEl?.querySelectorAll(".timeline-editor-edit-row");s&&s.forEach(t=>{t.style.width=`${e}px`}),this._rerenderTimeArea()}_rerenderTimeArea(){if(!this.timeAreaEl)return;const t=this._createTimeArea();this.timeAreaEl.replaceWith(t),this.timeAreaEl=t,this._syncTimeAreaScroll()}_setupEngineListeners(){this.engine.on("play",()=>{this.isPlaying=!0,this.classList.add("timeline-editor-playing"),this._scrollToCursorImmediate()}),this.engine.on("paused",()=>{this.isPlaying=!1,this.classList.remove("timeline-editor-playing")}),this.engine.on("setTimeByTick",({time:t})=>{this.cursorTime=t,this._updateCursorPosition(!0)}),this.engine.on("afterSetTime",({time:t})=>{this.cursorTime=t,this._updateCursorPosition(!1)})}render(){this.innerHTML="",this.timeAreaEl=this._createTimeArea(),this.appendChild(this.timeAreaEl),this.config.hideCursor||(this.cursorEl=this._createCursor(),this.appendChild(this.cursorEl)),this.style.setProperty("--timeline-start-left",`${this.config.startLeft}px`),this.style.setProperty("--timeline-content-padding",`${this.config.contentPadding}px`),this.style.setProperty("--timeline-scale-width",`${this.config.scaleWidth}px`);const t=document.createElement("div");t.className="timeline-editor-spacer",t.style.cssText="\n height: 10px;\n width: calc(var(--timeline-start-left) - 4px);\n background-color: #191b1d;\n flex-shrink: 0;\n position: relative;\n z-index: 101;\n ",this.appendChild(t);const e=document.createElement("div");e.className="timeline-editor-content",e.style.cssText="\n display: flex;\n flex: 1 1 0;\n overflow: hidden;\n position: relative;\n min-height: 0;\n min-width: 0;\n height: 0;\n ",this.labelColumnEl=this._createLabelColumn(),e.appendChild(this.labelColumnEl),this.editAreaEl=this._createEditArea(),e.appendChild(this.editAreaEl),this.appendChild(e),this._scrollX>0&&(this.editAreaEl.scrollLeft=this._scrollX,this._syncTimeAreaScroll()),this._scrollY>0&&(this.editAreaEl.scrollTop=this._scrollY,this._syncLabelColumnScroll()),this._updateCursorPosition()}_createTimeArea(){const t=document.createElement("div");t.className="timeline-editor-time-area";const e=this.config.contentPadding,i=document.createElement("div");i.className="timeline-editor-time-area-wrapper";const s=this.config.scaleCount*this.config.scaleWidth+this.config.startLeft+e;i.style.width=`${s}px`,i.style.height="100%",i.style.position="relative";const a=document.createElement("div");a.className="timeline-editor-time-area-interact",a.style.width=`${s}px`;const r=this.config.scaleCount*this.config.scaleSplitCount,o=this.config.scaleWidth/this.config.scaleSplitCount;for(let t=0;t<=r;t++){const i=document.createElement("div"),s=t%this.config.scaleSplitCount===0;if(i.className="timeline-editor-time-unit "+(s?"timeline-editor-time-unit-big":""),i.style.width=`${o}px`,0===t&&(i.style.marginLeft=this.config.startLeft+e-o+1+"px"),s){const e=document.createElement("div");e.className="timeline-editor-time-unit-scale";const s=t/this.config.scaleSplitCount*this.config.scale;if(this.callbacks.getScaleRender){const t=this.callbacks.getScaleRender(s);"string"==typeof t?e.innerHTML=t:t instanceof HTMLElement&&(e.innerHTML="",e.appendChild(t))}else e.textContent=0===t?"0s":`${s.toFixed(1)}s`;i.appendChild(e)}a.appendChild(i)}return i.appendChild(a),t.appendChild(i),this.timeAreaWrapperEl=i,t.addEventListener("click",i=>{if(this.isPlaying)return;const s=t.getBoundingClientRect(),a=i.clientX-s.left+this._scrollX-e,r=n(a,this.config);if(this.callbacks.onClickTimeArea){if(!1===this.callbacks.onClickTimeArea(i,{time:r}))return}this.setTime(Math.max(0,r))}),t}_createLabelColumn(){const t=document.createElement("div");t.className="timeline-editor-label-column",t.style.cssText=`\n width: ${this.config.startLeft}px;\n flex-shrink: 0;\n overflow: hidden;\n background-color: #191b1d;\n border-right: 1px solid rgba(255, 255, 255, 0.1);\n z-index: 200;\n position: relative;\n `;const e=document.createElement("div");return e.className="timeline-editor-label-inner",this.labelInnerEl=e,this.tracks.forEach((t,i)=>{const s=this._createLabelRow(t,i);e.appendChild(s)}),t.appendChild(e),t}_createLabelRow(t,e){const i=document.createElement("div");i.className="timeline-editor-label-row",i.style.cssText=`\n height: ${t.rowHeight||this.config.rowHeight}px;\n display: flex;\n align-items: center;\n padding: 0 8px;\n color: rgba(255, 255, 255, 0.7);\n font-size: 12px;\n font-weight: 500;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n box-sizing: border-box;\n position: relative;\n `,0===e&&(i.style.borderTop="1px solid rgba(255, 255, 255, 0.1)"),i.dataset.rowId=t.id,i.dataset.rowIndex=e;const s=document.createElement("span");if(s.className="timeline-editor-label-text",s.textContent=t.name||"",s.style.cssText="\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n ",i.appendChild(s),t.locked||(i.style.cursor="text",i.addEventListener("dblclick",e=>{e.stopPropagation(),this._startLabelEdit(i,s,t)})),t.locked){const t=document.createElement("span");t.className="timeline-editor-lock-icon",t.style.cssText="\n width: 10px;\n height: 10px;\n margin-left: 6px;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,0.4)'%3E%3Cpath d='M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z'/%3E%3C/svg%3E\");\n background-size: contain;\n background-repeat: no-repeat;\n flex-shrink: 0;\n ",i.appendChild(t)}if(!t.noDelete){const e=document.createElement("div");e.className="timeline-editor-row-delete",e.addEventListener("click",e=>{e.stopPropagation(),this._deleteTrack(t)}),i.appendChild(e)}return i}_createEditArea(){const t=document.createElement("div");t.className="timeline-editor-edit-area";const e=this.config.contentPadding,i=this.config.scaleCount*this.config.scaleWidth+e,s=document.createElement("div");return s.className="timeline-editor-rows",s.style.position="relative",s.style.width=`${i}px`,s.style.minWidth=`${i}px`,this.tracks.forEach((t,n)=>{const a=this._createRow(t,n,i,e);s.appendChild(a)}),t.appendChild(s),t.addEventListener("scroll",()=>{this._scrollX=t.scrollLeft,this._scrollY=t.scrollTop,this._syncTimeAreaScroll(),this._syncLabelColumnScroll(),this._updateCursorPosition()}),t}_syncLabelColumnScroll(){this.labelInnerEl&&(this.labelInnerEl.style.transform=`translateY(-${this._scrollY}px)`)}_createRow(t,e,i,s){const a=document.createElement("div");a.className="timeline-editor-edit-row",a.style.height=`${t.rowHeight||this.config.rowHeight}px`,a.style.width=`${i}px`,a.style.backgroundPosition=`${s}px 0`,a.dataset.rowId=t.id,a.dataset.rowIndex=e,a.addEventListener("click",e=>{if(e.target===a&&(this._cancelActiveEditing(),this.callbacks.onClickRow)){const i=e.currentTarget.getBoundingClientRect(),a=e.clientX-i.left+this._scrollX-s+this.config.startLeft,r=n(a,this.config);this.callbacks.onClickRow(e,{row:t,time:r})}}),a.addEventListener("dblclick",e=>{if(e.target===a&&this.callbacks.onDoubleClickRow){const i=e.currentTarget.getBoundingClientRect(),a=e.clientX-i.left+this._scrollX-s+this.config.startLeft,r=n(a,this.config);this.callbacks.onDoubleClickRow(e,{row:t,time:r})}}),a.addEventListener("contextmenu",e=>{if(e.target===a&&this.callbacks.onContextMenuRow){e.preventDefault();const i=e.currentTarget.getBoundingClientRect(),a=e.clientX-i.left+this._scrollX-s+this.config.startLeft,r=n(a,this.config);this.callbacks.onContextMenuRow(e,{row:t,time:r})}}),a.addEventListener("mousedown",i=>{i.target!==a&&i.target!==a.querySelector(".timeline-editor-row-label")||this._handleRowDragStart(i,t,e)});return(t.blocks||t.items||t.actions||[]).forEach(i=>{const s=this._createAction(i,t,e);a.appendChild(s)}),a}_startLabelEdit(t,e,i){if(t.querySelector("input"))return;const s=i.name||"",n=document.createElement("input");n.type="text",n.value=s,n.className="timeline-editor-row-label-input",n.style.cssText="\n flex: 1;\n min-width: 0;\n background: transparent;\n border: none;\n border-bottom: 1px solid rgba(255,255,255,0.3);\n color: inherit;\n font: inherit;\n outline: none;\n padding: 0;\n margin: 0;\n user-select: text;\n box-sizing: border-box;\n ";let a=!1;n.addEventListener("blur",()=>{if(a)return;a=!0;const t=n.value.trim();i.name=t,e.textContent=t,e.style.display="",n.remove(),this._emitChange(),this.dispatchEvent(new CustomEvent("trackrenamed",{detail:{track:i,name:t}}))}),n.addEventListener("keydown",t=>{"Enter"===t.key?(t.preventDefault(),n.blur()):"Escape"===t.key&&(n.value=s,n.blur())}),e.style.display="none",t.insertBefore(n,e),n.focus(),n.select()}_deleteTrack(t){const e=this.tracks.indexOf(t);e>-1&&this.tracks.splice(e,1),this.render(),this._emitChange(),this.dispatchEvent(new CustomEvent("trackdeleted",{detail:{track:t}}))}_deleteBlock(t,e){const i=e.blocks||e.items||e.actions||[],s=i.indexOf(t);s>-1&&i.splice(s,1),this.render(),this._emitChange(),this.dispatchEvent(new CustomEvent("blockdeleted",{detail:{block:t,track:e}}))}_startBlockNameEdit(t,e,i){const s=t.querySelector(".timeline-editor-action-content");if(!s||s.querySelector("input"))return;const n=e.name||"",a=document.createElement("input");a.type="text",a.value=n,a.className="timeline-editor-block-name-input",a.style.cssText="\n width: 100%;\n background: transparent;\n border: none;\n border-bottom: 1px solid rgba(255,255,255,0.3);\n color: inherit;\n font: inherit;\n outline: none;\n padding: 0;\n text-align: center;\n user-select: text;\n ";let r=!1;a.addEventListener("blur",()=>{if(r)return;r=!0;const t=a.value.trim();if(e.name=t,a.remove(),this.callbacks.getActionRender){const t=this.callbacks.getActionRender(e,i);"string"==typeof t&&(s.innerHTML=t)}else s.textContent=t;this._emitChange(),this.dispatchEvent(new CustomEvent("blockrenamed",{detail:{block:e,track:i,name:t}}))}),a.addEventListener("keydown",t=>{"Enter"===t.key?(t.preventDefault(),a.blur()):"Escape"===t.key&&(a.value=n,a.blur()),t.stopPropagation()}),a.addEventListener("mousedown",t=>t.stopPropagation()),a.addEventListener("click",t=>t.stopPropagation()),s.innerHTML="",s.appendChild(a),a.focus(),a.select()}_cancelActiveEditing(){const t=this.querySelector(".timeline-editor-block-name-input");t&&t.blur();const e=this.querySelector(".timeline-editor-row-label-input");e&&e.blur()}_handleRowDragStart(t,e,i){if(this.isPlaying||this.config.disableDrag||e.locked)return;if(0!==t.button)return;t.preventDefault();const s=this.editAreaEl.getBoundingClientRect(),a=this.config.contentPadding,r=t.clientX-s.left+this._scrollX-a+this.config.startLeft,o=n(r,this.config);this.dragState.isDragging=!0,this.dragState.isActuallyDragging=!1,this.dragState.type="item-create",this.dragState.row=e,this.dragState.rowIndex=i,this.dragState.startX=t.clientX,this.dragState.startTime=o,this.dragState.totalDeltaX=0,this.dragState.newItem=null,this.dragState.newItemEl=null,this._boundHandleMouseMove=this._handleMouseMove.bind(this),this._boundHandleMouseUp=this._handleMouseUp.bind(this),document.addEventListener("mousemove",this._boundHandleMouseMove),document.addEventListener("mouseup",this._boundHandleMouseUp)}_createAction(t,e,i){const a=document.createElement("div");a.className="timeline-editor-action",t.selected&&a.classList.add("selected");const r=this.config.contentPadding,o=s(t.start,this.config)-this.config.startLeft+r,l=s(t.end,this.config)-this.config.startLeft+r-o;a.style.left=`${o}px`,a.style.width=`${l}px`,a.dataset.actionId=t.id,a.dataset.rowIndex=i;const c=document.createElement("div");if(c.className="timeline-editor-action-content",this.callbacks.getActionRender){const i=this.callbacks.getActionRender(t,e);"string"==typeof i?c.innerHTML=i:i instanceof HTMLElement&&(c.innerHTML="",c.appendChild(i))}else c.textContent=t.name||"";if(a.appendChild(c),!1!==t.flexible&&!e.locked){const s=document.createElement("div");s.className="timeline-editor-action-left-stretch",a.appendChild(s);const n=document.createElement("div");n.className="timeline-editor-action-right-stretch",a.appendChild(n),s.addEventListener("mousedown",s=>this._handleResizeStart(s,t,e,i,"left")),n.addEventListener("mousedown",s=>this._handleResizeStart(s,t,e,i,"right"))}if(!1===t.movable||e.locked||a.addEventListener("mousedown",s=>{s.target.classList.contains("timeline-editor-action-left-stretch")||s.target.classList.contains("timeline-editor-action-right-stretch")||this._handleMoveStart(s,t,e,i)}),e.locked&&(a.classList.add("timeline-editor-action-locked"),a.style.cursor="default"),!t.noDelete&&!e.locked){const i=document.createElement("div");i.className="timeline-editor-action-delete",i.addEventListener("click",i=>{i.stopPropagation(),this._deleteBlock(t,e)}),i.addEventListener("mousedown",t=>{t.stopPropagation()}),a.appendChild(i)}return a.addEventListener("click",i=>{if(this.callbacks.onClickAction){const s=this.editAreaEl.getBoundingClientRect(),a=i.clientX-s.left+this._scrollX-r+this.config.startLeft,o=n(a,this.config);this.callbacks.onClickAction(i,{action:t,row:e,time:o})}}),a.addEventListener("dblclick",i=>{if(i.stopPropagation(),this.callbacks.onDoubleClickAction){const s=this.editAreaEl.getBoundingClientRect(),a=i.clientX-s.left+this._scrollX-r+this.config.startLeft,o=n(a,this.config);if(!1===this.callbacks.onDoubleClickAction(i,{action:t,row:e,time:o}))return}e.locked||this._startBlockNameEdit(a,t,e)}),a.addEventListener("contextmenu",i=>{if(this.callbacks.onContextMenuAction){i.preventDefault();const s=this.editAreaEl.getBoundingClientRect(),a=i.clientX-s.left+this._scrollX-r+this.config.startLeft,o=n(a,this.config);this.callbacks.onContextMenuAction(i,{action:t,row:e,time:o})}}),a}_createCursor(){const t=document.createElement("div");t.className="timeline-editor-cursor";const e=document.createElement("div");e.className="timeline-editor-cursor-top",t.appendChild(e);const i=document.createElement("div");return i.className="timeline-editor-cursor-area",t.appendChild(i),i.addEventListener("mousedown",t=>this._handleCursorDragStart(t)),t}_updateCursorPosition(t=!1){if(!this.cursorEl)return;const e=this.config.contentPadding,i=s(this.cursorTime,this.config)+e;this.cursorEl.style.left=i-this._scrollX+"px",t&&this.config.autoScroll&&this.editAreaEl&&this._autoScrollToCursor(i)}_scrollToCursorImmediate(){if(!this.editAreaEl||!this.config.autoScroll)return;const t=this.config.contentPadding,e=s(this.cursorTime,this.config)+t,i=this.editAreaEl.clientWidth,n=e-this.config.startLeft,a=this._scrollX,r=this._scrollX+i;if(n<a+50||n>r-50){const t=Math.max(0,n-i/3);this.editAreaEl.scrollLeft=t}}_autoScrollToCursor(t){const e=this.editAreaEl.clientWidth,i=t-this.config.startLeft,s=this._scrollX,n=this._scrollX+e;let a=null;if(i<s+50?a=Math.max(0,i-50):i>n-50&&(a=i-e+50),null!==a){const t=a-this._scrollX,e=Math.sign(t)*Math.min(Math.abs(t),8);this.editAreaEl.scrollLeft=this._scrollX+e}}_syncTimeAreaScroll(){this.timeAreaWrapperEl||(this.timeAreaWrapperEl=this.timeAreaEl?.querySelector(".timeline-editor-time-area-wrapper")),this.timeAreaWrapperEl&&(this.timeAreaWrapperEl.style.transform=`translateX(-${this._scrollX}px)`)}_handleCursorDragStart(t){if(!this.isPlaying&&!this.config.disableDrag){if(t.preventDefault(),t.stopPropagation(),this.callbacks.onCursorDragStart){if(!1===this.callbacks.onCursorDragStart(t,{time:this.cursorTime}))return}this.dragState.isDragging=!0,this.dragState.type="cursor",this.dragState.startX=t.clientX,this._boundHandleMouseMove=this._handleMouseMove.bind(this),this._boundHandleMouseUp=this._handleMouseUp.bind(this),document.addEventListener("mousemove",this._boundHandleMouseMove),document.addEventListener("mouseup",this._boundHandleMouseUp)}}_handleMoveStart(t,e,i,n){this.isPlaying||this.config.disableDrag||(t.preventDefault(),t.stopPropagation(),this._cancelActiveEditing(),this.dragState.isDragging=!0,this.dragState.isActuallyDragging=!1,this.dragState.type="action-move",this.dragState.action=e,this.dragState.row=i,this.dragState.rowIndex=n,this.dragState.startX=t.clientX,this.dragState.deltaX=0,this.dragState.totalDeltaX=0,this.dragState.currentLeft=s(e.start,this.config),this.dragState.currentWidth=s(e.end,this.config)-this.dragState.currentLeft,this._boundHandleMouseMove=this._handleMouseMove.bind(this),this._boundHandleMouseUp=this._handleMouseUp.bind(this),document.addEventListener("mousemove",this._boundHandleMouseMove),document.addEventListener("mouseup",this._boundHandleMouseUp))}_handleResizeStart(t,e,i,n,a){this.isPlaying||this.config.disableDrag||(t.preventDefault(),t.stopPropagation(),this._cancelActiveEditing(),this.dragState.isDragging=!0,this.dragState.isActuallyDragging=!1,this.dragState.type=`action-resize-${a}`,this.dragState.action=e,this.dragState.row=i,this.dragState.rowIndex=n,this.dragState.startX=t.clientX,this.dragState.deltaX=0,this.dragState.totalDeltaX=0,this.dragState.currentLeft=s(e.start,this.config),this.dragState.currentWidth=s(e.end,this.config)-this.dragState.currentLeft,this._boundHandleMouseMove=this._handleMouseMove.bind(this),this._boundHandleMouseUp=this._handleMouseUp.bind(this),document.addEventListener("mousemove",this._boundHandleMouseMove),document.addEventListener("mouseup",this._boundHandleMouseUp))}_handleMouseMove(t){if(this.dragState.isDragging)if("cursor"===this.dragState.type)this._handleCursorDrag(t);else if("action-move"===this.dragState.type){const e=t.clientX-this.dragState.startX;if(this.dragState.startX=t.clientX,this.dragState.deltaX+=e,this.dragState.totalDeltaX+=Math.abs(e),!this.dragState.isActuallyDragging&&this.dragState.totalDeltaX>3&&(this.dragState.isActuallyDragging=!0,this.callbacks.onActionMoveStart)){if(!1===this.callbacks.onActionMoveStart({action:this.dragState.action,row:this.dragState.row}))return void this._cancelDrag()}this.dragState.isActuallyDragging&&this._handleActionMove()}else if("action-resize-left"===this.dragState.type){const e=t.clientX-this.dragState.startX;if(this.dragState.startX=t.clientX,this.dragState.deltaX+=e,this.dragState.totalDeltaX+=Math.abs(e),!this.dragState.isActuallyDragging&&this.dragState.totalDeltaX>3&&(this.dragState.isActuallyDragging=!0,this.callbacks.onActionResizeStart)){if(!1===this.callbacks.onActionResizeStart({action:this.dragState.action,row:this.dragState.row,direction:"left"}))return void this._cancelDrag()}this.dragState.isActuallyDragging&&this._handleActionResizeLeft()}else if("action-resize-right"===this.dragState.type){const e=t.clientX-this.dragState.startX;if(this.dragState.startX=t.clientX,this.dragState.deltaX+=e,this.dragState.totalDeltaX+=Math.abs(e),!this.dragState.isActuallyDragging&&this.dragState.totalDeltaX>3&&(this.dragState.isActuallyDragging=!0,this.callbacks.onActionResizeStart)){if(!1===this.callbacks.onActionResizeStart({action:this.dragState.action,row:this.dragState.row,direction:"right"}))return void this._cancelDrag()}this.dragState.isActuallyDragging&&this._handleActionResizeRight()}else if("item-create"===this.dragState.type){const e=t.clientX-this.dragState.startX;this.dragState.totalDeltaX+=Math.abs(e-(this.dragState.lastDx||0)),this.dragState.lastDx=e,!this.dragState.isActuallyDragging&&this.dragState.totalDeltaX>3&&(this.dragState.isActuallyDragging=!0,this._createNewItemFromDrag()),this.dragState.isActuallyDragging&&this.dragState.newItem&&this._updateNewItemFromDrag(t)}}_createNewItemFromDrag(){const t=this.dragState.row,e=this.dragState.rowIndex,i=Math.max(0,this.dragState.startTime),s={id:`block-${Date.now()}`,name:"",start:i,end:i+.1,flexible:!0,movable:!0,metadata:{}};t.blocks||(t.blocks=[]),t.blocks.push(s),this.dragState.newItem=s;const n=this.editAreaEl.querySelector(`[data-row-index="${e}"]`);if(n){const i=this._createAction(s,t,e);i.classList.add("creating"),n.appendChild(i),this.dragState.newItemEl=i}}_updateNewItemFromDrag(t){const e=this.dragState.newItem;if(!e)return;const i=this.editAreaEl.getBoundingClientRect(),a=this.config.contentPadding,r=t.clientX-i.left+this._scrollX-a+this.config.startLeft,o=n(r,this.config),l=this.dragState.startTime;if(o>l?(e.start=Math.max(0,l),e.end=o):(e.start=Math.max(0,o),e.end=l),this._expandTimelineIfNeeded(e.end),this.dragState.newItemEl){const t=this.config.contentPadding,i=s(e.start,this.config)-this.config.startLeft+t,n=s(e.end,this.config)-this.config.startLeft+t-i;this.dragState.newItemEl.style.left=`${i}px`,this.dragState.newItemEl.style.width=`${Math.max(10,n)}px`}}_handleMouseUp(t){if(!this.dragState.isDragging)return;const e=this.dragState.type,i=this.dragState.action,s=this.dragState.row;if(this.dragState.isActuallyDragging){if("cursor"===e&&this.callbacks.onCursorDragEnd)this.callbacks.onCursorDragEnd(t,{time:this.cursorTime});else if("action-move"===e&&this.callbacks.onActionMoveEnd)this.callbacks.onActionMoveEnd({action:i,row:s});else if("action-resize-left"!==e&&"action-resize-right"!==e||!this.callbacks.onActionResizeEnd){if("item-create"===e&&this.dragState.newItem){const t=this.dragState.newItem;this.dragState.newItemEl&&this.dragState.newItemEl.classList.remove("creating"),this._emitChange(),this.dispatchEvent(new CustomEvent("itemcreated",{detail:{item:t,row:s}}))}}else this.callbacks.onActionResizeEnd({action:i,row:s});e&&e.startsWith("action-")&&this._emitChange()}else if("item-create"===e&&this.dragState.newItem){const t=this.dragState.row,e=this.dragState.newItem,i=t.blocks||t.items||t.actions||[],s=i.indexOf(e);s>-1&&i.splice(s,1),this.dragState.newItemEl&&this.dragState.newItemEl.remove()}this.dragState.isDragging=!1,this.dragState.isActuallyDragging=!1,this.dragState.type=null,this.dragState.action=null,this.dragState.row=null,this.dragState.totalDeltaX=0,this.dragState.newItem=null,this.dragState.newItemEl=null,this.dragState.lastDx=0,document.removeEventListener("mousemove",this._boundHandleMouseMove),document.removeEventListener("mouseup",this._boundHandleMouseUp)}_cancelDrag(){this.dragState.isDragging=!1,this.dragState.isActuallyDragging=!1,this.dragState.type=null,this.dragState.action=null,this.dragState.row=null,this.dragState.totalDeltaX=0,this.dragState.newItem=null,this.dragState.newItemEl=null,this.dragState.lastDx=0,document.removeEventListener("mousemove",this._boundHandleMouseMove),document.removeEventListener("mouseup",this._boundHandleMouseUp)}_handleCursorDrag(t){if(!this.editAreaEl)return;const e=this.editAreaEl.getBoundingClientRect(),i=this.config.contentPadding,s=t.clientX-e.left+this._scrollX-i+this.config.startLeft,a=Math.max(0,n(s,this.config));if(this.callbacks.onCursorDrag){if(!1===this.callbacks.onCursorDrag(t,{time:a}))return}this.cursorTime=a,this.engine.setTime(a),this._updateCursorPosition(!0)}_handleActionMove(){const t=this.dragState.action,e=this.dragState.row,i=this.config.gridSnap?this.config.scaleWidth/10:1;if(Math.abs(this.dragState.deltaX)>=i){const s=parseInt(this.dragState.deltaX/i);let a=this.dragState.currentLeft+s*i;if(this.config.gridSnap){0!==(a-this.config.startLeft)%i&&(a=this.config.startLeft+i*Math.round((a-this.config.startLeft)/i))}a=Math.max(this.config.startLeft,a),this.dragState.currentLeft=a,this.dragState.deltaX=this.dragState.deltaX%i;const r=n(a,this.config),o=t.end-t.start;if(this.callbacks.onActionMoving){if(!1===this.callbacks.onActionMoving({action:t,row:e,start:r,end:r+o}))return}t.start=r,t.end=r+o,this._expandTimelineIfNeeded(t.end),this._updateActionElement(t,this.dragState.rowIndex)}}_handleActionResizeLeft(){const t=this.dragState.action,e=this.dragState.row,i=this.config.gridSnap?this.config.scaleWidth/10:1;if(Math.abs(this.dragState.deltaX)>=i){const s=parseInt(this.dragState.deltaX/i);let a=this.dragState.currentLeft+s*i;if(this.config.gridSnap){0!==(a-this.config.startLeft)%i&&(a=this.config.startLeft+i*Math.round((a-this.config.startLeft)/i))}const r=this.dragState.currentLeft+this.dragState.currentWidth;a=Math.max(this.config.startLeft,a);const o=10;a=Math.min(a,r-o);const l=r-a;this.dragState.currentLeft=a,this.dragState.currentWidth=l,this.dragState.deltaX=this.dragState.deltaX%i;const c=n(a,this.config);if(this.callbacks.onActionResizing){if(!1===this.callbacks.onActionResizing({action:t,row:e,start:Math.max(0,c),end:t.end}))return}t.start=Math.max(0,c),this._updateActionElement(t,this.dragState.rowIndex)}}_handleActionResizeRight(){const t=this.dragState.action,e=this.dragState.row,i=this.config.gridSnap?this.config.scaleWidth/10:1;if(Math.abs(this.dragState.deltaX)>=i){const s=parseInt(this.dragState.deltaX/i);let a=this.dragState.currentWidth+s*i;const r=this.dragState.currentLeft+a;if(this.config.gridSnap){if(0!==(r-this.config.startLeft)%i){a=this.config.startLeft+i*Math.round((r-this.config.startLeft)/i)-this.dragState.currentLeft}}const o=10;a=Math.max(o,a),this.dragState.currentWidth=a,this.dragState.deltaX=this.dragState.deltaX%i;const l=this.dragState.currentLeft+a,c=n(l,this.config);if(this.callbacks.onActionResizing){if(!1===this.callbacks.onActionResizing({action:t,row:e,start:t.start,end:Math.max(t.start+.1,c)}))return}t.end=Math.max(t.start+.1,c),this._expandTimelineIfNeeded(t.end),this._updateActionElement(t,this.dragState.rowIndex)}}_updateActionElement(t,e){const i=this.editAreaEl.querySelector(`[data-row-index="${e}"]`);if(!i)return;const n=i.querySelector(`[data-action-id="${t.id}"]`);if(!n)return;const a=this.config.contentPadding,r=s(t.start,this.config)-this.config.startLeft+a,o=s(t.end,this.config)-this.config.startLeft+a-r;n.style.left=`${r}px`,n.style.width=`${o}px`}}customElements.get("trakk-editor")||customElements.define("trakk-editor",a),t.Trakk=a});
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Trakk={})}(this,function(t){"use strict";class e{constructor(){this.events={}}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}off(t,e){this.events[t]&&(this.events[t]=this.events[t].filter(t=>t!==e))}emit(t,e){return!this.events[t]||(this.events[t].forEach(t=>t(e)),!0)}}class i extends e{constructor(){super(),this._timerId=null,this._playRate=1,this._currentTime=0,this._playState="paused",this._prev=0,this._effectMap={},this._actionMap={},this._actionSortIds=[],this._next=0,this._activeActionIds=[]}get isPlaying(){return"playing"===this._playState}get isPaused(){return"paused"===this._playState}set effects(t){this._effectMap=t}set data(t){this.isPlaying&&this.pause(),this._dealData(t),this._dealClear(),this._dealEnter(this._currentTime)}setPlayRate(t){return t<=0?(console.error("Error: rate cannot be less than 0!"),!1):(this._playRate=t,this.emit("afterSetPlayRate",{rate:t,engine:this}),!0)}getPlayRate(){return this._playRate}reRender(){this.isPlaying||this._tickAction(this._currentTime)}setTime(t,e=!1){return this._currentTime=t,this._next=0,this._dealLeave(t),this._dealEnter(t),e?this.emit("setTimeByTick",{time:t,engine:this}):this.emit("afterSetTime",{time:t,engine:this}),!0}getTime(){return this._currentTime}play({toTime:t,autoEnd:e}={}){const i=this.getTime();return!(this.isPlaying||t&&t<=i)&&(this._playState="playing",this._startOrStop("start"),this.emit("play",{engine:this}),this._timerId=requestAnimationFrame(i=>{this._prev=i,this._tick({now:i,autoEnd:e,to:t})}),!0)}pause(){this.isPlaying&&(this._playState="paused",this._startOrStop("stop"),this.emit("paused",{engine:this})),this._timerId&&cancelAnimationFrame(this._timerId)}_end(){this.pause(),this.emit("ended",{engine:this})}_startOrStop(t){for(let e=0;e<this._activeActionIds.length;e++){const i=this._activeActionIds[e],s=this._actionMap[i],n=this._effectMap[s?.effectId];"start"===t?n?.source?.start?.({action:s,effect:n,engine:this,isPlaying:this.isPlaying,time:this.getTime()}):"stop"===t&&n?.source?.stop?.({action:s,effect:n,engine:this,isPlaying:this.isPlaying,time:this.getTime()})}}_tick(t){if(this.isPaused)return;const{now:e,autoEnd:i,to:s}=t;let n=this.getTime()+Math.min(1e3,e-this._prev)/1e3*this._playRate;this._prev=e,s&&s<=n&&(n=s),this.setTime(n,!0),this._tickAction(n),!s&&i&&this._next>=this._actionSortIds.length&&0===this._activeActionIds.length||s&&s<=n?this._end():this.isPaused||(this._timerId=requestAnimationFrame(t=>{this._tick({now:t,autoEnd:i,to:s})}))}_tickAction(t){this._dealEnter(t),this._dealLeave(t);const e=this._activeActionIds.length;for(let i=0;i<e;i++){const e=this._activeActionIds[i],s=this._actionMap[e],n=this._effectMap[s.effectId];n?.source?.update&&n.source.update({time:t,action:s,isPlaying:this.isPlaying,effect:n,engine:this})}}_dealClear(){for(;this._activeActionIds.length;){const t=this._activeActionIds.shift(),e=this._actionMap[t],i=this._effectMap[e?.effectId];i?.source?.leave&&i.source.leave({action:e,effect:i,engine:this,isPlaying:this.isPlaying,time:this.getTime()})}this._next=0}_dealEnter(t){for(;this._actionSortIds[this._next];){const e=this._actionSortIds[this._next],i=this._actionMap[e];if(!i.disable){if(i.start>t)break;if(i.end>t&&!this._activeActionIds.includes(e)){const s=this._effectMap[i.effectId];s?.source?.enter&&s.source.enter({action:i,effect:s,isPlaying:this.isPlaying,time:t,engine:this}),this._activeActionIds.push(e)}}this._next++}}_dealLeave(t){let e=0;for(;this._activeActionIds[e];){const i=this._activeActionIds[e],s=this._actionMap[i];if(s.start>t||s.end<t){const i=this._effectMap[s.effectId];i?.source?.leave&&i.source.leave({action:s,effect:i,isPlaying:this.isPlaying,time:t,engine:this}),this._activeActionIds.splice(e,1);continue}e++}}_dealData(t){const e=[];t.forEach(t=>{const i=t.blocks||t.items||t.actions||[];e.push(...i)});const i=e.sort((t,e)=>t.start-e.start),s={},n=[];i.forEach(t=>{n.push(t.id),s[t.id]={...t}}),this._actionMap=s,this._actionSortIds=n}}const s=(t,{startLeft:e,scale:i,scaleWidth:s})=>t/i*s+e,n=(t,{startLeft:e,scale:i,scaleWidth:s})=>(t-e)/s*i;class a extends HTMLElement{constructor(){super(),this.config={scale:1,scaleWidth:160,scaleCount:20,scaleSplitCount:10,startLeft:120,contentPadding:0,minScaleCount:10,maxScaleCount:1/0,rowHeight:32,autoScroll:!0,hideCursor:!1,disableDrag:!1,gridSnap:!0,grid:1,allowOverlap:!1},this.callbacks={onActionMoveStart:null,onActionMoving:null,onActionMoveEnd:null,onActionResizeStart:null,onActionResizing:null,onActionResizeEnd:null,onClickRow:null,onClickAction:null,onDoubleClickRow:null,onDoubleClickAction:null,onContextMenuRow:null,onContextMenuAction:null,onCursorDragStart:null,onCursorDrag:null,onCursorDragEnd:null,onClickTimeArea:null,getActionRender:null,getScaleRender:null},this.tracks=[],this.cursorTime=0,this.isPlaying=!1,this._scrollX=0,this._scrollY=0,this._selectedAction=null,this.timeAreaEl=null,this.timeAreaWrapperEl=null,this.editAreaEl=null,this.labelColumnEl=null,this.labelInnerEl=null,this.cursorEl=null,this.engine=new i,this.dragState={isDragging:!1,isActuallyDragging:!1,type:null,action:null,row:null,rowIndex:null,startX:0,startY:0,currentLeft:0,currentWidth:0,deltaX:0,totalDeltaX:0}}connectedCallback(){this.className="timeline-editor",this.render(),this._setupEngineListeners(),this._setupResizeObserver()}disconnectedCallback(){this.engine.pause(),this._cleanup()}_cleanup(){document.removeEventListener("mousemove",this._boundHandleMouseMove),document.removeEventListener("mouseup",this._boundHandleMouseUp),this._resizeObserver&&this._resizeObserver.disconnect()}_setupResizeObserver(){this._resizeObserver=new ResizeObserver(t=>{for(let e of t)this.editAreaEl&&this._updateCursorPosition()}),this._resizeObserver.observe(this)}setData(t){this.tracks=t||[],this.engine.data=this.tracks,this.render()}setConfig(t){Object.assign(this.config,t),this.render()}setCallbacks(t){Object.assign(this.callbacks,t)}on(t,e){this.callbacks.hasOwnProperty(t)&&(this.callbacks[t]=e)}getData(){return{tracks:this.tracks}}exportJSON(){return JSON.stringify(this.getData(),null,2)}importJSON(t){try{const e=JSON.parse(t),i=e.tracks||e.editorData||[];return this.setData(i),!0}catch(t){return console.error("Failed to import timeline data:",t),!1}}saveToLocalStorage(t="timeline-data"){try{return localStorage.setItem(t,this.exportJSON()),!0}catch(t){return console.error("Failed to save to localStorage:",t),!1}}loadFromLocalStorage(t="timeline-data"){try{const e=localStorage.getItem(t);return!!e&&this.importJSON(e)}catch(t){return console.error("Failed to load from localStorage:",t),!1}}setTime(t){this.cursorTime=Math.max(0,t),this.engine.setTime(this.cursorTime),this._updateCursorPosition()}getTime(){return this.engine.getTime()}getTotalTime(){let t=0;for(const e of this.tracks){const i=e.blocks||e.items||e.actions||[];for(const e of i)e.end>t&&(t=e.end)}return t}play(t={}){return this.engine.play(t)}pause(){this.engine.pause()}_syncEngineData(){this.engine.data=this.tracks}_emitChange(){this._syncEngineData(),this.dispatchEvent(new CustomEvent("change",{detail:{tracks:this.tracks}}))}selectAction(t,e=null){const i=this.querySelector(".timeline-editor-action.selected");if(i&&i.classList.remove("selected"),this._selectedAction,this._selectedAction=t?{action:t,row:e}:null,t){const e=this.querySelector(`[data-action-id="${t.id}"]`);e&&e.classList.add("selected")}this._emitSelect(t,e)}getSelectedAction(){return this._selectedAction}deselectAction(){this.selectAction(null,null)}_emitSelect(t,e){this.dispatchEvent(new CustomEvent("select",{detail:t?{action:t,row:e}:null}))}_wouldOverlap(t,e,i,s){if(!t.blocks)return!1;for(const n of t.blocks)if(n.id!==e&&i<n.end&&s>n.start)return!0;return!1}_getValidPosition(t,e,i,s,n="move"){if(this.config.allowOverlap)return{start:i,end:s};const a=s-i;if(!this._wouldOverlap(t,e,i,s))return{start:i,end:s};const r=(t.blocks||[]).filter(t=>t.id!==e).sort((t,e)=>t.start-e.start);if("move"===n){let n=i,o=s,l=1/0;for(const s of r){const r=s.start,c=r-a;if(c>=0&&!this._wouldOverlap(t,e,c,r)){const t=Math.abs(i-c);t<l&&(l=t,n=c,o=r)}const d=s.end,h=d+a;if(!this._wouldOverlap(t,e,d,h)){const t=Math.abs(i-d);t<l&&(l=t,n=d,o=h)}}return{start:n,end:o}}if("resize-left"===n){let t=i;for(const e of r)e.end>i&&e.end<=s&&(t=Math.max(t,e.end));return{start:t,end:s}}if("resize-right"===n){let t=s;for(const e of r)e.start<s&&e.start>=i&&(t=Math.min(t,e.start));return{start:i,end:t}}return{start:i,end:s}}_expandTimelineIfNeeded(t){const e=Math.ceil(t/this.config.scale)+2;if(e>this.config.scaleCount){const t=Math.min(e,this.config.maxScaleCount);if(t>this.config.scaleCount)return this.config.scaleCount=t,this._updateTimelineWidth(),!0}return!1}_updateTimelineWidth(){const t=this.config.contentPadding,e=this.config.scaleCount*this.config.scaleWidth+t,i=this.editAreaEl?.querySelector(".timeline-editor-rows");i&&(i.style.width=`${e}px`,i.style.minWidth=`${e}px`);const s=this.editAreaEl?.querySelectorAll(".timeline-editor-edit-row");s&&s.forEach(t=>{t.style.width=`${e}px`}),this._rerenderTimeArea()}_rerenderTimeArea(){if(!this.timeAreaEl)return;const t=this._createTimeArea();this.timeAreaEl.replaceWith(t),this.timeAreaEl=t,this._syncTimeAreaScroll()}_setupEngineListeners(){this.engine.on("play",()=>{this.isPlaying=!0,this.classList.add("timeline-editor-playing"),this._scrollToCursorImmediate()}),this.engine.on("paused",()=>{this.isPlaying=!1,this.classList.remove("timeline-editor-playing")}),this.engine.on("setTimeByTick",({time:t})=>{this.cursorTime=t,this._updateCursorPosition(!0)}),this.engine.on("afterSetTime",({time:t})=>{this.cursorTime=t,this._updateCursorPosition(!1)})}render(){this.innerHTML="",this.timeAreaEl=this._createTimeArea(),this.appendChild(this.timeAreaEl),this.config.hideCursor||(this.cursorEl=this._createCursor(),this.appendChild(this.cursorEl)),this.style.setProperty("--timeline-start-left",`${this.config.startLeft}px`),this.style.setProperty("--timeline-content-padding",`${this.config.contentPadding}px`),this.style.setProperty("--timeline-scale-width",`${this.config.scaleWidth}px`);const t=document.createElement("div");t.className="timeline-editor-spacer",t.style.cssText="\n height: 10px;\n width: calc(var(--timeline-start-left) - 4px);\n background-color: #191b1d;\n flex-shrink: 0;\n position: relative;\n z-index: 101;\n ",this.appendChild(t);const e=document.createElement("div");e.className="timeline-editor-content",e.style.cssText="\n display: flex;\n flex: 1 1 0;\n overflow: hidden;\n position: relative;\n min-height: 0;\n min-width: 0;\n height: 0;\n ",this.labelColumnEl=this._createLabelColumn(),e.appendChild(this.labelColumnEl),this.editAreaEl=this._createEditArea(),e.appendChild(this.editAreaEl),this.appendChild(e),this._scrollX>0&&(this.editAreaEl.scrollLeft=this._scrollX,this._syncTimeAreaScroll()),this._scrollY>0&&(this.editAreaEl.scrollTop=this._scrollY,this._syncLabelColumnScroll()),this._updateCursorPosition()}_createTimeArea(){const t=document.createElement("div");t.className="timeline-editor-time-area";const e=this.config.contentPadding,i=document.createElement("div");i.className="timeline-editor-time-area-wrapper";const s=this.config.scaleCount*this.config.scaleWidth+this.config.startLeft+e;i.style.width=`${s}px`,i.style.height="100%",i.style.position="relative";const a=document.createElement("div");a.className="timeline-editor-time-area-interact",a.style.width=`${s}px`;const r=this.config.scaleCount*this.config.scaleSplitCount,o=this.config.scaleWidth/this.config.scaleSplitCount;for(let t=0;t<=r;t++){const i=document.createElement("div"),s=t%this.config.scaleSplitCount===0;if(i.className="timeline-editor-time-unit "+(s?"timeline-editor-time-unit-big":""),i.style.width=`${o}px`,0===t&&(i.style.marginLeft=this.config.startLeft+e-o+1+"px"),s){const e=document.createElement("div");e.className="timeline-editor-time-unit-scale";const s=t/this.config.scaleSplitCount*this.config.scale;if(this.callbacks.getScaleRender){const t=this.callbacks.getScaleRender(s);"string"==typeof t?e.innerHTML=t:t instanceof HTMLElement&&(e.innerHTML="",e.appendChild(t))}else e.textContent=0===t?"0s":`${s.toFixed(1)}s`;i.appendChild(e)}a.appendChild(i)}return i.appendChild(a),t.appendChild(i),this.timeAreaWrapperEl=i,t.addEventListener("click",i=>{if(this.isPlaying)return;const s=t.getBoundingClientRect(),a=i.clientX-s.left+this._scrollX-e,r=n(a,this.config);if(this.callbacks.onClickTimeArea){if(!1===this.callbacks.onClickTimeArea(i,{time:r}))return}this.setTime(Math.max(0,r))}),t}_createLabelColumn(){const t=document.createElement("div");t.className="timeline-editor-label-column",t.style.cssText=`\n width: ${this.config.startLeft}px;\n flex-shrink: 0;\n overflow: hidden;\n background-color: #191b1d;\n border-right: 1px solid rgba(255, 255, 255, 0.1);\n z-index: 200;\n position: relative;\n `;const e=document.createElement("div");return e.className="timeline-editor-label-inner",this.labelInnerEl=e,this.tracks.forEach((t,i)=>{const s=this._createLabelRow(t,i);e.appendChild(s)}),t.appendChild(e),t}_createLabelRow(t,e){const i=document.createElement("div");i.className="timeline-editor-label-row",i.style.cssText=`\n height: ${t.rowHeight||this.config.rowHeight}px;\n display: flex;\n align-items: center;\n padding: 0 8px;\n color: rgba(255, 255, 255, 0.7);\n font-size: 12px;\n font-weight: 500;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n box-sizing: border-box;\n position: relative;\n `,0===e&&(i.style.borderTop="1px solid rgba(255, 255, 255, 0.1)"),i.dataset.rowId=t.id,i.dataset.rowIndex=e;const s=document.createElement("span");if(s.className="timeline-editor-label-text",s.textContent=t.name||"",s.style.cssText="\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n ",i.appendChild(s),t.locked||(i.style.cursor="text",i.addEventListener("dblclick",e=>{e.stopPropagation(),this._startLabelEdit(i,s,t)})),t.locked){const t=document.createElement("span");t.className="timeline-editor-lock-icon",t.style.cssText="\n width: 10px;\n height: 10px;\n margin-left: 6px;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,0.4)'%3E%3Cpath d='M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z'/%3E%3C/svg%3E\");\n background-size: contain;\n background-repeat: no-repeat;\n flex-shrink: 0;\n ",i.appendChild(t)}if(!t.noDelete){const e=document.createElement("div");e.className="timeline-editor-row-delete",e.addEventListener("click",e=>{e.stopPropagation(),this._deleteTrack(t)}),i.appendChild(e)}return i}_createEditArea(){const t=document.createElement("div");t.className="timeline-editor-edit-area";const e=this.config.contentPadding,i=this.config.scaleCount*this.config.scaleWidth+e,s=document.createElement("div");return s.className="timeline-editor-rows",s.style.position="relative",s.style.width=`${i}px`,s.style.minWidth=`${i}px`,this.tracks.forEach((t,n)=>{const a=this._createRow(t,n,i,e);s.appendChild(a)}),t.appendChild(s),t.addEventListener("scroll",()=>{this._scrollX=t.scrollLeft,this._scrollY=t.scrollTop,this._syncTimeAreaScroll(),this._syncLabelColumnScroll(),this._updateCursorPosition()}),t.addEventListener("click",t=>{this._selectedAction&&this.deselectAction()}),t}_syncLabelColumnScroll(){this.labelInnerEl&&(this.labelInnerEl.style.transform=`translateY(-${this._scrollY}px)`)}_createRow(t,e,i,s){const a=document.createElement("div");a.className="timeline-editor-edit-row",a.style.height=`${t.rowHeight||this.config.rowHeight}px`,a.style.width=`${i}px`,a.style.backgroundPosition=`${s}px 0`,a.dataset.rowId=t.id,a.dataset.rowIndex=e,a.addEventListener("click",e=>{if(e.target===a&&(this._cancelActiveEditing(),this.callbacks.onClickRow)){const i=e.currentTarget.getBoundingClientRect(),a=e.clientX-i.left+this._scrollX-s+this.config.startLeft,r=n(a,this.config);this.callbacks.onClickRow(e,{row:t,time:r})}}),a.addEventListener("dblclick",e=>{if(e.target===a&&this.callbacks.onDoubleClickRow){const i=e.currentTarget.getBoundingClientRect(),a=e.clientX-i.left+this._scrollX-s+this.config.startLeft,r=n(a,this.config);this.callbacks.onDoubleClickRow(e,{row:t,time:r})}}),a.addEventListener("contextmenu",e=>{if(e.target===a&&this.callbacks.onContextMenuRow){e.preventDefault();const i=e.currentTarget.getBoundingClientRect(),a=e.clientX-i.left+this._scrollX-s+this.config.startLeft,r=n(a,this.config);this.callbacks.onContextMenuRow(e,{row:t,time:r})}}),a.addEventListener("mousedown",i=>{i.target!==a&&i.target!==a.querySelector(".timeline-editor-row-label")||this._handleRowDragStart(i,t,e)});return(t.blocks||t.items||t.actions||[]).forEach(i=>{const s=this._createAction(i,t,e);a.appendChild(s)}),a}_startLabelEdit(t,e,i){if(t.querySelector("input"))return;const s=i.name||"",n=document.createElement("input");n.type="text",n.value=s,n.className="timeline-editor-row-label-input",n.style.cssText="\n flex: 1;\n min-width: 0;\n background: transparent;\n border: none;\n border-bottom: 1px solid rgba(255,255,255,0.3);\n color: inherit;\n font: inherit;\n outline: none;\n padding: 0;\n margin: 0;\n user-select: text;\n box-sizing: border-box;\n ";let a=!1;n.addEventListener("blur",()=>{if(a)return;a=!0;const t=n.value.trim();i.name=t,e.textContent=t,e.style.display="",n.remove(),this._emitChange(),this.dispatchEvent(new CustomEvent("trackrenamed",{detail:{track:i,name:t}}))}),n.addEventListener("keydown",t=>{"Enter"===t.key?(t.preventDefault(),n.blur()):"Escape"===t.key&&(n.value=s,n.blur())}),e.style.display="none",t.insertBefore(n,e),n.focus(),n.select()}_deleteTrack(t){const e=this.tracks.indexOf(t);e>-1&&this.tracks.splice(e,1),this.render(),this._emitChange(),this.dispatchEvent(new CustomEvent("trackdeleted",{detail:{track:t}}))}_deleteBlock(t,e){const i=e.blocks||e.items||e.actions||[],s=i.indexOf(t);s>-1&&i.splice(s,1),this.render(),this._emitChange(),this.dispatchEvent(new CustomEvent("blockdeleted",{detail:{block:t,track:e}}))}_startBlockNameEdit(t,e,i){const s=t.querySelector(".timeline-editor-action-content");if(!s||s.querySelector("input"))return;const n=e.name||"",a=document.createElement("input");a.type="text",a.value=n,a.className="timeline-editor-block-name-input",a.style.cssText="\n width: 100%;\n background: transparent;\n border: none;\n border-bottom: 1px solid rgba(255,255,255,0.3);\n color: inherit;\n font: inherit;\n outline: none;\n padding: 0;\n text-align: center;\n user-select: text;\n ";let r=!1;a.addEventListener("blur",()=>{if(r)return;r=!0;const t=a.value.trim();if(e.name=t,a.remove(),this.callbacks.getActionRender){const t=this.callbacks.getActionRender(e,i);"string"==typeof t&&(s.innerHTML=t)}else s.textContent=t;this._emitChange(),this.dispatchEvent(new CustomEvent("blockrenamed",{detail:{block:e,track:i,name:t}}))}),a.addEventListener("keydown",t=>{"Enter"===t.key?(t.preventDefault(),a.blur()):"Escape"===t.key&&(a.value=n,a.blur()),t.stopPropagation()}),a.addEventListener("mousedown",t=>t.stopPropagation()),a.addEventListener("click",t=>t.stopPropagation()),s.innerHTML="",s.appendChild(a),a.focus(),a.select()}_cancelActiveEditing(){const t=this.querySelector(".timeline-editor-block-name-input");t&&t.blur();const e=this.querySelector(".timeline-editor-row-label-input");e&&e.blur()}_handleRowDragStart(t,e,i){if(this.isPlaying||this.config.disableDrag||e.locked)return;if(0!==t.button)return;t.preventDefault();const s=this.editAreaEl.getBoundingClientRect(),a=this.config.contentPadding,r=t.clientX-s.left+this._scrollX-a+this.config.startLeft,o=n(r,this.config);this.dragState.isDragging=!0,this.dragState.isActuallyDragging=!1,this.dragState.type="item-create",this.dragState.row=e,this.dragState.rowIndex=i,this.dragState.startX=t.clientX,this.dragState.startTime=o,this.dragState.totalDeltaX=0,this.dragState.newItem=null,this.dragState.newItemEl=null,this._boundHandleMouseMove=this._handleMouseMove.bind(this),this._boundHandleMouseUp=this._handleMouseUp.bind(this),document.addEventListener("mousemove",this._boundHandleMouseMove),document.addEventListener("mouseup",this._boundHandleMouseUp)}_createAction(t,e,i){const a=document.createElement("div");a.className="timeline-editor-action",t.selected&&a.classList.add("selected");const r=this.config.contentPadding,o=s(t.start,this.config)-this.config.startLeft+r,l=s(t.end,this.config)-this.config.startLeft+r-o;a.style.left=`${o}px`,a.style.width=`${l}px`,a.dataset.actionId=t.id,a.dataset.rowIndex=i;const c=document.createElement("div");if(c.className="timeline-editor-action-content",this.callbacks.getActionRender){const i=this.callbacks.getActionRender(t,e);"string"==typeof i?c.innerHTML=i:i instanceof HTMLElement&&(c.innerHTML="",c.appendChild(i))}else c.textContent=t.name||"";if(a.appendChild(c),!1!==t.flexible&&!e.locked){const s=document.createElement("div");s.className="timeline-editor-action-left-stretch",a.appendChild(s);const n=document.createElement("div");n.className="timeline-editor-action-right-stretch",a.appendChild(n),s.addEventListener("mousedown",s=>this._handleResizeStart(s,t,e,i,"left")),n.addEventListener("mousedown",s=>this._handleResizeStart(s,t,e,i,"right"))}if(!1===t.movable||e.locked||a.addEventListener("mousedown",s=>{s.target.classList.contains("timeline-editor-action-left-stretch")||s.target.classList.contains("timeline-editor-action-right-stretch")||this._handleMoveStart(s,t,e,i)}),e.locked&&(a.classList.add("timeline-editor-action-locked"),a.style.cursor="default"),!t.noDelete&&!e.locked){const i=document.createElement("div");i.className="timeline-editor-action-delete",i.addEventListener("click",i=>{i.stopPropagation(),this._deleteBlock(t,e)}),i.addEventListener("mousedown",t=>{t.stopPropagation()}),a.appendChild(i)}return e.locked||a.addEventListener("mousedown",i=>{i.target.classList.contains("timeline-editor-action-left-stretch")||i.target.classList.contains("timeline-editor-action-right-stretch")||i.target.classList.contains("timeline-editor-action-delete")||this.selectAction(t,e)}),a.addEventListener("click",i=>{if(i.stopPropagation(),this.callbacks.onClickAction){const s=this.editAreaEl.getBoundingClientRect(),a=i.clientX-s.left+this._scrollX-r+this.config.startLeft,o=n(a,this.config);this.callbacks.onClickAction(i,{action:t,row:e,time:o})}}),a.addEventListener("dblclick",i=>{if(i.stopPropagation(),this.callbacks.onDoubleClickAction){const s=this.editAreaEl.getBoundingClientRect(),a=i.clientX-s.left+this._scrollX-r+this.config.startLeft,o=n(a,this.config);if(!1===this.callbacks.onDoubleClickAction(i,{action:t,row:e,time:o}))return}e.locked||this._startBlockNameEdit(a,t,e)}),a.addEventListener("contextmenu",i=>{if(this.callbacks.onContextMenuAction){i.preventDefault();const s=this.editAreaEl.getBoundingClientRect(),a=i.clientX-s.left+this._scrollX-r+this.config.startLeft,o=n(a,this.config);this.callbacks.onContextMenuAction(i,{action:t,row:e,time:o})}}),a}_createCursor(){const t=document.createElement("div");t.className="timeline-editor-cursor";const e=document.createElement("div");e.className="timeline-editor-cursor-top",t.appendChild(e);const i=document.createElement("div");return i.className="timeline-editor-cursor-area",t.appendChild(i),i.addEventListener("mousedown",t=>this._handleCursorDragStart(t)),t}_updateCursorPosition(t=!1){if(!this.cursorEl)return;const e=this.config.contentPadding,i=s(this.cursorTime,this.config)+e;this.cursorEl.style.left=i-this._scrollX+"px",t&&this.config.autoScroll&&this.editAreaEl&&this._autoScrollToCursor(i)}_scrollToCursorImmediate(){if(!this.editAreaEl||!this.config.autoScroll)return;const t=this.config.contentPadding,e=s(this.cursorTime,this.config)+t,i=this.editAreaEl.clientWidth,n=e-this.config.startLeft,a=this._scrollX,r=this._scrollX+i;if(n<a+50||n>r-50){const t=Math.max(0,n-i/3);this.editAreaEl.scrollLeft=t}}_autoScrollToCursor(t){const e=this.editAreaEl.clientWidth,i=t-this.config.startLeft,s=this._scrollX,n=this._scrollX+e;let a=null;if(i<s+50?a=Math.max(0,i-50):i>n-50&&(a=i-e+50),null!==a){const t=a-this._scrollX,e=Math.sign(t)*Math.min(Math.abs(t),8);this.editAreaEl.scrollLeft=this._scrollX+e}}_syncTimeAreaScroll(){this.timeAreaWrapperEl||(this.timeAreaWrapperEl=this.timeAreaEl?.querySelector(".timeline-editor-time-area-wrapper")),this.timeAreaWrapperEl&&(this.timeAreaWrapperEl.style.transform=`translateX(-${this._scrollX}px)`)}_handleCursorDragStart(t){if(!this.isPlaying&&!this.config.disableDrag){if(t.preventDefault(),t.stopPropagation(),this.callbacks.onCursorDragStart){if(!1===this.callbacks.onCursorDragStart(t,{time:this.cursorTime}))return}this.dragState.isDragging=!0,this.dragState.type="cursor",this.dragState.startX=t.clientX,this._boundHandleMouseMove=this._handleMouseMove.bind(this),this._boundHandleMouseUp=this._handleMouseUp.bind(this),document.addEventListener("mousemove",this._boundHandleMouseMove),document.addEventListener("mouseup",this._boundHandleMouseUp)}}_handleMoveStart(t,e,i,n){this.isPlaying||this.config.disableDrag||(t.preventDefault(),t.stopPropagation(),this._cancelActiveEditing(),this.dragState.isDragging=!0,this.dragState.isActuallyDragging=!1,this.dragState.type="action-move",this.dragState.action=e,this.dragState.row=i,this.dragState.rowIndex=n,this.dragState.startX=t.clientX,this.dragState.deltaX=0,this.dragState.totalDeltaX=0,this.dragState.currentLeft=s(e.start,this.config),this.dragState.currentWidth=s(e.end,this.config)-this.dragState.currentLeft,this._boundHandleMouseMove=this._handleMouseMove.bind(this),this._boundHandleMouseUp=this._handleMouseUp.bind(this),document.addEventListener("mousemove",this._boundHandleMouseMove),document.addEventListener("mouseup",this._boundHandleMouseUp))}_handleResizeStart(t,e,i,n,a){this.isPlaying||this.config.disableDrag||(t.preventDefault(),t.stopPropagation(),this._cancelActiveEditing(),this.dragState.isDragging=!0,this.dragState.isActuallyDragging=!1,this.dragState.type=`action-resize-${a}`,this.dragState.action=e,this.dragState.row=i,this.dragState.rowIndex=n,this.dragState.startX=t.clientX,this.dragState.deltaX=0,this.dragState.totalDeltaX=0,this.dragState.currentLeft=s(e.start,this.config),this.dragState.currentWidth=s(e.end,this.config)-this.dragState.currentLeft,this._boundHandleMouseMove=this._handleMouseMove.bind(this),this._boundHandleMouseUp=this._handleMouseUp.bind(this),document.addEventListener("mousemove",this._boundHandleMouseMove),document.addEventListener("mouseup",this._boundHandleMouseUp))}_handleMouseMove(t){if(this.dragState.isDragging)if("cursor"===this.dragState.type)this._handleCursorDrag(t);else if("action-move"===this.dragState.type){const e=t.clientX-this.dragState.startX;if(this.dragState.startX=t.clientX,this.dragState.deltaX+=e,this.dragState.totalDeltaX+=Math.abs(e),!this.dragState.isActuallyDragging&&this.dragState.totalDeltaX>3&&(this.dragState.isActuallyDragging=!0,this.callbacks.onActionMoveStart)){if(!1===this.callbacks.onActionMoveStart({action:this.dragState.action,row:this.dragState.row}))return void this._cancelDrag()}this.dragState.isActuallyDragging&&this._handleActionMove()}else if("action-resize-left"===this.dragState.type){const e=t.clientX-this.dragState.startX;if(this.dragState.startX=t.clientX,this.dragState.deltaX+=e,this.dragState.totalDeltaX+=Math.abs(e),!this.dragState.isActuallyDragging&&this.dragState.totalDeltaX>3&&(this.dragState.isActuallyDragging=!0,this.callbacks.onActionResizeStart)){if(!1===this.callbacks.onActionResizeStart({action:this.dragState.action,row:this.dragState.row,direction:"left"}))return void this._cancelDrag()}this.dragState.isActuallyDragging&&this._handleActionResizeLeft()}else if("action-resize-right"===this.dragState.type){const e=t.clientX-this.dragState.startX;if(this.dragState.startX=t.clientX,this.dragState.deltaX+=e,this.dragState.totalDeltaX+=Math.abs(e),!this.dragState.isActuallyDragging&&this.dragState.totalDeltaX>3&&(this.dragState.isActuallyDragging=!0,this.callbacks.onActionResizeStart)){if(!1===this.callbacks.onActionResizeStart({action:this.dragState.action,row:this.dragState.row,direction:"right"}))return void this._cancelDrag()}this.dragState.isActuallyDragging&&this._handleActionResizeRight()}else if("item-create"===this.dragState.type){const e=t.clientX-this.dragState.startX;this.dragState.totalDeltaX+=Math.abs(e-(this.dragState.lastDx||0)),this.dragState.lastDx=e,!this.dragState.isActuallyDragging&&this.dragState.totalDeltaX>3&&(this.dragState.isActuallyDragging=!0,this._createNewItemFromDrag()),this.dragState.isActuallyDragging&&this.dragState.newItem&&this._updateNewItemFromDrag(t)}}_createNewItemFromDrag(){const t=this.dragState.row,e=this.dragState.rowIndex,i=Math.max(0,this.dragState.startTime),s={id:`block-${Date.now()}`,name:"",start:i,end:i+.1,flexible:!0,movable:!0,metadata:{}};t.blocks||(t.blocks=[]),t.blocks.push(s),this.dragState.newItem=s;const n=this.editAreaEl.querySelector(`[data-row-index="${e}"]`);if(n){const i=this._createAction(s,t,e);i.classList.add("creating"),n.appendChild(i),this.dragState.newItemEl=i}}_updateNewItemFromDrag(t){const e=this.dragState.newItem;if(!e)return;const i=this.editAreaEl.getBoundingClientRect(),a=this.config.contentPadding,r=t.clientX-i.left+this._scrollX-a+this.config.startLeft,o=n(r,this.config),l=this.dragState.startTime;if(o>l?(e.start=Math.max(0,l),e.end=o):(e.start=Math.max(0,o),e.end=l),this._expandTimelineIfNeeded(e.end),this.dragState.newItemEl){const t=this.config.contentPadding,i=s(e.start,this.config)-this.config.startLeft+t,n=s(e.end,this.config)-this.config.startLeft+t-i;this.dragState.newItemEl.style.left=`${i}px`,this.dragState.newItemEl.style.width=`${Math.max(10,n)}px`}}_handleMouseUp(t){if(!this.dragState.isDragging)return;const e=this.dragState.type,i=this.dragState.action,s=this.dragState.row;if(this.dragState.isActuallyDragging){if("cursor"===e&&this.callbacks.onCursorDragEnd)this.callbacks.onCursorDragEnd(t,{time:this.cursorTime});else if("action-move"===e&&this.callbacks.onActionMoveEnd)this.callbacks.onActionMoveEnd({action:i,row:s});else if("action-resize-left"!==e&&"action-resize-right"!==e||!this.callbacks.onActionResizeEnd){if("item-create"===e&&this.dragState.newItem){const t=this.dragState.newItem;this.dragState.newItemEl&&this.dragState.newItemEl.classList.remove("creating"),this._emitChange(),this.dispatchEvent(new CustomEvent("itemcreated",{detail:{item:t,row:s}}))}}else this.callbacks.onActionResizeEnd({action:i,row:s});e&&e.startsWith("action-")&&this._emitChange()}else if("item-create"===e&&this.dragState.newItem){const t=this.dragState.row,e=this.dragState.newItem,i=t.blocks||t.items||t.actions||[],s=i.indexOf(e);s>-1&&i.splice(s,1),this.dragState.newItemEl&&this.dragState.newItemEl.remove()}this.dragState.isDragging=!1,this.dragState.isActuallyDragging=!1,this.dragState.type=null,this.dragState.action=null,this.dragState.row=null,this.dragState.totalDeltaX=0,this.dragState.newItem=null,this.dragState.newItemEl=null,this.dragState.lastDx=0,document.removeEventListener("mousemove",this._boundHandleMouseMove),document.removeEventListener("mouseup",this._boundHandleMouseUp)}_cancelDrag(){this.dragState.isDragging=!1,this.dragState.isActuallyDragging=!1,this.dragState.type=null,this.dragState.action=null,this.dragState.row=null,this.dragState.totalDeltaX=0,this.dragState.newItem=null,this.dragState.newItemEl=null,this.dragState.lastDx=0,document.removeEventListener("mousemove",this._boundHandleMouseMove),document.removeEventListener("mouseup",this._boundHandleMouseUp)}_handleCursorDrag(t){if(!this.editAreaEl)return;const e=this.editAreaEl.getBoundingClientRect(),i=this.config.contentPadding,s=t.clientX-e.left+this._scrollX-i+this.config.startLeft,a=Math.max(0,n(s,this.config));if(this.callbacks.onCursorDrag){if(!1===this.callbacks.onCursorDrag(t,{time:a}))return}this.cursorTime=a,this.engine.setTime(a),this._updateCursorPosition(!0)}_handleActionMove(){const t=this.dragState.action,e=this.dragState.row,i=this.config.gridSnap?this.config.scaleWidth/10:1;if(Math.abs(this.dragState.deltaX)>=i){const s=parseInt(this.dragState.deltaX/i);let a=this.dragState.currentLeft+s*i;if(this.config.gridSnap){0!==(a-this.config.startLeft)%i&&(a=this.config.startLeft+i*Math.round((a-this.config.startLeft)/i))}a=Math.max(this.config.startLeft,a),this.dragState.currentLeft=a,this.dragState.deltaX=this.dragState.deltaX%i;const r=t.end-t.start;let o=n(a,this.config),l=o+r;const c=this._getValidPosition(e,t.id,o,l,"move");if(o=c.start,l=c.end,this.callbacks.onActionMoving){if(!1===this.callbacks.onActionMoving({action:t,row:e,start:o,end:l}))return}t.start=o,t.end=l,this._expandTimelineIfNeeded(t.end),this._updateActionElement(t,this.dragState.rowIndex)}}_handleActionResizeLeft(){const t=this.dragState.action,e=this.dragState.row,i=this.config.gridSnap?this.config.scaleWidth/10:1;if(Math.abs(this.dragState.deltaX)>=i){const s=parseInt(this.dragState.deltaX/i);let a=this.dragState.currentLeft+s*i;if(this.config.gridSnap){0!==(a-this.config.startLeft)%i&&(a=this.config.startLeft+i*Math.round((a-this.config.startLeft)/i))}const r=this.dragState.currentLeft+this.dragState.currentWidth;a=Math.max(this.config.startLeft,a);const o=10;a=Math.min(a,r-o);const l=r-a;this.dragState.currentLeft=a,this.dragState.currentWidth=l,this.dragState.deltaX=this.dragState.deltaX%i;let c=Math.max(0,n(a,this.config));const d=t.end;if(c=this._getValidPosition(e,t.id,c,d,"resize-left").start,this.callbacks.onActionResizing){if(!1===this.callbacks.onActionResizing({action:t,row:e,start:c,end:d}))return}t.start=c,this._updateActionElement(t,this.dragState.rowIndex)}}_handleActionResizeRight(){const t=this.dragState.action,e=this.dragState.row,i=this.config.gridSnap?this.config.scaleWidth/10:1;if(Math.abs(this.dragState.deltaX)>=i){const s=parseInt(this.dragState.deltaX/i);let a=this.dragState.currentWidth+s*i;const r=this.dragState.currentLeft+a;if(this.config.gridSnap){if(0!==(r-this.config.startLeft)%i){a=this.config.startLeft+i*Math.round((r-this.config.startLeft)/i)-this.dragState.currentLeft}}const o=10;a=Math.max(o,a),this.dragState.currentWidth=a,this.dragState.deltaX=this.dragState.deltaX%i;const l=this.dragState.currentLeft+a,c=t.start;let d=Math.max(c+.1,n(l,this.config));if(d=this._getValidPosition(e,t.id,c,d,"resize-right").end,this.callbacks.onActionResizing){if(!1===this.callbacks.onActionResizing({action:t,row:e,start:c,end:d}))return}t.end=d,this._expandTimelineIfNeeded(t.end),this._updateActionElement(t,this.dragState.rowIndex)}}_updateActionElement(t,e){const i=this.editAreaEl.querySelector(`[data-row-index="${e}"]`);if(!i)return;const n=i.querySelector(`[data-action-id="${t.id}"]`);if(!n)return;const a=this.config.contentPadding,r=s(t.start,this.config)-this.config.startLeft+a,o=s(t.end,this.config)-this.config.startLeft+a-r;n.style.left=`${r}px`,n.style.width=`${o}px`}}customElements.get("trakk-editor")||customElements.define("trakk-editor",a),t.Trakk=a});
|
|
2
2
|
//# sourceMappingURL=trakk.js.map
|