From c48eeb01bd726895dc577d8b843b2a75883eee07 Mon Sep 17 00:00:00 2001 From: Ananya Sen Date: Fri, 10 Feb 2012 16:03:52 -0800 Subject: Merge from /joseeight/ninja-internal/tree/FileIO Signed-off-by: Ananya Sen --- .../Timeline/TimelineTrack.reel/TimelineTrack.js | 433 +++++++++++++++++++++ 1 file changed, 433 insertions(+) create mode 100644 js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js (limited to 'js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js') diff --git a/js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js b/js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js new file mode 100644 index 00000000..62688825 --- /dev/null +++ b/js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js @@ -0,0 +1,433 @@ +var Montage = require("montage/core/core").Montage; +var Component = require("montage/ui/component").Component; +var Collapser = require("js/panels/Timeline/Collapser").Collapser; +var defaultEventManager = require("montage/core/event/event-manager").defaultEventManager; + +var TimelineTrack = exports.TimelineTrack = Montage.create(Component, { + + hasTemplate:{ + value:true + }, + + _trackID:{ + value:null, + writable:true, + serializable:true, + enumerable:true + }, + + trackID:{ + serializable:true, + get:function () { + return this._trackID; + }, + set:function (value) { + this._trackID = value; + this.needsDraw = true; + } + }, + + // Are the various collapsers collapsed or not + _isMainCollapsed:{ + value:"" + }, + isMainCollapsed:{ + get:function () { + return this._isMainCollapsed; + }, + set:function (newVal) { + if (newVal !== this._isMainCollapsed) { + this._isMainCollapsed = newVal; + this.needsDraw = true; + } + + } + }, + _isTransformCollapsed:{ + value:true + }, + isTransformCollapsed:{ + get:function () { + return this._isTransformCollapsed; + }, + set:function (newVal) { + if (newVal !== this._isTransformCollapsed) { + this._isTransformCollapsed = newVal; + this.needsDraw = true; + } + } + }, + _isPositionCollapsed:{ + value:true + }, + isPositionCollapsed:{ + get:function () { + return this._isPositionCollapsed; + }, + set:function (newVal) { + if (newVal !== this._isPositionCollapsed) { + this._isPositionCollapsed = newVal; + this.needsDraw = true; + } + } + }, + _isStyleCollapsed:{ + value:true + }, + isStyleCollapsed:{ + get:function () { + return this._isStyleCollapsed; + }, + set:function (newVal) { + if (newVal !== this._isStyleCollapsed) { + this._isStyleCollapsed = newVal; + this.needsDraw = true; + } + } + }, + + _tweens:{ + serializable:true, + enumerable:true, + value:[] + }, + + tweens:{ + serializable:true, + enumerable:true, + get:function () { + return this._spans; + }, + set:function (newVal) { + this._spans = newVal; + } + }, + + _tweenRepetition:{ + serializable:true, + value:null + }, + + tweenRepetition:{ + serializable:true, + get:function () { + return this._spanRepetition; + }, + set:function (newVal) { + this._spanRepetition = newVal; + } + }, + + trackDuration:{ + value:0 + }, + + currentKeyframeRule:{ + value:null + }, + + nextKeyframe:{ + value:1 + }, + + currentMillisecClicked:{ + value:0 + }, + + isAnimated:{ + value:false + }, + + _animatedElement:{ + serializable:true, + enumerable:true, + writable:true, + value:null + }, + + animatedElement:{ + serializable:true, + get:function () { + return this._animatedElement; + }, + set:function (val) { + this._animatedElement = val; + } + }, + + animationName:{ + value:null + }, + + keyFramePropertyData:{ + value:[] + }, + + ninjaStylesContoller:{ + value:null + }, + + _positionCollapser:{ + value:null + }, + _mainCollapser:{ + value:null + }, + _transformCollapser:{ + value:null + }, + _styleCollapser:{ + value:null + }, + + prepareForDraw:{ + value:function () { + this.init(); + this.ninjaStylesContoller = this.application.ninja.stylesController; + this.track_lane.addEventListener("click", this, false); + this.keyFramePropertyData = new Array(); + } + }, + + draw:{ + value:function () { + if (this._mainCollapser.isCollapsed !== this.isMainCollapsed) { + this._mainCollapser.toggle(false); + } + if (this._positionCollapser.isCollapsed !== this.isPositionCollapsed) { + this._positionCollapser.toggle(false); + } + if (this._transformCollapser.isCollapsed !== this.isTransformCollapsed) { + this._transformCollapser.toggle(false); + } + if (this._styleCollapser.isCollapsed !== this.isStyleCollapsed) { + this._styleCollapser.toggle(false); + } + } + }, + + handleClick:{ + value:function (ev) { + // TEMP - if the SHIFT key is down, add a new keyframe or split an existing span + // This needs to move to a keyboard shortcut that is TBD + if (ev.shiftKey) { + if (this.application.ninja.timeline.arrLayers[this.trackID - 1].element.length == 1) { + if (this.tweens.length < 1) { + this.insertTween(0); + this.addAnimationRuleToElement(ev); + } else { + this.handleNewTween(ev); + } + } else { + alert("There must be exactly one element in an animated layer.") + } + } + } + }, + + handleNewTween:{ + value:function (ev) { + if (ev.offsetX > this.tweens[this.tweens.length - 1].keyFramePosition) { + this.insertTween(ev.offsetX); + } else { + this.splitTween(ev); + } + } + }, + + insertTween:{ + value:function (clickPos) { + + // calculate new tween's keyframe percent by clickPos + var currentMillisecPerPixel = Math.floor(this.application.ninja.timeline.millisecondsOffset / 80); + var currentMillisec = currentMillisecPerPixel * clickPos; + + // need to check timeline master duration if greater than this track duration + this.trackDuration = currentMillisec; + + var newTween = {}; + if (clickPos == 0) { + newTween.spanWidth = 0; + newTween.keyFramePosition = 0; + newTween.keyFrameMillisec = 0; + newTween.keyframeID = 0; + newTween.spanPosition = 0; + newTween.timelineTrack = this; + this.tweens.push(newTween); + } else { + newTween.spanWidth = clickPos - this.tweens[this.tweens.length - 1].keyFramePosition; + newTween.keyFramePosition = clickPos; + newTween.keyFrameMillisec = currentMillisec; + newTween.keyframeID = this.nextKeyframe; + newTween.spanPosition = clickPos - newTween.spanWidth; + newTween.timelineTrack = this; + this.tweens.push(newTween); + + var animatedProperties = new Array(); + animatedProperties["top"] = this.keyFramePropertyData[0]["top"]; + animatedProperties["left"] = this.keyFramePropertyData[0]["left"]; + this.keyFramePropertyData[this.nextKeyframe] = animatedProperties; + + // update the animation duration + var animationDuration = Math.round(this.trackDuration / 1000) + "s"; + this.ninjaStylesContoller.setElementStyle(this.animatedElement, "-webkit-animation-duration", animationDuration); + + this.nextKeyframe += 1; + } + } + }, + + splitTween:{ + value:function (ev) { + alert("Splitting an existing span with a new keyframe is not yet supported.") + //console.log("splitting tween at span offsetX: " + ev.offsetX); + } + }, + + addAnimationRuleToElement:{ + value:function (tweenEvent) { + this.animatedElement = this.application.ninja.timeline.currentLayerSelected.element[0]; + var initAnimatedProperties = new Array(); + initAnimatedProperties["top"] = this.animatedElement.offsetTop; + initAnimatedProperties["left"] = this.animatedElement.offsetLeft; + this.keyFramePropertyData[0] = initAnimatedProperties; + + var animationDuration = Math.round(this.trackDuration / 1000) + "s"; + this.animationName = this.animatedElement.className + this.trackID; + + this.ninjaStylesContoller.setElementStyle(this.animatedElement, "-webkit-animation-name", this.animationName); + this.ninjaStylesContoller.setElementStyle(this.animatedElement, "-webkit-animation-duration", animationDuration); + this.ninjaStylesContoller.setElementStyle(this.animatedElement, "-webkit-animation-iteration-count", "infinite"); + + var initRule = "@-webkit-keyframes " + this.animationName + " { 0% {top: " + this.animatedElement.offsetTop + "px; left: " + this.animatedElement.offsetLeft + "px;} 100% {top: " + this.animatedElement.offsetTop + "px; left: " + this.animatedElement.offsetLeft + "px;} }"; + this.currentKeyframeRule = this.ninjaStylesContoller.addRule(initRule); + + this.isAnimated = true; + + this.insertTween(tweenEvent.offsetX); + } + }, + + updateKeyframeRule:{ + value:function () { + // delete the current rule + this.ninjaStylesContoller.deleteRule(this.currentKeyframeRule); + + // build the new keyframe string + var keyframeString = "@-webkit-keyframes " + this.animationName + " {"; + + for (var i = 0; i < this.keyFramePropertyData.length; i++) { + + var keyframePercent = Math.round((this.tweens[i].keyFrameMillisec / this.trackDuration) * 100) + "%"; + + var keyframePropertyString = " " + keyframePercent + " {"; + keyframePropertyString += "top: " + this.keyFramePropertyData[i]["top"] + "px;"; + keyframePropertyString += " left: " + this.keyFramePropertyData[i]["left"] + "px;"; + keyframePropertyString += "}"; + keyframeString += keyframePropertyString; + } + keyframeString += " }"; + + // set the keyframe string as the new rule + this.currentKeyframeRule = this.ninjaStylesContoller.addRule(keyframeString); + } + }, + + // Init and event handler for layer expand/collapse + init:{ + value:function () { + var that = this; + + this.label = this.element.querySelector(".label-main"); + this.myContent = this.element.querySelector(".content-main"); + this.labelPosition = this.element.querySelector(".label-position"); + this.contentPosition = this.element.querySelector(".content-position"); + this.labelTransform = this.element.querySelector(".label-transform"); + this.contentTransform = this.element.querySelector(".content-transform"); + this.labelStyles = this.element.querySelector(".label-styles"); + this.contentStyles = this.element.querySelector(".content-styles"); + + this._mainCollapser = Collapser.create(); + this._mainCollapser.clicker = this.label; + this._mainCollapser.myContent = this.myContent; + this._mainCollapser.contentHeight = 60; + this._mainCollapser.isLabelClickable = false; + this._mainCollapser.element = this.element; + this._mainCollapser.isCollapsed = this.isMainCollapsed; + this._mainCollapser.isAnimated = true; + this._mainCollapser.labelClickEvent = function () { + that.isMainCollapsed = that._mainCollapser.isCollapsed; + } + this._mainCollapser.needsDraw = true; + + this._positionCollapser = Collapser.create(); + this._positionCollapser.clicker = this.labelPosition; + this._positionCollapser.myContent = this.contentPosition; + this._positionCollapser.contentHeight = 60; + this._positionCollapser.isLabelClickable = true; + this._positionCollapser.element = this.element; + this._positionCollapser.isCollapsed = this.isPositionCollapsed; + this._positionCollapser.isAnimated = true; + this._positionCollapser.labelClickEvent = function () { + that.isPositionCollapsed = that._positionCollapser.isCollapsed; + } + this._positionCollapser.needsDraw = true; + + this._transformCollapser = Collapser.create(); + this._transformCollapser.clicker = this.labelTransform; + this._transformCollapser.myContent = this.contentTransform; + this._transformCollapser.contentHeight = 100; + this._transformCollapser.isLabelClickable = false; + this._transformCollapser.element = this.element; + this._transformCollapser.isCollapsed = this.isTransformCollapsed; + this._transformCollapser.isAnimated = true; + this._transformCollapser.labelClickEvent = function () { + that.isTransformCollapsed = that._transformCollapser.isCollapsed; + } + this._transformCollapser.needsDraw = true; + + this._styleCollapser = Collapser.create(); + this._styleCollapser.clicker = this.labelStyles; + this._styleCollapser.myContent = this.contentStyles; + this._styleCollapser.contentHeight = 60; + this._styleCollapser.isLabelClickable = false; + this._styleCollapser.element = this.element; + this._styleCollapser.isCollapsed = this.isStyleCollapsed; + this._styleCollapser.isAnimated = true; + this._styleCollapser.labelClickEvent = function () { + that.isStyleCollapsed = that._styleCollapser.isCollapsed; + } + this._styleCollapser.needsDraw = true; + + // Register event handler for layer events. + var that = this; + defaultEventManager.addEventListener("layerEvent", this, false); + + } + }, + + handleLayerEvent:{ + value:function (layerEvent) { + + if (layerEvent.layerID !== this.trackID) { + return; + } + + if (layerEvent.layerEventType === "labelClick") { + if (layerEvent.layerEventLocale === "content-main") { + this._mainCollapser.bypassAnimation = layerEvent.bypassAnimation; + this._mainCollapser.toggle(); + } else if (layerEvent.layerEventLocale === "content-position") { + this._positionCollapser.bypassAnimation = layerEvent.bypassAnimation; + this._positionCollapser.handleCollapserLabelClick(); + } else if (layerEvent.layerEventLocale === "content-transform") { + this._transformCollapser.bypassAnimation = layerEvent.bypassAnimation; + this._transformCollapser.handleCollapserLabelClick(); + } else if (layerEvent.layerEventLocale === "content-style") { + this._styleCollapser.bypassAnimation = layerEvent.bypassAnimation; + this._styleCollapser.handleCollapserLabelClick(); + } + } + } + } +}); \ No newline at end of file -- cgit v1.2.3