script.aculo.usを読み解く

第6回 effects.js(後編)基礎エフェクトの組み合わせからなる15種類の複合エフェクト

この記事を読むのに必要な時間:およそ 23.5 分

Effect.Shrink

0826:Effect.Shrink = function(element) {
0827:  element = $(element);
0828:  var options = Object.extend({
0829:    direction: 'center',
0830:    moveTransition: Effect.Transitions.sinoidal,
0831:    scaleTransition: Effect.Transitions.sinoidal,
0832:    opacityTransition: Effect.Transitions.none
0833:  }, arguments[1] || { });
0834:  var oldStyle = {
0835:    top: element.style.top,
0836:    left: element.style.left,
0837:    height: element.style.height,
0838:    width: element.style.width,
0839:    opacity: element.getInlineOpacity() };
0840:
0841:  var dims = element.getDimensions();
0842:  var moveX, moveY;
0843:  
0844:  switch (options.direction) {
0845:    case 'top-left':
0846:      moveX = moveY = 0;
0847:      break;
0848:    case 'top-right':
0849:      moveX = dims.width;
0850:      moveY = 0;
0851:      break;
0852:    case 'bottom-left':
0853:      moveX = 0;
0854:      moveY = dims.height;
0855:      break;
0856:    case 'bottom-right':
0857:      moveX = dims.width;
0858:      moveY = dims.height;
0859:      break;
0860:    case 'center':  
0861:      moveX = dims.width / 2;
0862:      moveY = dims.height / 2;
0863:      break;
0864:  }
0865:  
0866:  return new Effect.Parallel(
0867:    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
0868:      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
0869:      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
0870:    ], Object.extend({            
0871:         beforeStartInternal: function(effect) {
0872:           effect.effects[0].element.makePositioned().makeClipping(); 
0873:         },
0874:         afterFinishInternal: function(effect) {
0875:           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
0876:       }, options)
0877:  );
0878:};
0879:

826~879行目のEffect.Shrinkは,吸い込まれるように縮小して消えるエフェクトです。吸い込まれる方向を選べるようになっています。吸い込むエフェクトは,Effect.OpacityとEffect.MoveとEffect.ScaleをEffect.Parallelで並列に動かすことからできています。Effect.Growのように出発点に移動する必要はありません。

Effect.Growとほとんど同じなので,解説は省略します。

'top-left'
'top-right'
'bottom-left'
'bottom-right'
'center'

Effect.Pulsate

0880:Effect.Pulsate = function(element) {
0881:  element = $(element);
0882:  var options    = arguments[1] || { };
0883:  var oldOpacity = element.getInlineOpacity();
0884:  var transition = options.transition || Effect.Transitions.sinoidal;
0885:  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
0886:  reverser.bind(transition);
0887:  return new Effect.Opacity(element, 
0888:    Object.extend(Object.extend({  duration: 2.0, from: 0,
0889:      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
0890:    }, options), {transition: reverser}));
0891:};
0892:

880~892行目のEffect.Pulsateは,透明と不透明の間で点滅するエフェクトです。Effect.Opacityでできています。

883行目で,要素の透明度を保存します。エフェクト後に元に戻すためです。

884行目で,透明度の変化の元となる関数をオプションから設定します。デフォルトはsinoidalです。

885行目で,pulse関数をx軸対称にしたものに,先ほどのtransitionの関数を適用する関数です。オプションでパルスの回数を与えることができます。

886行目で、bindメソッドを使っていますが、結果を受けていないので、意味がありません。バグでしょう。

887行目で,Effect.Opacityを以下のオプションでかけます。

888行目で,デフォルトでは、持続時間は2.0秒、初期透明度は0(透明)です。

889行目で,終了後のフックで,要素の透明度を元に戻します。

890行目で,transitionには先ほどのreverserを使います。

Effect.Fold

0893:Effect.Fold = function(element) {
0894:  element = $(element);
0895:  var oldStyle = {
0896:    top: element.style.top,
0897:    left: element.style.left,
0898:    width: element.style.width,
0899:    height: element.style.height };
0900:  element.makeClipping();
0901:  return new Effect.Scale(element, 5, Object.extend({   
0902:    scaleContent: false,
0903:    scaleX: false,
0904:    afterFinishInternal: function(effect) {
0905:    new Effect.Scale(element, 1, { 
0906:      scaleContent: false, 
0907:      scaleY: false,
0908:      afterFinishInternal: function(effect) {
0909:        effect.element.hide().undoClipping().setStyle(oldStyle);
0910:      } });
0911:  }}, arguments[1] || { }));
0912:};
0913:

893~913行目のEffect.Foldは,縦に縮んだあと,横に縮むエフェクトです。Effect.Scaleを2段使ってできています。

895~899行目で,要素の位置と大きさを保存します。エフェクト後に元に戻すためです。

900行目で,makePositionedでpositionを'relative'にして,移動に備えます。

901行目で,Effect.Scaleを倍率5%(かなり小さい)でかけます。オプションは以下です。これで縦に縮めます。

902行目で,要素の内容のフォントサイズは変えません。

903行目で,横幅は変えません。

904行目で,終了後のフックで,もう一段のEffect.Scaleを倍率1%(とても小さい)でかけます。オプションは以下です。これで横に縮めます。

906行目で,要素の内容のフォントサイズは変えません。

907行目で,縦幅は変えません。

908行目で,終了後のフックで,要素を隠すとともに,要素をundoClippingしてoverflowを元に戻し,位置と大きさを元に戻します。

著者プロフィール

源馬照明(げんまてるあき)

名古屋大学大学院多元数理科学研究科1年。学部生のときにSchemeの素晴らしさを知ったのをきっかけに,関数型言語の世界へ。JavaScriptに,ブラウザからすぐに試せる関数型言語としての魅力と将来性を感じている。

ブログ:Gemmaの日記

コメント

コメントの記入