comic-bubbles
Version:
Animated comic bubbles - what else?
180 lines (140 loc) • 6.89 kB
JavaScript
import { charsDrawn, counter, resetCharsDrawn } from './heartbeat.mjs'
import { drawRow } from './fontMapper.mjs'
import { getScene } from './sceneCache.mjs'
import { getResourceUrl } from './helperFunctions.mjs'
let tempSceneCanvas = document.createElement('canvas')
let tempSceneCtx = tempSceneCanvas.getContext('2d')
var cornerImg = new Image()
cornerImg.src = getResourceUrl('corner image path', '/resources/corner.png')
export function paintBubbles(sceneId) {
let scene = getScene(sceneId)
tempSceneCanvas.width = scene.bounds.width
tempSceneCanvas.height = scene.bounds.height
tempSceneCtx.width = scene.bounds.width
tempSceneCtx.height = scene.bounds.height
resetCharsDrawn()
let bubCon = scene.bubCon
bubCon.parent.canvas.width = bubCon.parent.canvas.width
bubCon.canvas.width = bubCon.getWidth()
bubCon.canvas.height = bubCon.getHeight()
bubCon.ctx().width = bubCon.getWidth()
bubCon.ctx().height = bubCon.getHeight()
/* bubCon.ctx().fillStyle = 'red'
bubCon.ctx().fillRect(0, 0, bubCon.getWidth(), bubCon.getHeight())
bubCon.parent.ctx().drawImage(bubCon.canvas, bubCon.getX(), bubCon.getY()) */
for (let i = 0; i < bubCon.bubbleArr.length; i++) {
paintBubble(sceneId, bubCon.bubbleArr[i])
}
let tempBlackCanvas = document.createElement('canvas')
let tempBlackCtx = tempBlackCanvas.getContext('2d')
tempBlackCtx.width = scene.bounds.width
tempBlackCtx.height = scene.bounds.height
tempBlackCtx.fillStyle = 'black'
tempBlackCtx.fillRect(0, 0, tempBlackCtx.width, tempBlackCtx.height)
tempBlackCtx.globalCompositeOperation = 'destination-in'
tempBlackCtx.drawImage(tempSceneCanvas, 0, 0)
tempBlackCtx.globalCompositeOperation = 'source-over'
//evaluateFullBorder()
bubCon.parent.ctx().drawImage(tempBlackCanvas, 1, 0)
bubCon.parent.ctx().drawImage(tempBlackCanvas, -1, 0)
bubCon.parent.ctx().drawImage(tempBlackCanvas, 0, 1)
bubCon.parent.ctx().drawImage(tempBlackCanvas, 0, -1)
//Shadow
for (let i = 0; i < 4; i++) {
bubCon.parent.ctx().drawImage(tempBlackCanvas, -1, i)
bubCon.parent.ctx().drawImage(tempBlackCanvas, 0, i)
bubCon.parent.ctx().drawImage(tempBlackCanvas, 1, i)
}
bubCon.parent.ctx().drawImage(tempBlackCanvas, -1, 2)
bubCon.parent.ctx().drawImage(tempBlackCanvas, 0, 2)
bubCon.parent.ctx().drawImage(tempBlackCanvas, 1, 2)
bubCon.parent.ctx().drawImage(tempSceneCanvas, 0, 0)
for (let i = 0; i < bubCon.bubbleArr.length; i++) {
paintRows(sceneId, bubCon.bubbleArr[i].body.text)
}
}
export function paintBubble(sceneId, bubble) {
let scene = getScene(sceneId)
if (charsDrawn < counter) {
let ctx = bubble.parent.parent.ctx()
fillBubbleMask(sceneId, bubble.body.getX(), bubble.body.getY(), bubble.body.getWidth(), bubble.body.getHeight())
// Draw arrow
if (bubble.arrow.painted) {
let arrowCanvas = document.createElement('canvas')
let arrowCtx = arrowCanvas.getContext('2d')
let top = Math.round(bubble.body.getHeight() / 3) + 3
arrowCtx.fillStyle = 'white'
let width = bubble.arrow.width + 4
let y = top
let x = 0
while (width > 0) {
arrowCtx.fillRect(x, y, width, 1)
y--
width -= 3
x += 3
}
tempSceneCtx.drawImage(arrowCanvas, bubble.getX(), bubble.getY())
}
// Draw connector
if (bubble.connector.painted) {
let smallestBodyWidth = Math.min(bubble.body.getWidth(), bubble.parent.bubble(bubble.arrIdx - 1).body.getWidth())
let xPos = smallestBodyWidth / 2 + bubble.arrow.width - bubble.connector.width / 2
tempSceneCtx.fillStyle = 'white'
let parent = bubble.parent.bubble(bubble.arrIdx - 1)
let minX = Math.max(parent.body.getX(), bubble.body.getX())
let maxX = Math.min(parent.body.getX() + parent.body.getWidth(), bubble.body.getX() + bubble.body.getWidth())
let maxWidth = ((maxX - minX) / 3) * 2
let xPosMiddle = Math.round(minX + maxWidth / 2 + bubble.connector.width / 2)
let parentY = parent.body.getY() + parent.body.getHeight()
let height = bubble.body.getY() - parentY
let thisX = bubble.getX() + bubble.arrow.width
tempSceneCtx.fillRect(xPosMiddle, parentY, bubble.connector.width, height)
}
}
}
function fillBubbleMask(sceneId, x, y, width, height) {
let scene = getScene(sceneId)
var bubbleMaskCanvas = document.createElement('canvas')
bubbleMaskCanvas.width = scene.ctx().width
bubbleMaskCanvas.height = scene.ctx().height
var bubbleMaskCtx = bubbleMaskCanvas.getContext('2d')
var cornerCanvas = document.createElement('canvas')
var cornerCtx = cornerCanvas.getContext('2d')
cornerCanvas.width = cornerImg.width
cornerCanvas.height = cornerImg.height
cornerCtx.drawImage(cornerImg, 0, 0)
bubbleMaskCtx.fillStyle = 'white'
bubbleMaskCtx.fillRect(x, y, width, height)
bubbleMaskCtx.globalCompositeOperation = 'destination-out'
cornerCtx.translate(cornerImg.width / 2, cornerImg.height / 2)
cornerCtx.rotate((Math.PI / 2) * 3)
cornerCtx.clearRect(-cornerImg.width / 2, -cornerImg.height / 2, cornerCanvas.width, cornerCanvas.height)
cornerCtx.drawImage(cornerImg, -cornerImg.width / 2, -cornerImg.height / 2)
cornerCtx.translate(-cornerImg.width / 2, -cornerImg.height / 2)
bubbleMaskCtx.drawImage(cornerCanvas, x, y + height - cornerCanvas.height)
cornerCtx.translate(cornerImg.width / 2, cornerImg.height / 2)
cornerCtx.rotate((Math.PI / 2) * 3)
cornerCtx.clearRect(-cornerImg.width / 2, -cornerImg.height / 2, cornerCanvas.width, cornerCanvas.height)
cornerCtx.drawImage(cornerImg, -cornerImg.width / 2, -cornerImg.height / 2)
cornerCtx.translate(-cornerImg.width / 2, -cornerImg.height / 2)
bubbleMaskCtx.drawImage(cornerCanvas, x + width - cornerImg.width, y + height - cornerImg.height)
cornerCtx.translate(cornerImg.width / 2, cornerImg.height / 2)
cornerCtx.rotate((Math.PI / 2) * 3)
cornerCtx.clearRect(-cornerImg.width / 2, -cornerImg.height / 2, cornerCanvas.width, cornerCanvas.height)
cornerCtx.drawImage(cornerImg, -cornerImg.width / 2, -cornerImg.height / 2)
cornerCtx.translate(-cornerImg.width / 2, -cornerImg.height / 2)
bubbleMaskCtx.drawImage(cornerCanvas, x + width - cornerImg.width, y)
cornerCtx.translate(cornerImg.width / 2, cornerImg.height / 2)
cornerCtx.rotate((Math.PI / 2) * 3)
cornerCtx.clearRect(-cornerImg.width / 2, -cornerImg.height / 2, cornerCanvas.width, cornerCanvas.height)
cornerCtx.drawImage(cornerImg, -cornerImg.width / 2, -cornerImg.height / 2)
cornerCtx.translate(-cornerImg.width / 2, -cornerImg.height / 2)
bubbleMaskCtx.drawImage(cornerCanvas, x, y)
bubbleMaskCtx.globalCompositeOperation = 'source-over'
tempSceneCtx.drawImage(bubbleMaskCanvas, 0, 0)
}
export function paintRows(sceneId, text) {
for (let i = 0; i < text.rowArr.length; i++) {
drawRow(sceneId, text.row(i))
}
}