Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【JavaScript】conic-gradient生成ツールのコード

 どうも!LSSです!!

 

先日公開した

little-strange.hatenablog.com

の、ツール自体のコードです。

ざっくりした解説もつけてみました。

【JavaScript】コード作成ツールの作り方【さわり】 - Little Strange Software

【JavaScript】コード作成ツールの作り方【コード出力篇】 - Little Strange Software

を基本とした、ちょっとややこしくなった(カラーパレットを増やせる部分)感じですね。

 

 

コード

<p>繰り返し回数<br /><input id="ctrrng" style="width: 100%;" max="36" min="1" type="range" value="1" /></p>
<p><input id="ctradd" type="button" value="色追加" /></p>
<div id="ctr"></div>
<div id="gamen"></div>
<p> </p>
<p>コード</p>
<div id="cgamen" style="background-color: #eeeeee; padding: 0.6em; border-radius: 5px;"></div>

<script>

cl=['#000000','#ffffff'];
ctrw();
gw();
ctr.addEventListener('input',fctr,false);
ctrrng.addEventListener('input',gw,false);
ctradd.addEventListener('click',fctradd,false);

function fctradd(e){
cl.push('#ffffff');
ctrw();
gw();
}

function fctr(e){
for(i=0;i<cl.length;i++){
cl[i]=document.getElementById('ctrcl'+i).value;
}
gw();
}

function ctrw(){
ctxt='';
for(i=0;i<cl.length;i++){
ctxt+='<input id="ctrcl'+i+'" type="color" value="'+cl[i]+'"/>';
}
ctr.innerHTML=ctxt;
}

function gw(){
txt='<style>\n';
txt+='.grdx{\n';
txt+='width:300px;\nheight:200px;\n';
txt+='background-image:'+(ctrrng.value=='1'?'':'repeating-')+'conic-gradient(';
for(i=0;i<cl.length;i++){
txt+=cl[i]+',';
}
txt+=cl[0]+(ctrrng.value=='1'?'':' '+(360/ctrrng.value)+'deg')+');\n';
txt+='}\n';
txt+='</style>\n';
txt+='<div class="grdx"></div>\n';
gamen.innerHTML=txt;
cgamen.innerHTML=txt.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br/>');
}

</script>

 

コードをざっくり分けると、

  • 画面を構成するHTML部分
  • 配列変数の初期設定や、初回ページ表示時の画面構築の呼び出し、イベントリスナーを設定する初期設定部分
  • 「色追加」ボタンを押した時の処理を行う fctradd関数
  • カラーパレットの色が変更された時の処理を行う fctr関数
  • カラーパレットを画面に出力する ctrw関数
  • サンプルとコードを画面に出力する gw関数

に分かれます。(関数名はテキトーにつけた任意の名前です)

 

 

ツールを構成するHTML

<p>繰り返し回数<br /><input id="ctrrng" style="width: 100%;" max="36" min="1" type="range" value="1" /></p>
<p><input id="ctradd" type="button" value="色追加" /></p>
<div id="ctr"></div>
<div id="gamen"></div>
<p> </p>
<p>コード</p>
<div id="cgamen" style="background-color: #eeeeee; padding: 0.6em; border-radius: 5px;"></div>

 

上から、
「繰り返し回数を設定するスライダー」
「色追加ボタン」
「id="ctr"と名付けた、カラーパレット配置用の領域」
「id="gamen"と名付けた、サンプル表示用の領域」
「id="cgamen"と名付けた、コード表示用の領域」
となっています。

 

 

初期設定

cl=['#000000','#ffffff'];
ctrw();
gw();
ctr.addEventListener('input',fctr,false);
ctrrng.addEventListener('input',gw,false);
ctradd.addEventListener('click',fctradd,false);

 

まず、「cl」という配列変数を用意し、「#000000」と「#ffffff」という2つの色コードをデフォルトとして入れています。

