Skip to content

Commit

Permalink
Merge pull request #58 from lebornjose/story/animation
Browse files Browse the repository at this point in the history
feat: 抖动
  • Loading branch information
lebornjose authored Dec 15, 2024
2 parents 0c176ab + 7116f43 commit 216c23a
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 16 deletions.
3 changes: 0 additions & 3 deletions src/view/videoEffect/matrix.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,8 @@ onMounted(() => {
let matrix = new TransformationMatrix()
matrix.scale(0.5, 0.5); // 缩放0.5
matrix.translate(0.5, 0); // 向右平移
matrix.rotate(15); // 旋转15
// matrix1.multiply(matrix2);
gl.uniformMatrix3fv(u_MvpMatrix, false, matrix.elements);
Expand Down
26 changes: 13 additions & 13 deletions src/view/videoEffect/transition.vue
Original file line number Diff line number Diff line change
Expand Up @@ -149,26 +149,26 @@ onMounted(() => {
gl.bufferData(gl.ARRAY_BUFFER, source, gl.STATIC_DRAW);
const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
// 方法绑定当前缓冲区范围到gl.ARRAY_BUFFER,成为当前顶点缓冲区对象的通用顶点属性并指定它的布局
// 方法绑定当前缓冲区范围到gl.ARRAY_BUFFER,成为当前顶点缓冲区对象的通用顶点属性并指定它的布局
gl.vertexAttribPointer(
a_Position,
2,
gl.FLOAT,
false,
0,
0
a_Position,
2,
gl.FLOAT,
false,
0,
0
);
// 无论怎样,都需要你使用enableVertexAttribArray()方法,来激活每一个属性以便使用,不被激活的属性是不会被使用的。一旦激活,以下其他方法就可以获取到属性的值了
gl.enableVertexAttribArray(a_Position);
const texCoordLocation = gl.getAttribLocation(gl.program, 'a_texCoord');
gl.vertexAttribPointer(
texCoordLocation,
2,
gl.FLOAT,
false,
0,
0
texCoordLocation,
2,
gl.FLOAT,
false,
0,
0
);
gl.enableVertexAttribArray(texCoordLocation);
Expand Down
161 changes: 161 additions & 0 deletions src/view/videoEffect/video_animation.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,164 @@
<template>
<<<<<<< HEAD
<div class="container">
<h2>视频动画</h2>
<canvas id="webgl"></canvas>
<p>时间: {{ currentTime }}</p>
<div class="flex">
<button @click="play">播放</button>
<button @click="pause">暂停</button>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { initShaders } from '../../utils/utils';
let gl: any = null
let video: any = null
const vertexShaderSource = `
attribute vec2 a_Position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main(){
vec3 position = vec3(vec2(2.0,2.0)*a_Position-vec2(1.0, 1.0), 1.0);
gl_Position = vec4(position.xy, 0.0, 1.0);
v_texCoord = a_texCoord;
}
`;
//片段着色器
// vec2 jitter = vec2(sin(u_time + v_texCoord.x * 100.0), cos(uTime + v_texCoord.y * 100.0)) * 0.01;
let fragmentShaderSource = `
precision mediump float;
varying vec2 v_position;
uniform sampler2D u_Sampler;
uniform float u_time;
varying vec2 v_texCoord;
void main() {
vec2 jitter = vec2(sin(u_time + v_texCoord.x * 100.0), cos(u_time + v_texCoord.y * 100.0)) * 0.01;
vec4 color = texture2D(u_Sampler, v_texCoord + jitter);
gl_FragColor = color;
}
`;
const currentTime = ref(0)
const state = ref(0) // 0 暂停, 1 播放状态
const play = () => {
state.value = 1
let startTime = performance.now();
video.play();
const start = () => {
requestAnimationFrame(() => {
if(state.value) {
let time = performance.now()
currentTime.value = (time - startTime) / 1000
if(currentTime.value > 6) {
video.pause()
}
start()
}
})
}
start()
}
const pause = () => {
state.value = 0
video.pause();
}
onMounted(() => {
const canvas: any = document.getElementById('webgl');
canvas.width = 360;
canvas.height = 640;
gl = canvas.getContext('webgl');
initShaders(gl, vertexShaderSource, fragmentShaderSource);
// 给画布填充色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
const source = new Float32Array([1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]);
const sourceBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, sourceBuffer);
gl.bufferData(gl.ARRAY_BUFFER, source, gl.STATIC_DRAW);
const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
// 方法绑定当前缓冲区范围到gl.ARRAY_BUFFER,成为当前顶点缓冲区对象的通用顶点属性并指定它的布局
gl.vertexAttribPointer(
a_Position,
2,
gl.FLOAT,
false,
0,
0
);
// 无论怎样,都需要你使用enableVertexAttribArray()方法,来激活每一个属性以便使用,不被激活的属性是不会被使用的。一旦激活,以下其他方法就可以获取到属性的值了
gl.enableVertexAttribArray(a_Position);
const texCoordLocation = gl.getAttribLocation(gl.program, 'a_texCoord');
gl.vertexAttribPointer(
texCoordLocation,
2,
gl.FLOAT,
false,
0,
0
);
gl.enableVertexAttribArray(texCoordLocation);
/* 图像预处理 */
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
/* 准备三个角色 */
gl.activeTexture(gl.TEXTURE0);
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
/* 获取uniform变量 */
const u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');
gl.uniform1i(u_Sampler, 0);
const uTimeLocation = gl.getUniformLocation(gl.program, 'u_time');
gl.uniform1f(uTimeLocation, performance.now() * 0.001);
// 建立video对象 *
video = document.createElement('video')
video.src = '/video/output.mp4';
video.autoplay = false;
video.loop = false;
video.setAttribute("crossOrigin", 'Anonymous');
const render = () => {
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGB,
gl.RGB,
gl.UNSIGNED_BYTE,
video
)
const currentTime = performance.now() * 0.001; // 转换为秒
const uTime = gl.getUniformLocation(gl.program, 'u_time');
gl.uniform1f(uTime, currentTime);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
if (!video.paused) {
requestAnimationFrame(render);
}
}
video.addEventListener('loadeddata', function (e) {
video.currentTime = 0;
setTimeout(() => {
console.log('end');
render();
}, 50);
})
video.addEventListener('playing', () => {
render();
})
})
</script>
=======
<div class="container">
<h2>视频动画</h2>
<canvas id="webgl"></canvas>
Expand All @@ -18,3 +178,4 @@ const pause = () => {

}
</script>
>>>>>>> main

0 comments on commit 216c23a

Please sign in to comment.