Graviness Blog

算数・数学・科学・電脳・雑記・アホの順の密度で記事が構成されます。
<< October 2018 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 >> ブログランキング・にほんブログ村へ
 
RECOMMEND
ビッグバン宇宙論 (上)
ビッグバン宇宙論 (上) (JUGEMレビュー »)
サイモン・シン, 青木 薫
RECENT COMMENT
  • 豊臣秀吉と曾呂利新左衛門から学ぶ数列の和
    優乃 (07/12)
  • 【誰か解いて】漸化式 a_(n+1) = f(n) * a_n ^ g(n) + h(n) の一般項
    優乃 (02/18)
  • 【誰か解いて】漸化式 a_(n+1) = f(n) * a_n ^ g(n) + h(n) の一般項
    S.S.+ (02/16)
  • 豊臣秀吉と曾呂利新左衛門から学ぶ数列の和
    坂井昭 (03/19)
  • d/dx(x↑↑n): 高さが定数のテトレーションの微分 - 数学的帰納法を用いる方法
    (09/30)
  • 全ての三角形は二等辺三角形
    優乃 (09/28)
  • 全ての三角形は二等辺三角形
    亀レス (09/28)
  • 全ての三角形は二等辺三角形
    優乃 (09/24)
  • 全ての三角形は二等辺三角形
    亀レス (09/23)
  • 【未解決】新しい演算子を創る
    $_ (09/10)
RECENT TRACKBACK
MOBILE
qrcode
PROFILE
無料ブログ作成サービス JUGEM
 
【DHTML】 加速・減速を考慮したアニメーションプログラム
前回の投稿で述べた考え方をプログラムに取り入れたのが,JavaScript / DHTML Class Libraryにある,

AbstractAnimationクラス
  アニメーションの枠組みを定義した抽象クラス.
AbstractEasingAnimationクラス
  AbstractAnimationクラスを継承した,加減速を考慮したアニメーションの抽象クラス.
  上記sのアルゴリズムが含まれます.
LinearAnimationクラス
  AbstractEasingAnimationクラスを継承した,加減速を考慮した直線アニメーションクラス(具象クラス).
LinearAnimationTest.html
  LinearAnimationクラスの使用例.

です.継承やら隠蔽やら抽象クラスやらと色々とややこしいことをしているので,じっくり見るかたは注意して下さい.

ちなみに,加減速を考慮した円運動アニメーションの例はこちら

関連:
イージングの考え方
【数学・DHTML】 イージング [Easing] (1)
【数学・DHTML】 イージング [Easing] (2)
【数学】 イージングロジックメモ
【数学・DHTML】 イージング [Easing] (3)
【DHTML】 加速・減速を考慮したアニメーションプログラム
【数学・DHTML】 イージング [Easing] (4)
【数学・DHTML】 イージング [Easing] (5)
【JavaScript】多重に派生されたクラスのコンストラクタで,基底クラスのコンストラクタを呼び出す方法
/**
 * 継承関数.
 * @param subClass 派生クラス
 * @param superClass 基底クラス
 */

function inherit(subClass, superClass) {
    var Temp = new Function();
    Temp.prototype = superClass.prototype;
    subClass.prototype = new Temp;
}



function SuperClass() {
    alert("SuperClass Constructor");

    this.q = "superclass";
}

function SubClass() {
    alert("SubClass Constructor");
    this.constructor(); // SuperClassのコンストラクタを呼び出す.

    this.r = "subclass";
}

// 継承
inherit(SubClass, SuperClass);

var a = new SubClass();
alert(a.q);
alert(a.r);
この状態でnew SubClass()とすると,SubClassのコンストラクタが呼び出され,次いでSuperClassのコンストラクタが呼び出される.

上記のような例では問題ない.問題は下記のように二重に派生させた場合だ.
/**
 * 継承関数.
 * @param subClass 派生クラス
 * @param superClass 基底クラス
 */

function inherit(subClass, superClass) {
    var Temp = new Function();
    Temp.prototype = superClass.prototype;
    subClass.prototype = new Temp;
}



function SuperSuperClass() {
    alert("SuperSuperClass Constructor");

    this.p = "supersuperclass";
}


function SuperClass() {
    alert("SuperClass Constructor");
    this.constructor(); // SuperSuperClassのコンストラクタを呼び出す.

    this.q = "superclass";
}

function SubClass() {
    alert("SubClass Constructor");
    this.constructor(); // SuperClassのコンストラクタを呼び出す.

    this.r = "subclass";
}

