export default class AnimationUI{constructor(animation,timeline,parentElement){this._animation=animation;this._timeline=timeline;this._parentElement=parentElement;if(this._animation.source().keyframesRule()){this._keyframes=this._animation.source().keyframesRule().keyframes();} this._nameElement=parentElement.createChild('div','animation-name');this._nameElement.textContent=this._animation.name();this._svg=parentElement.createSVGChild('svg','animation-ui');this._svg.setAttribute('height',Animation.AnimationUI.Options.AnimationSVGHeight);this._svg.style.marginLeft='-'+Animation.AnimationUI.Options.AnimationMargin+'px';this._svg.addEventListener('contextmenu',this._onContextMenu.bind(this));this._activeIntervalGroup=this._svg.createSVGChild('g');UI.installDragHandle(this._activeIntervalGroup,this._mouseDown.bind(this,Animation.AnimationUI.MouseEvents.AnimationDrag,null),this._mouseMove.bind(this),this._mouseUp.bind(this),'-webkit-grabbing','-webkit-grab');this._cachedElements=[];this._movementInMs=0;this._color=Animation.AnimationUI.Color(this._animation);} static Color(animation){const names=Object.keys(Animation.AnimationUI.Colors);const color=Animation.AnimationUI.Colors[names[String.hashCode(animation.name()||animation.id())%names.length]];return color.asString(Common.Color.Format.RGB);} animation(){return this._animation;} setNode(node){this._node=node;} _createLine(parentElement,className){const line=parentElement.createSVGChild('line',className);line.setAttribute('x1',Animation.AnimationUI.Options.AnimationMargin);line.setAttribute('y1',Animation.AnimationUI.Options.AnimationHeight);line.setAttribute('y2',Animation.AnimationUI.Options.AnimationHeight);line.style.stroke=this._color;return line;} _drawAnimationLine(iteration,parentElement){const cache=this._cachedElements[iteration];if(!cache.animationLine){cache.animationLine=this._createLine(parentElement,'animation-line');} cache.animationLine.setAttribute('x2',(this._duration()*this._timeline.pixelMsRatio()+Animation.AnimationUI.Options.AnimationMargin).toFixed(2));} _drawDelayLine(parentElement){if(!this._delayLine){this._delayLine=this._createLine(parentElement,'animation-delay-line');this._endDelayLine=this._createLine(parentElement,'animation-delay-line');} const fill=this._animation.source().fill();this._delayLine.classList.toggle('animation-fill',fill==='backwards'||fill==='both');const margin=Animation.AnimationUI.Options.AnimationMargin;this._delayLine.setAttribute('x1',margin);this._delayLine.setAttribute('x2',(this._delay()*this._timeline.pixelMsRatio()+margin).toFixed(2));const forwardsFill=fill==='forwards'||fill==='both';this._endDelayLine.classList.toggle('animation-fill',forwardsFill);const leftMargin=Math.min(this._timeline.width(),(this._delay()+this._duration()*this._animation.source().iterations())*this._timeline.pixelMsRatio());this._endDelayLine.style.transform='translateX('+leftMargin.toFixed(2)+'px)';this._endDelayLine.setAttribute('x1',margin);this._endDelayLine.setAttribute('x2',forwardsFill?(this._timeline.width()-leftMargin+margin).toFixed(2):(this._animation.source().endDelay()*this._timeline.pixelMsRatio()+margin).toFixed(2));} _drawPoint(iteration,parentElement,x,keyframeIndex,attachEvents){if(this._cachedElements[iteration].keyframePoints[keyframeIndex]){this._cachedElements[iteration].keyframePoints[keyframeIndex].setAttribute('cx',x.toFixed(2));return;} const circle=parentElement.createSVGChild('circle',keyframeIndex<=0?'animation-endpoint':'animation-keyframe-point');circle.setAttribute('cx',x.toFixed(2));circle.setAttribute('cy',Animation.AnimationUI.Options.AnimationHeight);circle.style.stroke=this._color;circle.setAttribute('r',Animation.AnimationUI.Options.AnimationMargin/2);if(keyframeIndex<=0){circle.style.fill=this._color;} this._cachedElements[iteration].keyframePoints[keyframeIndex]=circle;if(!attachEvents){return;} let eventType;if(keyframeIndex===0){eventType=Animation.AnimationUI.MouseEvents.StartEndpointMove;}else if(keyframeIndex===-1){eventType=Animation.AnimationUI.MouseEvents.FinishEndpointMove;}else{eventType=Animation.AnimationUI.MouseEvents.KeyframeMove;} UI.installDragHandle(circle,this._mouseDown.bind(this,eventType,keyframeIndex),this._mouseMove.bind(this),this._mouseUp.bind(this),'ew-resize');} _renderKeyframe(iteration,keyframeIndex,parentElement,leftDistance,width,easing){function createStepLine(parentElement,x,strokeColor){const line=parentElement.createSVGChild('line');line.setAttribute('x1',x);line.setAttribute('x2',x);line.setAttribute('y1',Animation.AnimationUI.Options.AnimationMargin);line.setAttribute('y2',Animation.AnimationUI.Options.AnimationHeight);line.style.stroke=strokeColor;} const bezier=UI.Geometry.CubicBezier.parse(easing);const cache=this._cachedElements[iteration].keyframeRender;if(!cache[keyframeIndex]){cache[keyframeIndex]=bezier?parentElement.createSVGChild('path','animation-keyframe'):parentElement.createSVGChild('g','animation-keyframe-step');} const group=cache[keyframeIndex];group.style.transform='translateX('+leftDistance.toFixed(2)+'px)';if(easing==='linear'){group.style.fill=this._color;const height=InlineEditor.BezierUI.Height;group.setAttribute('d',['M',0,height,'L',0,5,'L',width.toFixed(2),5,'L',width.toFixed(2),height,'Z'].join(' '));}else if(bezier){group.style.fill=this._color;InlineEditor.BezierUI.drawVelocityChart(bezier,group,width);}else{const stepFunction=Animation.AnimationTimeline.StepTimingFunction.parse(easing);group.removeChildren();const offsetMap={'start':0,'middle':0.5,'end':1};const offsetWeight=offsetMap[stepFunction.stepAtPosition];for(let i=0;i1);for(let i=0;i0&&ithis._timeline.duration()*0.8){this._timeline.setDuration(this._timeline.duration()*1.2);} this.redraw();} _mouseUp(event){this._movementInMs=(event.clientX-this._downMouseX)/this._timeline.pixelMsRatio();if(this._mouseEventType===Animation.AnimationUI.MouseEvents.KeyframeMove){this._keyframes[this._keyframeMoved].setOffset(this._offset(this._keyframeMoved));}else{this._animation.setTiming(this._duration(),this._delay());} this._movementInMs=0;this.redraw();delete this._mouseEventType;delete this._downMouseX;delete this._keyframeMoved;} _onContextMenu(event){function showContextMenu(remoteObject){if(!remoteObject){return;} const contextMenu=new UI.ContextMenu(event);contextMenu.appendApplicableItems(remoteObject);contextMenu.show();} this._animation.remoteObjectPromise().then(showContextMenu);event.consume(true);}} export const MouseEvents={AnimationDrag:'AnimationDrag',KeyframeMove:'KeyframeMove',StartEndpointMove:'StartEndpointMove',FinishEndpointMove:'FinishEndpointMove'};export const Options={AnimationHeight:26,AnimationSVGHeight:50,AnimationMargin:7,EndpointsClickRegionSize:10,GridCanvasHeight:40};export const Colors={'Purple':Common.Color.parse('#9C27B0'),'Light Blue':Common.Color.parse('#03A9F4'),'Deep Orange':Common.Color.parse('#FF5722'),'Blue':Common.Color.parse('#5677FC'),'Lime':Common.Color.parse('#CDDC39'),'Blue Grey':Common.Color.parse('#607D8B'),'Pink':Common.Color.parse('#E91E63'),'Green':Common.Color.parse('#0F9D58'),'Brown':Common.Color.parse('#795548'),'Cyan':Common.Color.parse('#00BCD4')};self.Animation=self.Animation||{};Animation=Animation||{};Animation.AnimationUI=AnimationUI;Animation.AnimationUI.MouseEvents=MouseEvents;Animation.AnimationUI.Options=Options;Animation.AnimationUI.Colors=Colors;