@solidrt/components 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/image.tsx +40 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/components",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "license": "MIT",
5
5
  "author": "Antoine van Wel",
6
6
  "type": "module",
@@ -15,6 +15,6 @@
15
15
  ],
16
16
  "peerDependencies": {
17
17
  "@solidjs/signals": "2.0.0-beta.14",
18
- "@solidrt/core": "0.0.9"
18
+ "@solidrt/core": "0.0.10"
19
19
  }
20
20
  }
package/src/image.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { createSignal, onCleanup } from "@solidjs/signals"
1
+ import { createSignal, createEffect, onCleanup } from "@solidjs/signals"
2
2
  import { decodeImage, createTexture } from "@solidrt/core/gpu"
3
3
  import type { LayoutProps, PointerProps } from "@solidrt/core"
4
4
  import type { StyleProps } from "./types"
@@ -12,22 +12,45 @@ export interface ImageProps extends PointerProps {
12
12
  //TODO onLoad, onError
13
13
  //TODO release texture in onCleanup
14
14
  export function Image(props: ImageProps) {
15
- let [res] = createSignal(async () => {
16
- let bytes: Uint8Array
17
- if (typeof props.src === "string") {
18
- let response = await fetch(props.src)
19
- bytes = await response.bytes()
20
- } else {
21
- bytes = props.src
22
- }
23
- let { data, width, height } = decodeImage(bytes)
24
- let id = createTexture(data, width, height)
25
- return { id, width, height }
26
- })
15
+ let [res, setRes] = createSignal<{ id: number; width: number; height: number }>()
16
+
17
+ // Load (and decode) whenever src changes. A url is fetched; bytes are used
18
+ // directly. The async result is pushed into the signal so the texture shows
19
+ // once ready; a stale flag drops results from a superseded src.
20
+ createEffect(
21
+ () => props.src,
22
+ (source) => {
23
+ let stale = false
24
+
25
+ ;(async () => {
26
+ let bytes: Uint8Array
27
+ if (typeof source === "string") {
28
+ let response = await fetch(source)
29
+ bytes = await response.bytes()
30
+ } else {
31
+ bytes = source
32
+ }
33
+ if (stale) return
34
+ let { data, width, height } = decodeImage(bytes)
35
+ let id = createTexture(data, width, height)
36
+ setRes({ id, width, height })
37
+ })()
38
+
39
+ return () => {
40
+ stale = true
41
+ }
42
+ },
43
+ )
27
44
 
28
45
  let src = () => res()?.id
29
46
  let hasBorder = () => (props.style?.borderWidth ?? 0) > 0
30
47
 
48
+ // A texture sizes from its own width/height (not the box around it), so the
49
+ // numeric layout dimensions are forwarded to it. Omitting height lets the
50
+ // texture follow the image's intrinsic aspect ratio.
51
+ let texW = () => (typeof props.layout?.width === "number" ? props.layout.width : undefined)
52
+ let texH = () => (typeof props.layout?.height === "number" ? props.layout.height : undefined)
53
+
31
54
  onCleanup(() => {
32
55
  //TODO release texture
33
56
  })
@@ -35,6 +58,8 @@ export function Image(props: ImageProps) {
35
58
  return (
36
59
  <view
37
60
  {...props.layout}
61
+ overflow={props.style?.borderRadius != null ? "hidden" : props.layout?.overflow}
62
+ clipRadius={props.style?.borderRadius}
38
63
  x={props.style?.x}
39
64
  y={props.style?.y}
40
65
  scale={props.style?.scale}
@@ -53,9 +78,9 @@ export function Image(props: ImageProps) {
53
78
  pointerEvents={props.pointerEvents}
54
79
  >
55
80
  {props.style?.backgroundColor != null ? (
56
- <d-rect color={props.style.backgroundColor} radius={props.style?.borderRadius} />
81
+ <d-rect color={props.style?.backgroundColor} radius={props.style?.borderRadius} />
57
82
  ) : null}
58
- <texture src={src()} />
83
+ <texture src={src()} width={texW()} height={texH()} />
59
84
  {hasBorder() ? (
60
85
  <d-rect
61
86
  drawStyle="stroke"