// 継承
inherit(SuperClass, SuperSuperClass);
inherit(SubClass, SuperClass);

var a = new SubClass();
alert(a.p);
alert(a.q); // undefined
alert(a.r);
この状態でnew SubClass()とすると,SubClassのコンストラクタが呼び出され,次いでSuperSuperClassのコンストラクタが呼び出され,終了する.なんとSuperClassのコンストラクタは呼び出されない.これはまずい.

色々と試行錯誤した結果,次に示すコードに変更し,このSuperClassのコンストラクタが呼び出されない問題を解決した.
続きを読む >>
【DHTML】 メモ - 互換モード,標準モードによる右下点の座標
■ BackCompat

   ┌──────width-──────┐
   borderL                    borderR
   ┌─-┐                    ┌─-┐
 ┌A━━━━━━━━━━━━━━━┓┐
 │┃                              ┃|borderT
h│┃   ┏━━━━━━━━━━┓   ┃┘
e│┃   ┃                    ┃   ┃
i│┃   ┃                    ┃   ┃
g│┃   ┃                    ┃   ┃
h│┃   ┃                    ┃   ┃
t│┃   ┗━━━━━━━━━━┛   ┃┐
 │┃                              ┃|borderB
 └┗━━━━━━━━━━━━━━━B┘

A : parseInt(style.left)
B : parseInt(style.left) + parseInt(style.width)

■ CSS1Compat

┌────-offsetWidth─────┐
borderL                    borderR
┌─-┐                    ┌─-┐
A━━━━━━━━━━━━━━━┓┐       ┐
┃   ┌───-width────┐   ┃|borderT|
┃h┌┏━━━━━━━━━━┓   ┃┘       |
┃e│┃                    ┃   ┃         |
┃i│┃                    ┃   ┃         |offsetHeight
┃g│┃                    ┃   ┃         |
┃h│┃                    ┃   ┃         |
┃t└┗━━━━━━━━━━┛   ┃┐       |
┃                              ┃|borderB|
┗━━━━━━━━━━━━━━━B┘       ┘

A : parseInt(style.left)
B : parseInt(style.left) + layer.offsetWidth

枠線のある要素で,取れてると思ってた右下点の座標が取得できてなくて嵌った.
旧サイトのファイルを再構成しようと思う
旧サイト(Virgo)のコンテンツですが,今でも使えそうなので,ファイルをトップレベルへ移行すると共に,今のファイル構成を再構成しようと思う.
閲覧者には特に影響はありませんが,旧鯖の広告が取れるなどして使いやすくなると思います.
Web制作メモ
.htaccess
ディレクトリアクセスを許可
Options Indexes
その見え方を設定
IndexOptions オプション オプション・・・
FancyIndexing : アイコン表示で見やすく示します。
IconsAreLinks : ファイル名を箇条書きに表示します。
SuppressLastModified : 最終更新日を表示させないようにします。
SuppressSize : ファイルサイズ表示させないようにします。
拡張子xxxでPHPを実行する
AddType application/x-httpd-php .xxx

PHP実行ファイルのファイル名
- 拡張子はphtml -
ローカル作業時の話で,IE6に*.phpファイルをドラッグ&ドロップして表示確認を行おうとすると,ダウンロードのダイアログが表示される.IE6はphpファイルをHTMLファイルとして認識しないようだ.FirefoxはOK.このため,*.phpでHTMLファイルを作成しておくと,ローカルでの作業効率が悪い.ファイル名を*.php.htmlにしておいたが,(PHPが実行されるファイルは*.phpに限られるため)FTP転送時にindex.phpに変更する作業が伴うため,これも面倒..htaccessでPHP実行をphtml拡張子に適用,ローカルファイル名も*.phtmlにしておくことでこれが解消される.

ディレクトリ変更時
- エラードキュメントにJavaScriptを記述 -
サーバのディレクトリ構造変更時,変更のあったドキュメントへGoogleなどから飛んできた場合,ユーザは404エラーを見ることになる.
ここでエラーページのURIはその間違えたURIであるため,404エラードキュメントにJavaScriptを記述し,location.hrefを参照することで正しいURIへ移動を促すことができる.location.replaceで直移動させる方法や,「ひょっとして〜(正しいURI)」を表示する方法がある.この場合,.htaccessで正しいURIへリダイレクトする方法が一番スマートだが,変更があったことを明示したいときはここで示した方法もあり.重要なのはエラードキュメントにJavaScriptを記述することで何か便利になるかも知れないということ.
ちなみにエラードキュメントをPHPなどにしておけば,リンクが切れしているURIやユーザが間違えてアクセスするURIを集計することも可能になる.

