使用 Velocity.js 从 URL 渲染 SVG 动画
Posted
技术标签:
【中文标题】使用 Velocity.js 从 URL 渲染 SVG 动画【英文标题】:Render SVG from URL for animation with Velocity.js 【发布时间】:2018-02-18 06:05:41 【问题描述】:我正在构建一个界面来预览应用于 SVG 的动画。我正在尝试使用 React 中的 Velocity.js 库来定位 SVG 的内部动画路径。我正在使用create-react-app。
我可以将 .svg 文件拖放到 react-dropzone 输入中,该输入提供带有 File
对象的回调。我可以将File
对象转换为base64 编码的DataURL,然后我可以将其提供给<object>
标签。这会使用完整的扩展 xml 标记呈现 SVG。
return (
<object style=
width: '100%'
id=`svg-$uuid`
type="image/svg+xml" data=dataURL
/>)
任何使用 javascript 访问 SVG 的 contentDocument
的尝试(为了将 g
和 path
元素直接定位为动画)都会导致以下错误:
document.getElementById('svg-665790ae-2a36-446e-9ea9-856442e8b1dc').contentDocument
Uncaught DOMException: Failed to read the 'contentDocument' property from 'htmlObjectElement':
Blocked a frame with origin "http://localhost:3000" from accessing a cross-origin frame.
我正在开发本地开发环境,在 localhost:3000
上为 React 应用程序提供服务。
作为一种可能的解决方法,我将有问题的 SVG 上传到远程 AWS S3 存储桶。然后我通过远程 URL 检索 SVG,并尝试以某种方式呈现它。我尝试了以下方法:
React SVG <use>
tag
<svg>
<use xlinkHref=url></use>
</svg>
这会产生以下标记,但没有可见的 SVG:
<svg>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://s3.amazonaws.com/.../example.svg">
</use>
</svg>
<object>
标签
<object
style=
width: '100%',
id=`svg-$uuid` type="image/svg+xml" data=url
/>
这会导致以下标记,没有可见的 SVG,并导致浏览器立即将 SVG 作为文件下载。
<object id="svg-..." type="image/svg+xml" data="https://s3.amazonaws.com/.../example.svg" style="width: 100%;"></object>
react-inlinesvg库
此库发出 XHR 请求以检索 SVG,然后将其嵌入到 DOM 中。
<Isvg src=url/>
这会导致以下错误:
XMLHttpRequest cannot load https://s3.amazonaws.com/.../example.svg.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
SVGInjector
首先,我使用 SVG url 安装了一个简单的 <img>
标签:
return (
<img
ref=node => this.testSVG = node
src=url id="svg" type="image/svg+xml" />
)
这也会导致上述XMLHttpRequest
错误。尝试使用节点ref
(即SVGInjector(this.testSVG)
)或以这种方式从componentDidMount
调用SVGInjector
:
const el = document.getElementById('svg');
SVGInjector(el);
导致警告消失,但只显示损坏的图像标签。
任何帮助解决这些CORS
警告或有关在 React 中为动画目的将 SVG 嵌入 DOM 的正确方法的指导,将不胜感激。也许我需要做的是通过服务器下载图像,并暂时直接从服务器文件系统提供它,例如,从/public
文件夹。这不是我的首选方法,因为我已经在使用 AWS S3 进行图像托管。
【问题讨论】:
如果您控制您的代码尝试跨域加载图像的服务器 (https://s3.amazonaws.com/.../example.svg
),则需要将该服务器配置为包含 Access-Control-Allow-Origin 响应标头它为这些图像提供服务。如果你不控制那个服务器,那么你必须使用某种代理——或者是你在自己的后端设置的东西,或者是一个开放的 CORS 代理。请参阅***.com/a/43881141/441757 答案中的如何使用 CORS 代理解决“No Access-Control-Allow-Origin 标头”问题部分,例如代码+说明
谢谢!这似乎成功了。我现在可以使用 react-inlinesvg 组件来渲染 SVG。我关注 this post 并打开了我的 AWS S3 CORS。我将尝试删除标头以查看最佳配置。
【参考方案1】:
答案是在 AWS S3 控制台中启用 CORS。见***.com/questions/17533888/s3-access-control-allow-origin-header。 CORS配置似乎默认没有启用,所以我必须保存它才能使其生效。
<!-- Sample policy -->
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
感谢sideshowbarker 的推荐。正如他所提到的,如果您从另一个域提供图像,而您无权访问,则可能需要使用代理。请参阅***.com/a/43881141/441757,在如何使用 CORS 代理解决“No Access-Control-Allow-Origin header”问题部分下,了解详细信息。
【讨论】:
以上是关于使用 Velocity.js 从 URL 渲染 SVG 动画的主要内容,如果未能解决你的问题,请参考以下文章