用鼠标控制点位
<canvas id="canvas">canvas>
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 a_Position;
void main() {
gl_Position = a_Position;
gl_PointSize = 50.0;
}
script>
<script id="fragmentShader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1,1,0,1);
}
script>
<script type="module">
import { initShaders } from "./utils.js";
const canvas = document.querySelector("#canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const vsSource = document.querySelector("#vertexShader").innerText;
const fsSource = document.querySelector("#fragmentShader").innerText;
const gl = canvas.getContext("webgl");
initShaders(gl, vsSource, fsSource);
const a_Position = gl.getAttribLocation(gl.program, "a_Position");
gl.vertexAttrib1f(a_Position, 0.1);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, 1);
canvas.addEventListener("click", ({ clientX, clientY }) => {
const { left, top, width, height } = canvas.getBoundingClientRect();
const [cssX, cssY] = [clientX - left, clientY - top];
const [halfWidth, halfHeight] = [width / 2, height / 2];
const [xBaseCenter, yBaseCenter] = [
cssX - halfWidth,
cssY - halfHeight,
];
const yBaseCenterTop = -yBaseCenter;
const [x, y] = [xBaseCenter / halfWidth, yBaseCenterTop / halfHeight];
gl.vertexAttrib2f(a_Position, x, y);
gl.drawArrays(gl.POINTS, 0, 1);
});
script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
utils.js
export function initShaders(gl, vsSource, fsSource) {
const program = gl.createProgram();
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
gl.program = program;
return true;
}
function loadShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 这里核心点主要在: canvas坐标系和webgl坐标系之间的差异,由此计算出鼠标在webgl坐标系中的位置,并且控制点的位置
两者坐标系的核心算法
const { left, top, width, height } = canvas.getBoundingClientRect();
const [cssX, cssY] = [clientX - left, clientY - top];
const [halfWidth, halfHeight] = [width / 2, height / 2];
const [xBaseCenter, yBaseCenter] = [
cssX - halfWidth,
cssY - halfHeight
];
const yBaseCenterTop = -yBaseCenter;
const [x, y] = [xBaseCenter / halfWidth, yBaseCenterTop / halfHeight];