前回の基礎エフェクトの解説に引き続いて、
このような複雑でドラマチックなエフェクトが、
Effect. | フェードアウトするエフェクト | Effect. | フェードインするエフェクト | Effect. | ホワッと消えるエフェクト | Effect. | すだれを上げるようなエフェクト | Effect. | すだれを降ろすようなエフェクト | Effect. | テレビのスイッチを切るように消えるエフェクト | Effect. | ポロリと落ちるように消えるエフェクト | Effect. | ブルブルと左右に震えるエフェクト | Effect. | お店のシャッターを降ろすようなエフェクト | Effect. | お店のシャッターを上げるようなエフェクト | Effect. | 縮小して消えるエフェクト | Effect. | 飛び出すように拡大して現れるエフェクト | Effect. | 吸い込まれるように縮小して消えるエフェクト | Effect. | 透明と不透明の間で点滅するエフェクト | Effect. | 縦に縮んだあと、 |
---|
それでは前回の続きからコードを見ていきましょう。
Effect.Fade
0526:/* ------------- combination effects ------------- */
0527:
0528:Effect.Fade = function(element) {
0529: element = $(element);
0530: var oldOpacity = element.getInlineOpacity();
0531: var options = Object.extend({
0532: from: element.getOpacity() || 1.0,
0533: to: 0.0,
0534: afterFinishInternal: function(effect) {
0535: if (effect.options.to!=0) return;
0536: effect.element.hide().setStyle({opacity: oldOpacity});
0537: }
0538: }, arguments[1] || { });
0539: return new Effect.Opacity(element,options);
0540:};
0541:
526~541行目のEffect.

530行目で、
532行目で、
533行目で、
534行目で、
536行目の、hideメソッドとsetStyleメソッドのチェーンが美しいです。
539行目で、
Effect.Appear
0542:Effect.Appear = function(element) {
0543: element = $(element);
0544: var options = Object.extend({
0545: from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
0546: to: 1.0,
0547: // force Safari to render floated elements properly
0548: afterFinishInternal: function(effect) {
0549: effect.element.forceRerendering();
0550: },
0551: beforeSetup: function(effect) {
0552: effect.element.setOpacity(effect.options.from).show();
0553: }}, arguments[1] || { });
0554: return new Effect.Opacity(element,options);
0555:};
0556:
542~556行目のEffect.

