225 lines
5.6 KiB
JavaScript
225 lines
5.6 KiB
JavaScript
const vs = `
|
|
attribute vec3 aPos;
|
|
attribute vec2 aVertexTextureCoord;
|
|
varying highp vec2 vTextureCoord;
|
|
|
|
void main(void){
|
|
gl_Position = vec4(aPos, 1);
|
|
vTextureCoord = aVertexTextureCoord;
|
|
}
|
|
`;
|
|
|
|
const fs = `
|
|
varying highp vec2 vTextureCoord;
|
|
uniform sampler2D uSampler;
|
|
|
|
void main(void) {
|
|
gl_FragColor = texture2D(uSampler, vTextureCoord);
|
|
}
|
|
`;
|
|
|
|
const vertex = [
|
|
-1, -1, 0.0,
|
|
1, -1, 0.0,
|
|
1, 1, 0.0,
|
|
-1, 1, 0.0,
|
|
];
|
|
|
|
const vertexIndice = [
|
|
0, 1, 2,
|
|
0, 2, 3,
|
|
];
|
|
|
|
const texCoords = [
|
|
0.0, 0.0,
|
|
1.0, 0.0,
|
|
1.0, 1.0,
|
|
0.0, 1.0,
|
|
];
|
|
function createShader(gl, src, type) {
|
|
const shader = gl.createShader(type);
|
|
gl.shaderSource(shader, src);
|
|
gl.compileShader(shader);
|
|
|
|
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
console.error(`Error compiling shader: ${gl.getShaderInfoLog(shader)}`);
|
|
}
|
|
return shader;
|
|
}
|
|
|
|
const buffers = {};
|
|
|
|
function createRenderer(canvas, width, height) {
|
|
const gl = canvas.getContext('webgl');
|
|
if (!gl) {
|
|
console.error('Unable to get webgl context.');
|
|
return;
|
|
}
|
|
|
|
const info = xhs.getSystemInfoSync();
|
|
gl.canvas.width = info.pixelRatio * width;
|
|
gl.canvas.height = info.pixelRatio * height;
|
|
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
|
|
|
const vertexShader = createShader(gl, vs, gl.VERTEX_SHADER);
|
|
const fragmentShader = createShader(gl, fs, gl.FRAGMENT_SHADER);
|
|
|
|
const program = gl.createProgram();
|
|
gl.attachShader(program, vertexShader);
|
|
gl.attachShader(program, fragmentShader);
|
|
gl.linkProgram(program);
|
|
|
|
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
console.error('Unable to initialize the shader program.');
|
|
return;
|
|
}
|
|
|
|
gl.useProgram(program);
|
|
|
|
const texture = gl.createTexture();
|
|
gl.activeTexture(gl.TEXTURE0);
|
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
|
|
buffers.vertexBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.vertexBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertex), gl.STATIC_DRAW);
|
|
|
|
buffers.vertexIndiceBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.vertexIndiceBuffer);
|
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexIndice), gl.STATIC_DRAW);
|
|
|
|
const aVertexPosition = gl.getAttribLocation(program, 'aPos');
|
|
gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0, 0);
|
|
gl.enableVertexAttribArray(aVertexPosition);
|
|
|
|
buffers.trianglesTexCoordBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.trianglesTexCoordBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW);
|
|
|
|
const vertexTexCoordAttribute = gl.getAttribLocation(program, 'aVertexTextureCoord');
|
|
gl.enableVertexAttribArray(vertexTexCoordAttribute);
|
|
gl.vertexAttribPointer(vertexTexCoordAttribute, 2, gl.FLOAT, false, 0, 0);
|
|
|
|
const samplerUniform = gl.getUniformLocation(program, 'uSampler');
|
|
gl.uniform1i(samplerUniform, 0);
|
|
|
|
return (arrayBuffer, width, height) => {
|
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBuffer);
|
|
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
|
|
};
|
|
}
|
|
|
|
Page({
|
|
onShareAppMessage() {
|
|
return {
|
|
title: 'camera',
|
|
path: 'page/component/pages/camera/camera',
|
|
};
|
|
},
|
|
|
|
data: {
|
|
src: '',
|
|
videoSrc: '',
|
|
position: 'back',
|
|
mode: 'scanCode',
|
|
result: {},
|
|
frameWidth: 0,
|
|
frameHeight: 0,
|
|
width: 288,
|
|
height: 358,
|
|
showCanvas: false,
|
|
},
|
|
|
|
onReady() {
|
|
this.ctx = xhs.createCameraContext();
|
|
// const selector = xhs.createSelectorQuery();
|
|
// selector.select('#webgl')
|
|
// .node(this.init)
|
|
// .exec()
|
|
},
|
|
init(res) {
|
|
if (this.listener) {
|
|
this.listener.stop();
|
|
}
|
|
const canvas = res.node;
|
|
const render = createRenderer(canvas, this.data.width, this.data.height);
|
|
|
|
// if (!render || typeof render !== 'function') return
|
|
|
|
this.listener = this.ctx.onCameraFrame(frame => {
|
|
render(new Uint8Array(frame.data), frame.width, frame.height);
|
|
|
|
const {
|
|
frameWidth,
|
|
frameHeight,
|
|
} = this.data;
|
|
|
|
if (frameWidth === frame.width && frameHeight == frame.height) return;
|
|
this.setData({
|
|
frameWidth: frame.width,
|
|
frameHeight: frame.height,
|
|
|
|
});
|
|
});
|
|
this.listener.start();
|
|
},
|
|
takePhoto() {
|
|
this.ctx.takePhoto({
|
|
quality: 'high',
|
|
success: res => {
|
|
this.setData({
|
|
src: res.tempImagePath,
|
|
});
|
|
},
|
|
});
|
|
},
|
|
startRecord() {
|
|
this.ctx.startRecord({
|
|
success: () => {
|
|
console.log('startRecord');
|
|
},
|
|
});
|
|
},
|
|
stopRecord() {
|
|
this.ctx.stopRecord({
|
|
success: res => {
|
|
this.setData({
|
|
src: res.tempThumbPath,
|
|
videoSrc: res.tempVideoPath,
|
|
});
|
|
},
|
|
});
|
|
},
|
|
togglePosition() {
|
|
this.setData({
|
|
position: this.data.position === 'front'
|
|
? 'back' : 'front',
|
|
});
|
|
},
|
|
error(e) {
|
|
console.log(e.detail);
|
|
},
|
|
|
|
handleShowCanvas() {
|
|
const that = this;
|
|
|
|
this.setData({
|
|
showCanvas: !this.data.showCanvas,
|
|
}, () => {
|
|
if (this.data.showCanvas) {
|
|
const selector = xhs.createSelectorQuery();
|
|
selector.select('#webgl')
|
|
.node(this.init)
|
|
.exec();
|
|
}
|
|
});
|
|
},
|
|
});
|