拓冰建站拓冰建站
首页 / 资讯中心 / 正文

如何在 tldraw 中实现随缩放级别请求合适图片分辨率(steppedScreenScale)

如何在 tldraw 中实现随缩放级别请求合适图片分辨率steppedScreenScale【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw当画布上的图片被缩小显示时如果你的资源存储仍然返回原图浏览器就要下载、解码一张远大于可视区域的大图。tldraw 的做法是缩小或缩放图片形状时通过TLAssetStore的resolve方法向你的资源存储请求一个与当前屏幕尺寸匹配的分辨率版本。你的任务就是实现这个resolve处理器利用上下文中的steppedScreenScale计算出该请求多宽的图并把带尺寸参数的 URL 返回给编辑器。前提条件使用 tldraw SDK 的 React 应用编辑器通过Tldraw assets{...}接收你自己的TLAssetStore你的图片后端能够按请求宽度返回图片比如 URL 查询参数或图片处理服务的端点。resolve只是改写 URL真正的变体生成由你的存储侧完成。理解 resolve 收到的 TLAssetContext每次编辑器需要显示一个资产drop、粘贴、缩放、复制粘贴等触发都会调用你TLAssetStore的resolve(asset, ctx)ctx的类型是TLAssetContext字段如下见 TLAssetContext 接口定义属性类型含义screenScalenumber资产相对原始尺寸的屏幕缩放比。1000px 的图显示为 500px 时是0.5。以 CSS 像素计不是设备像素steppedScreenScalenumberscreenScale向上取整到最近的 2 的幂次倍数适合做分级缓存dprnumber设备像素比Retina 屏上是 2 或 3networkEffectiveTypestring \| null浏览器连接类型slow-2g、2g、3g、4g依赖navigator.connection非所有浏览器可用shouldResolveToOriginalboolean复制/粘贴和未显式指定pixelRatio的 SVG 导出时为true此时应返回原图steppedScreenScale的计算在编辑器里可以直接看到Editor#resolveAssetUrl 用Math.pow(2, Math.ceil(Math.log2(zoom)))把screenScale向上取到最近的 2 的幂次。取整的目的是让缩放过程中 URL 只在少数几个档位之间切换而不是每帧都变。官方性能文档给了一个例子文档示例数值一张 4000px 宽的照片缩小到屏幕上只占 200px 时screen scale 为 0.05向上步进到 0.0625于是请求4000 * 0.0625 250px宽的图再乘dpr而不是完整的 4000px。这能直接减少内存占用和解码开销。另外分辨率更新做了防抖缩放过程中图片不会在不同尺寸之间来回抖动见 性能文档。实现带分辨率切换的 TLAssetStore完整的存储实现需要upload文件入库并返回 URL和resolve把 URL 改写为合适的变体两个方法remove可选。下面是核心路径resolve部分与 Assets 文档中的示例一致import { Tldraw, TLAssetStore } from tldraw import tldraw/tldraw.css const assetStore: TLAssetStore { // 文件入库返回 { src }src 会存进资产的 props async upload(asset, file) { // 上传到你的存储返回长期有效的 URL return { src: /uploads/photo.jpg } }, resolve(asset, ctx) { if (!asset.props.src) return null // 导出、复制粘贴场景必须返回原图 if (ctx.shouldResolveToOriginal) { return asset.props.src } // 非图片资产不做处理 if (asset.type ! image) return asset.props.src // 按当前显示尺寸请求对应宽度的图 const width Math.ceil(asset.props.w * ctx.steppedScreenScale * ctx.dpr) return ${asset.props.src}?w${width} }, } export default function App() { return ( div style{{ position: fixed, inset: 0 }} Tldraw assets{assetStore} / /div ) }几个必须注意的点resolve是可选方法不实现时默认返回asset.props.src即每次都用原图。返回null表示资产不可用形状会渲染 broken-asset 占位。示例中的?w${width}是文档给出的 URL 方案参数名和拼接方式要替换成你的图片服务实际支持的格式如果你的后端不支持按宽度出图需要先在后端加这个能力前端这一步本身不产生变体。ctx.steppedScreenScale * ctx.dpr得到的是设备像素宽度CSS 像素再乘dpr是文档明确的换算方式。如果你已经实现了存储只想在现有resolve上加分辨率逻辑把宽度计算加进去即可其他改写逻辑如鉴权 token保留在原位置。验证是否生效文档给出的判断依据是tldraw 会在缩小或缩放图片形状时向资源存储请求低分辨率版本所以验证方式是观察实际请求的 URL 是否随缩放变化在resolve中加一行console.log(ctx.steppedScreenScale, ctx.dpr, asset.id)或打开浏览器 Network 面板观察图片请求。往画布放一张大图逐步缩小视图。按文档示例的比例如 4000px 原图缩到 200px 显示缩放时请求宽度应从原始宽度降到步进档位对应的宽度示例中为 250px × dpr。确认缩放过程中请求不是每帧变化分辨率更新有防抖URL 只在步进档位间切换。复制画布上的图片再粘贴或不指定pixelRatio导出 SVG请求应回到asset.props.src原图对应shouldResolveToOriginal: true分支。可选增强与边界生产实现通常还会处理慢网络和设备像素比等因素。仓库里 tldraw.com 客户端的实现multiplayerAssetStore展示了文档支持的完整组合方式可按需借鉴用clamp(context.steppedScreenScale, 1 / 32, 1)限制缩放档位下限乘上资产的pixelRatio ?? 1得到真实源图宽度并用Math.min保证请求宽度不超过原图非4g连接时乘0.5的networkCompensation降低目标宽度fileSize低于 1.5MB 的图不值得 resize只走格式转换动画图片和矢量图SVG不做图像变换直接返回原 URL——变换服务会破坏动画帧或 SVG 内嵌内容非http(s)的src如 data URL不做改写。边界与限制dpr和networkEffectiveType来自运行环境navigator.connection只在部分浏览器主要是 Blink 系可用代码里要容忍null。该机制只作用于你实现的TLAssetStore默认的inlineBase64AssetStore把文件转成 data URL没有多分辨率可言优化只在自托管存储下成立。请求的是当前显示所需的分辨率不改变文档里存的资产记录也不影响导出质量导出走shouldResolveToOriginal。更多上下文见 Assets 文档TLAssetStore接口、自定义资产类型、存储后端和 Performance 文档LOD、防抖缩放等其余渲染优化手段。【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门