スポンサーサイト

2014.01.27 Monday

一定期間更新がないため広告を表示しています

  • -
  • -
  • -

iOS6がリリースされiPhone5が発売されました。

いままでスマホなんてまったく興味がなかったのに。

まったく興味がなかったので4の発売直前に

3GSを買ってからだんだんとiPhoneの魅力に、、、。

それ以来この発表が楽しみになってしまいました。

すごいなapple。

現在JB4Sを使用中ですが5は見送りま〜す。

欲しいですが。

ちなみにちょっと友達の5使わせてもらったんですが、

処理がメッチャ早い!そして軽い!すごい!

iOS6よりinput type="file"が使える!fileReaderも使える!

以下fileReaderに関するメモです。。


iPhoneってinput type="file"が使えなかったんですよね。


これ結構残念な仕様だなぁとずっと思ってました。


それがついに開放!


そしてこのブログでも長いことひっぱてますお絵かきアプリ、


以前作ってみた時、撮った写真にお絵かきできたらいいな、


と思ったのですが、


まぁ、まずファイルにアクセスできないし、ブラウザだけで


完結できないし、とか考えつつあきらめていたのですが、


iOS6にて両方いけるようになったのでとりあえず試してみました。


ちなみに1点残念な事がありまして、どーやらwindows版safariの


提供が終了してしまったようで、win safariはfileReaderが使えないまま


最後を迎えてしまったようです。。。


まずはinput type="file"のデザインをCSSでこっそり隠す

input type="file"ってそーいえばデザインどーする?!


とちょっとググってみたら、透明にして重ねる!みたいな記事が


結構ヒット。やっぱり同じ悩みを持つ方は結構いるんだなと。


html

<ul>
    <li>写真にお絵かき<input type="file" id="fake" /></li>
    <li>・・・・</li>
    <li>・・・・</li>
    <li>・・・・</li>
</ul>

css

li {
	line-height: 75px;
	position: relative;
	margin: 0 auto;
	width: 320px;
}
#fake {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	opacity: 0;
}
一応webkit系であればli全体がクリックできた

のですが他ブラウザは(あまり確認してませんが、、、)デフォルトの

ボタン部分をちゃんとクリックしないと認識できなかった為

かなり危険なデザインです。はい。


ファイルを選択してcanvasへ描き出す


var tar = $("#illustMenu li");
//input type file、fileReader使える??
if(!window.FileReader || $('#fake').get(0).disabled) $(tar[0]).css('display', 'none');
 
$("#illustMenu li").bind("click", function() {
    scrollTo(0, 0);
    var index = $("#illustMenu li").index(this);
    var myImg = new Image();
    if(!index) {
        var $fake = $('#fake').get(0);
        $fake.onchange = function() {
            var file = $fake.files[0];
            if(!file.type.match('image.*')) {
                alert('画像以外は読込めません');
                return;
            };
            var fr = new FileReader();
            fr.onload = function() {
                myImg.src = fr.result;
                callback();
            };
            fr.onerror = function() {
                alert('読込めませんでした');
            };
            fr.readAsDataURL(file);
        };
    } else {
        myImg.src = "img/illust/" + index + ".png";
        callback();
    };
    function callback() {
        myImg.onload = function() {
            var iw = myImg.width;
            var ih = myImg.height;
            if(!index) {
                ・・・・・
                ・・・・・
            };
            if(W > 600 && !retina) {
                ctx.drawImage(myImg, 0, 0, iw, ih);
            } else {
                ctx.drawImage(myImg, 0, 0, iw/2, ih/2);
            };
        };
    };
});
とりあえずfileReaderが使えるか?input type fileが使えるか?

使えれば「写真にお絵かき」メニューを表示する。

onchangeイベントにて以下実行。

fileapiにてファイルにアクセスしてfileReaderで読み込む。

readAsDataURL()メソッドでDataURLスキームに変換して読み込む。

そしてonloadイベントで画像サイズを調整してcanvasに描画。

OK。以外とあっさり。よかった。

PCで確認する分には。



ここからどっぷりはまりました、、、、。

