思路:React-Native
本人是没有Canvas
,能够利用react-native-webview
注入html
做一个Canvas
,把写入Webview
的html
作为可变的字符串,每写一条canvas
就在字符串上的script标签里增加对应的语句,每一次增加都是异步的,通过onMessage
去获取Webview
往外传的值
- 初始化一个html页面
window.onload
里去执行咱们要增加的js字符串
private state: State = { js: `const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');window.document.body.appendChild(canvas);`, end: '', // js尾巴 style: {width: 1, height: 1}};
<WebView style={[style]} javaScriptEnabledAndroid={true} overScrollMode="never" mixedContentMode="always" thirdPartyCookiesEnabled allowUniversalAccessFromFileURLs javaScriptEnabled={true} domStorageEnabled={false} automaticallyAdjustContentInsets={true} scalesPageToFit={false} showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} onMessage={(e) => { }} source={{ html: `<!DOCTYPE html> <html lang="en"> <head> <meta content='width=device-width, initial-scale=1, maximum-scale=1' name='viewport'> <style> html { -ms-content-zooming: none; -ms-touch-action: pan-x pan-y; } * { user-select: none; -ms-user-select: none; -moz-user-select: none; -webkit-user-select: none; padding: 0; margin: 0; } </style> </head> <body> <script> window.onload = () => { ${js + end} } </script> </body> </html>` }}/>
- 写js的代码
设置宽高
public setStyle = (options: { width: number; height: number }, ratio = 1) => { return new Promise<Canvas>((resolve) => { const {style, js} = this.state; this.setState({ style: {...style, ...options}, js: js + `canvas.width = ${options.width * ratio};canvas.height = ${options.height * ratio};` } as State, () => resolve(this)); }); };
- 非凡解决
画图片,须要在图片image.load
实现之后写别的js
private changeJs = (newJs: string, callback: () => void, newEnd?: string) => { const {js, end} = this.state; this.setState({ js: js + newJs, end: end + (newEnd || "") } as State, callback);};// 设置图片public setImage = (src: string, x: number, y: number, w: number, h: number) => { const imageName = this.randCode(); // 随机字符串 return new Promise<Canvas>((resolve) => { this.changeJs(`const ${imageName} = new Image();${imageName}.src = "${src}";${imageName}.setAttribute("crossOrigin", 'Anonymous');${imageName}.onload = function() { ctx.drawImage(${imageName}, ${x}, ${y}, ${w}, ${h}); window['ReactNativeWebView'] && window['ReactNativeWebView'].postMessage(JSON.stringify({ onKey: "${imageName}", }));// 把尾巴 }; 作为一段放在最初面的`, () => resolve(this), `};`); });};
- 获取webview的值(
window.ReactNativeWebView.postMessage
)
打印