アイテム' + itemCount + '
' + '詳細' + itemCount + '
' + '通常inputタグで「autocomplete="off"」とすると、自動入力が阻止できる。 ただChromeでは(バージョン 40.0.2214.93現在)この設定が反映されず自動入力されてしまい、思わぬトラブルになってしまう。
クライアント側のChrome設定で阻止するのも何だか。 力技ですが、HTMLにダミーのパスワードタグを記述しておくと回避できる模様。
HTML5のグラフライブラリ「Flotr2」を使ってみる。
JavaScriptは「flotr2.min.js」を読み込み、表示する要素のあとにグラフ実行スクリプトを記述する。 ※データはあらかじめスクリプト等で、多次元配列を生成 ※getElementById()にidを指定 ※canvasを利用するので、グラフ表示幅、高さを指定
(function function_name(container, horizontal) { var graph = Flotr.draw(container, graph_data, {options}); })(document.getElementById(id));
(function basic_pie(container) {
var graph;
graph = Flotr.draw(
container,
company_sales_graph_values,
{
HtmlText : false,
grid : {
verticalLines : false,
horizontalLines : false
},
xaxis : { showLabels : false },
yaxis : { showLabels : false },
pie : {
show : true,
explode : 6
},
mouse : { track : true },
legend : {
position : 'ne',
backgroundColor : '#ffffff'
}
}
);
})(document.getElementById("values1-graph"));
(function bars_stacked(container, horizontal) {
var graph, i;
graph = Flotr.draw(
container,
month_sales_graph_values,
{
legend : {
backgroundColor : '#D2E8FF' // Light blue
},
bars : {
show : true,
stacked : true,
horizontal : horizontal,
barWidth : 0.6,
lineWidth : 1,
shadowSize : 0
},
xaxis : {
noTicks : 12,
tickFormatter : function (n) {
n = Math.round(n);
return n + '月';
},
min: 1,
max: 12
},
mouse : { track : true },
grid : {
verticalLines : horizontal,
horizontalLines : !horizontal
},
legend : {
position : 'ne',
backgroundColor : '#ffffff'
}
});
})(document.getElementById("values2-graph"));
HTML5エキスパートで有名な吉川さん(同性w)からCodeIQの問題があったので挑戦!
「DOM操作の最適化によるJavaScriptチューニングにチャレンジ!」
var button = document.querySelector('button'),
ul = document.querySelector('#output'),
itemCount = 0;
function addItems() {
for ( var i = 0; i < 10; i++ ) {
itemCount++;
ul.innerHTML += ''
+ 'アイテム' + itemCount + '
'
+ '詳細' + itemCount + '
'
+ ' ';
}
}
30分くらいでざっとコーディングして提出
var button = document.querySelector('button'),
ul = document.getElementById('output'),
itemId = 0;
var itemTemplate = '';
var addCount = 10;
var output = document.getElementById("output");
function createItem() {
itemId++;
var item = new Object();
item.title = 'アイテム' + itemId;
item.detail = '詳細' + itemId;
return item;
}
function loadItemTemplate(item) {
var li = document.createElement('li');
var article = document.createElement('article');
var h1 = document.createElement('h1');
var p = document.createElement('p');
article.setAttribute('class', 'item');
h1.setAttribute('class', 'title');
p.setAttribute('class', 'detail');
h1.textContent = item.title;
p.textContent = item.detail;
article.appendChild(h1);
article.appendChild(p);
li.appendChild(article);
return li;
}
function addItems() {
for ( var i = 0; i < addCount; i++ ) {
itemTemplate = loadItemTemplate(createItem());
document.getElementById('output').appendChild(itemTemplate);
}
}
テンプレートのHTML生成がループしてるので無駄だなと思いつつ、この程度だと計測時間が変わらなかったのでとりあえず。
丁寧にアドバイスを頂きました。
var button = document.querySelector('button'),
ul = document.getElementById('output'),
itemId = 0;
var template;
var addCount = 10;
var li;
var article;
var h1;
var p;
loadItemTemplate();
function createItem() {
itemId++;
var item = new Object();
item.title = 'アイテム' + itemId;
item.detail = '詳細' + itemId;
return item;
}
function loadItemTemplate() {
template = document.createElement('li');
article = document.createElement('article');
h1 = document.createElement('h1');
p = document.createElement('p');
article.setAttribute('class', 'item');
h1.setAttribute('class', 'title');
p.setAttribute('class', 'detail');
article.appendChild(h1);
article.appendChild(p);
template.appendChild(article);
}
function bindItem(item) {
h1.textContent = item.title;
p.textContent = item.detail;
var itemRow = template.cloneNode(true);
ul.appendChild(itemRow);
}
function addItems() {
for ( var i = 0; i < addCount; i++ ) {
bindItem(createItem());
}
}
cloneNode()を利用してみたけど、なんかViewの分離がちょっと汚くなっちゃたかな? insertNode()とかを使って、ツリーを操作した方がスムーズなのかも。
ROMEのデモサイトで、HTML5 x WebGLを使ってミュージックビデオを作ろうというプロジェクトらしいです。
ライブラリは「Three.js」をメインに使っている模様。
WEBGL EXAMPLESにいくつかのサンプルがあります。 これとか凄い質感。 ソースどうやって吐き出してるんだろうか?
いちおう、サンプルコードは
3-dreams-of-blackからダウンロードできるみたいです。
3DやWebGLをネーティブでコーディイングするのはやっぱり大変! Flashだと「Alternativa3D」「 Away3D」「Papervision3D」らが有名ですが、JavaScriptの場合は「Three.js」「Sprite3D.js」「jQuery 3D」とかでしょうか?
この中でも「Three.js」が一番強力そう(妄想)なので試してみる事に。
この中に「example」があるので動作確認できます。
THREE.js Doc 引数説明とサンプルがあるので、どういう動作するのかの材料になるかと。
とりあえずメインの「three.js(three.min.js)」とパフォーマンス監視ツール「Stats.js」を読み込む
グラフィック描画するベースのhtml要素を追加し、JavaScriptで取得する。 ここまでは、何の知識もいらないかと。
var container;
container = document.getElementById('container');
3Dオブジェクトの視点であるCameraを追加するが、今回はOrthographicCamera()を利用する。
var left = window.innerWidth / - 2;
var right = window.innerWidth / 2;
var top = window.innerHeight / 2;
var bottom = window.innerHeight / - 2;
var camera = new THREE.OrthographicCamera(left, right, top, bottom, -2000, 1000);
camera.position.x = 200;
camera.position.y = 100;
camera.position.z = 200;
引数の内容は、
OrthographicCamera(left, right, top, bottom, near, far, projectionMatrix)
ちなみに、現在3種類のカメラがある。
・THREE.OrthographicCamera:平行投影(正投影) ・THREE.PerspectiveCamera:透視投影 ・THREE.CombinedCamera:透視投影と平行投影の複合
Sceneはグラフィックオブジェクトを配置する元のオブジェクトです。
scene = new THREE.Scene();
Three.jsの3Dオブジェクトは以下のものがあります。
・THREE.CubeGeometry ・THREE.CylinderGeometry ・THREE.ExtrudeGeometry ・THREE.IcosahedronGeometry ・THREE.LatheGeometry ・THREE.OctahedronGeometry ・THREE.PlaneGeometry ・THREE.SphereGeometry ・THREE.TorusGeometry ・THREE.TorusKnotGeometry ・THREE.BinaryLoader ・THREE.UTF8Loader
だいたい名前で想像がつくが、今回は直方体の CubeGeometry を利用。
MeshLambertMaterial() で光反射のマテリアルを作成。 元の3Dオブジェクトとマテリアルを引数に、Mesh()でCubeオブジェクトを作成し、Sceneに追加します。 (Three.jsの場合、Cubeオブジェクトというよりメッシュと言った方が通じるか?)
var geometry = new THREE.CubeGeometry(50, 50, 50);
var params = {
color: 0xffffff,
shading: THREE.FlatShading,
overdraw: true
};
var material = new THREE.MeshLambertMaterial(params);
var cube = new THREE.Mesh(geometry, material);
cube.scale.y = Math.floor(Math.random() * 2 + 1);
cube.position.x = Math.floor((Math.random() * 1000 - 500) / 50) * 50 + 25;
cube.position.y = (cube.scale.y * 50) / 2;
cube.position.z = Math.floor((Math.random() * 1000 - 500) / 50) * 50 + 25;
scene.add(cube);
Lightを追加する事で、3Dに影をつけて奥行き感を出します。
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.x = 0.5;
directionalLight.position.y = 1.5;
directionalLight.position.z = 3.5;
directionalLight.position.normalize();
scene.add(directionalLight);
var ambientLight = new THREE.AmbientLight(0x10);
scene.add(ambientLight);
Lightには以下のものがある。
・THREE.AmbientLight ・THREE.DirectionalLight ・THREE.PointLight ・THREE.SpotLight
どう違うかは、後に調べてみよう。。。
Renderer系には以下の種類があるようだが、今回は無難に CanvasRenderer を利用する。
・CanvasRenderer ・WebGLRenderer ・DOMRenderer ・SVGRenderer
CanvasRenderer.domElement をcontainer(HTML要素)に追加後、Scene と Camera をレンダリングする。
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
renderer.render(scene, camera);
とりあえず3D静止オブジェクトが描画される。
アニメーションさせる場合は requestAnimationFrame() で時間軸をつけてやる。
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
var timer = Date.now() * 0.0001;
camera.position.x = Math.cos(timer) * 200;
camera.position.z = Math.sin(timer) * 200;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
animate() でrequestAnimationFrame()を連続で呼び、render()で状態に応じてレンダリング処理している。
Cube Sample
Chrome環境で、テクスチャーをつけてないので結構スムーズに動きます。 何となく、Papervision3Dに近い気がしました。 ただ、これだけのサンプルだと何のイベントもないので「で?」ですねw 次は、イベント使ったサンプルを調べてみよう。
HTML5 Filesystem APIと「input type="file"」利用してドラッグ&ドロップを実現するサンプル input[type="file"]とFileSystem APIを連携する方法
最近、HTML5を高速化する方法が流行ってますね。
HTML5でアプリ!と言ってもやはりネイティブに比べると格段に遅いです。 とくに相対的にスマホやタブレットアプリの処理では顕著だと思います。 ブラウザベースなので、基本どうやってもネイティブには勝てないと思いますが、それでも現状より速くする手法は色々ありますよね。
サイバーエージェントの中の人、「HTML5 Web Applicationのつくりかた」の記事も参考にちょっとメモしてみました。
小さな画像はCSSに直接画像をbase64で埋め込む。
みたいな
画像をbase64に変換するには、プログラミングするもよし、ツールを使うもよし。
ちなみにPHPだったら、
いわゆる1枚画像で座標を指定して、画像をパーツを表示する手法 ゲームのテクスチャでよく使われる手法ですね。
ちなみに、Adobe Fireworks CS6からは標準で書き出し機能が搭載されました。 (それ以前は機能拡張で対応) CSSスプライト書き出し機能の使い方
これは言わずもがな。 ただ、高機能な分面倒かな?と
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = '画像URL';
$("#sample").attr('width', img.width);
$("#sample").attr('height', img.height);
ctx.drawImage(img, 0, 0, img.width, img.height);
※jQuery利用
画像サイズを取得して、Contextに描画する際にサイズ指定します。 事前にサイズがわかってる場合はCanvasにサイズ指定すればいいですが、それってどうよ?と個人的には思います。
MacBookPro Retinaの登場によりこれから、高解像度にも柔軟に対応する必要がでてきました。 そこで登場するのが恐らくSVGの技術かと。
Ai→Canvasっていうプラグインを使うと、ベジェ曲線とかパス情報データを書き出してくれます。 で、これをCanvas の Context に直接わりあてる何とも合理的な方法です。
転送データをJSONにしたり、圧縮をかける事によりデータ転送を減らすようにしてます。 (流石はソーシャルの中の人)
gzip転送する場合は、Apacheで mod_deflat を有効にする必要があります。
まぁ、普通のサービス運営ではここまでする機会はないとは思いますが、知っておく知識ではありますね。
SassはCSSを拡張して、効率よくコーディングできるメタ言語です。 ※「Sassを覚えよう!」、「Sass、そしてSassy CSS (SCSS)」などを参考
環境構築は「Scout」を利用します。 OSX専用なら「Codekit」ってのもあります。
Sassは、それだけでトピックが長くなりそうなので割愛(と言うか勉強中)
OptiPNGで必要の無い情報を削除し、画像容量を軽量化します。 画像数が多い場合には有利。
ちょっと高速化から話がずれますが、ブラウザ上でローカル処理をするとURLリンクが活用できません。 window.onhashchange を利用してページ遷移の履歴みたいに利用します。
http://hoge.com/page1#1
みたいな。 これでネット検索でアクセスした時に同じ結果を出す事ができます。
これも画像とは関係ないですが、HTMLの軽量化になるかと。 ただファイルアップする度にやる必要があるので、自動化する仕組みを作っておかないと忘れがちな作業ではありますが・・・。