ではiPhoneで確認。


問題なくファイル選択画面登場。


適当な写真を選択。


まったくもってきちんと描画されない、、、、。


縦、横もおかしい。


ググってググってまたググって。


そこでふと思い出したMobileSafariのリソース制限。


これかぁ。


canvasにリサイズして書き出したくても


どーにもきちんと読み込まれない。


これはやっぱりimageオブジェクトで読み込んだ時


おかしくなってるのか??


上限35メガピクセル。


iPhone4sのカメラは800万画素で8メガピクセル。


ただ2メガピクセル以上はうんたらかんたら。


よくわからん。


さらにcanvasの上限は2メガバイト。


よくわからん。


とりあえずの結果

まず4sで撮影したデフォルト画像はcanvasに書き出した際


おかしなことになる。さらに縦・横認識していない。


しかしフォトストリームから読み込むと問題なく書き出され


縦・横も認識される。


iPad2で撮影したデフォルト画像はcanvasに書き出した際


きちんと書き出されるが縦・横が認識されていない?


ただiPad2で4sで撮影したフォトストリームの画像は


問題なく書き出され縦・横も認識された。


3GSではフォトストリームの画像もおかしなことに、、、。


うーんよくわからん。


おそらくそのRAMとリソース制限の関係でしょうか??


もう少しつっこんで

描きだし時にバグるのはしょうがないとして

なぜ縦・横を認識しない?

ググってみると画像にはExifという画像の様々なデータ

が書き込まれたものがあると。なるほど。

そんでそれはバイナリデータで抽出可能。


なんともめんどくさそう。


fileapiに出会った時これは一体何に使うんだ?


と思っていったreadAsArrayBuffer。


バイナリデータを読み込めます。


まさか早速お世話になるとは。


JPEG画像からExif情報を抽出する


未知な世界のバイナリ。


ということでとりあえず上のコードをお借りして


いったんExifデータを確認させていただくと、


しっかりorientation6又は1となってる。


これで分岐すればとりあえず対応はできそう。


そのうちバイナリの勉強でもしよう。


さいごに

まともには使えませんがとりあえず実装してみました。


お絵かきアプリ


それとあまり関係ありませんがgetImageDataで取得した


imageDataオブジェクトをputImageDataで描き出す際


変換マトリックスを適用する方法ご存知の方いませんでしょうか??


回転させたいだけなんですが、、、。ご存知の方コメントいただけたら


うれしいです。


いつもいつも簡単に終わるかなと思って取り掛かるんですが、


予想外の時間がかかってしまいます。


いい加減他の勉強を始めなければ、、、



相変わらず広告が挿入されております。

更新頻度が少なすぎる。。。

とあるサイトをとりあえずスマホに対応させたいなぁ、

簡単な感じでいいんだけど、、、。

と長いこと考えていてやっと重い腰を上げてとりかかってみました。

その時躓いたことなどをメモ。

htmlは弄らず(増やさず)CSSのみで対応したい

CMS(CMSをあまり理解していませんが、、、)など使用してなかったので

更新の度にPC用、スマホ用両方更新するのメンドクサイ。

とりえずCSSだけでどうにかしよう。

どうにかなるだろう。

とりあえずやってみたこと

  • 不要な画像、ナビゲーションをdisplay: none
  • 各セクションのdivのwidthを100%に
  • 消したいテキストはtext-indentで画像置き換え
  • リストのナビゲーションのアンカーをブロック要素に
  • nth-child(n)::afterでcontentを挿入


まずはがんがんdisplay: none;で画像やら不要なナビを非表示に。

なんて無駄が多いんだ。

body,div#header,div#main,div#footerなどのdivのwidthを100%に変更。

その際子のブロック要素にうっかりwidth: 100%を設定し、paddingを設定してしまうと

横スクロールが出てしまうのでご注意を。

そんで画像に置き換えたいテキストがあればCSSのtext-indentで画像置換え。

画像置換えは→[CSS]画像置換「-9999px」のパフォーマンスを改善した新しいテクニック

