Skip to content

feat(widgets) New ScreenshotWidget#9454

Merged
ibgreen merged 13 commits intomasterfrom
ib/screenshot-widget
Feb 23, 2025
Merged

feat(widgets) New ScreenshotWidget#9454
ibgreen merged 13 commits intomasterfrom
ib/screenshot-widget

Conversation

@ibgreen
Copy link
Copy Markdown
Collaborator

@ibgreen ibgreen commented Feb 20, 2025

Closes #

Background

  • Time to build out our widget library.
  • Trivial screenshot widget mostly to get a feeling for the API

Screenshot 2025-02-21 at 11 38 13 AM

Change List

  • Added basic usage docs to the widget module main page
  • Added a small abstract class, WidgetImpl, handling a fair bit of common code, allowing widget author to focus on implementing the onRenderHTML method.
  • Added a widget example using preact without JSX to tests/app/widgets
  • Widget props are now supplied by default. Before: new Widget({}) After: new Widget()
  • Experimentally export preact components
import {_components} from '@deck.gl/widgets';
const {IconButton} = _components;
h(IconButton, props, children)

@ibgreen ibgreen requested a review from chrisgervang February 20, 2025 22:44
@coveralls
Copy link
Copy Markdown

coveralls commented Feb 20, 2025

Coverage Status

coverage: 91.55% (-0.06%) from 91.607%
when pulling 9bbfe69 on ib/screenshot-widget
into 9752123 on master.

@ibgreen
Copy link
Copy Markdown
Collaborator Author

ibgreen commented Feb 20, 2025

Note: Since deck.gl doesn't clear the color of its canvas anymore, the screenshots have a dark background instead of white.

@ibgreen
Copy link
Copy Markdown
Collaborator Author

ibgreen commented Feb 20, 2025

@chrisgervang Wonder if one could record a short video using MediaRecorder APIs...

Copy link
Copy Markdown
Collaborator

@chrisgervang chrisgervang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @ibgreen, thanks for adding the new screenshot widget—great low-hanging fruit! To keep things easier to maintain, I'd prefer implementing the UI of all core widgets using Preact. As a comparison, MapLibre's controls are all written in pure JS and can be quite challenging to edit.

I really like a lot of the implementation of this abstract class and could see all of the core widgets benefiting from using it. For those who prefer pure-JS, they can always create their own versions, and if we can keep Preact out of the base class I think it'd be a suitable export to provide outside users too (that said, I agree with giving it an experimental status for a while too).

Comment thread modules/widgets/src/pure-js/screenshot-widget.ts Outdated
Comment on lines +11 to +12
/** Widget positioning within the view. Default 'top-left'. */
placement?: WidgetPlacement;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the base class can include this one. Widgets rendered over the map, like markers or popups, wouldn't have a concept of placement -- they'd hardcode to "fill".

Comment thread modules/widgets/src/pure-js/screenshot-widget.ts Outdated
}
}

function createCameraIcon({size = 24, color = 'black'} = {}) {
Copy link
Copy Markdown
Collaborator

@chrisgervang chrisgervang Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could make the icon re-colorable, resizable, and replaceable with CSS

  • Give the SVG a black fill for color masking
  • Convert your SVG to CSS with a convertor like this.
  • Remove height and width attributes (widget sets to 100%)
  • And add css to the stylesheet like this, with a unique CSS class name and variable for the icon.

For consistency with the other icons in the core set, you can use this Google Symbol too.

Give this a try:

url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="black"><path d="M480-260q75 0 127.5-52.5T660-440q0-75-52.5-127.5T480-620q-75 0-127.5 52.5T300-440q0 75 52.5 127.5T480-260Zm0-80q-42 0-71-29t-29-71q0-42 29-71t71-29q42 0 71 29t29 71q0 42-29 71t-71 29ZM160-120q-33 0-56.5-23.5T80-200v-480q0-33 23.5-56.5T160-760h126l74-80h240l74 80h126q33 0 56.5 23.5T880-680v480q0 33-23.5 56.5T800-120H160Zm0-80h640v-480H638l-73-80H395l-73 80H160v480Zm320-240Z"/></svg>')

Comment thread modules/widgets/src/pure-js/widget-impl.ts Outdated
@felixpalmer
Copy link
Copy Markdown
Collaborator

Note: Since deck.gl doesn't clear the color of its canvas anymore, the screenshots have a dark background instead of white.

Add a backgroundColor prop? This is surely going to be a common complaint

@ibgreen
Copy link
Copy Markdown
Collaborator Author

ibgreen commented Feb 21, 2025

Add a backgroundColor prop? This is surely going to be a common complaint

  • AFAIK CSS colors won't do it, it is the drawingBuffer that is captured, and if it has black transparent background pixels that is what we get.
  • IIRC, we used to be able to set the clear field on View to a color, but the less flexible clearing in the new WebGPU style API probably made us drop that feature.
  • Being able to capture a DOM hieararchy is of course useful (to e.g. include separate canvas basemap and widgets in our case), there are (fairly complicated) modules for that such as https://github.com/niklasvh/html2canvas
  • Perhaps add a captureScreen callback to let users include something like that?

@ibgreen
Copy link
Copy Markdown
Collaborator Author

ibgreen commented Feb 21, 2025

@chrisgervang Included some improvements to the widget module main page, will remove if it controversial.

@ibgreen
Copy link
Copy Markdown
Collaborator Author

ibgreen commented Feb 21, 2025

I am getting prettier error on CI but not locally???

Comment thread modules/widgets/src/pure-js/widget-impl.ts Outdated
@chrisgervang
Copy link
Copy Markdown
Collaborator

I am getting prettier error on CI but not locally???

Is it related to the .yarn state this PR is adding?

Copy link
Copy Markdown
Collaborator

@chrisgervang chrisgervang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a couple comments and I'd like to stick with JSX preact in this module. We could document how it's possible to use h in custom widgets.

Things to follow up on:

  • Apply padding to the icons (The camera is too big, the others have padding built into their SVG)
  • Export preact components as an experimental export (I don't want to guarantee)
  • Use base class in the other widgets

@ibgreen
Copy link
Copy Markdown
Collaborator Author

ibgreen commented Feb 21, 2025

I am getting prettier error on CI but not locally???

Is it related to the .yarn state this PR is adding?

Probably. deck is still on yarn 1 which always trips me up, there are no volta clauses in the examples. We should delete that .yarn state.

if (!element) return;
const layers = this.layers;
if (this.deck?.props.layerFilter) {
const ui = h(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ibgreen here's an example, the api reference for h, and you can use components with

import {_components} from '@deck.gl/widgets';
const {IconButton} = _components;

h(IconButton, props, children)

Comment on lines +43 to +49
this.placement = props.placement ?? this.placement;
this.viewId = props.viewId ?? this.viewId;
}

setProps(props: Partial<LayerListWidgetProps>) {
this.placement = props.placement ?? this.placement;
this.viewId = props.viewId ?? this.viewId;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call out: The widget system expects properties like placement and viewId to be assigned at the top-level. Not all widgets would expose these as props.

@ibgreen ibgreen merged commit 16e5966 into master Feb 23, 2025
@ibgreen ibgreen deleted the ib/screenshot-widget branch February 27, 2025 20:27
@ibgreen ibgreen mentioned this pull request Mar 4, 2025
62 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants