Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP - Selection Copy + a11y features #110

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2a950bc
screen readers / text selection / translation V0
AlaricBaraou Feb 27, 2021
00e8feb
Merge remote-tracking branch 'upstream/master'
AlaricBaraou Mar 1, 2021
b410f0d
react to radius changes
AlaricBaraou Mar 1, 2021
2fabe96
text selection color
AlaricBaraou Mar 1, 2021
aa2edfa
demo fix and selection thikness
AlaricBaraou Mar 1, 2021
128d4c3
fix selection child transform
AlaricBaraou Mar 1, 2021
09499ce
clear selection + selection material
AlaricBaraou Mar 2, 2021
99e3047
Merge remote-tracking branch 'upstream/master'
AlaricBaraou Mar 4, 2021
cb24d4c
html correct position
AlaricBaraou Mar 4, 2021
b8f44d3
dom selection position
AlaricBaraou Mar 5, 2021
413e158
overlaying html edge cases
AlaricBaraou Mar 5, 2021
50d914c
translation keep formating
AlaricBaraou Mar 5, 2021
45d839a
module separation v0
AlaricBaraou Mar 6, 2021
d58db14
use CSS matrix3d for aligning DOM overlays more accurately with persp…
lojjic Mar 7, 2021
7d6bae2
cherry picked + SR outline
lojjic Mar 7, 2021
42053ac
manage selection without deleting potential Text childs
AlaricBaraou Mar 7, 2021
d0623de
dynamic selection manager
AlaricBaraou Mar 7, 2021
c2d6250
bug fixs, cleaning
AlaricBaraou Mar 8, 2021
f15d0ce
fix selection color + comments
AlaricBaraou Mar 8, 2021
f812299
separate selectable and a11y in two make functions
AlaricBaraou Mar 23, 2021
671d971
split textHighlighter
AlaricBaraou Mar 24, 2021
af344c5
TextHighlight as Group Subclass
AlaricBaraou Mar 25, 2021
6325ae0
move props to makers
AlaricBaraou Mar 27, 2021
04c4c8c
move textRectToCssMatrix to selectionutils
AlaricBaraou Mar 27, 2021
63d3115
selection managed by TextHighligh, exposed by makeSelectable
AlaricBaraou Mar 27, 2021
163d610
fix selectionMaterial
AlaricBaraou Apr 4, 2021
696d6ab
fix a11y translation and text update
AlaricBaraou Apr 4, 2021
3769051
make observeMutation optional
AlaricBaraou Apr 4, 2021
16fdca6
fix merge conflict
AlaricBaraou Apr 6, 2021
ef15677
Merge branch 'master' into master
AlaricBaraou Apr 6, 2021
b580de6
Merge branch 'master' into master
AlaricBaraou Apr 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 45 additions & 7 deletions packages/troika-3d-text/src/facade/SelectionManagerFacade.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ListFacade } from 'troika-3d'
import { Matrix4, Plane, Vector2, Vector3 } from 'three'
import { getCaretAtPoint, getSelectionRects } from 'troika-three-text'
import { invertMatrix4 } from 'troika-three-utils'
import { getCaretAtPoint } from 'troika-three-text'
import SelectionRangeRect from './SelectionRangeRect.js'

