背景画像を設定するUserScript
下の画像ファイルのリスト(list)から壁紙(背景画像)を表示します。
JavaScriptのほうをもう少しなんとかしたいので、ご意見をよろしくおねがいします
TL;DR
下にあるの画像ファイルのリストから壁紙を表示します
APIでテーブル(csvファイル)を読んでページメニューに表示
CSSを書き換えて、壁紙を変更、表示
背景画像リスト
(以下、ややこしいですが、リスト(list)という名のテーブルです)
テーブル記法で壁紙のリストを記述する
テーブルは、APIからアクセスできる
1行目は見出し(読み飛ばす)
そして、
1列目はラベル(ページメニューに表示)
2列目が画像ファイルのURL(背景画像になる)
3列目以降はコメント(無視される)
となっています。
テーブル名は、APIから読み出す都合上、list(固定)となっております。
テーブル名を変更する場合はスクリプト(script.js)と併せて変更してください。
listラベル | URL | コメント |
1 お城 | [https://i.gyazo.com/dfc1f0531bd78404ccacb74921f48f89.jpg] | /masui/壁紙 より |
2 青空 | [https://i.gyazo.com/4bb0a5bc34948a548ddfd92d7ad39788.jpg] | 自由に使っていいそうなので |
3 花 | [https://i.gyazo.com/7536a66e09cb7b9714b9d24d17638b15.jpg] | 使ってみた |
4 なんだっけ | [https://i.gyazo.com/2f74c77562bd663e934447eeb38a3087.jpg] | 自由ってすばらしい。 |
リストの分割もできる
list5 | [https://i.gyazo.com/14a9b5c0efaec1f970bcc0c083e6a0c8.png] | /masui/壁紙 より |
6 海とヨット | [https://i.gyazo.com/86b9c9e6c6961029baafc802392df14a.jpg] |
7 夕焼け | [https://i.gyazo.com/34ff46bfde0226b0629688ad059d740d.png] | 朝焼けだったらどうしよう |
8 山霧 | [https://i.gyazo.com/769b3290aec0248c8ca270cf3a7de06b.png] |
9 | [https://i.gyazo.com/feea0947664de8376739ae478cec0fba.png] |
やってみよう
自分のページを変更
1 UserCSSの設定(これ以外の設定は、一時的に外しておくこと)
css@import "/api/code/customize/背景画像を設定するUserScript/style.css";
2 UserScriptの設定(これ以外の設定は、一時的に外しておくこと)
jsimport '/api/code/customize/背景画像を設定するUserScript/script.js'
3リロード
UserCSSとUserScriptを読み込んで反映させる
ページメニューに「壁紙」が追加されていれば、とりあえず OK
動作確認
ページメニューに「壁紙」が追加される
壁紙のメニューに背景画像のリストが表示される
リストの項目を選択すると、背景画像が表示される
「ランダム」を選択すると、リスト中の背景画像をランダムに表示される
「消す」を選択すると、背景画像が消える
編集権があるならば、リストの追加、削除など、編集してみる
リロードして、編集内容が反映されているか確認
あとは他のUserCSSとUserScriptとのすり合わせを行ってください
コピペして使う場合の注意点
お試し用ということリストのURLをこのプロジェクト宛に固定しています
スクリプトを修正してください
確認のため、リストの追加、削除など、編集してみてください
リロードして、編集内容が反映されているか確認
修正が反映されるのはリロード時です
何につかうのか
複数のScrapboxプロジェクトを背景画像によって識別する(オススメ)
背景画像に意味のある画像を表示させる
カレンダー
重点目標やスローガン
各種チートシート
ランダムネスを利用した、強制連想法(アイデア出し)に
気分転換に
うまく表示されないときは
おそらく、だいたいCSSの表示の優先順位のせいです。
CSSの優先順位、よくわかんねーです。
わかっていることを書きます。
settings や UserCSSの設定のbody要素に、
background-color:
や
background-image:
が設定されていると、そちらの設定のほうが優先されて表示されなくなります。
また、style要素を書き換えるタイプのUserScriptだと、あとから実行したほうが該当箇所を上書きしてしまいます。
そういうわけで、意外に簡単に表示されなくなります。
!important
でなんとかする手もあるのですが、それだと原因の特定が難しくなります。
あとは、言いにくいけど、たぶんバグがあるよね。(できれば直したいです)
UserCSSの解説
body要素
前述のように、外部CSSのほうが優先されるので、body{} は書かないことにします。
ページ
hover の状態で不透明になり、非hoverの状態のときは少しだけ半透明になるようにしています。
style.css.page {
/* 透明度の設定 */
opacity:0.8;
}
.page:hover {
/* 不透明 */
opacity:1;
}
ページリスト(透明/不透明の設定のみ)
style.css .page-list {
/* 透明度の設定 */
opacity:0.5;
}
.page-list:hover {
/* 不透明 */
opacity:1;
}
関連ページリスト(透明/不透明の設定のみ)
style.css .related-page-list {
/* 透明度の設定 */
opacity:0.5;
}
.related-page-list:hover {
/* 不透明 */
opacity:1;
}
UserScriptの解説
正直、JavaScriptはよくわかんねーです。
わらかんなりに説明します。なので、間違ったことを書いているかもしれません。ご容赦を。
やっていることは、
APIを叩いてCSVファイルを読み込む
ページメニューに追加
style要素を使ってCSSを変更し、背景画像を変更
やっていない(できないていない)ことは
画像ファイルのURLが妥当かどうかのチェック
エラーデータのリストからの除外
データ件数の制限(データが増えたらどうしよう)
重複チェック
その他、エラー処理とか例外処理とかデータチェックとか
など、いろいろ
最初のほうの url の値は、サンプルとして、このページのリスト(list、ファイル名だと、list.csv)決め打ちにしています。
スクリプトをコピペして使う場合は、この値を変更してください。
script.js const url = '/api/table/'
//+ scrapbox.Project.name + '/' //カレントのプロジェクトを指定
+ 'customize/' //プロジェクト名
+ '背景画像を設定するUserScript' //ページ名
+ '/list.csv' // テーブル名+ '.csv' (csvファイル名)
const lists = new Promise((resolve, reject) => {
fetch(url)
.then(response => response.text())
.then(text =>
text.split('\n').slice(1)
.map(line => line.replace(/^,/g,""))
.join('\n') )
.then(resolve)
.catch(reject)
})
const change_css = url => {
//console.log(url)
let style = document.getElementById('__bgi__')
if (style){ style.remove() }
const css =
'body {'
+ ' background-image: url("' + url + '");'
// どうしても上手くいかないときのみ、↓こちらをお試しください
//+ ' background-image: url("' + url + '") !important;'
+ ' background-repeat: repeat-y;'
+ ' background-attachment: scroll;'
+ ' background-position: center top ;'
+ ' background-size: 100% auto;'
+ '}'
//console.log(css)
style = document.createElement('style')
style.setAttribute('id', '__bgi__')
style.appendChild(document.createTextNode(css))
document.head.appendChild(style)
}
const choice = (arr) => arr[Math.floor(Math.random()*arr.length)]
scrapbox.PageMenu.addMenu({
title: '壁紙',
image: 'https://gyazo.com/8a40fddd4f7225e0226401afff3e5795/raw',
// アイコンは https://icooon-mono.com/ から
onClick: async () => {
scrapbox.PageMenu('壁紙').addItem({ title: 'Now loading...', onClick: () => null })
await lists.then((text) => {
scrapbox.PageMenu('壁紙').removeAllItems()
scrapbox.PageMenu('壁紙').addItem({
title: '消す',
onClick: () => {
const style = document.getElementById('__bgi__')
if (style) { style.remove() }
}
})
const urls = text.split("\n")
.map( line => {
//console.log(line)
const res = line.split(',')
const name = res[0]
const url = res[1].replace(/\[|\]/g,"")
//console.log(url)
scrapbox.PageMenu('壁紙').addItem({
title: name,
onClick: () => {change_css(url)}
})
return url
})
//console.log(urls)
scrapbox.PageMenu('壁紙').addItem({
title: 'ランダム',
onClick: () => {change_css(choice(urls))}
})
})
}
})