これがグラデーションの各色を管理する変数で、これにより最初からある2つのカラーパレットのデフォルトが黒(#000000)と白(#ffffff)となります。

 

そして、カラーパレットを書き出す「ctrw」とサンプル・コードを書き出す「gw」の自作関数を呼び出して、画面を完成させています。

 

あとは、数が操作で変動するカラーパレットたち…を配下に持つ「id="ctr"」というdiv要素に「inputイベントが発生したらfctr関数を実行する」イベントリスナーを設定。

※実際にイベントを発生させるのはその配下に書き出した各カラーパレット達ですが、イベントは発生すると上位要素に伝播するので、それらをまとめたdivタグに設定するだけでイベントを監視できます。今回のように「後から追加したinputタグに対してもイベントリスナーを働かせたい」場合に有効な方法です。

 

あとは「繰り返し回数」を調節できるスライダー「ctrrng」が変更された時に、サンプルとコードを書き出すgw関数を呼び出すというイベントリスナーの設定。

「色追加」ボタンである「ctradd」をクリックした時に、カラーパレットを増やすfctradd関数を呼び出すイベントリスナーを設定しています。

 

今回のツールの仕事としては、主な部分は上記だけで、あとは下請けとなる各関数におまかせ、ですね^^

 

 

fctradd関数 「色追加」ボタンが押された時の処理

function fctradd(e){
cl.push('#ffffff');
ctrw();
gw();
}

 

配列変数「cl」に '#ffffff' を追加するだけの簡単なお仕事ですw

「cl」を元に、カラーパレットを表示する処理は「ctrw」関数のほうに任せているので、ctrwの呼び出しと、追加された時点でグラデーションのサンプルやコードも変わってくるのでgwも呼び出しています。

 

 

fctr関数「カラーパレット」の色が変更された時の処理

function fctr(e){
for(i=0;i<cl.length;i++){
cl[i]=document.getElementById('ctrcl'+i).value;
}
gw();
}

 

「どのカラーパレットが変更されたか」は気にせず、「いずれかのカラーパレットが変更された時」に実行される処理です。

for構文によるループ処理で、配列変数「cl」の全ての要素に対して「対応するカラーパレットの現在の色コード(value)を各clに代入」するという処理を行っています。

それが終わると、gw関数を呼び出してサンプルやコードの再描画を行っています。

 

 

 

ctrw関数 「カラーパレット」を書き出す処理

function ctrw(){
ctxt='';
for(i=0;i<cl.length;i++){
ctxt+='<input id="ctrcl'+i+'" type="color" value="'+cl[i]+'"/>';
}
ctr.innerHTML=ctxt;
}

 

カラーパレットとなる「type="color"」なinputタグを、配列変数「cl」の要素数分繰り返して繋げた文字列を生成。

その後、id="ctr"なdivタグに対してそれを書き出す(innerHTML)という事を行っています。

 

 

gw関数 「サンプル」と「コード」を書き出す処理

function gw(){
txt='<style>\n';
txt+='.grdx{\n';
txt+='width:300px;\nheight:200px;\n';
txt+='background-image:'+(ctrrng.value=='1'?'':'repeating-')+'conic-gradient(';
for(i=0;i<cl.length;i++){
txt+=cl[i]+',';
}
txt+=cl[0]+(ctrrng.value=='1'?'':' '+(360/ctrrng.value)+'deg')+');\n';
txt+='}\n';
txt+='</style>\n';
txt+='<div class="grdx"></div>\n';
gamen.innerHTML=txt;
cgamen.innerHTML=txt.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br/>');
}

 

サンプルとして実際にブラウザ上で解釈される「HTMLコード」を組み立てて、gamen.innerHTML=txt;

で書き出す処理を行っています。(\nは改行コード)

 

サンプルを書き出した後、その組み立てたHTMLコードを

txt.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br/>')

で「タグ無効化(タグがそのままブラウザ上に表示される状態)」変換したものを、「コード」であるid="cgamen"なdiv要素に書き出しています。

 

※タグ無効化処理…まず「全ての(g)」「&」を「&amp;」に変換、したものを、全ての「<」を「&lt;」に変換、したものを…(以下略)

 

 

以上がこのツールの全貌です

「関数」を「下請け」として仕事を任せる、という事にすると、ざっくりとした全体の処理は「初期設定」の数行だけになります。

 

今回は「サンプルを書き出す元となるカラーパレットも設定に応じたものを都度書き出す」という二重の処理になってるのがちょっとややこしかったですが、「仕事の割り振り」を考えて仕組みを構築する事で、全体の流れが完成します^^

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^