troika-3d-text
Advanced tools
Comparing version 0.25.0 to 0.26.0
@@ -6,2 +6,18 @@ # Change Log | ||
# [0.26.0](https://github.com/protectwise/troika/compare/v0.25.0...v0.26.0) (2020-05-24) | ||
### Bug Fixes | ||
* **troika-3d-text:** [#46](https://github.com/protectwise/troika/issues/46) fix error on script load when `document` not present ([1b005ec](https://github.com/protectwise/troika/commit/1b005ec0b4fb45b0b96cbb3270627de569f51b0e)) | ||
### Features | ||
* **troika-3d-text:** experimental `colorRanges` feature ([c4971c3](https://github.com/protectwise/troika/commit/c4971c3b10dff597fb071b2039a6874df99c70a9)) | ||
# [0.25.0](https://github.com/protectwise/troika/compare/v0.24.1...v0.25.0) (2020-05-19) | ||
@@ -8,0 +24,0 @@ |
{ | ||
"name": "troika-3d-text", | ||
"version": "0.25.0", | ||
"version": "0.26.0", | ||
"description": "Troika 3D Text", | ||
@@ -18,5 +18,5 @@ "author": "Jason Johnston <jason.johnston@protectwise.com>", | ||
"dependencies": { | ||
"troika-3d": "^0.25.0", | ||
"troika-three-utils": "^0.25.0", | ||
"troika-worker-utils": "^0.25.0" | ||
"troika-3d": "^0.26.0", | ||
"troika-three-utils": "^0.26.0", | ||
"troika-worker-utils": "^0.26.0" | ||
}, | ||
@@ -31,3 +31,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "a2a487e422ad6d62fd4a4d5a7c4d95111ed3afdb" | ||
"gitHead": "4eeeca1356c3017690152bd2becc915ab88a9c18" | ||
} |
@@ -20,2 +20,3 @@ import { Object3DFacade } from 'troika-3d' | ||
'color', | ||
'colorRanges', | ||
'depthOffset', | ||
@@ -22,0 +23,0 @@ 'clipRect', |
@@ -168,3 +168,4 @@ /** | ||
includeCaretPositions=false, | ||
chunkedBoundsSize=8192 | ||
chunkedBoundsSize=8192, | ||
colorRanges=null | ||
}, | ||
@@ -195,2 +196,3 @@ callback, | ||
let glyphAtlasIndices = null | ||
let glyphColors = null | ||
let caretPositions = null | ||
@@ -347,5 +349,10 @@ let totalBounds = null | ||
} | ||
if (colorRanges) { | ||
glyphColors = new Uint8Array(renderableGlyphCount * 3) | ||
} | ||
let renderableGlyphIndex = 0 | ||
let prevCharIndex = -1 | ||
let colorCharIndex = -1 | ||
let chunk | ||
let currentColor | ||
lines.forEach(line => { | ||
@@ -415,2 +422,13 @@ const {count:lineGlyphCount, width:lineWidth} = line | ||
// Track current color range | ||
if (colorRanges) { | ||
const {charIndex} = glyphInfo | ||
while(charIndex > colorCharIndex) { | ||
colorCharIndex++ | ||
if (colorRanges.hasOwnProperty(colorCharIndex)) { | ||
currentColor = colorRanges[colorCharIndex] | ||
} | ||
} | ||
} | ||
// Get atlas data for renderable glyphs | ||
@@ -469,2 +487,10 @@ if (!glyphObj.isWhitespace && !glyphObj.isEmpty) { | ||
glyphAtlasIndices[idx] = glyphAtlasInfo.atlasIndex | ||
// Add colors | ||
if (colorRanges) { | ||
const start = idx * 3 | ||
glyphColors[start] = currentColor >> 16 & 255 | ||
glyphColors[start + 1] = currentColor >> 8 & 255 | ||
glyphColors[start + 2] = currentColor & 255 | ||
} | ||
} | ||
@@ -477,6 +503,2 @@ } | ||
}) | ||
// Create the final output for the rendeable glyphs | ||
glyphBounds = new Float32Array(glyphBounds) | ||
glyphAtlasIndices = new Float32Array(glyphAtlasIndices) | ||
} | ||
@@ -496,2 +518,3 @@ | ||
caretHeight, //height of cursor from bottom to top | ||
glyphColors, //color for each glyph, if color ranges supplied | ||
chunkedBounds, //total rects per (n=chunkedBoundsSize) consecutive glyphs | ||
@@ -498,0 +521,0 @@ ascender: ascender * fontSizeMult, //font ascender |
@@ -1,2 +0,2 @@ | ||
import { DataTexture, LinearFilter, LuminanceFormat } from 'three' | ||
import { Color, DataTexture, LinearFilter, LuminanceFormat } from 'three' | ||
import { defineWorkerModule, ThenableWorkerModule } from 'troika-worker-utils' | ||
@@ -17,3 +17,3 @@ import { createSDFGenerator } from './SDFGenerator.js' | ||
} | ||
const linkEl = document.createElement('a') //for resolving relative URLs to absolute | ||
const tempColor = new Color() | ||
let hasRequested = false | ||
@@ -78,3 +78,4 @@ | ||
* @property {Float32Array} glyphBounds - List of [minX, minY, maxX, maxY] quad bounds for each glyph. | ||
* @property {Float32Array} glyphAtlasIndices - List holding each glyph's index in the SDF atlas | ||
* @property {Float32Array} glyphAtlasIndices - List holding each glyph's index in the SDF atlas. | ||
* @property {Uint8Array} [glyphColors] - List holding each glyph's [r, g, b] color, if `colorRanges` was supplied. | ||
* @property {Float32Array} [caretPositions] - A list of caret positions for all glyphs; this is | ||
@@ -114,4 +115,3 @@ * the bottom [x,y] of the cursor position before each char, plus one after the last char. | ||
// URLs to absolute so they can be resolved in the worker | ||
linkEl.href = args.font || CONFIG.defaultFontURL | ||
args.font = linkEl.href | ||
args.font = toAbsoluteURL(args.font || CONFIG.defaultFontURL) | ||
@@ -121,2 +121,17 @@ // Normalize text to a string | ||
// Normalize colors | ||
if (args.colorRanges != null) { | ||
let colors = {} | ||
for (let key in args.colorRanges) { | ||
if (args.colorRanges.hasOwnProperty(key)) { | ||
let val = args.colorRanges[key] | ||
if (typeof val !== 'number') { | ||
val = tempColor.set(val).getHex() | ||
} | ||
colors[key] = val | ||
} | ||
} | ||
args.colorRanges = colors | ||
} | ||
Object.freeze(args) | ||
@@ -183,2 +198,3 @@ | ||
glyphAtlasIndices: result.glyphAtlasIndices, | ||
glyphColors: result.glyphColors, | ||
caretPositions: result.caretPositions, | ||
@@ -228,3 +244,13 @@ caretHeight: result.caretHeight, | ||
// Utility for making URLs absolute | ||
let linkEl | ||
function toAbsoluteURL(path) { | ||
if (!linkEl) { | ||
linkEl = typeof document === 'undefined' ? {} : document.createElement('a') | ||
} | ||
linkEl.href = path | ||
return linkEl.href | ||
} | ||
const fontProcessorWorkerModule = defineWorkerModule({ | ||
@@ -231,0 +257,0 @@ name: 'FontProcessor', |
@@ -15,2 +15,3 @@ import { | ||
const glyphIndexAttrName = 'aTroikaGlyphIndex' | ||
const glyphColorAttrName = 'aTroikaGlyphColor' | ||
@@ -74,7 +75,9 @@ | ||
* used with `applyClipRect` to choose an optimized `maxInstancedCount`. | ||
* @param {Uint8Array} [glyphColors] - An array holding r,g,b values for each glyph. | ||
*/ | ||
updateGlyphs(glyphBounds, glyphAtlasIndices, totalBounds, chunkedBounds) { | ||
updateGlyphs(glyphBounds, glyphAtlasIndices, totalBounds, chunkedBounds, glyphColors) { | ||
// Update the instance attributes | ||
updateBufferAttr(this, glyphBoundsAttrName, glyphBounds, 4) | ||
updateBufferAttr(this, glyphIndexAttrName, glyphAtlasIndices, 1) | ||
updateBufferAttr(this, glyphColorAttrName, glyphColors, 3) | ||
this._chunkedBounds = chunkedBounds | ||
@@ -134,8 +137,12 @@ this.maxInstancedCount = glyphAtlasIndices.length | ||
const attr = geom.getAttribute(attrName) | ||
// If length isn't changing, just update the attribute's array data | ||
if (attr && attr.array.length === newArray.length) { | ||
attr.array.set(newArray) | ||
attr.needsUpdate = true | ||
} else { | ||
geom.setAttribute(attrName, new InstancedBufferAttribute(newArray, itemSize)) | ||
if (newArray) { | ||
// If length isn't changing, just update the attribute's array data | ||
if (attr && attr.array.length === newArray.length) { | ||
attr.array.set(newArray) | ||
attr.needsUpdate = true | ||
} else { | ||
geom.setAttribute(attrName, new InstancedBufferAttribute(newArray, itemSize)) | ||
} | ||
} else if (attr) { | ||
geom.deleteAttribute(attrName) | ||
} | ||
@@ -142,0 +149,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import { createDerivedMaterial } from 'troika-three-utils' | ||
import { createDerivedMaterial, voidMainRegExp } from 'troika-three-utils' | ||
import { Vector2, Vector4, Matrix3 } from 'three' | ||
@@ -11,6 +11,9 @@ | ||
uniform mat3 uTroikaOrient; | ||
uniform bool uTroikaUseGlyphColors; | ||
attribute vec4 aTroikaGlyphBounds; | ||
attribute float aTroikaGlyphIndex; | ||
attribute vec3 aTroikaGlyphColor; | ||
varying vec2 vTroikaSDFTextureUV; | ||
varying vec2 vTroikaGlyphUV; | ||
varying vec3 vTroikaGlyphColor; | ||
` | ||
@@ -43,2 +46,3 @@ | ||
normal = uTroikaOrient * normal; | ||
vTroikaGlyphColor = uTroikaUseGlyphColors ? aTroikaGlyphColor / 255.0 : diffuse; | ||
` | ||
@@ -114,2 +118,3 @@ | ||
uTroikaOrient: {value: new Matrix3()}, | ||
uTroikaUseGlyphColors: {value: true}, | ||
uTroikaSDFDebug: {value: false} | ||
@@ -120,3 +125,17 @@ }, | ||
fragmentDefs: FRAGMENT_DEFS, | ||
fragmentColorTransform: FRAGMENT_TRANSFORM | ||
fragmentColorTransform: FRAGMENT_TRANSFORM, | ||
customRewriter({vertexShader, fragmentShader}) { | ||
let uDiffuseRE = /\buniform\s+vec3\s+diffuse\b/ | ||
if (uDiffuseRE.test(fragmentShader)) { | ||
// Replace all instances of `diffuse` with our varying | ||
fragmentShader = fragmentShader | ||
.replace(uDiffuseRE, 'varying vec3 vTroikaGlyphColor') | ||
.replace(/\bdiffuse\b/g, 'vTroikaGlyphColor') | ||
// Make sure the vertex shader declares the uniform so we can grab it as a fallback | ||
if (!uDiffuseRE.test(vertexShader)) { | ||
vertexShader = vertexShader.replace(voidMainRegExp, 'uniform vec3 diffuse;\n$&') | ||
} | ||
} | ||
return { vertexShader, fragmentShader } | ||
} | ||
}) | ||
@@ -123,0 +142,0 @@ |
@@ -166,2 +166,13 @@ import { | ||
/** | ||
* @member {object|null} colorRanges | ||
* WARNING: This API is experimental and may change. | ||
* This allows more fine-grained control of colors for individual or ranges of characters, | ||
* taking precedence over the material's `color`. Its format is an Object whose keys each | ||
* define a starting character index for a range, and whose values are the color for each | ||
* range. The color value can be a numeric hex color value, a `THREE.Color` object, or | ||
* any of the strings accepted by `THREE.Color`. | ||
*/ | ||
this.colorRanges = null | ||
/** | ||
* @member {number} depthOffset | ||
@@ -225,2 +236,3 @@ * This is a shortcut for setting the material's `polygonOffset` and related properties, | ||
anchorY: this.anchorY, | ||
colorRanges: this.colorRanges, | ||
includeCaretPositions: true //TODO parameterize | ||
@@ -238,3 +250,4 @@ }, textRenderInfo => { | ||
textRenderInfo.totalBounds, | ||
textRenderInfo.chunkedBounds | ||
textRenderInfo.chunkedBounds, | ||
textRenderInfo.glyphColors | ||
) | ||
@@ -335,2 +348,3 @@ | ||
uniforms.uTroikaTotalBounds.value.fromArray(totalBounds) | ||
uniforms.uTroikaUseGlyphColors.value = !!textInfo.glyphColors | ||
@@ -415,3 +429,4 @@ let clipRect = this.clipRect | ||
'anchorX', | ||
'anchorY' | ||
'anchorY', | ||
'colorRanges' | ||
] | ||
@@ -418,0 +433,0 @@ SYNCABLE_PROPS.forEach(prop => { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2004316
35549
90
3
8
1
11
+ Addedtroika-3d@0.26.0(transitive)
+ Addedtroika-animation@0.26.0(transitive)
+ Addedtroika-core@0.26.0(transitive)
+ Addedtroika-three-utils@0.26.0(transitive)
+ Addedtroika-worker-utils@0.26.1(transitive)
- Removedtroika-3d@0.25.0(transitive)
- Removedtroika-animation@0.25.0(transitive)
- Removedtroika-core@0.25.0(transitive)
- Removedtroika-three-utils@0.25.0(transitive)
- Removedtroika-worker-utils@0.25.0(transitive)
Updatedtroika-3d@^0.26.0
Updatedtroika-three-utils@^0.26.0
Updatedtroika-worker-utils@^0.26.0