ヘッダー、フッターのナビをうまいこと必要な分だけ利用してなんとなくナビを作成。

リスト内アンカーをブロックにして入りきらいテキストは...表示にするため、

text-overflow、white-space、overflowを設定。

 ↓こんな感じでリストメニューはOK??
.navi li {
    width: 100%;
    border-bottom: solid 1px #ccc;
}
.navi li a {
    text-decoration: none;
    display: block;
    padding: 10px 20px 10px 10px;
    margin-right: 5px;
    background: url('../images/arrow.png') no-repeat right center;
    -webkit-background-size: 20px 20px;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
}


そして擬似要素before afterでコンテンツを挿入。

こんなんで大丈夫だろうかと思いつつも続行。

ボタンはCSS3 Button Generatoここで素敵なのが簡単に作れますね。

retina用にアイコンサイズは倍で作って

-webkit-background-size:これで半分表示に。

 予想外。意外とまとまった。

このCSSをどう読み込むか、ヘッド内でメディアクエリで読み込むか。

とも思ったけどjavascriptでユーザーエージェントで判別して

既存のCSSを書きかえることにしました。

PCサイト、スマートフォンサイトの切り替えをどうしよう。

ここ、悩みました。

とりあずの対応だったんですがなんとなくこの機能は譲れなっかたんです。

ヘッド内でメディアクエリで分岐したらPC表記への切り替えられても

ページ遷移したら戻っちゃうし。そもそも全html直したくないし。

普通はPHPとかでやるんですよね、きっと。

が、しかし、PHPよくわからなかったので、

javascriptのセッションストレージという便利なものがあったのでそれで対応。

以下自信ないですがコード。
(function() {
    // セッションストレージに対応してるか?
    if(typeof sessionStorage === 'undefined') return;
    
    var spFlag = false;
    var n = navigator.userAgent;
    var uap = new RegExp('iPhone|Android.+Mobile|iPod');
    //ユーザーエージェントにてスマホ判別
    if(n.match(uap)) {
        spFlag = true;
        //対応しててもプライベートブラウズだとエラーになってしまうので。
        try {
            //セッションスタートかどうかチェック
            //confirmはお好みで
            //if(sessionStorage['SPorPC'] == undefined) sessionStorage['SPorPC'] = confirm('スマートフォン用サイトを表示しますか?') ? 'sp' : 'pc';
            if(sessionStorage['SPorPC'] == undefined) sessionStorage['SPorPC'] = 'sp';
        } catch(e) {
            //プライベートブラウズ時、他ストレージエラー時はスマホフラグをfalseに
            spFlag = false;
        };
    };
    
    //PC、スマホ切り替えボタンにclickイベントをliveで紐付け
    $('#pc, #sp').live('click', function() {
        sessionStorage['SPorPC'] = this.id;
        scrollTo(0,0);
        //changeView();// no load
        location.reload();// reload
    });
    
    function changeView() {
        //スマホの時のみ呼ばれsessionStorageがPCかSPかを
        //判別してフラグを書き換えます。
        spFlag = !(sessionStorage['SPorPC'] == 'pc');
        
        //既存(PC用)のスタイルシートをデフォルトのままかスマホ用に書き換えてます。
        //全てのスタイルシートを書き換えてるので変更の無いCSSもスマホ用が必要になってしまいますが、、、。
        //下はスマホ用は頭に「sp_」を付けて正規表現でパスを書き換えています。
        var $path = $('link[rel="stylesheet"]');
        for(var i = 0,len = $path.length; i < len; i++) {
            $path[i].href = changePath($path[i].href);
        };
        
        function changePath(path) {
            //コピペするとこの正規表現のバックスラッシュがエラーになりますのでご注意を。
            var trim = path.match(/sp_[0-9a-z]+¥.css|[0-9a-z]+¥.css/);
            
            trim[1] = (spFlag) ? 'sp_' + trim[0] : trim[0].replace('sp_', '');
            var changedPath = path.replace(trim[0], trim[1]);
            return changedPath;
        };
        
        //viewportをheadに挿入
        if(spFlag) {
            var meta = '<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0" />';
            $('head').append(meta);
        } else if(!spFlag && n.indexOf('Android') != -1) {
            //AndroidはPCサイトに切り替えた際PC用のwidthをviewportに設定しないとdivice-widthのままになっているような気がします。
            var meta = '<meta name="viewport" content="width=980" />';
            $('head').append(meta);
        };
        
        $(function() {
            //スクロールしてURLバーを隠します
            scrollTo(0,1);
            //PCからスマホ、スマホからPCへの切り替えボタンを挿入。
            if(spFlag) {
                var btn = '<div id="spbtn"><a href="javascript:void(0);" class="btn" id="pc">PC</a></div>';
                $('h1').after(btn);
                
                var $switch = $('#switch');
                if($switch) $switch.remove();
            } else {
                var swt = '<div id="switch">表示切替 : <a href="javascript:void(0);" id="sp">スマートフォン</a></div>';
                $('#footer').after(swt);
                
                var $spbtn = $('#spbtn');
                if($spbtn) $spbtn.remove();
            };
        });
    };
    //スマホだったらchangeViewを実行
    if(spFlag) changeView();
    
})();


