saneatsu
11/25/2019 - 7:37 AM

JavascriptのTips

Jsのテキストを複数行にしながら作る方法

http://kimizuka.hatenablog.com/entry/2014/09/12/095957

拡張子を削除する

removeExtension (filename) {
  const reg=/(.*)(?:\.([^.]+$))/
  return filename.match(reg)[1]
},

拡張子だけ取得

getExtension (filename) {
  const reg=/(.*)(?:\.([^.]+$))/
  return filename.match(reg)[2]
},
var hoge = 'rdiempvthwomoyl.mp4'
const reg=/(.*)(?:\.([^.]+$))/

hoge.match(reg)
(3) ["rdiempvthwomoyl.mp4", "rdiempvthwomoyl", "mp4", index: 0, input: "rdiempvthwomoyl.mp4", groups: undefined]

hoge.match(reg)[2]
"mp4"

var fuga = 'aaa.bbb.ccc'
fuga.match(reg)
(3) ["aaa.bbb.ccc", "aaa.bbb", "ccc", index: 0, input: "aaa.bbb.ccc", groups: undefined]

URLからファイル名を取得する

const url = 'https://storage.googleapis.com/test_anime_afreco_api_image/20191226053220_11cc87e91d9b946c/without_back_2_201912261433_iafsxkikweqdhav.mp4'

// 拡張子付きで
var filename_ex = url.match(".+/(.+?)([\?#;].*)?$")[1];
// without_back_2_201912261433_iafsxkikweqdhav.mp4

// 拡張子無しで
var filename = url.match(".+/(.+?)\.[a-z]+([\?#;].*)?$")[1];
// without_back_2_201912261433_iafsxkikweqdhav

時間のフォーマットを変換(時:分:秒)

Vue.filter('minutes', (value) => {
  if (!value || typeof value !== ""number"") return ""00:00""
  let temp_min = parseInt(value / 60),
      sec = parseInt(value % 60),
      hour = parseInt(temp_min / 60),
      min = parseInt(temp_min % 60)

  // 0で埋める
  hour = hour < 10 ? ""0"" + hour : hour
  min = min < 10 ? ""0"" + min : min
  sec = sec < 10 ? ""0"" + sec : sec

  if (hour == '00') {
    return min + ':' + sec;
  } else {
    return hour + ':' + min + ':' + sec;
  }
})

Stringの日付のフォーマットを変更する関数

toLocaleString (strDate) {
  const date = new Date(strDate)
  const year = date.getFullYear()
  const month = date.getMonth()
  const day = date.getDate()
  const hour = ('0'+date.getHours()).slice(-2)
  const min = ('0'+date.getMinutes()).slice(-2)
  return [year, month+1, day].join('/') + ' ' + [hour, min].join(':')
}

リストから特定の条件にマッチした要素のみが入ったリストを作成する

return this.todos.filter((todo) => {
    return this.current < 0 ? true : this.current === todo.state
}, this)
 
// 以下をしているのと同じこと
this.todos.filter((todo) => {
  if (this.current == -1) {
    // 全て表示の場合
    return true
  } else {
    // 表示させたい作業ステータスと同じものだけtrueを返す
    return this.current === todo.state
  }
})

リスト内のオブジェクトだけを取り出す

return this.options.reduce((a, b) => {
    return Object.assign(a, { [b.value]: b.label }) // 第一引数(a)に第2引数をコピー
}, {})
 
// 以下と同じことをしている
let result = {}
for (let i=0; i<this.options.length; i++) {
  const key = this.options[i].value,
    value = this.options[i].label
  result[key] = value
}
return result
 
/*
options: [
  { value: -1, label: 'すべて' },
  { value: 0, label: '作業中' },
  { value: 1, label: '完了' }
]
      
上のようなオブジェクトを以下のようにしたいときに使える
 
{ 0: '作業中', 1: '完了', -1: 'すべて' }
*/

tabindexの値を取得

const objs = document.getElementsByClassName('v-text-field__slot')
const index = document.activeElement.tabIndex
console.log(objs.length)
console.log(index)
console.log(objs[index-2])
console.log(objs[index-1])
objs[index-1].focus()

imgのsrcを再読込する際にキャッシュを消したい