const THICKNESS = 0.25 //rect depth as percentage of height
Expand All @@ -16,7 +15,7 @@ const noClip = Object.freeze([-Infinity, -Infinity, Infinity, Infinity])
* Manager facade for selection rects and user selection behavior
*/
class SelectionManagerFacade extends ListFacade {
constructor (parent, onSelectionChange) {
constructor(parent, onSelectionChange) {
super(parent)
const textMesh = parent.threeObject

Expand All @@ -42,11 +41,17 @@ class SelectionManagerFacade extends ListFacade {
}

const onDragStart = e => {
if (e.which === 3) {//contextmenu
return false
}
const textRenderInfo = textMesh.textRenderInfo
if (textRenderInfo) {
const textPos = textMesh.worldPositionToTextCoords(e.intersection.point, tempVec2)
const caret = getCaretAtPoint(textRenderInfo, textPos.x, textPos.y)
if (caret) {
textMesh.highlight.startIndex = caret.charIndex
textMesh.highlight.endIndex = caret.charIndex
textMesh.updateSelection(textRenderInfo)
onSelectionChange(caret.charIndex, caret.charIndex)
parent.addEventListener('drag', onDrag)
parent.addEventListener('dragend', onDragEnd)
Expand All @@ -56,6 +61,9 @@ class SelectionManagerFacade extends ListFacade {
}

const onDrag = e => {
if (e.which === 3) {//contextmenu
return false
}
const textRenderInfo = textMesh.textRenderInfo
if (e.ray && textRenderInfo) {
// If it's hitting on the Text mesh, do an exact translation; otherwise raycast to an
Expand All @@ -65,12 +73,14 @@ class SelectionManagerFacade extends ListFacade {
if (ix && ix.object === textMesh && ix.point) {
textPos = textMesh.worldPositionToTextCoords(ix.point, tempVec2)
} else {
const ray = e.ray.clone().applyMatrix4(invertMatrix4(textMesh.matrixWorld, tempMat4))
textPos = ray.intersectPlane(tempPlane.setComponents(0, 0, 1, 0), tempVec3)
// const ray = e.ray.clone().applyMatrix4(invertMatrix4(textMesh.matrixWorld, tempMat4))
// textPos = ray.intersectPlane(tempPlane.setComponents(0, 0, 1, 0), tempVec3)
}
if (textPos) {
const caret = getCaretAtPoint(textRenderInfo, textPos.x, textPos.y)
if (caret) {
textMesh.highlight.endIndex = caret.charIndex
textMesh.updateSelection(textRenderInfo)
onSelectionChange(this.selectionStart, caret.charIndex)
}
}
Expand All @@ -83,18 +93,46 @@ class SelectionManagerFacade extends ListFacade {
parent.removeEventListener('dragend', onDragEnd)
}

const onMissClick = e => {
let target = e.target
do {
if (target.$facadeId === textMesh.parent.$facade.$facadeId) {
return
}
target = target.parent
} while (target !== null)
//clear selection
const textRenderInfo = textMesh.textRenderInfo
if (textRenderInfo) {
textMesh.highlight.startIndex = 0
textMesh.highlight.endIndex = 0
textMesh.updateSelection(textRenderInfo)
}
}

//clear selection if missed click
parent.getSceneFacade().addEventListener('click', onMissClick)

parent.addEventListener('dragstart', onDragStart)
parent.addEventListener('mousedown', onDragStart)
var canvas = parent.getSceneFacade().parent._threeRenderer.domElement;
canvas.addEventListener('contextmenu', (e) => {
textMesh._domElSelectedText.style.pointerEvents = 'auto'
textMesh.selectDomText()
window.setTimeout(() => {
textMesh._domElSelectedText.style.pointerEvents = 'none'
}, 50)
})

this._cleanupEvents = () => {
onDragEnd()
parent.getSceneFacade().removeEventListener('click', onMissClick)
parent.removeEventListener('dragstart', onDragStart)
parent.removeEventListener('mousedown', onDragStart)
}
}

afterUpdate() {
this.data = getSelectionRects(this.textRenderInfo, this.selectionStart, this.selectionEnd)
super.afterUpdate()
}

Expand All @@ -106,7 +144,7 @@ class SelectionManagerFacade extends ListFacade {
return this._clipRect
}

destructor () {
destructor() {
this._cleanupEvents()
super.destructor()
}
Expand Down
18 changes: 10 additions & 8 deletions packages/troika-3d-text/src/facade/Text3DFacade.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Object3DFacade } from 'troika-3d'
import { Text } from 'troika-three-text'
import { Text, makeDOMAcessible, makeSelectable } from 'troika-three-text'
import SelectionManagerFacade from './SelectionManagerFacade.js'

// Properties that will simply be forwarded to the TextMesh:
Expand All @@ -19,6 +19,7 @@ const TEXT_MESH_PROPS = [
'whiteSpace',
'material',
'color',
'selectionColor',
'colorRanges',
'fillOpacity',
'outlineOpacity',
Expand All @@ -36,7 +37,8 @@ const TEXT_MESH_PROPS = [
'orientation',
'glyphGeometryDetail',
'sdfGlyphSize',
'debugSDF'
'debugSDF',
'selectionMaterial'
]


Expand Down Expand Up @@ -93,18 +95,18 @@ class Text3DFacade extends Object3DFacade {

super.afterUpdate()

if (this.text !== this._prevText) {
// TODO mirror to DOM... this._domEl.textContent = this.text
// Clear selection when text changes
this.selectionStart = this.selectionEnd = -1
this._prevText = this.text
if (this.accessible && !this.threeObject.isDOMAccessible) {
makeDOMAcessible(this.threeObject)
}
if (this.selectable && !this.threeObject.isSelectable) {
makeSelectable(this.threeObject)
}

this._updateSelection()
}

_updateSelection() {
const {selectable, selectionStart, selectionEnd} = this
const { selectable, selectionStart, selectionEnd } = this
let selFacade = this._selectionFacade
if (selectable !== this._selectable) {
this._selectable = selectable
Expand Down
3 changes: 3 additions & 0 deletions packages/troika-examples/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ html, body {
color: #FFF;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
overflow: hidden;
width: 100vw;
height: 100vh;
}

.examples {
Expand Down
Loading