545行目で、
546行目で、
548行目で、
551行目で、
554行目で、
Effect.Puff
0557:Effect.Puff = function(element) {
0558: element = $(element);
0559: var oldStyle = {
0560: opacity: element.getInlineOpacity(),
0561: position: element.getStyle('position'),
0562: top: element.style.top,
0563: left: element.style.left,
0564: width: element.style.width,
0565: height: element.style.height
0566: };
0567: return new Effect.Parallel(
0568: [ new Effect.Scale(element, 200,
0569: { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
0570: new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
0571: Object.extend({ duration: 1.0,
0572: beforeSetupInternal: function(effect) {
0573: Position.absolutize(effect.effects[0].element)
0574: },
0575: afterFinishInternal: function(effect) {
0576: effect.effects[0].element.hide().setStyle(oldStyle); }
0577: }, arguments[1] || { })
0578: );
0579:};
0580:
557~580行目のEffect.

559~566行目で、
567行目で、
568行目で、
570行目で、
572行目で、
575行目で、
Effect.BlindUp
0581:Effect.BlindUp = function(element) {
0582: element = $(element);
0583: element.makeClipping();
0584: return new Effect.Scale(element, 0,
0585: Object.extend({ scaleContent: false,
0586: scaleX: false,
0587: restoreAfterFinish: true,
0588: afterFinishInternal: function(effect) {
0589: effect.element.hide().undoClipping();
0590: }
0591: }, arguments[1] || { })
0592: );
0593:};
0594:
581~594行目のEffect.

583行目で、
584行目で、
585行目で、
586行目で、
587行目で、
588行目で、
Effect.BlindDown
0595:Effect.BlindDown = function(element) {
0596: element = $(element);
0597: var elementDimensions = element.getDimensions();
0598: return new Effect.Scale(element, 100, Object.extend({
0599: scaleContent: false,
0600: scaleX: false,
0601: scaleFrom: 0,
0602: scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
0603: restoreAfterFinish: true,
0604: afterSetup: function(effect) {
0605: effect.element.makeClipping().setStyle({height: '0px'}).show();
0606: },
0607: afterFinishInternal: function(effect) {
0608: effect.element.undoClipping();
0609: }
0610: }, arguments[1] || { }));
0611:};
0612:
595~612行目のEffect.

597行目で、
598行目で、
599行目で、
600行目で、
601行目で、
602行目で、
603行目で、
604行目で、
607行目で、
Effect.SwitchOff
0613:Effect.SwitchOff = function(element) {
0614: element = $(element);
0615: var oldOpacity = element.getInlineOpacity();
0616: return new Effect.Appear(element, Object.extend({
0617: duration: 0.4,
0618: from: 0,
0619: transition: Effect.Transitions.flicker,
0620: afterFinishInternal: function(effect) {
0621: new Effect.Scale(effect.element, 1, {
0622: duration: 0.3, scaleFromCenter: true,
0623: scaleX: false, scaleContent: false, restoreAfterFinish: true,
0624: beforeSetup: function(effect) {
0625: effect.element.makePositioned().makeClipping();
0626: },
0627: afterFinishInternal: function(effect) {
0628: effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
0629: }
0630: })
0631: }
0632: }, arguments[1] || { }));
0633:};
0634:
613~634行目のEffect.

615行目で、
616行目で、
617行目で、
618行目で、
619行目で、
620行目で、
622行目で、
623行目で、
624行目で、
627行目で、
Effect.DropOut
0635:Effect.DropOut = function(element) {
0636: element = $(element);
0637: var oldStyle = {
0638: top: element.getStyle('top'),
0639: left: element.getStyle('left'),
0640: opacity: element.getInlineOpacity() };
0641: return new Effect.Parallel(
0642: [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
0643: new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
0644: Object.extend(
0645: { duration: 0.5,
0646: beforeSetup: function(effect) {
0647: effect.effects[0].element.makePositioned();
0648: },
0649: afterFinishInternal: function(effect) {
0650: effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
0651: }
0652: }, arguments[1] || { }));
0653:};
0654:
635~654行目のEffect.

637行目で、
641行目で、
642行目で、
643行目で、
645行目で、
646行目で、
649行目で、
Effect.Shake
0655:Effect.Shake = function(element) {
0656: element = $(element);
0657: var options = Object.extend({
0658: distance: 20,
0659: duration: 0.5
0660: }, arguments[1] || {});
0661: var distance = parseFloat(options.distance);
0662: var split = parseFloat(options.duration) / 10.0;
0663: var oldStyle = {
0664: top: element.getStyle('top'),
0665: left: element.getStyle('left') };
0666: return new Effect.Move(element,
0667: { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) {
0668: new Effect.Move(effect.element,
0669: { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
0670: new Effect.Move(effect.element,
0671: { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
0672: new Effect.Move(effect.element,
0673: { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
0674: new Effect.Move(effect.element,
0675: { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
0676: new Effect.Move(effect.element,
0677: { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
0678: effect.element.undoPositioned().setStyle(oldStyle);
0679: }}) }}) }}) }}) }}) }});
0680:};
0681:
655~681行目のEffect.

