关于javascript:ReactNative-Canvas

10次阅读

共计 2184 个字符,预计需要花费 6 分钟才能阅读完成。

思路:React-Native本人是没有 Canvas,能够利用react-native-webview 注入 html 做一个 Canvas,把写入Webviewhtml作为可变的字符串,每写一条 canvas 就在字符串上的 script 标签里增加对应的语句,每一次增加都是异步的,通过 onMessage 去获取 Webview 往外传的值

  1. 初始化一个 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>`
   }}
/>
  1. 写 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));
        });
    };
  1. 非凡解决
    画图片,须要在图片 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), `};
`);
    });
};
  1. 获取 webview 的值 (window.ReactNativeWebView.postMessage)
    打印
正文完
 0