@hxa-rn/react-native-gcanvas 6.0.24-beta.1 → 6.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -2
- package/LICENSE +203 -21
- package/README.md +207 -207
- package/harmony/gcanvas/LICENSE +203 -21
- package/harmony/gcanvas/NOTICE +32 -32
- package/harmony/gcanvas/OAT.xml +37 -37
- package/harmony/gcanvas/build-profile.json5 +16 -16
- package/harmony/gcanvas/hvigorfile.ts +1 -1
- package/harmony/gcanvas/index.ets +1 -1
- package/harmony/gcanvas/oh-package.json5 +14 -14
- package/harmony/gcanvas/src/main/cpp/CMakeLists.txt +126 -126
- package/harmony/gcanvas/src/main/cpp/GCanvasNapi.cpp +485 -485
- package/harmony/gcanvas/src/main/cpp/GCanvasXComponent.cpp +106 -106
- package/harmony/gcanvas/src/main/cpp/GcanvasPackage.h +24 -24
- package/harmony/gcanvas/src/main/ets/GCanvasModuleTurboModule.ts +448 -448
- package/harmony/gcanvas/src/main/ets/GCanvasNativeEngine.ts +206 -206
- package/harmony/gcanvas/src/main/ets/components/GCanvasView.ets +64 -64
- package/harmony/gcanvas/src/main/module.json5 +21 -21
- package/harmony/gcanvas/src/main/resources/base/element/string.json +12 -12
- package/harmony/gcanvas/src/main/resources/en_US/element/string.json +8 -8
- package/harmony/gcanvas/src/main/resources/zh_CN/element/string.json +12 -12
- package/harmony/gcanvas.har +0 -0
- package/package.json +4 -4
- package/packages/gcanvas/.babelrc +4 -4
- package/packages/gcanvas/.eslintrc.js +133 -133
- package/packages/gcanvas/package.json +19 -19
- package/packages/gcanvas/rollup.config.js +13 -13
- package/packages/gcanvas/src/bridge/react-native.js +286 -286
- package/packages/gcanvas/src/bridge/weex.js +210 -210
- package/packages/gcanvas/src/context/2d/FillStyleLinearGradient.js +16 -16
- package/packages/gcanvas/src/context/2d/FillStylePattern.js +7 -7
- package/packages/gcanvas/src/context/2d/FillStyleRadialGradient.js +16 -16
- package/packages/gcanvas/src/context/2d/OffScreenRenderingContext.js +48 -48
- package/packages/gcanvas/src/context/2d/RenderingContext.js +787 -787
- package/packages/gcanvas/src/context/webgl/ActiveInfo.js +10 -10
- package/packages/gcanvas/src/context/webgl/Buffer.js +20 -20
- package/packages/gcanvas/src/context/webgl/Framebuffer.js +20 -20
- package/packages/gcanvas/src/context/webgl/GLenum.js +300 -300
- package/packages/gcanvas/src/context/webgl/GLmethod.js +141 -141
- package/packages/gcanvas/src/context/webgl/GLtype.js +22 -22
- package/packages/gcanvas/src/context/webgl/Program.js +20 -20
- package/packages/gcanvas/src/context/webgl/Renderbuffer.js +20 -20
- package/packages/gcanvas/src/context/webgl/RenderingContext.js +1479 -1479
- package/packages/gcanvas/src/context/webgl/Shader.js +21 -21
- package/packages/gcanvas/src/context/webgl/ShaderPrecisionFormat.js +10 -10
- package/packages/gcanvas/src/context/webgl/Texture.js +21 -21
- package/packages/gcanvas/src/context/webgl/UniformLocation.js +21 -21
- package/packages/gcanvas/src/context/webgl/classUtils.js +2 -2
- package/packages/gcanvas/src/env/canvas.js +210 -210
- package/packages/gcanvas/src/env/image.js +76 -76
- package/packages/gcanvas/src/env/off-screen-canvas.js +74 -74
- package/packages/gcanvas/src/index.js +56 -56
- package/src/components/CanvasView.js +20 -20
- package/src/components/GCanvasComponent.js +408 -408
- package/src/index.js +69 -69
- package/src/packages/gcanvas/.babelrc +4 -4
- package/src/packages/gcanvas/.eslintrc.js +133 -133
- package/src/packages/gcanvas/package.json +19 -19
- package/src/packages/gcanvas/rollup.config.js +13 -13
- package/src/packages/gcanvas/src/bridge/react-native.js +288 -288
- package/src/packages/gcanvas/src/bridge/weex.js +210 -210
- package/src/packages/gcanvas/src/context/2d/FillStyleLinearGradient.js +16 -16
- package/src/packages/gcanvas/src/context/2d/FillStylePattern.js +7 -7
- package/src/packages/gcanvas/src/context/2d/FillStyleRadialGradient.js +16 -16
- package/src/packages/gcanvas/src/context/2d/OffScreenRenderingContext.js +48 -48
- package/src/packages/gcanvas/src/context/2d/RenderingContext.js +801 -801
- package/src/packages/gcanvas/src/context/webgl/ActiveInfo.js +10 -10
- package/src/packages/gcanvas/src/context/webgl/Buffer.js +20 -20
- package/src/packages/gcanvas/src/context/webgl/Framebuffer.js +20 -20
- package/src/packages/gcanvas/src/context/webgl/GLenum.js +300 -300
- package/src/packages/gcanvas/src/context/webgl/GLmethod.js +141 -141
- package/src/packages/gcanvas/src/context/webgl/GLtype.js +22 -22
- package/src/packages/gcanvas/src/context/webgl/Program.js +20 -20
- package/src/packages/gcanvas/src/context/webgl/Renderbuffer.js +20 -20
- package/src/packages/gcanvas/src/context/webgl/RenderingContext.js +1479 -1479
- package/src/packages/gcanvas/src/context/webgl/Shader.js +21 -21
- package/src/packages/gcanvas/src/context/webgl/ShaderPrecisionFormat.js +10 -10
- package/src/packages/gcanvas/src/context/webgl/Texture.js +21 -21
- package/src/packages/gcanvas/src/context/webgl/UniformLocation.js +21 -21
- package/src/packages/gcanvas/src/context/webgl/classUtils.js +2 -2
- package/src/packages/gcanvas/src/env/canvas.js +210 -210
- package/src/packages/gcanvas/src/env/image.js +76 -76
- package/src/packages/gcanvas/src/env/off-screen-canvas.js +74 -74
- package/src/packages/gcanvas/src/index.js +56 -56
- package/src/specs/v1/GCanvasViewNativeComponent.ts +42 -42
- package/src/specs/v1/NativeGCanvasModule.ts +140 -140
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {getTransferedObjectUUID} from './classUtils';
|
|
2
|
-
|
|
3
|
-
const name = 'WebGLShader';
|
|
4
|
-
|
|
5
|
-
function uuid(id) {
|
|
6
|
-
return getTransferedObjectUUID(name, id);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default class WebGLShader {
|
|
10
|
-
className = name;
|
|
11
|
-
|
|
12
|
-
constructor(id, type) {
|
|
13
|
-
this.id = id;
|
|
14
|
-
this.type = type;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
static uuid = uuid;
|
|
18
|
-
|
|
19
|
-
uuid() {
|
|
20
|
-
return uuid(this.id);
|
|
21
|
-
}
|
|
1
|
+
import {getTransferedObjectUUID} from './classUtils';
|
|
2
|
+
|
|
3
|
+
const name = 'WebGLShader';
|
|
4
|
+
|
|
5
|
+
function uuid(id) {
|
|
6
|
+
return getTransferedObjectUUID(name, id);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default class WebGLShader {
|
|
10
|
+
className = name;
|
|
11
|
+
|
|
12
|
+
constructor(id, type) {
|
|
13
|
+
this.id = id;
|
|
14
|
+
this.type = type;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static uuid = uuid;
|
|
18
|
+
|
|
19
|
+
uuid() {
|
|
20
|
+
return uuid(this.id);
|
|
21
|
+
}
|
|
22
22
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export default class WebGLShaderPrecisionFormat {
|
|
2
|
-
className = 'WebGLShaderPrecisionFormat';
|
|
3
|
-
|
|
4
|
-
constructor({
|
|
5
|
-
rangeMin, rangeMax, precision
|
|
6
|
-
}) {
|
|
7
|
-
this.rangeMin = rangeMin;
|
|
8
|
-
this.rangeMax = rangeMax;
|
|
9
|
-
this.precision = precision;
|
|
10
|
-
}
|
|
1
|
+
export default class WebGLShaderPrecisionFormat {
|
|
2
|
+
className = 'WebGLShaderPrecisionFormat';
|
|
3
|
+
|
|
4
|
+
constructor({
|
|
5
|
+
rangeMin, rangeMax, precision
|
|
6
|
+
}) {
|
|
7
|
+
this.rangeMin = rangeMin;
|
|
8
|
+
this.rangeMax = rangeMax;
|
|
9
|
+
this.precision = precision;
|
|
10
|
+
}
|
|
11
11
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {getTransferedObjectUUID} from './classUtils';
|
|
2
|
-
|
|
3
|
-
const name = 'WebGLTexture';
|
|
4
|
-
|
|
5
|
-
function uuid(id) {
|
|
6
|
-
return getTransferedObjectUUID(name, id);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default class WebGLTexture {
|
|
10
|
-
className = name;
|
|
11
|
-
|
|
12
|
-
constructor(id, type) {
|
|
13
|
-
this.id = id;
|
|
14
|
-
this.type = type;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
static uuid = uuid;
|
|
18
|
-
|
|
19
|
-
uuid() {
|
|
20
|
-
return uuid(this.id);
|
|
21
|
-
}
|
|
1
|
+
import {getTransferedObjectUUID} from './classUtils';
|
|
2
|
+
|
|
3
|
+
const name = 'WebGLTexture';
|
|
4
|
+
|
|
5
|
+
function uuid(id) {
|
|
6
|
+
return getTransferedObjectUUID(name, id);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default class WebGLTexture {
|
|
10
|
+
className = name;
|
|
11
|
+
|
|
12
|
+
constructor(id, type) {
|
|
13
|
+
this.id = id;
|
|
14
|
+
this.type = type;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static uuid = uuid;
|
|
18
|
+
|
|
19
|
+
uuid() {
|
|
20
|
+
return uuid(this.id);
|
|
21
|
+
}
|
|
22
22
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {getTransferedObjectUUID} from './classUtils';
|
|
2
|
-
|
|
3
|
-
const name = 'WebGLUniformLocation';
|
|
4
|
-
|
|
5
|
-
function uuid(id) {
|
|
6
|
-
return getTransferedObjectUUID(name, id);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default class WebGLUniformLocation {
|
|
10
|
-
className = name;
|
|
11
|
-
|
|
12
|
-
constructor(id, type) {
|
|
13
|
-
this.id = id;
|
|
14
|
-
this.type = type;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
static uuid = uuid;
|
|
18
|
-
|
|
19
|
-
uuid() {
|
|
20
|
-
return uuid(this.id);
|
|
21
|
-
}
|
|
1
|
+
import {getTransferedObjectUUID} from './classUtils';
|
|
2
|
+
|
|
3
|
+
const name = 'WebGLUniformLocation';
|
|
4
|
+
|
|
5
|
+
function uuid(id) {
|
|
6
|
+
return getTransferedObjectUUID(name, id);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default class WebGLUniformLocation {
|
|
10
|
+
className = name;
|
|
11
|
+
|
|
12
|
+
constructor(id, type) {
|
|
13
|
+
this.id = id;
|
|
14
|
+
this.type = type;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static uuid = uuid;
|
|
18
|
+
|
|
19
|
+
uuid() {
|
|
20
|
+
return uuid(this.id);
|
|
21
|
+
}
|
|
22
22
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export function getTransferedObjectUUID(name, id) {
|
|
2
|
-
return `${name.toLowerCase()}-${id}`;
|
|
1
|
+
export function getTransferedObjectUUID(name, id) {
|
|
2
|
+
return `${name.toLowerCase()}-${id}`;
|
|
3
3
|
}
|
|
@@ -1,210 +1,210 @@
|
|
|
1
|
-
import Element from '@flyskywhy/react-native-browser-polyfill/src/DOM/Element';
|
|
2
|
-
import GContext2D from '../context/2d/RenderingContext';
|
|
3
|
-
import GContextWebGL from '../context/webgl/RenderingContext';
|
|
4
|
-
import {PixelRatio} from 'react-native';
|
|
5
|
-
|
|
6
|
-
function sleepMs(ms) {
|
|
7
|
-
for (var start = new Date(); new Date() - start <= ms; ) {}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default class GCanvas extends Element {
|
|
11
|
-
static GBridge = null;
|
|
12
|
-
|
|
13
|
-
id = null;
|
|
14
|
-
_renderLoopId = null;
|
|
15
|
-
_context = null;
|
|
16
|
-
_clientWidth = 100;
|
|
17
|
-
_clientHeight = 150;
|
|
18
|
-
_width = 100;
|
|
19
|
-
_height = 150;
|
|
20
|
-
|
|
21
|
-
_needRender = true;
|
|
22
|
-
|
|
23
|
-
constructor(
|
|
24
|
-
id,
|
|
25
|
-
{
|
|
26
|
-
isAutoClearRectBeforePutImageData,
|
|
27
|
-
isResetGlViewportAfterSetWidthOrHeight,
|
|
28
|
-
devicePixelRatio,
|
|
29
|
-
disableAutoSwap,
|
|
30
|
-
style,
|
|
31
|
-
},
|
|
32
|
-
) {
|
|
33
|
-
super('canvas');
|
|
34
|
-
this.id = id;
|
|
35
|
-
this.disabled = false;
|
|
36
|
-
this.webglInterval = null;
|
|
37
|
-
|
|
38
|
-
this._isAutoClearRectBeforePutImageData = isAutoClearRectBeforePutImageData;
|
|
39
|
-
this._isResetGlViewportAfterSetWidthOrHeight = isResetGlViewportAfterSetWidthOrHeight;
|
|
40
|
-
this._devicePixelRatio = devicePixelRatio || PixelRatio.get();
|
|
41
|
-
this._disableAutoSwap = disableAutoSwap;
|
|
42
|
-
this._swapBuffers = () => {
|
|
43
|
-
this._context && this._context.flushJsCommands2CallNative();
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
this._clientWidth = style.width | 0; // width is fixed not float just like Web
|
|
47
|
-
this._clientHeight = style.height | 0;
|
|
48
|
-
this._width = style.width | 0; // width is fixed not float just like Web
|
|
49
|
-
this._height = style.height | 0;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
get clientWidth() {
|
|
53
|
-
return this._clientWidth;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
get clientHeight() {
|
|
57
|
-
return this._clientHeight;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
set clientWidth(value) {
|
|
61
|
-
this._clientWidth = value | 0; // width is fixed not float just like Web
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
set clientHeight(value) {
|
|
65
|
-
this._clientHeight = value | 0;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
get width() {
|
|
69
|
-
return this._width;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
set width(value) {
|
|
73
|
-
if (this._context) {
|
|
74
|
-
if (this._context.className === 'CanvasRenderingContext2D') {
|
|
75
|
-
this._context.clearRect(0, 0, this._clientWidth, this._clientHeight);
|
|
76
|
-
} else {
|
|
77
|
-
this._context.drawingBufferWidth = this._clientWidth * PixelRatio.get() | 0;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
this._conditionallyResetGlViewport();
|
|
81
|
-
}
|
|
82
|
-
this._width = value | 0; // width is fixed not float just like Web
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
get height() {
|
|
86
|
-
return this._height;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
set height(value) {
|
|
90
|
-
if (this._context) {
|
|
91
|
-
if (this._context.className === 'CanvasRenderingContext2D') {
|
|
92
|
-
this._context.clearRect(0, 0, this._clientWidth, this._clientHeight);
|
|
93
|
-
} else {
|
|
94
|
-
this._context.drawingBufferHeight = this._clientHeight * PixelRatio.get() | 0;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
this._conditionallyResetGlViewport();
|
|
98
|
-
}
|
|
99
|
-
this._height = value | 0;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
_conditionallyResetGlViewport() {
|
|
103
|
-
if (!this._isResetGlViewportAfterSetWidthOrHeight) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
let isNormalCanvas = true;
|
|
108
|
-
if (global.createCanvasElements) {
|
|
109
|
-
if (global.createCanvasElements.findIndex(canvas => canvas === this) > -1) {
|
|
110
|
-
isNormalCanvas = false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (isNormalCanvas) {
|
|
115
|
-
GCanvas.GBridge.callResetGlViewport(this.id);
|
|
116
|
-
} else {
|
|
117
|
-
// resetGlViewport to global.createCanvasElements which comes from
|
|
118
|
-
// document.createElement('canvas') (as offscreen canvas) when replace
|
|
119
|
-
// require('resize-image-data') in https://github.com/flyskywhy/PixelShapeRN/blob/master/src/utils/canvasUtils.js
|
|
120
|
-
// is invoked too frequently, and since such canvas style is {position: 'absolute'}
|
|
121
|
-
// so no need of resetGlViewport, so no GCanvas.GBridge.callResetGlViewport() here
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
getContext(type, attributes = {}) {
|
|
126
|
-
if (this._context) {
|
|
127
|
-
this._context._resetContextAttributes(attributes);
|
|
128
|
-
|
|
129
|
-
return this._context;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (type.match(/webgl/i)) {
|
|
133
|
-
this._context = new GContextWebGL(this);
|
|
134
|
-
this._context.drawingBufferWidth = this._clientWidth * PixelRatio.get() | 0;
|
|
135
|
-
this._context.drawingBufferHeight = this._clientHeight * PixelRatio.get() | 0;
|
|
136
|
-
this._context.componentId = this.id;
|
|
137
|
-
|
|
138
|
-
GCanvas.GBridge.callSetContextType(this.id, 1); // 0 for 2d; 1 for webgl
|
|
139
|
-
|
|
140
|
-
if (!this._disableAutoSwap) {
|
|
141
|
-
const render = () => {
|
|
142
|
-
if (this._needRender) {
|
|
143
|
-
this._context.flushJsCommands2CallNative();
|
|
144
|
-
this._needRender = false;
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
this.webglInterval = setInterval(render, 16);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// On Android, need `sleepMs()` by `for(;;)` to wait enough (or wait until m_requestInitialize be true?) to
|
|
152
|
-
// let `mProxy->SetClearColor` be invoked in renderLoop() of core/android/3d/view/grenderer.cpp
|
|
153
|
-
// at the very first, otherwise can't `gl.clearColor` right away on canvas.getContext('webgl')
|
|
154
|
-
// like https://github.com/flyskywhy/react-native-gcanvas/issues/24
|
|
155
|
-
sleepMs(100);
|
|
156
|
-
|
|
157
|
-
if (__DEV__) {
|
|
158
|
-
// TODO: need test again to see if can remove sleepMs(130).
|
|
159
|
-
// https://github.com/flyskywhy/snakeRN/tree/v3.0.0 sometimes (1st load js on new installed debug apk)
|
|
160
|
-
// will cause `Error: Invalid value of `0` passed to `checkMaxIfStatementsInShader` in
|
|
161
|
-
// `node_modules/pixi.js/lib/core/renderers/webgl/utils/checkMaxIfStatmentsInShader.js` ,
|
|
162
|
-
// `sleepMs()` by `for(;;)` wait enough can fix it, don't know why maybe also
|
|
163
|
-
// `setContextType can not find canvas with id` as described below.
|
|
164
|
-
sleepMs(130);
|
|
165
|
-
}
|
|
166
|
-
if (this._devicePixelRatio > 0) {
|
|
167
|
-
GCanvas.GBridge.callSetDevicePixelRatio(this.id, this._devicePixelRatio);
|
|
168
|
-
}
|
|
169
|
-
} else if (type.match(/2d/i)) {
|
|
170
|
-
this._context = new GContext2D(this);
|
|
171
|
-
this._context.componentId = this.id;
|
|
172
|
-
GCanvas.GBridge.callSetContextType(this.id, 0);
|
|
173
|
-
|
|
174
|
-
// TODO: need test again to see if can remove sleepMs(130).
|
|
175
|
-
// iOS need at least sleepMs(130), otherwise will crash with https://github.com/flyskywhy/PixelShapeRN
|
|
176
|
-
// modified to resizeImageData with canvas and GCanvas.GBridge.callResetGlViewport(this.id) despite isNormalCanvas
|
|
177
|
-
sleepMs(130);
|
|
178
|
-
|
|
179
|
-
if (this._devicePixelRatio > 0) {
|
|
180
|
-
GCanvas.GBridge.callSetDevicePixelRatio(this.id, this._devicePixelRatio);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
this._renderLoopId = requestAnimationFrame(this._renderLoop.bind(this));
|
|
184
|
-
} else {
|
|
185
|
-
throw new Error('not supported context ' + type);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return this._context;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
_renderLoop() {
|
|
192
|
-
if (this.disabled) {
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
this._context.flushJsCommands2CallNative();
|
|
196
|
-
this._renderLoopId = requestAnimationFrame(this._renderLoop.bind(this));
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// default 0.92 comes from https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toDataURL
|
|
200
|
-
toDataURL(type = 'image/png', encoderOptions = 0.92) {
|
|
201
|
-
let quality = encoderOptions < 0.0 ? 0.0 : encoderOptions;
|
|
202
|
-
quality = quality > 1.0 ? 1.0 : quality;
|
|
203
|
-
|
|
204
|
-
return GCanvas.GBridge.callToDataURL(this.id, type, quality);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
reset() {
|
|
208
|
-
GCanvas.GBridge.callReset(this.id);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
1
|
+
import Element from '@flyskywhy/react-native-browser-polyfill/src/DOM/Element';
|
|
2
|
+
import GContext2D from '../context/2d/RenderingContext';
|
|
3
|
+
import GContextWebGL from '../context/webgl/RenderingContext';
|
|
4
|
+
import {PixelRatio} from 'react-native';
|
|
5
|
+
|
|
6
|
+
function sleepMs(ms) {
|
|
7
|
+
for (var start = new Date(); new Date() - start <= ms; ) {}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default class GCanvas extends Element {
|
|
11
|
+
static GBridge = null;
|
|
12
|
+
|
|
13
|
+
id = null;
|
|
14
|
+
_renderLoopId = null;
|
|
15
|
+
_context = null;
|
|
16
|
+
_clientWidth = 100;
|
|
17
|
+
_clientHeight = 150;
|
|
18
|
+
_width = 100;
|
|
19
|
+
_height = 150;
|
|
20
|
+
|
|
21
|
+
_needRender = true;
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
id,
|
|
25
|
+
{
|
|
26
|
+
isAutoClearRectBeforePutImageData,
|
|
27
|
+
isResetGlViewportAfterSetWidthOrHeight,
|
|
28
|
+
devicePixelRatio,
|
|
29
|
+
disableAutoSwap,
|
|
30
|
+
style,
|
|
31
|
+
},
|
|
32
|
+
) {
|
|
33
|
+
super('canvas');
|
|
34
|
+
this.id = id;
|
|
35
|
+
this.disabled = false;
|
|
36
|
+
this.webglInterval = null;
|
|
37
|
+
|
|
38
|
+
this._isAutoClearRectBeforePutImageData = isAutoClearRectBeforePutImageData;
|
|
39
|
+
this._isResetGlViewportAfterSetWidthOrHeight = isResetGlViewportAfterSetWidthOrHeight;
|
|
40
|
+
this._devicePixelRatio = devicePixelRatio || PixelRatio.get();
|
|
41
|
+
this._disableAutoSwap = disableAutoSwap;
|
|
42
|
+
this._swapBuffers = () => {
|
|
43
|
+
this._context && this._context.flushJsCommands2CallNative();
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
this._clientWidth = style.width | 0; // width is fixed not float just like Web
|
|
47
|
+
this._clientHeight = style.height | 0;
|
|
48
|
+
this._width = style.width | 0; // width is fixed not float just like Web
|
|
49
|
+
this._height = style.height | 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get clientWidth() {
|
|
53
|
+
return this._clientWidth;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get clientHeight() {
|
|
57
|
+
return this._clientHeight;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
set clientWidth(value) {
|
|
61
|
+
this._clientWidth = value | 0; // width is fixed not float just like Web
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
set clientHeight(value) {
|
|
65
|
+
this._clientHeight = value | 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get width() {
|
|
69
|
+
return this._width;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
set width(value) {
|
|
73
|
+
if (this._context) {
|
|
74
|
+
if (this._context.className === 'CanvasRenderingContext2D') {
|
|
75
|
+
this._context.clearRect(0, 0, this._clientWidth, this._clientHeight);
|
|
76
|
+
} else {
|
|
77
|
+
this._context.drawingBufferWidth = this._clientWidth * PixelRatio.get() | 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this._conditionallyResetGlViewport();
|
|
81
|
+
}
|
|
82
|
+
this._width = value | 0; // width is fixed not float just like Web
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get height() {
|
|
86
|
+
return this._height;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
set height(value) {
|
|
90
|
+
if (this._context) {
|
|
91
|
+
if (this._context.className === 'CanvasRenderingContext2D') {
|
|
92
|
+
this._context.clearRect(0, 0, this._clientWidth, this._clientHeight);
|
|
93
|
+
} else {
|
|
94
|
+
this._context.drawingBufferHeight = this._clientHeight * PixelRatio.get() | 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this._conditionallyResetGlViewport();
|
|
98
|
+
}
|
|
99
|
+
this._height = value | 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
_conditionallyResetGlViewport() {
|
|
103
|
+
if (!this._isResetGlViewportAfterSetWidthOrHeight) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let isNormalCanvas = true;
|
|
108
|
+
if (global.createCanvasElements) {
|
|
109
|
+
if (global.createCanvasElements.findIndex(canvas => canvas === this) > -1) {
|
|
110
|
+
isNormalCanvas = false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (isNormalCanvas) {
|
|
115
|
+
GCanvas.GBridge.callResetGlViewport(this.id);
|
|
116
|
+
} else {
|
|
117
|
+
// resetGlViewport to global.createCanvasElements which comes from
|
|
118
|
+
// document.createElement('canvas') (as offscreen canvas) when replace
|
|
119
|
+
// require('resize-image-data') in https://github.com/flyskywhy/PixelShapeRN/blob/master/src/utils/canvasUtils.js
|
|
120
|
+
// is invoked too frequently, and since such canvas style is {position: 'absolute'}
|
|
121
|
+
// so no need of resetGlViewport, so no GCanvas.GBridge.callResetGlViewport() here
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getContext(type, attributes = {}) {
|
|
126
|
+
if (this._context) {
|
|
127
|
+
this._context._resetContextAttributes(attributes);
|
|
128
|
+
|
|
129
|
+
return this._context;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (type.match(/webgl/i)) {
|
|
133
|
+
this._context = new GContextWebGL(this);
|
|
134
|
+
this._context.drawingBufferWidth = this._clientWidth * PixelRatio.get() | 0;
|
|
135
|
+
this._context.drawingBufferHeight = this._clientHeight * PixelRatio.get() | 0;
|
|
136
|
+
this._context.componentId = this.id;
|
|
137
|
+
|
|
138
|
+
GCanvas.GBridge.callSetContextType(this.id, 1); // 0 for 2d; 1 for webgl
|
|
139
|
+
|
|
140
|
+
if (!this._disableAutoSwap) {
|
|
141
|
+
const render = () => {
|
|
142
|
+
if (this._needRender) {
|
|
143
|
+
this._context.flushJsCommands2CallNative();
|
|
144
|
+
this._needRender = false;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
this.webglInterval = setInterval(render, 16);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// On Android, need `sleepMs()` by `for(;;)` to wait enough (or wait until m_requestInitialize be true?) to
|
|
152
|
+
// let `mProxy->SetClearColor` be invoked in renderLoop() of core/android/3d/view/grenderer.cpp
|
|
153
|
+
// at the very first, otherwise can't `gl.clearColor` right away on canvas.getContext('webgl')
|
|
154
|
+
// like https://github.com/flyskywhy/react-native-gcanvas/issues/24
|
|
155
|
+
sleepMs(100);
|
|
156
|
+
|
|
157
|
+
if (__DEV__) {
|
|
158
|
+
// TODO: need test again to see if can remove sleepMs(130).
|
|
159
|
+
// https://github.com/flyskywhy/snakeRN/tree/v3.0.0 sometimes (1st load js on new installed debug apk)
|
|
160
|
+
// will cause `Error: Invalid value of `0` passed to `checkMaxIfStatementsInShader` in
|
|
161
|
+
// `node_modules/pixi.js/lib/core/renderers/webgl/utils/checkMaxIfStatmentsInShader.js` ,
|
|
162
|
+
// `sleepMs()` by `for(;;)` wait enough can fix it, don't know why maybe also
|
|
163
|
+
// `setContextType can not find canvas with id` as described below.
|
|
164
|
+
sleepMs(130);
|
|
165
|
+
}
|
|
166
|
+
if (this._devicePixelRatio > 0) {
|
|
167
|
+
GCanvas.GBridge.callSetDevicePixelRatio(this.id, this._devicePixelRatio);
|
|
168
|
+
}
|
|
169
|
+
} else if (type.match(/2d/i)) {
|
|
170
|
+
this._context = new GContext2D(this);
|
|
171
|
+
this._context.componentId = this.id;
|
|
172
|
+
GCanvas.GBridge.callSetContextType(this.id, 0);
|
|
173
|
+
|
|
174
|
+
// TODO: need test again to see if can remove sleepMs(130).
|
|
175
|
+
// iOS need at least sleepMs(130), otherwise will crash with https://github.com/flyskywhy/PixelShapeRN
|
|
176
|
+
// modified to resizeImageData with canvas and GCanvas.GBridge.callResetGlViewport(this.id) despite isNormalCanvas
|
|
177
|
+
sleepMs(130);
|
|
178
|
+
|
|
179
|
+
if (this._devicePixelRatio > 0) {
|
|
180
|
+
GCanvas.GBridge.callSetDevicePixelRatio(this.id, this._devicePixelRatio);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this._renderLoopId = requestAnimationFrame(this._renderLoop.bind(this));
|
|
184
|
+
} else {
|
|
185
|
+
throw new Error('not supported context ' + type);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return this._context;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
_renderLoop() {
|
|
192
|
+
if (this.disabled) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
this._context.flushJsCommands2CallNative();
|
|
196
|
+
this._renderLoopId = requestAnimationFrame(this._renderLoop.bind(this));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// default 0.92 comes from https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toDataURL
|
|
200
|
+
toDataURL(type = 'image/png', encoderOptions = 0.92) {
|
|
201
|
+
let quality = encoderOptions < 0.0 ? 0.0 : encoderOptions;
|
|
202
|
+
quality = quality > 1.0 ? 1.0 : quality;
|
|
203
|
+
|
|
204
|
+
return GCanvas.GBridge.callToDataURL(this.id, type, quality);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
reset() {
|
|
208
|
+
GCanvas.GBridge.callReset(this.id);
|
|
209
|
+
}
|
|
210
|
+
}
|