123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- import * as THREE from 'three'
- function wordWrap(text, context, options) {
- const words = text.split(" ")
- const lines = []
- let line = ""
- const maxWidth = options.width - (8 * 2)
- words.forEach(word => {
- const newLine = line+word+" "
- const metrics = context.measureText(newLine.trim())
- let fontWidth = metrics.actualBoundingBoxLeft + metrics.actualBoundingBoxRight
- if(fontWidth > maxWidth) {
- lines.push(line.trim())
- line = word + " "
- } else {
- line = newLine
- }
- })
- if (line != "") {
- lines.push(line.trim())
- }
- return lines
- }
- export function buildCanvasText(text, inOptions = {}) {
- const options = {width: 512, height: 512, font: "86px Arial", textAlign: "center", lineWidth: 8}
- if(inOptions.width) options.width = inOptions.width
- if(inOptions.height) options.height = inOptions.height
- if(inOptions.font) options.font = inOptions.font
- if(inOptions.textAlign) options.textAlign = inOptions.textAlign
- if(inOptions.lineWidth) options.lineWidth = inOptions.lineWidth
- const texture = generateMap(text, options)
- const alphaMap = generateAlphaMap(text, options)
- const material = new THREE.MeshBasicMaterial({transparent: true, map: texture, side: THREE.DoubleSide, alphaMap: alphaMap, alphaTest: 0.1})
- const geometry = new THREE.PlaneGeometry(4,4)
- const textMesh = new THREE.Mesh(geometry, material)
- textMesh.castShadow = true
- return textMesh
- }
- function generateMap(text, options) {
- const textCanvas = document.createElement('canvas')
- textCanvas.width = options.width
- textCanvas.height = options.height
- const context = textCanvas.getContext('2d')
- context.clearRect(0, 0, options.width, options.height)
- context.font = options.font
- context.textAlign = options.textAlign
- context.lineWidth = options.lineWidth
- context.lineCap = "round"
- context.lineJoin = "round"
- const lines = wordWrap(text, context, options)
- for(let i = 0; i < lines.length; i++) {
- const lineToDraw = lines[i]
- const metrics = context.measureText(lineToDraw)
- let fontHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent
- // context.beginPath()
- // context.fillStyle = "rbga(0,0,0,0.5)"
- // context.rect(0,0, options.width, options.height)
- // context.fill()
- context.beginPath()
- context.strokeStyle = "black"
- context.strokeText(lineToDraw, options.width / 2, 8 + (fontHeight * (i + 1)))
- context.beginPath()
- context.fillStyle = "white"
- context.fillText(lineToDraw, options.width / 2, 8 + (fontHeight * (i + 1)))
- }
- const texture = new THREE.CanvasTexture(textCanvas)
- texture.minFilter = THREE.LinearFilter;
- texture.wrapS = THREE.ClampToEdgeWrapping;
- texture.wrapT = THREE.ClampToEdgeWrapping;
- texture.needsUpdate = true
- return texture
- }
- function generateAlphaMap(text, options) {
- const textCanvas = document.createElement('canvas')
- textCanvas.width = options.width
- textCanvas.height = options.height
- const context = textCanvas.getContext('2d')
- context.clearRect(0, 0, options.width, options.height)
- context.beginPath()
- context.fillStyle = "black"
- context.rect(0, 0, options.width, options.height)
- context.fill()
- // context.beginPath()
- // context.strokeStyle = "magenta"
- // context.rect(0,0, options.width, options.height)
- // context.stroke()
- context.font = options.font
- context.textAlign = options.textAlign
- context.lineWidth = options.lineWidth
- context.lineCap = "round"
- context.lineJoin = "round"
- const lines = wordWrap(text, context, options)
- for(let i = 0; i < lines.length; i++) {
- const lineToDraw = lines[i]
- const metrics = context.measureText(lineToDraw)
- let fontHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent
- // context.beginPath()
- // context.fillStyle = "rbga(0,0,0,0.5)"
- // context.rect(0,0, options.width, options.height)
- // context.fill()
- context.beginPath()
- context.strokeStyle = "white"
- context.strokeText(lineToDraw, options.width / 2, 8 + (fontHeight * (i + 1)))
- context.beginPath()
- context.fillStyle = "white"
- context.fillText(lineToDraw, options.width / 2, 8 + (fontHeight * (i + 1)))
- }
- const texture = new THREE.CanvasTexture(textCanvas)
- texture.minFilter = THREE.LinearFilter;
- texture.wrapS = THREE.ClampToEdgeWrapping;
- texture.wrapT = THREE.ClampToEdgeWrapping;
- texture.needsUpdate = true
- return texture
- }
|