vap-frame-parser.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * Tencent is pleased to support the open source community by making vap available.
  3. *
  4. * Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the MIT License (the "License"); you may not use this file except in
  7. * compliance with the License. You may obtain a copy of the License at
  8. *
  9. * http://opensource.org/licenses/MIT
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed under the License is
  12. * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  13. * either express or implied. See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. export default class FrameParser {
  17. constructor(source, headData) {
  18. this.config = source || {}
  19. this.headData = headData
  20. this.frame = []
  21. this.textureMap = {}
  22. }
  23. async init() {
  24. this.initCanvas()
  25. await this.parseSrc(this.config)
  26. this.canvas.parentNode.removeChild(this.canvas)
  27. this.frame = this.config.frame || []
  28. return this
  29. }
  30. initCanvas() {
  31. const canvas = document.createElement('canvas')
  32. const ctx = canvas.getContext('2d')
  33. canvas.style.display = 'none'
  34. document.body.appendChild(canvas)
  35. this.ctx = ctx
  36. this.canvas = canvas
  37. }
  38. loadImg(url) {
  39. return new Promise((resolve, reject) => {
  40. // console.log('load img:', url)
  41. const img = new Image()
  42. img.crossOrigin = 'anonymous'
  43. img.onload = function() {
  44. resolve(this)
  45. }
  46. img.onerror = function(e) {
  47. console.error('frame 资源加载失败:' + url)
  48. reject(new Error('frame 资源加载失败:' + url))
  49. }
  50. img.src = url
  51. })
  52. }
  53. parseSrc(dataJson) {
  54. const src = (this.srcData = {})
  55. return Promise.all(
  56. (dataJson.src || []).map(async item => {
  57. if (item.srcType === 'txt') {
  58. item.textStr = item.srcTag.replace(/\[(.*)\]/, ($0, $1) => {
  59. return this.headData[$1]
  60. })
  61. item.img = this.makeTextImg(item)
  62. } else if (item.srcType === 'img') {
  63. item.imgUrl = item.srcTag.replace(/\[(.*)\]/, ($0, $1) => {
  64. return this.headData[$1]
  65. })
  66. try {
  67. item.img = await this.loadImg(item.imgUrl + '?t=' + Date.now())
  68. } catch (e) {}
  69. }
  70. src[item.srcId] = item
  71. })
  72. )
  73. }
  74. /**
  75. * 文字转换图片
  76. * @param {*} param0
  77. */
  78. makeTextImg({ textStr, w, h, color, style }) {
  79. const ctx = this.ctx
  80. ctx.canvas.width = w
  81. ctx.canvas.height = h
  82. const fontSize = Math.min(parseInt(w / textStr.length, 10), h - 8) // 需留一定间隙
  83. const font = [`${fontSize}px`, 'Arial']
  84. if (style === 'b') {
  85. font.unshift('bold')
  86. }
  87. ctx.font = font.join(' ')
  88. ctx.textBaseline = 'middle'
  89. ctx.textAlign = 'center'
  90. ctx.fillStyle = color
  91. ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
  92. ctx.fillText(textStr, w / 2, h / 2)
  93. // console.log('frame : ' + textStr, ctx.canvas.toDataURL('image/png'))
  94. return ctx.getImageData(0, 0, w, h)
  95. }
  96. getFrame(frame) {
  97. return this.frame.find(item => {
  98. return item.i === frame
  99. })
  100. }
  101. }