最初はリロードしないで表示を切り替えるつもりだったので色々無駄が多いです。

 ページをロードしないとどーもviewportがうまいこといきませんでした。

更にリロードしてもAndroidがどーもしっくりこなかったので

PCサイト用のwidthを入れてみたらまぁなんとか。

キャッシュなんですかね〜?

それでこれを全てのhtmlで読み込んでる共通のスクリプト(あればですが、、、)

に記述すればPC用表示にして他のページに移動してもPC表記のまま!

すぐぶちあたった欠点

なんといってもプライベートブラウズではwebストレージが使用できません!!

残念。

だけどChromeのシークレットモードはOKでした!

それとPC、SP切り替えをまたいでブラウザの戻るボタンで移動すると

キャッシュを読んでるためなんだかなぁ。って感じです。

それとAndroidのページ内移動(a href="#top"ってやつです)、

 これ一回しかできないんですね。

そんなこと思いもせず結構悩みました。

ここはjavascriptで対応するしかなさそうですね。

それと直接関係ないですがiPhoneはどうやらjQueryの

live関数と相性が悪いらしくイベントが登録されないみたいです。

JQueryのliveイベントがiPhoneのSafariで登録できない

確かにonclick属性を入れたらちゃんとイベントが実行されました。

上のコードの切り替えボタンは

javascript:void(0)あたりが効いてるのでしょうか?

一応動きます。

結論

viewport、特にAndroidがよくわかりません!

Androidが欲しい。

何かミスがありましたらご指摘いただけると嬉しいです。

prefix

without prefix