658行目で、
659行目で、
661行目で、
662行目で、
663~665行目で、
666~679行目で、
右に20px動かします。左に40px動かします。右に40px動かします。左に40px動かします。右に40px動かします。左に20px動かします。これで原点に戻ってきました。
678行目で、
ちなみに、
Effect.YetanotherShake = function (element) {
element = $(element);
var options = Object.extend({distance:20, duration:0.5}, arguments[1] || {});
var distance = parseFloat(options.distance) * 2;
var oldStyle = {top:element.getStyle("top"), left:element.getStyle("left")};
options = Object.extend({x:distance, y:0, transition:function(pos){
return (Math.sin(6*pos*Math.PI)/2)
}, afterFinish: function(effect) {
effect.element.undoPositioned().setStyle(oldStyle)
}},options);
return new Effect.Move(element, options);
}
Effect.SlideDown
0682:Effect.SlideDown = function(element) {
0683: element = $(element).cleanWhitespace();
0684: // SlideDown need to have the content of the element wrapped in a container element with fixed height!
0685: var oldInnerBottom = element.down().getStyle('bottom');
0686: var elementDimensions = element.getDimensions();
0687: return new Effect.Scale(element, 100, Object.extend({
0688: scaleContent: false,
0689: scaleX: false,
0690: scaleFrom: window.opera ? 0 : 1,
0691: scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
0692: restoreAfterFinish: true,
0693: afterSetup: function(effect) {
0694: effect.element.makePositioned();
0695: effect.element.down().makePositioned();
0696: if (window.opera) effect.element.setStyle({top: ''});
0697: effect.element.makeClipping().setStyle({height: '0px'}).show();
0698: },
0699: afterUpdateInternal: function(effect) {
0700: effect.element.down().setStyle({bottom:
0701: (effect.dims[0] - effect.element.clientHeight) + 'px' });
0702: },
0703: afterFinishInternal: function(effect) {
0704: effect.element.undoClipping().undoPositioned();
0705: effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
0706: }, arguments[1] || { })
0707: );
0708:};
0709:
682~709行目のEffect.

683行目で、
685行目で、
686行目で、
687行目で、
688行目で、
689行目で、
690行目で、
691行目で、
692行目で、
693行目で、
694行目で、
696行目で、
697行目で、
699行目で、
703行目で、
705行目で、
Effect.SlideUp
0710:Effect.SlideUp = function(element) {
0711: element = $(element).cleanWhitespace();
0712: var oldInnerBottom = element.down().getStyle('bottom');
0713: var elementDimensions = element.getDimensions();
0714: return new Effect.Scale(element, window.opera ? 0 : 1,
0715: Object.extend({ scaleContent: false,
0716: scaleX: false,
0717: scaleMode: 'box',
0718: scaleFrom: 100,
0719: scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
0720: restoreAfterFinish: true,
0721: afterSetup: function(effect) {
0722: effect.element.makePositioned();
0723: effect.element.down().makePositioned();
0724: if (window.opera) effect.element.setStyle({top: ''});
0725: effect.element.makeClipping().show();
0726: },
0727: afterUpdateInternal: function(effect) {
0728: effect.element.down().setStyle({bottom:
0729: (effect.dims[0] - effect.element.clientHeight) + 'px' });
0730: },
0731: afterFinishInternal: function(effect) {
0732: effect.element.hide().undoClipping().undoPositioned();
0733: effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
0734: }
0735: }, arguments[1] || { })
0736: );
0737:};
0738:
710~738行目のEffect.
717行目と719行目でscaleModeが2回登場するのはバグでしょう。

Effect.Squish
0739:// Bug in opera makes the TD containing this element expand for a instance after finish
0740:Effect.Squish = function(element) {
0741: return new Effect.Scale(element, window.opera ? 1 : 0, {
0742: restoreAfterFinish: true,
0743: beforeSetup: function(effect) {
0744: effect.element.makeClipping();
0745: },
0746: afterFinishInternal: function(effect) {
0747: effect.element.hide().undoClipping();
0748: }
0749: });
0750:};
0751:
739~751行目のEffect.

741行目で、
742行目で、
743行目で、
746行目で、
Effect.Grow
0752:Effect.Grow = function(element) {
0753: element = $(element);
0754: var options = Object.extend({
0755: direction: 'center',
0756: moveTransition: Effect.Transitions.sinoidal,
0757: scaleTransition: Effect.Transitions.sinoidal,
0758: opacityTransition: Effect.Transitions.full
0759: }, arguments[1] || { });
0760: var oldStyle = {
0761: top: element.style.top,
0762: left: element.style.left,
0763: height: element.style.height,
0764: width: element.style.width,
0765: opacity: element.getInlineOpacity() };
0766:
0767: var dims = element.getDimensions();
0768: var initialMoveX, initialMoveY;
0769: var moveX, moveY;
0770:
0771: switch (options.direction) {
0772: case 'top-left':
0773: initialMoveX = initialMoveY = moveX = moveY = 0;
0774: break;
0775: case 'top-right':
0776: initialMoveX = dims.width;
0777: initialMoveY = moveY = 0;
0778: moveX = -dims.width;
0779: break;
0780: case 'bottom-left':
0781: initialMoveX = moveX = 0;
0782: initialMoveY = dims.height;
0783: moveY = -dims.height;
0784: break;
0785: case 'bottom-right':
0786: initialMoveX = dims.width;
0787: initialMoveY = dims.height;
0788: moveX = -dims.width;
0789: moveY = -dims.height;
0790: break;
0791: case 'center':
0792: initialMoveX = dims.width / 2;
0793: initialMoveY = dims.height / 2;
0794: moveX = -dims.width / 2;
0795: moveY = -dims.height / 2;
0796: break;
0797: }
0798:
0799: return new Effect.Move(element, {
0800: x: initialMoveX,
0801: y: initialMoveY,
0802: duration: 0.01,
0803: beforeSetup: function(effect) {
0804: effect.element.hide().makeClipping().makePositioned();
0805: },
0806: afterFinishInternal: function(effect) {
0807: new Effect.Parallel(
0808: [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
0809: new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
0810: new Effect.Scale(effect.element, 100, {
0811: scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
0812: sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
0813: ], Object.extend({
0814: beforeSetup: function(effect) {
0815: effect.effects[0].element.setStyle({height: '0px'}).show();
0816: },
0817: afterFinishInternal: function(effect) {
0818: effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
0819: }
0820: }, options)
0821: )
0822: }
0823: });
0824:};
0825:
752~825行目のEffect.

754~759行目で、
755行目で、
756行目で、
757行目で、
758行目で、
760~765行目で、
767行目で、
768行目で、
769行目で、
771~797行目で、
'top-left' | ![]() | 移動する必要がありません。Effect. |
---|---|---|
'top-right' | ![]() | 右上の出発点が動いていないように見せるため、 |
'bottom-left' | ![]() | 同様に、 |
'bottom-right' | ![]() | 同様に、 |
'center' | ![]() | 同様に、 |
799行目で、
803行目で、
806行目で、
808行目で、
809行目で、
810行目で、
814行目で、
817行目で、
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.

Effect.
'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.

883行目で、
884行目で、
885行目で、
886行目で、bindメソッドを使っていますが、結果を受けていないので、意味がありません。バグでしょう。
887行目で、
888行目で、
889行目で、
890行目で、
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.

895~899行目で、
900行目で、
901行目で、
902行目で、
903行目で、
904行目で、
906行目で、
907行目で、
908行目で、
その他のエフェクト
Effect.Morph
914~1003行目のEffect.
new Effect.Morph('error_message',{
style:'background:#f00; color:#fff;'+
'border: 20px solid #f88; font-size:2em',
duration:0.8
});
0914:Effect.Morph = Class.create(Effect.Base, {
0915: initialize: function(element) {
0916: this.element = $(element);
0917: if (!this.element) throw(Effect._elementDoesNotExistError);
0918: var options = Object.extend({
0919: style: { }
0920: }, arguments[1] || { });
0921:
0922: if (!Object.isString(options.style)) this.style = $H(options.style);
0923: else {
0924: if (options.style.include(':'))
0925: this.style = options.style.parseStyle();
0926: else {
0927: this.element.addClassName(options.style);
0928: this.style = $H(this.element.getStyles());
0929: this.element.removeClassName(options.style);
0930: var css = this.element.getStyles();
0931: this.style = this.style.reject(function(style) {
0932: return style.value == css[style.key];
0933: });
0934: options.afterFinishInternal = function(effect) {
0935: effect.element.addClassName(effect.options.style);
0936: effect.transforms.each(function(transform) {
0937: effect.element.style[transform.style] = '';
0938: });
0939: }
0940: }
0941: }
0942: this.start(options);
0943: },
0944:
915~944行目のinitializeは、
918行目で、
options.
922行目で、
924行目で、
926行目で、CSSクラス名の方法なら、以下の処理をします。
927行目で、一時的にそのクラス名を要素に追加します。
928行目で、要素のCSSスタイルを取得して、ハッシュテーブルにします。
929行目で、そのクラス名を要素から削除して元に戻します。
930行目で、クラス名を追加していない状態の、要素のCSSスタイルを取得します。
931行目で、rejectメソッドを使って、クラス名を追加してもしなくても値が変わらなかったプロパティを、処理から外します。
934行目で、終了後のフックで、クラス名を実際に追加すると同時に、クラス名を追加することで変化があったプロパティをスタイルから外します
0945: setup: function(){
0946: function parseColor(color){
0947: if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
0948: color = color.parseColor();
0949: return $R(0,2).map(function(i){
0950: return parseInt( color.slice(i*2+1,i*2+3), 16 )
0951: });
0952: }
0953: this.transforms = this.style.map(function(pair){
0954: var property = pair[0], value = pair[1], unit = null;
0955:
0956: if (value.parseColor('#zzzzzz') != '#zzzzzz') {
0957: value = value.parseColor();
0958: unit = 'color';
0959: } else if (property == 'opacity') {
0960: value = parseFloat(value);
0961: if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
0962: this.element.setStyle({zoom: 1});
0963: } else if (Element.CSS_LENGTH.test(value)) {
0964: var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
0965: value = parseFloat(components[1]);
0966: unit = (components.length == 3) ? components[2] : null;
0967: }
0968:
0969: var originalValue = this.element.getStyle(property);
0970: return {
0971: style: property.camelize(),
0972: originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
0973: targetValue: unit=='color' ? parseColor(value) : value,
0974: unit: unit
0975: };
0976: }.bind(this)).reject(function(transform){
0977: return (
0978: (transform.originalValue == transform.targetValue) ||
0979: (
0980: transform.unit != 'color' &&
0981: (isNaN(transform.originalValue) || isNaN(transform.targetValue))
0982: )
0983: )
0984: });
0985: },
945~985行目のsetupは、
946~952行目のparseColorは、
947行目で、
948行目で、
949行目で、
953行目で、
954行目で、
956~967行目で、
第1のパターンでは、
956行目で、
957行目で、
958行目で、
第2のパターンでは、
959行目で、
第3のパターンでは、
964行目で、
965行目で、
966行目で、
969行目で、
970~975行目で、
976行目で、
以上の結果を、
0986: update: function(position) {
0987: var style = { }, transform, i = this.transforms.length;
0988: while(i--)
0989: style[(transform = this.transforms[i]).style] =
0990: transform.unit=='color' ? '#'+
0991: (Math.round(transform.originalValue[0]+
0992: (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
0993: (Math.round(transform.originalValue[1]+
0994: (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
0995: (Math.round(transform.originalValue[2]+
0996: (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
0997: (transform.originalValue +
0998: (transform.targetValue - transform.originalValue) * position).toFixed(3) +
0999: (transform.unit === null ? '' : transform.unit);
1000: this.element.setStyle(style, true);
1001: }
1002:});
1003:
986~1003行目のupdateは、
988行目で、
989行目で、
997行目で、
1000行目で、
Effect.Transform
Effect.
デモをご覧ください。このように使います。
// Effect.Transformを作って、後で呼び出す例
var transformation = new Effect.Transform([
{ 'div.morphing': // DIV要素で、CSSクラスが'morphing'のものを指定する
'font-size:20px;padding-left:40em;opacity:0.5' }, //目標のCSSに向かって徐々に変化する
{ 'error_message': // DOM idでの指定。やはり'#error_message'とCSSセレクタで指定することもできる。
'width:480px;border-width:10px;' + //目標のCSS
'border-right-width:20px;' +
'margin:20px;margin-bottom:-20px;' +
'font-size:30px;' +
'background:#954' }
],{ duration: 1.3 });
// 後で呼ぶ。
transformation.play();
1004:Effect.Transform = Class.create({
1005: initialize: function(tracks){
1006: this.tracks = [];
1007: this.options = arguments[1] || { };
1008: this.addTracks(tracks);
1009: },
1004~1021行目のinitializeは、
1010: addTracks: function(tracks){
1011: tracks.each(function(track){
1012: track = $H(track);
1013: var data = track.values().first();
1014: this.tracks.push($H({
1015: ids: track.keys().first(),
1016: effect: Effect.Morph,
1017: options: { style: data }
1018: }));
1019: }.bind(this));
1020: return this;
1021: },
1010~1021行目のaddTracksは、
配列で与えられた、要素のidと目標のCSSをそれぞれkeys().first()とvalues().first()を使って取りだして、this. 1022~1033行目のplayは、 1025行目で、 1026行目で、 1027行目で、 1028行目で、mapのmapからできた配列の入れ子を、flattenでつぶして、Effect. 1034~1044行目のElement. 1045行目で、 1048~1066行目のparseStyleは、 1047行目で、 1050行目で、 1053行目で、 1057行目で、 1061行目で、 1067~1087行目のgetStylesは、 1068行目で、 1069行目で、 1070行目で、 1076行目で、 1078行目で、 1079行目で、 1083行目で、 1084行目で、 addMethodsメソッドを使います。 1088~1122行目で、 1089~1093行目で、 1094行目で、 1096行目で、 1097行目で、 1100~1104行目で、 1107~1116行目で、 1118~1120行目で、 1122行目で、1022: play: function(){
1023: return new Effect.
その他の実用的な関数
1034:Element.CSS_PROPERTIES = $w(
1035: 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
1036: 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
1037: 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
1038: 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
1039: 'fontSize fontWeight height left letterSpacing lineHeight ' +
1040: 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
1041: 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
1042: 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
1043: 'right textIndent top width wordSpacing zIndex');
1044:
1045:Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
1046:
String.
1047:String.__parseStyleElement = document.createElement('div');
1048:String.prototype.parseStyle = function(){
1049: var style, styleRules = $H();
1050: if (Prototype.Browser.WebKit)
1051: style = new Element('div',{style:this}).style;
1052: else {
1053: String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
1054: style = String.__parseStyleElement.childNodes[0].style;
1055: }
1056:
1057: Element.CSS_PROPERTIES.each(function(property){
1058: if (style[property]) styleRules.set(property, style[property]);
1059: });
1060:
1061: if (Prototype.Browser.IE && this.include('opacity'))
1062: styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
1063:
1064: return styleRules;
1065:};
1066:
Element.
1067:if (document.defaultView && document.defaultView.getComputedStyle) {
1068: Element.getStyles = function(element) {
1069: var css = document.defaultView.getComputedStyle($(element), null);
1070: return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
1071: styles[property] = css[property];
1072: return styles;
1073: });
1074: };
1075:} else {
1076: Element.getStyles = function(element) {
1077: element = $(element);
1078: var css = element.currentStyle, styles;
1079: styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
1080: results[property] = css[property];
1081: return results;
1082: });
1083: if (!styles.opacity) styles.opacity = element.getOpacity();
1084: return styles;
1085: };
1086:};
1087:
エフェクトをElementクラスのメソッドにする
1088:Effect.Methods = {
1089: morph: function(element, style) {
1090: element = $(element);
1091: new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
1092: return element;
1093: },
1094: visualEffect: function(element, effect, options) {
1095: element = $(element)
1096: var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
1097: new Effect[klass](element, options);
1098: return element;
1099: },
1100: highlight: function(element, options) {
1101: element = $(element);
1102: new Effect.Highlight(element, options);
1103: return element;
1104: }
1105:};
1106:
1107:$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
1108: 'pulsate shake puff squish switchOff dropOut').each(
1109: function(effect) {
1110: Effect.Methods[effect] = function(element, options){
1111: element = $(element);
1112: Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
1113: return element;
1114: }
1115: }
1116:);
1117:
1118:$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
1119: function(f) { Effect.Methods[f] = Element[f]; }
1120:);
1121:
1122:Element.addMethods(Effect.Methods);