
this is take #2 of this PR https://github.com/tldraw/tldraw/pull/3764 This continues the idea kicked off in https://github.com/tldraw/tldraw/pull/3684 to explore LOD and takes it in a different direction. Several things here to call out: - our dotcom version would start to use Cloudflare's image transforms - we don't rewrite non-image assets - we debounce zooming so that we're not swapping out images while zooming (it creates jank) - we load different images based on steps of .25 (maybe we want to make this more, like 0.33). Feels like 0.5 might be a bit too much but we can play around with it. - we take into account network connection speed. if you're on 3g, for example, we have the size of the image. - dpr is taken into account - in our case, Cloudflare handles it. But if it wasn't Cloudflare, we could add it to our width equation. - we use Cloudflare's `fit=scale-down` setting to never scale _up_ an image. - we don't swap the image in until we've finished loading it programatically (to avoid a blank image while it loads) TODO - [x] We need to enable Cloudflare's pricing on image transforms btw @steveruizok 😉 - this won't work quite yet until we do that. ### Change Type <!-- ❗ Please select a 'Scope' label ❗️ --> - [x] `sdk` — Changes the tldraw SDK - [ ] `dotcom` — Changes the tldraw.com web app - [ ] `docs` — Changes to the documentation, examples, or templates. - [ ] `vs code` — Changes to the vscode plugin - [ ] `internal` — Does not affect user-facing stuff <!-- ❗ Please select a 'Type' label ❗️ --> - [ ] `bugfix` — Bug fix - [x] `feature` — New feature - [ ] `improvement` — Improving existing features - [ ] `chore` — Updating dependencies, other boring stuff - [ ] `galaxy brain` — Architectural changes - [ ] `tests` — Changes to any test code - [ ] `tools` — Changes to infrastructure, CI, internal scripts, debugging tools, etc. - [ ] `dunno` — I don't know ### Test Plan 1. Test images on staging, small, medium, large, mega 2. Test videos on staging - [x] Unit Tests - [ ] End to end tests ### Release Notes - Assets: make option to transform urls dynamically to provide different sized images on demand.
40 lines
1.7 KiB
TypeScript
40 lines
1.7 KiB
TypeScript
import { AssetContextProps, MediaHelpers, TLAsset } from 'tldraw'
|
|
import { ASSET_BUCKET_ORIGIN, ASSET_UPLOADER_URL } from './config'
|
|
|
|
export async function resolveAsset(asset: TLAsset | null | undefined, context: AssetContextProps) {
|
|
if (!asset || !asset.props.src) return null
|
|
|
|
// We don't deal with videos at the moment.
|
|
if (asset.type === 'video') return asset.props.src
|
|
|
|
// Assert it's an image to make TS happy.
|
|
if (asset.type !== 'image') return null
|
|
|
|
// Don't try to transform data: URLs, yikes.
|
|
if (!asset.props.src.startsWith('http:') && !asset.props.src.startsWith('https:'))
|
|
return asset.props.src
|
|
|
|
// Don't try to transform animated images.
|
|
if (MediaHelpers.isAnimatedImageType(asset?.props.mimeType) || asset.props.isAnimated)
|
|
return asset.props.src
|
|
|
|
// Assets that are under a certain file size aren't worth transforming (and incurring cost).
|
|
if (asset.props.fileSize === -1 || asset.props.fileSize < 1024 * 1024 * 1.5 /* 1.5 MB */)
|
|
return asset.props.src
|
|
|
|
// N.B. navigator.connection is only available in certain browsers (mainly Blink-based browsers)
|
|
// 4g is as high the 'effectiveType' goes and we can pick a lower effective image quality for slower connections.
|
|
const networkCompensation =
|
|
!context.networkEffectiveType || context.networkEffectiveType === '4g' ? 1 : 0.5
|
|
|
|
const width = Math.ceil(asset.props.w * context.steppedScreenScale * networkCompensation)
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
return asset.props.src
|
|
}
|
|
|
|
// On preview, builds the origin for the asset won't be the right one for the Cloudflare transform.
|
|
const src = asset.props.src.replace(ASSET_UPLOADER_URL, ASSET_BUCKET_ORIGIN)
|
|
|
|
return `${ASSET_BUCKET_ORIGIN}/cdn-cgi/image/width=${width},dpr=${context.dpr},fit=scale-down,quality=92/${src}`
|
|
}
|