div.css-testbox {
    margin: 10px auto;
    width: 300px;
    height: 300px;
    border: solid 1px #cdcdcd;
}
div.box-prefix {
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    -o-border-radius: 10px;
    -ms-border-radius: 10px;
    -webkit-box-shadow: 0px 0px 5px 3px rgba(0,0,0,.2);
    -moz-box-shadow: 0px 0px 5px 3px rgba(0,0,0,.2);
    -o-box-shadow: 0px 0px 5px 3px rgba(0,0,0,.2);
    -ms-box-shadow: 0px 0px 5px 3px rgba(0,0,0,.2);
}
div.box-without-prefix {
    border-radius: 10px;
    box-shadow: 0px 0px 5px 3px rgba(0,0,0,.2);
}
@-webkit-keyframes rotate {
    0% {
        -webkit-transform: rotate(0deg);
    }
    100% {
        -webkit-transform: rotate(360deg)
    }
}
@-moz-keyframes rotate {
    0% {
        -moz-transform: rotate(0deg);
    }
    100% {
        -moz-transform: rotate(360deg)
    }
}
@-o-keyframes rotate {
    0% {
        -o-transform: rotate(0deg);
    }
    100% {
        -o-transform: rotate(360deg)
    }
}
@-ms-keyframes rotate {
    0% {
        -ms-transform: rotate(0deg);
    }
    100% {
        -ms-transform: rotate(360deg)
    }
}
@keyframes rotate {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg)
    }
}
/*
    animation-name: ;keyframeの名前
    animation-duration: ;実行時間(1000sm>1s>1秒)
    animation-timing-function: ;easing
    animation-delay: ;開始時間(1000sm>1s>1秒)
    animation-iteration-count: ;実行回数(infinite>無限)
    aniamation-direction: ;反転再生(normal,alternate)
*/
.animation-prefix {
    -webkit-animation: rotate 5s ease-in-out infinite;
    -moz-aniamation: rotate 5s ease-in-out infinite;
    -o-animation: rotate 5s ease-in-out infinite;
    -ms-animation: rotate 5s ease-in-out infinite;
}
.animation-without-prefix {
    animation: rotate 5s ease-in-out infinite;
}
/*
    transition-property: ;cssプロパティ名(all,none,プロパティ名)
    transition-duration: ;実行時間(1000sm>1s>1秒)
    transition-timing-function: ;easing
    transition-delay: ;開始時間(1000sm>1s>1秒)
*/
.transition-prefix {
    width: 100%;
    height: 100%;
    -webkit-transition: width 500ms ease-in-out 0, height 1s ease-in-out 0;
    -moz-transition: width 500ms ease-in-out 0, height 1s ease-in-out 0;
    -o-transition: width 500ms ease-in-out 0, height 1s ease-in-out 0;
    -ms-transition: width 500ms ease-in-out 0, height 1s ease-in-out 0;
}
.transition-without-prefix {
    transition: width 500ms ease-in-out 0, height 1s ease-in-out 0;
}
.transition-prefix:hover { width: 80%; height: 80%; } .transition-without-prefix:hover { width: 80%; height: 80%; }
いつも思い出せないcss3 animationとtransitionとプレフィックスのメモ。

マウスオーバーかタッチでtransitionを実行。

プレフィックスがあると適用されないプロパティもある。

当然ないと適用されないプロパティが沢山

やっぱし併記が必要。

早くプレフィックス無しで動いて欲しいな。


 最近音楽系アプリが楽しくてしょうがない。

とりあえずielectribeとnanostudioを入れてみんだけど、

すごすぎる!昔一生懸命お金貯めて買った機材の 2割 2%くらいの値段で

同じようなことが、、、

そんでせっかくだからHTML5でBGM再生しようと思ったんだけど

どーにもループがうまく出来ない。なぜ?

途切れるんですよ、繋ぎ目で。

なんかいろいろ試したけどsetTimeoutで交互に繋げるのが

一番スムーズになったみたい。

でもiOSではまだ1音しか鳴らせないし。

なんかもっとスムーズに繋げる方法どなたかご存知ないでしょうか??


そんで全然関係ございませんが、なんとなく今更jQtouchって

どんな感じかしらと思って使ってみました。

なにを作ろうかと考えてまたもやHTML5、CANVASにてスクラッチカードもどきを作成。




safariかChromeじゃないとうまく表示できません!

4 / 6同じ絵柄です。2箇所まで削れて、絵柄が合えば貯まっていきます。

3箇所以上削る、絵柄が揃わないと消えます。

scratch card

cake_scratch
デフォルト
とりあえず普通に画像がシャッフルされます

default_scratch
カスタム
cakeがかわいい

probability
確率変動??
1箇所スクラッチで画像ごとに50%、30%、10%、8%、2%と出現確率を設定しました
社内SEにょえのブログ参考に
させていただきました。

コード

scratch.js
default_scratch.js
scratch.css
<div id="scratchBox">
        <div id="cover">
            <span id="back" class="btn">&lt;&lt;back</span>
            <span id="next" class="btn">Loading....</span>
        </div>
        <canvas id="can"></canvas>
        <canvas id="can_bg"></canvas>
        <canvas id="can_is"></canvas>
    </div>
scratch.js、scratch.cssがまぁベースになりまして、

default_scratch.jsにて各種設定を指定して実行しています。

default_scratch.jsとscratch.cssを少しいじりまして上のスクラッチを作成してみました。

