ブラウザの中でスタンド使いになってみた。
はじめに
今までは真面目に開発していたが、少しふざけたものを作ってみようと思い、今回のChrome拡張を作ってみました。
それと以前拝見した以下の記事や
やAtomのactivate-power-modeに影響され、今回作るChrome拡張を決めました。
リリースしたChrome拡張概要
textareaやinput上でキータイプをするとエフェクトが表示されます。
先ほど紹介したChrome拡張と同様の仕様ですね。
そこにactivate-power-modeのコンボのような連続したキータイプの際に別のエフェクトを発生させます。
キータイプを500ms以内の間隔で連続30回以上タイプした後にエンターキーを押すとセリフと効果音が表示されます。
タイプするたびにlocalstorageにタイプした時間と連続タイプ数を保存します。
Jojo experience - chromeウェブストア
作り方
ソースは以下のリポジトリにあります。
temori1919/jojo_experience
今回はcontent_scriptsスクリプトという形式で作成します。
{
"manifest_version": 2,
"name": "Jojo experience",
"version": "1.0.0",
"description": "スタンド使いになれるChrome Extensionです",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": [
"jquery.min.js",
"soundEffect.js",
"caretposition.js"
]
}
],
"web_accessible_resources": [
"images/*"
],
"permissions": [
"storage"
]
}
キャレット位置の取得にcaretposition.jsというjsライブラリを使用させていただきました。
document.onkeydown = e => {
const current = document.activeElement
if (e.key === 'Backspace') {
return true
}
if (current.type === 'textarea' || current.type === 'text' || current.type === 'search') {
(async () => {
// タイピング時間の記録
let type_time = localStorage.type_time
// タイピング数のカウント
let type_count = localStorage.type_count
// タイピングの感覚が500ミリ秒以下ならタイピング数をカウントする
if (type_time !== undefined && type_count !== undefined && (new Date().getTime() - type_time) < 500) {
localStorage.type_count = parseInt(type_count) + 1
} else {
localStorage.type_count = 1
}
localStorage.type_time = new Date().getTime()
const isEnter = e.key === 'Enter'
// キャレットの位置の取得
const caretPosition = Measurement.caretPos(current)
let prefix = isEnter ? 'ora2' : 'ora'
let imgUrl = chrome.extension.getURL('images/' + prefix + '.png')
// オラ
let image = await appnedCss('images/' + prefix + '.png', isEnter ? rand(80, 100) : rand(10, 20), caretPosition.top + rand(-10, 10), caretPosition.left + rand(-10, 10))
image = await animateRemove(image, isEnter, caretPosition)
// タイプカウントの回数が30以上でエンターをタイプしたらセリフと効果音を表示
if (isEnter && type_count > 30) {
localStorage.type_count = 1
// 時
image = await appnedCss('images/toki.png', rand(80, 100), caretPosition.top, caretPosition.left, 400)
image = await animateRemove(image, isEnter, caretPosition, 200)
// エフェクト
image = await appnedCss('images/effect' + rand(1, 4) + '.png', rand(80, 100), caretPosition.top, caretPosition.left, 600)
await animateRemove(image, isEnter, caretPosition)
}
})()
}
}
/**
* 乱数生成
*
* @param min
* @param max
* @returns {number}
*/
function rand(min, max) {
return Math.floor(Math.random() * (max - min) + min)
}
/**
* imgをappend
*
* @param imgUrl
* @param size
* @param top
* @param left
* @param delay
* @returns {Promise<any>}
*/
function appnedCss(imgUrl, size, top, left, delay) {
return new Promise(resolve => {
delay = delay === undefined ? 0: delay
setTimeout(() => {
imgUrl = chrome.extension.getURL(imgUrl)
img = $(`<img width="${size}">`)
img.attr('src', imgUrl)
img.css({
'position': 'absolute',
'top': top,
'left': left,
'zIndex': 100000
})
$('body').append(img)
resolve(img)
}, delay)
})
}
/**
* imgのアニメーションと削除
*
* @param img
* @param isEnter
* @param positon
* @param delay
* @returns {Promise<any>}
*/
function animateRemove(img, isEnter, positon, delay) {
return new Promise(resolve => {
delay = delay === undefined ? 0: delay
setTimeout(() => {
const size = isEnter ? rand(80, 100) : rand(10, 20)
img.animate({
'top': positon.top + rand(-40, 40),
'left': positon.left + rand(-40, 40),
'width': size + (isEnter ? rand(30, 50) : rand(10, 20)),
'opacity': 0
}, 1000, () => {
img.remove()
})
resolve(null)
}, delay)
})
}
本体はES2017で書いています。
コメントは適当なのでご容赦下さいw
キータイプするとタイプした時間とキータイプ回数がカウントUPされます。
前回時間とタイプした時間が500ms以内ならカウントUP、それ以外なら1を保存します。
それとimgを追加してアニメーションで表示しています。
また、エンターが押された後の処理はasync awaitで直列的に処理させるようにしています。
最後に
ちょっとふざけたものを作りたくて、今回の拡張をリリースしました。
正直邪魔にしかならない拡張機能なので、お試しで入れた場合は少し使って削除するのがいいと思いますww
興味がある方は追加してみて下さい。
Discussion