/*
このファイルを
を使ってHTML内に置くと、
"whiteareaID"というIDを付けたHTML要素の上部にCANVASが表示され、
自動的に動作を開始します。
(最初のH2タグの位置までをCANVASの縦サイズとしています)
以下は、ある程度コメントでプログラムの案内をしています。
*/
//オブジェクトに関数を書く様式でプログラムを書いています。
app = {
uid : Date.now(), //uidと言ってもデバッグプリントやHTML要素のIDとして使っているだけのものです
//ページ読み込み完了時の関数
onload : function( e ) {
console.log( this.uid, "onload" );
//CANVAS作成など
this.timerID = null;
this.timerMS = 120;
var canvasElement = document.createElement( "canvas" );
canvasElement.id = "canvas" + this.uid;
canvasElement.innerHTML = '';
canvasElement.style.backgroundColor = "RGB(0,32,96)";
this.p = document.getElementById( "whiteareaID" );
this.p.appendChild( canvasElement );
this.cc = document.getElementById( canvasElement.id ).getContext( "2d" );
//ccはCanvasContextの略です
//---vars1
//varsの中に星やカメラなどアプリケーションの動きに関する
//変数を置いています。「なんかいいことあるかな」と思って。
this.vars = {
image : new Image(),
pixelStart : 162,
cnt : 29,
}
this.vars.image.onload = function( e ) {
}
this.vars.image.src = "20191103-indexJS/Sheet1.png";
//画面の上のほうクリックで情報表示
var app = this;
this.pixel = this.vars.pixelStart; //2とかにするとファミコンみたいな画質になります。
if( 1 ) {
this.cc.canvas.style.imageRendering = "pixelated";
this.cc.canvas.style.imageRendering = "optimizeSpeed";
}
this.onresize();
abc = false;
setTimeout( function() { abc = true; }, 3000 );
addEventListener( "resize", app.onresize.bind( app ), false );
addEventListener( "scroll", app.onscroll.bind( app ), false );
//このbindというのは、その関数(たとえばonresize)実行時、
//その関数内でthisにあたるオブジェクトを
//引数で指定したオブジェクトに変更するというものです。
//これをやらないとthisはwindowになります。
},//onload()
//---onresize
//ウィンドウリサイズ時の関数
onresize : function( e ) {
console.log( this.uid, "onresize" );
var canvasElement = this.cc.canvas;
var h2;
//homepage6047のページの最初のH2タグ(日記日付を書いているタグ)を検索
for( var i = 0; i < this.p.children.length; i++ ) {
var child = this.p.children[ i ];
if( child.tagName == "H2" ) {
h2 = child;
break;
}
}
//そのH2タグの位置までをCANVASの縦サイズとする
var pr = this.p.getBoundingClientRect();
var w = pr.width;
var h = h2.offsetTop;
with( canvasElement.style ) {
position = "absolute";
left = "0px";
top = "0px";
width = w + "px";
height = h + "px";
zIndex = -2;
}
this.cc.canvasWidth = w;
this.cc.canvasHeight = h;
//cssのwidthはそのままに、canvasのwidthをpixelで割った小さいサイズに
//するので画質が落ちます。
this.cc.canvas.width = w / this.pixel;
this.cc.canvas.height = h / this.pixel;
this.cc.scale( 1 / this.pixel, 1 / this.pixel );
this.draw( this.cc );
this.onscroll(); //このonscroll関数の中にsetInterval()があり、アニメ開始となる。
},//onresize()
//---draw
//画面描画
draw : function( cc ) {
cc.clearRect( 0, 0, cc.canvasWidth, cc.canvasHeight );
let h = cc.canvasHeight;
let rate = h / this.vars.image.height;
let w = this.vars.image.width * rate;
let offsetW = ( cc.canvasWidth - w ) / 2;
cc.drawImage( this.vars.image, offsetW, 0, w, h );
if( this.pixel == 1 ) {
cc.font = "24px ''";
cc.fillStyle = "RGBA(255,255,255,0.5)";
let text = "スーパーファミコンみたいなモザイク処理… だけ";
let x = ( cc.canvasWidth - cc.measureText( text ).width ) / 2;
let y = cc.canvasHeight - 8;
cc.fillText( text, x, y );
}
},//draw()
//---onscroll
//ウィンドウがスクロールされたときの関数
onscroll : function( e ) {
//画面外ならスクリプトを停止する。画面内ならスクリプトを開始する。
//そうしないと常にパソコンのCPUを使い続ける(熱を出し続ける)ので…
var rect = this.cc.canvas.getBoundingClientRect();
var canvasTop = rect.top;
var canvasBottom = rect.top + rect.height;
var windowBottom = window.innerHeight;
var overTheTop = canvasBottom - 200 < 0;
var overTheBottom = canvasTop + 200 > windowBottom;
var isVisible = !overTheTop && !overTheBottom;
if( this.timerID && !isVisible ) this.stop();
else if( !this.timerID && isVisible ) this.start();
},
//この setInterval() でアニメ開始となる
start : function() {
console.log( this.uid, "start" );
this.timerID = setInterval( this.frame.bind( this ), this.timerMS );
// this.frame();
},
//アニメ停止
stop : function() {
console.log( this.uid, "stop" );
clearInterval( this.timerID );
this.timerID = 0;
},
//setInterval()から呼ばれる関数(映像1フレーム分の処理)
frame : function() {
if( ! abc ) return;
this.draw( this.cc );
if( this.pixel == 1 ) return;
this.pixel = 0.2 * this.vars.cnt * this.vars.cnt + 0.8;
this.vars.cnt --;
//check.
if( this.pixel < 1 ) {
this.pixel = 1;
}
this.onresize();
},//frame()
};//app
//ページ読み込み完了で、onload関数を実行する
addEventListener( "load", app.onload.bind( app ), false );
//The End of the Script.