表示調整
閉じる
挿絵表示切替ボタン
▼配色
▼行間
▼文字サイズ
▼メニューバー
×閉じる

ブックマークに追加しました

設定
0/400
設定を保存しました
エラーが発生しました
※文字以内
ブックマークを解除しました。

エラーが発生しました。

エラーの原因がわからない場合はヘルプセンターをご確認ください。

ブックマーク機能を使うにはログインしてください。
とある割烹芸人の開発日誌 ~100日以内に割烹エディターをリリースする割烹芸人~  作者: とある割烹芸人まーくつーせかんど
α版への道
15/48

44日目 割烹芸人の開発4

正直コード見ても面白くないと思うので後書きだけ眺めてもらえばいいかも。

今回はカスタム区切りを作っていきます。


editor.jsのプラグインにはセパレーターもあるのですが、設定の種類がないのでもう少しカスタマイズします。


挿絵(By みてみん)



デフォルトだとこの種類しかなくてあんまり拡張できないのでカスタマイズします。


具体的には


・線の太さ

・線の種類

・線の色


を指定できるようにします。ということでカスタムブロックを作っていきます。まずはSepatatorクラスを作ります。



class Separator{


}



constructor({data, config, api}){

this.api = api;


this.data = {

type: data.type !== undefined ? data.type : 'solid',

width:data.width !== undefined ? data.width :'medium',

color:data.color !== undefined ? data.color :'#000',

};


this.settings = [

{

name:'solid',

icon:'実線'

},

{

name:'dashed',

icon:'破線'

},

{

name:'dotted',

icon:'点線'

},

{

name:'thin',

icon:'細線'

},

{

name:'medium',

icon:'普通'

},

{

name:'thick',

icon:'太線'

},

{

name:'color',

icon:'線色'

}


]


this._element = this.drawView();

}


render(){

return this._element;

};


drawView() {

let div = document.createElement('DIV');


div.classList.add('separetor');


return div;

}


save(toolsContent){

return{

type:this.data.type,

width:this.data.width,

color:this.data.color

}

}


static get toolbox(){

return{

icon:'区切',

title:'区切り線の挿入'

};

}



次にレンダー、コンストラクタ、セーブ、ツールボックスです。


drawViewでdivを指定して、これにボーダーを付けることで区切り線を実現します。小説家になろうではhrにスタイルを含めるのが無理なのでdivを使ってます。


また本家でiconはSVGを使ってますが、日本語には漢字という便利なものがあるのでそれでいきます。正直日本だけで運用するなら画像より漢字の方が情報量と正確性があっていいと思います。


世界向けに作るならまぁ画像の方が便利そうではありますね。今回は小説家になろう限定なのでそれでいいと思う。


dataのパラメータとして、type、width、colorを用意しました。


線の種類、太さ、色をここに入れるようにしてます。


種類と、太さは3つのボタンで選べるようにして、colorはinputで選択できるようにします。


ということでrendersettingsを設定します。