srcの最後のgetパラメータとして更新日時を入れることで違うものだと判断させることが出来る 以下の関数で現在時刻を得て、それを?の後に付け足す

getDate () {
  const now = new Date()
  const year = now.getFullYear()
  const month = now.getMonth()
  const day = now.getDate()
  const hour = ('0'+now.getHours()).slice(-2)
  const min = ('0'+now.getMinutes()).slice(-2)
  const sec = ('0'+now.getSeconds()).slice(-2)
  return `${year}${(month + 1)}${day}${hour}${min}${sec}`
}

https://ka2.org/optimize-browser-cache-of-static-resources/

Base64をBlobに変換

base64ToBlob (base64) {
  let bin = atob(base64.replace(/^.*,/, ''))
  let buffer = new Uint8Array(bin.length)
  for (let i=0; i<bin.length; i++) {
    buffer[i] = bin.charCodeAt(i)
  }
  try {
    return new Blob([buffer.buffer], { type: 'image/png' })
  } catch (e) {
    return null
  }
},

https://gitlab.com/deep_anime/biz_front/blob/add-bounding-box/front/pages/-adjust-mouth-canvas.vue#L281

透過画像かチェックする

alphaCheck () {
  const { resizedWidth, resizedHeight } = this.getResizedImgSize()

  let imageData, alpha
  this.haveAlpha = false
  for (let w=0; w<resizedWidth; w+=5) {
    for (let h=0; h<resizedHeight; h+=5) {
      imageData = this.ctx.getImageData(w, h, 1, 1)
      alpha = imageData.data[3]
      console.log(alpha)
      if (alpha === 0) {
        console.log('透過画像です')
        this.haveAlpha = true
        break
      }
    }
    if (alpha === 0) break
  }
  if (!this.haveAlpha) console.log('透過画像では有りません')
},
/**
 * canvasの描画用にリサイズされた画像サイズを取得
 */
getResizedImgSize () {
  let resizedWidth, resizedHeight
  if (this.uploadedImg.width >= this.uploadedImg.height) {
    const rate = this.canvas.width/this.uploadedImg.width
    resizedWidth = this.canvas.width,
    resizedHeight = this.uploadedImg.height*rate
  } else {
    const rate = this.canvas.height/this.uploadedImg.height
    resizedWidth = this.uploadedImg.width*rate,
    resizedHeight = this.canvas.height
  }
  return { resizedWidth, resizedHeight }
},

https://gitlab.com/deep_anime/biz_front/blob/add-bounding-box/front/pages/-adjust-mouth-canvas.vue#L281

配列を同じ値で埋める

1. Array.prototype.fill()を使う

const len: number = 10;      // 作りたい配列の長さ
const el: string = 'foo';    // 埋めたい値
const ary = new Array<string>(len).fill('foo');

console.log(ary.join(','));    // foo,foo,foo,foo,foo,foo,foo,foo,foo,foo

以下のようにArrayのコンストラクターは引数が数値一つだけの場合、その長さを持った配列を作ります。

fill()メソッドは、配列中の開始インデックスから終了インデックスまでの要素を固定値で設定します。

  • 第1引数: 設定する値
  • 第2引数: 開始インデックス
  • 第3引数: 終了インデックスを指定します。

※ 第2、第3引数を省略すると配列にすべて同じ値を設定します。

const ary1 = [3];    // 3という要素を持つ配列
const ary2 = new Array(3);    // 長さが3の配列
const ary3 = new Array(3, 6, 88, 1);    // 長さが4の配列

2. forループによる初期化

const len: number = 10;
const word: string = 'foo';

const ary = new Array<string>(len);
for (let i = 0, len = ary.length; i < len; i++) {
    ary[i] = word;
    // ary.push(word);
}

参考

KonvaでCanvasに描画されている画像を保存

Konva.StageでもKonva.LayerでもKonva.ImageでもtoDataURL()でbase64に変換可能。 base64をBlobに変換する方法はこのドキュメント上の方書いてある

https://konvajs.org/docs/data_and_serialization/Stage_Data_URL.html

独自エラーメッセージ

function HogeError (message) {
  this.name = 'HogeError'
  this.message = (message || '')
}
HogeError.prototype = Error.prototype