引数の説明はdefault_script.jsファイルに記載してあります。

canvasを3枚重ね、1枚目にスクラッチ部分を描き、2枚目に画像を配置、3枚目にパスを描き

そこでisPointInPathにてどこが削られたか判定しています。

案の定retinaディスプレイに少々躓きました、、が大分なれてきました!

画像を倍で作成し、半分で表示ってやつですが、同じようにcanvasもscale(2,2)にて

半分表示を行っているのですが、タッチ座標を取得する3枚目もscale2倍にして

悩んでしまいました。。

勉強がてら無理してクラスを使って作ったまとまりのないコードになり、

大分前に中途半端に作成したものを、再度作り直したりしたので、

かなり無茶な部分も多いと思いますがよかったら使ってみてください。

ちょっとずるもできちゃいますし、コードに関しても責任は持てませんが、、、。

canvasとコールバックで出てくるページに背景画像を

指定して、スクラッチ分のお好きな画像を用意し、指定すれば結構簡単にカードがつくれます!

色々素材も作ろうと思ったんですが時間がなくてできませんでした!!

とりあえず作ったドットのパターン素材だけ

ドット

さみしい。いずれもっと増やしたい。

チェックのパターン素材は

Tartan Designer

この素晴らしいサイトで作成できます。

かわいいケーキのイラストは素材庭園さんよりお借りしました。

jQtouch

そんでそれをアプリの一部的な使い方ができるかなぁとか思い、jQtouchに組み込んでみました。

icon

iPhone,iPadの方はこちらからどうぞ。

一応iPhoneのフル画面に最適かしていますので

下のツールバー分ちょっと狭い感じですが、、、、。

以前jQueryMobileを使ってみたのですが、正直自分的にはjQueryMobileの方が良かったです。

いろいろカスタムもしやすそうだったし、情報も多かった。

jQtouchはあまり活発ではないようですね。

がしかし、一瞬でiPhoneサイトが完成します!

すばらしい!

スマフォ最適化の勉強中ですがアンドロイドを触ったことがない!!

うーんほしい。いろいろ試してみたい。

けどこれからはデータベースの勉強に没頭しよう。

 ヤバイ、、あまりに更新していないので広告が挿入。

なのでとりあえず。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>test</title>
<script type="text/javascript">
window.onload = function() {
    console.log('test' in window);
    test.addEventListener('click', function() { alert('click') }, false);
};
</script>
</head>
<body>
<div id="test">test</div>
</body>
</html>


これalertが出るんです。知りませんでした。いつもFirefox使ってたから。

IE、Chrome、SafariなんかはHTMLのidが自動的にグローバル変数?として

扱えるみたい?

いやぁ。もっと早くこんな情報に出会っていたかった。


それともうひとつ。

最近いまさらながらWSHの存在を知りVBScriptにてバッチファイルを作成してみました。

これ何気にすごい便利なんですね!DOMを使えば自在に自動でWEBにアクセスし放題。

単純作業にはもってこい。

DOMのアクセスはjQueryさんにお世話になりっぱなしでしたが、

少しネイティブなDOMを経験できました。

これまたもっと早く出会っていたかった。

そこでひとつ躓いたところ

WEBからとってきたデータをエクセルに書き出して、

そこからあるセルをダブルクリックで次のVBSファイルを

VBAから呼び出そうとしたんですが、

「呼び出し先が呼び出しを拒否しました」

エラーが出る。。。。

ダイアログやプレビュー画面、セルがアクティブ(編集中)に

他のシートを参照すると「呼び出し先が呼び出しを拒否しました」

エラーが出るみたいですね。

ダブルクリックじゃなくてちゃんとボタン作ればよかったんですが、

なかなか悩みました。



ついこないだやっと確定申告終わったぁ〜ってすがすがしい気分を

味わいつつ、時がすぎるのが早いもので。



calendar

S M T W T F S
      1
2345678
9101112131415
16171819202122
23242526272829
30      
<< April 2017 >>

profile

last entry:2013/06/10

selected entries

categories

archives

recent comment

search this site.

others