renderSettings(){

const wrapper = document.createElement('div');


this.settings.forEach(tune =>{

let button = document.createElement('div');


button.classList.add(this.api.styles.settingsButton);


button.innerHTML = tune.icon;

wrapper.appendChild(button);


if(tune.name === 'solid' || tune.name === 'dashed' || tune.name === 'dotted'){

button.classList.toggle(this.api.styles.settingsButtonActive, tune.name === this.data.type);

}else if(tune.name === 'thin' || tune.name === 'medium' || tune.name === 'thick'){

button.classList.toggle(this.api.styles.settingsButtonActive, tune.name === this.data.width);

}else{

if(this._element.innerHTML !==''){

button.classList.toggle(this.api.styles.settingsButtonActive);

}

}


button.addEventListener('click', ()=>{

if(tune.name === 'solid' || tune.name === 'dashed' || tune.name === 'dotted'){


button.classList.add(this.api.styles.settingsButtonActive);


this._changeBorderType(tune.name);


wrapper.querySelectorAll(`.${this.api.styles.settingsButton}`).forEach(el => {

if(tune.name==='solid' && (el.innerHTML === '破線' || el.innerHTML === '点線') ){

el.classList.remove(this.api.styles.settingsButtonActive);

}else if(tune.name==='dashed' && (el.innerHTML === '実線' || el.innerHTML === '点線') ){

el.classList.remove(this.api.styles.settingsButtonActive);

}else if(tune.name==='dotted' && (el.innerHTML === '破線' || el.innerHTML === '実線') ){

el.classList.remove(this.api.styles.settingsButtonActive);

}

});

}else if(tune.name === 'thin' || tune.name === 'medium' || tune.name === 'thick'){


button.classList.add(this.api.styles.settingsButtonActive);


this._changeBorderWidth(tune.name);


wrapper.querySelectorAll(`.${this.api.styles.settingsButton}`).forEach(el => {

if(tune.name==='thin' && (el.innerHTML === '普通' || el.innerHTML === '太線') ){

el.classList.remove(this.api.styles.settingsButtonActive);

}else if(tune.name==='medium' && (el.innerHTML === '太線' || el.innerHTML === '細線') ){

el.classList.remove(this.api.styles.settingsButtonActive);

}else if(tune.name==='thick' && (el.innerHTML === '普通' || el.innerHTML === '細線') ){

el.classList.remove(this.api.styles.settingsButtonActive);

}

});

}else if(tune.name === 'color'){

button.classList.toggle(this.api.styles.settingsButtonActive);

if(button.classList.contains(this.api.styles.settingsButtonActive)){

this._showColorPicker();

}else{

this._hideColorPicker();

}



}else{


}

});

});


return wrapper;

}


_borderStyleSet(){

this._element.setAttribute("style", `border-top:${this.data.width} ${this.data.type} ${this.data.color};`);

}


_changeBorderWidth(tune){

this.data.width=tune;

this._borderStyleSet();

}



_changeBorderType(tune){

this.data.type=tune;

this._borderStyleSet();

}


_showColorPicker(){

const input = document.createElement('input');


input.type = 'color';

input.value = this.data.color;

this._element.appendChild(input);


input.onchange = () => {

this.data.color = input.value;

this._borderStyleSet();

};


}


_hideColorPicker(){

this._element.innerHTML='';

}


挿絵(By みてみん)


種類と太さはそれぞれ1つしか有効にならないように、どれかがアクティブになったらそれ以外を非アクティブ化してます。


正直、一回全部非アクティブにして、該当だけをアクティブにするのがキレイなコードかなと思います。今はちょっと汚い。そのうち直す(たぶん)


showColorPickerで線色を押すとカラーボックスが出てくるようにして、選んだ色を線に反映させるようにしています。


挿絵(By みてみん)


ボタンを非アクティブ化すれば_hideColorPickerで消します。


サニタイズとヴァリエーションは指定してません。というのもユーザーが値を入力できないからです。


ということで完成版です。


挿絵(By みてみん)



はい、そんなわけで区切り線の完成です。

挿絵(By みてみん)


だいたいエラー出して怒られて修正してを繰り返して完成させていきます。

評価をするにはログインしてください。
ブックマークに追加
ブックマーク機能を使うにはログインしてください。
― 新着の感想 ―
このエピソードに感想はまだ書かれていません。
感想一覧
+注意+

特に記載なき場合、掲載されている作品はすべてフィクションであり実在の人物・団体等とは一切関係ありません。
特に記載なき場合、掲載されている作品の著作権は作者にあります(一部作品除く)。
作者以外の方による作品の引用を超える無断転載は禁止しており、行った場合、著作権法の違反となります。

この作品はリンクフリーです。ご自由にリンク(紹介)してください。
この作品はスマートフォン対応です。スマートフォンかパソコンかを自動で判別し、適切なページを表示します。

↑ページトップへ