その他
FancyIndexingオプションはブラウザによって,一覧に表示されるファイル名が途中で切れるため,必ずしも見やすくなるとは限らない.
【JavaScript】 メモ
Singletonで実装したいクラスがあったのですが,気になるのがマルチスレッド下(setTimeout, setInterval関数使用時)で,そのユニークなインスタンスのメソッドの同期がとれているかということ.

試してみた結果,どうやら大丈夫な模様.
【JavaScript】 テキストフィールドの初期化方法
フォームの入力欄に初期値を与えておくことが,ユーザビリティの向上に繋がることがある.

以下のような郵便番号を入力する例でも,△里茲Δ暴藉値が入っていれば,「半角で入力するんだ」とか「7桁だな」とか「‐(ハイフン)を含めるんだな」とか,入力するための必要情報をそれとなくユーザに与えることができる.
郵便番号 :
郵便番号 :
後者のようにするのはよい.しかし,このままではユーザは入力する前にその初期値を消さなくてはいけない,という作業を行わせてしまうことになる.

どうでもいいが,うちの会社のシステムは日付(西暦)を入力するだけでも,同システムのくせに2桁のとこがあったり,4桁のとこがあったりして使いにくいことこの上ない.

さて,ここからは開発側の話.
ということで,通常はこの初期値をJavaScriptで消すことになる.消すタイミングはテキストフィールドにフォーカスが当たったときだ.それも最初のフォーカス時だけ.素直に実装すれば以下のようになるはず.
<form id="DATA">
    郵便番号 : <input id="ZIP" type="text" maxLength="8" value="123-4567">
</form>

<script type="text/JavaScript"><!--

// 最初のフォーカス時に真
var focused = false;

document.forms["DATA"].elements["ZIP"].onfocus = function() {
    if (!focused) {
        this.value = ""; // Delete
        focused = true;
    }
};

//-->
</script>
上記ソース,実際の例はこちら

これの気持ちの悪いところは,グローバルな変数 focused の存在.このように実装してしまうと入力欄が多い場合,その数だけこのようなグローバル変数を用意しなくてはいけなくなる.onFocusメソッドも,この変数も,活きるのはユーザがフォーカスを当てる最初の一回だけである.

ということでこれを解消するのが以下のソースだ.
<form id="DATA">
    郵便番号 : <input id="ZIP" type="text" maxLength="8" value="123-4567">
</form>

<script type="text/JavaScript"><!--

document.forms["DATA"].elements["ZIP"].onfocus = function() {
    this.value = "";
    this.onfocus = null;
};

//-->
</script>
上記ソース,実際の例はこちら

これでグローバル変数の存在も消えたし,onFocusメソッドの起動も最初の一回のみで,そのあとイベントがJavaScript上に発生することもない.

IE6,Opera7,Netscape7で正常に動作することを確認.
→ どちらのコードもFirefoxでエラーになるけど,どうやらonFocus,onBlurメソッドのバグっぽいなぁ.(エラーが起きても引き続きJavaScriptは動作しますので致命的なものではありません.)
【DHTML】 続・一連のアニメーションをスキップさせる手段
【DHTML】 一連のアニメーションをスキップさせる手段の続き.
バージョンアップしたので報告.
ファイル構成,使用方法は変化していません.

■ ファイルの説明
system.js
共通
・Functionクラスへの継承メソッドの追加.
・エラーメッセージ関数.
animation_lib.js
アニメーションフレームワーク.
・Animation抽象クラス.
・AnimationManagerクラス.
を含む.
simple_animations.js
Animationクラスを実装したシンプルなアニメーションクラス群.
・SimpleStraightAnimationクラス.
・SimpleSignCurveAnimationクラス.
を含む.サンプルのために用意したクラス.
sample.html
アニメーションフレームワークを使ったサンプル.

■ 変更点
・アニメーションインスタンスの単一マネージャへの複数登録を許可するように変更.
同じアニメーションを連続して再生することが可能になりました.例では赤が連続してます.また,マネージャへの複数登録が許されたので,赤→青→赤なども可能です.前回はこれが不可能でした.
(まえで実装してなかったのかよ,とかいう突っ込みはなしで.JavaのHashMapクラスとかないから結構面倒だったのね)
これしかできなかったのが,こう出来るようになった.
・Animation#addInitializeListenerメソッドの追加.
アニメーションインスタンスの個別の初期化時処理が可能になりました.
・destroyリスナメソッドの引数にcurrentFrame, endFrameを渡すように変更.
destroyメソッドが呼ばれた時点の現在のフレーム位置,最終フレーム位置が情報としてリスナに渡されます.
(いちいちEventクラス作るのも面倒だし,これで十分でしょう)
【DHTML】 一連のアニメーションをスキップさせる手段
ミクシィでDHTMLコミュニティの管理を行っているのですが,以下のトピックを書き込みました.

