Skip to content

Commit

Permalink
feat: .clipDisabled attribute property for <lume-clip-plane> to e…
Browse files Browse the repository at this point in the history
…asily toggle the behavior on/off
  • Loading branch information
trusktr committed Mar 4, 2022
1 parent 100f00d commit 6b69d0a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 17 deletions.
8 changes: 7 additions & 1 deletion docs/js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1670,7 +1670,7 @@ const clipPlaneExample = stripIndent(html`
<lume-scene id="scene" perspective="800" webgl shadowmap-type="pcfsoft">
<lume-ambient-light color="white" intensity="0.4"></lume-ambient-light>
<lume-camera-rig active initial-distance="400" max-distance="7000" min-distance="100">
<lume-camera-rig active initial-polar-angle="30" initial-distance="400" max-distance="7000" min-distance="100">
<lume-point-light
position="200 -200 200"
intensity="0.6"
Expand All @@ -1687,6 +1687,7 @@ const clipPlaneExample = stripIndent(html`
has="clip-planes"
clip-planes="#clipPlane"
flip-clip="false"
clip-disabled="false"
sidedness="double"
cast-shadow="false"
receive-shadow="true"
Expand Down Expand Up @@ -1717,6 +1718,11 @@ const clipPlaneExample = stripIndent(html`
<lume-scene id="ui">
<lume-node size-mode="proportional literal" size="1 80">
<label>
Clipping enabled:
<input type="checkbox" checked onchange="console.log(box.clipDisabled = !box.clipDisabled)" />
</label>
<br />
<label>
Flip clip:
<input
Expand Down
51 changes: 36 additions & 15 deletions src/behaviors/mesh-behaviors/ClipPlanesBehavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import {ClipPlane} from '../../core/ClipPlane.js'

import type {Material} from 'three'

export type ClipPlanesBehaviorAttributes = 'clipPlanes'
export type ClipPlanesBehaviorAttributes = 'clipPlanes' | 'flipClip' | 'clipDisabled'

let refCount = 0

/**
* @class ClipPlaneBehavior
* @class ClipPlanesBehavior
*
* When applied to an element with GL content, allows specifying one or more
* planes to clip the content with.
* [`<lume-clip-plane>`](../../core/ClipPlane) elements to clip the content with.
*
* This class extends from MeshBehavior, enforcing that the behavior can be used
* only on elements that have geometry and material.
Expand All @@ -27,7 +27,7 @@ let refCount = 0
*/
@reactive
export class ClipPlanesBehavior extends MeshBehavior {
static _observedProperties = ['clipPlanes', 'flipClip', ...(MeshBehavior._observedProperties || [])]
static _observedProperties = ['clipPlanes', 'flipClip', 'clipDisabled', ...(MeshBehavior._observedProperties || [])]

// TODO reactive array?
#clipPlanes: Array<ClipPlane> = []
Expand All @@ -38,28 +38,36 @@ export class ClipPlanesBehavior extends MeshBehavior {
*
* *attribute*
*
* Adds a clip-planes attribute to the host elements that accepts one or
* more selectors, comma separated, that define which `<lume-clip-plane>`
* elements are to be used as clip planes. If a selector matches an element
* that is not a `<lume-clip-plane>`, it is ignored. If a selector matches
* more than one element, all of them that are clip planes are used.
* Default: `[]`
*
* The corresponding `clip-planes` attribute accepts one or more selectors,
* comma separated, that define which
* [`<lume-clip-plane>`](../../core/ClipPlane) elements are to be used as
* clip planes. If a selector matches an element that is not a
* `<lume-clip-plane>`, it is ignored. If a selector matches more than one
* element, all of them that are clip planes are used.
*
* ```html
* <lume-box has="clip-planes" clip-planes=".foo, .bar"></lume-box>
* <lume-box has="clip-planes" clip-planes=".foo, .bar, #baz"></lume-box>
* ```
*
* The property can also be set with a string (comma separated selectors),
* or a mixed array of strings (selectors) or `<lume-clip-plane>` element
* instances.
*
* ```js
* el.clipPlanes = ".some-plane"
* // or
* const plane = document.querySelector('.some-clip-plane')
* mesh.clipPlanes = [plane, "#someOtherPlane"]
* el.clipPlanes = [plane, "#someOtherPlane"]
* ```
*
* The property getter returns the current collection of `<lume-clip-plane>`
* instances that are being applied, not the original string or array of
* values passed into the attribute or setter.
* The property getter returns the currently applicable collection of
* `<lume-clip-plane>` instances, not the original string or array of values
* passed into the attribute or setter. Applicable planes are those that are
* connected into the document, and that participate in rendering (composed,
* either in the top level document, in a ShadowRoot, or distributed to a
* slot in a ShadowRoot).
*/
@stringAttribute('')
get clipPlanes(): Array<ClipPlane> {
Expand Down Expand Up @@ -129,12 +137,25 @@ export class ClipPlanesBehavior extends MeshBehavior {
*
* *attribute*
*
* Default: `false`
*
* By default, the side of a plane that is clipped is in its positive Z
* direction. Setting this to `true` will reverse clipping to the other
* side.
*/
@booleanAttribute(false) flipClip = false

/**
* @property {boolean} clipDisabled
*
* *attribute*
*
* Default: `false`
*
* If `true`, clipping is not applied.
*/
@booleanAttribute(false) clipDisabled = false

#observer: MutationObserver | null = null

override loadGL() {
Expand Down Expand Up @@ -169,7 +190,7 @@ export class ClipPlanesBehavior extends MeshBehavior {

this.element.needsUpdate()

if (!planes.length) {
if (!planes.length || this.clipDisabled) {
mat.clippingPlanes = null
mat.clipShadows = false // FIXME upstream: don't forget this or Three.js has a bug that still attempts to perform clipping even if clippingPlanes is null.
return
Expand Down
2 changes: 1 addition & 1 deletion src/core/ClipPlane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const clipNormal: [number, number, number] = [0, 0, -1]
* child of a `<lume-clip-plane>`, as in the below example.
*
* To clip an element, add a
* [`clip-planes`](../behaviors/mesh-behaviors/ClipPlane) behavior to the
* [`clip-planes`](../behaviors/mesh-behaviors/ClipPlanesBehavior) behavior to the
* element with the `has=""` attribute, then assign any number of connected
* `<lume-clip-plane>` elements to the element's `clipPlanes` property.
*
Expand Down

0 comments on commit 6b69d0a

Please sign in to comment.