一連のアニメーションをスキップさせる方法を模索中

初心者もどうぞと言うわりに初心者には濃い話で申し訳ないですが,以下の問題にたいしてアイデアを頂きたいです.

以下のアニメーションは
http://www.graviness.com/files/animation_skip0.html
\屬移動,⇔个移動,青が移動,SKIPの文字列が消える,ソ了
というものです.

問題は,どんなタイミングであってもSKIPをクリックした時点で全てのアニメーションをスキップさせ,状態をイ飽楾圓靴燭い箸いΔ海箸任后

SKIPをクリックするとskipAnimation関数が呼び出され,一連のアニメーションをスキップさせる,そして自分自身(SKIPの文字列)を消す,という処理を行うものとします.

上記アニメーションは同時に最大3つのsetTimeout関数を使ったスレッドが走ります.
この程度なら,以下のようにすることができるのですが,
http://www.graviness.com/files/animation_skip1.html
ソースを見れば分かるようにタイマー変数,カウント変数などグローバル変数が増えますし,skipAnimation関数の中身が複雑化してきます.新しいアニメーション(例えばmoveYellow)が増えたとき,またはもっと複雑なアニメーション時(スレッドから複数スレッドが派生したりするとき)に保守が面倒という難点があります.

上記のタイマー変数はいらないのでは?と考えらるかも知れませんが,setTimeou関数の第2引数が大きいとき(例えば3000msec)に,SKIPを押したときに即停止ということができなくなります.

詳しくないのですが,FLASHではユーザはフレームをスキップ先に指定するだけで,あとの複雑な内部処理は行ってくれている感じがするのですが,どうなんでしょうか?同じように苦労されているのでしょうか?

簡単な方法がありそうなのですが見つかりません.何か良いアイデアはありませんでしょうか?
(根本の関数構成,アニメーション方法が間違ってるのかも知れません)
長文申し訳ありません.
これに対し複数の方から,意見・実装したものを頂きました.
本当にありがとうございました.
それらの意見をもとに私なりに実装したものが以下です.(本当は全書き込みを引用したかったのですが,SNSの趣旨上それはしていません)
遅くなりましたが,皆さんの意見を参考にコードを書いてみました.
とりあえず,サンプルは
http://www.graviness.com/files/animation/sample.html
です.

■ ファイルの説明
system.js
  共通
  ・Functionクラスへの継承メソッドの追加.
  ・エラーメッセージ関数.
animation_lib.js
  アニメーションフレームワーク.
  ・Animation抽象クラス.
  ・AnimationManagerクラス.
  を含む.
simple_animations.js
  Animationクラスを実装したシンプルなアニメーションクラス群.
  ・SimpleStraightAnimationクラス.
  ・SimpleSignCurveAnimationクラス.
  を含む.サンプルのために用意したクラス.
sample.html
  アニメーションフレームワークを使ったサンプル.

■ アニメーション処理の実装方法
アニメーションの具体的な処理は,Animation抽象クラスを継承することで行う.
Animationクラスのサブクラスは,
・init
  初期化処理.
  startメソッドの最初に呼び出される.
・move(int currentFrame, int endFrame)
  アニメーションの具体的処理.
  軌跡等をcurrentFrame, endFrameの情報を使用し,実装する.
・clear
  終了時処理.
  アニメーション終了時(終了フレーム到達時,
  destroyメソッド呼び出し時)に呼び出される.
これらのメソッドをオーバーライドする必要がある.
これらを実装したクラスが例えば,直線アニメーションを表現するSimpleStraightAnimationであったり,サイン曲線アニメーションを表現するSimpleSignCurveAnimationだったりする.

■ 基本的な使用手順
1. アニメーションインスタンスの生成(複数可)
  SimpleStraightAnimation, SimpleSignCurveAnimation等のインスタンス.
2. 生成したアニメーションインスタンス群をアニメーションマネージャへ登録(追加).
  2.1. 開始アニメーションの登録(追加).
    AnimationManager#add(startingAnimation);
    を使用する.
  2.2. 子アニメーションの登録(追加).
    登録(追加)方法は複数あるが,通常は「ある<親アニメーション>の<フレーム位置>から,<該当アニメーション>を開始する.」ことになる.AnimationManager#add(<該当アニメーション>, <親アニメーション>, <フレーム位置>)を使用する.
3. アニメーションを開始する.
  AnaimationManager#startを使用する.
  手順2.1で登録(追加)されたアニメーションインスタンスが実行される.

■ スキップ
一連のアニメーションをスキップさせたいときは,AnimationManager#destoryを呼び出す.この時点で AnimationManagerのインスタンスに登録(追加)された全てのAnimationインスタンスのdestoryメソッドが実行され,アニメーションが全停止する.
スキップ時の具体的処理はAnimationManagerクラスに追加することになる. AnimationManager#addDestroyListener(Function destroyListener)を使用する.destroyListenerが終了時処理の関数になり,destroyListener関数に終了時の処理を書く.

■ その他1
Animationクラスの抽象メソッドclearメソッドはそのサブクラスのインスタンス共通の終了処理になるが,インスタンス固有の終了処理が必要になる場合がある.これはAnimationクラスにその固有終了処理の実装を満足させるaddDestroyListenerメソッドを使用することで対応する.(恐らくaddInitializeListenerメソッドの需要も考えられるが,これは未実装)

HTMLのサンプルでは,全てのアニメーション終了時に「SKIPの文字列を消す」という処理が必要になる.これは「SkipAnimation 文字列」をクリックすることで呼び出されるAnimationManager#destoryメソッドを呼び出すことで実行されるが,Animation インスタンスはAnimationManager#destoryメソッドを実行しないため,それとは別にAnimationインスタンス固有の終了処理を追加できる必要があった.これが上記のAnimation#addDestroyListenerメソッドになる.サンプルでは青アニメーションが最後に終了するため, blueAnimation変数でこのaddDestoryListenerメソッドを使用している.

■ その他2
勿論,AnimationManagerクラスがなくとも,Animationクラスのみでの単独,並列?アニメーション実行も可能です.

■ 私が思う利点
・AnimationManagerの存在により,次に実行するアニメーションを意識せずに,Animationクラスのサブクラスを実装できる.これにより,Animationクラスのサブクラスの独立性が高まり,再利用性も高くなっている.
・一連のアニメーションをフレーム位置で管理できる.
・AnimationManagerの登録(追加)メソッドは,アニメーションの開始順に記述する必要がないため,アニメーション変更時も柔軟に対応できる.
・シーケンシャルなアニメーションの構造を親アニメーション,子アニメーションというような管理にしているため,イメージしやすい.アニメーションAからB,Cが開始し,BからDが開始するみたいな感じ.
・描画処理時間を極力邪魔しない実装.アニメーション時,一番呼び出し回数の多いAnimation#_runメソッド内での分岐処理を少なくしている.ハードコーディング時とほぼ変わらないと思われる.

P.S.
ふぅ,疲れた・・・.
AnimationクラスからAnimationManagerクラスは見えないように実装したかったけど,
無理でした.JavaScriptなら力技で出来るけど,なんか邪道でしたくなかった.
使用例も少ないため,バグが多数混在しているはずです.
査収して頂けると嬉しいです.
以前から,DHTMLでのアニメーションの保守性の低さはアニメーション用のフレームワーク作成でしか回避できないと思っていたので,これで楽できそうです.まだ,完成ではないのでもっと良いものになったら,またここで紹介したいと思います.
右側メニュー左側コンテンツ
メニューは右側?左側?

(トラックバックテストを兼ねて)

逆に言うと「右側メニュー,左側コンテンツ」にすれば,新鮮味を与えられる,とも言える.
ニュースサイトで右側に広告が配置されているのはこういった効果を多少期待してのことかも知れない.
当たり前だが,長期でこれをやってはいけない.使いやすさを犠牲にするほど価値はなく,ただのストレスに変化してしまうからだ.

右脳がイメージ&空間を処理しているならば,右側からの視覚イメージはレギュラーな左側より多少はイレギュラーなはずである.
脳にちょっとした刺激を与え,印象付けるには右側にいつもと違う風景を与えることだ.
バーでは自分が右側に座る.プレゼントを渡すときは相手の右側から,告白するときも相手の右側からチャレンジして欲しい.脳に(無意識化のレベルで)ドキッとさせる効果はあるはずである.
ちなみに車の運転で右に廻るときに少しストレスを感じるのは,恐らくそれは右ハンドルだからだ.フレームが邪魔!

(C) 2018 ブログ JUGEM Some Rights Reserved.