假设你是一个前端程序员,现在你想创建一个HTML文件,这个文件能够选择本地的png文件加载到canvas,这个canvas固定大小,第二步,需要设置这个canvas能够在鼠标所在的位置利用鼠标的滚轮进行缩放这个图片,第三步需要结合WebGL技术保证缩放时候的图像能够像矢量图一样的清晰,能给出一个完整的样例吗
时间: 2023-06-16 16:08:22 浏览: 81
前端开发-canvas-图片缩放
当然可以,以下是一个简单的HTML文件示例,可以选择本地PNG文件并在Canvas中显示。鼠标滚动时,图像会缩放,同时使用WebGL技术以保持清晰度。
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Canvas Image Viewer</title>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<input type="file" id="file-input">
<br>
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
initWebGL(canvas);
};
document.getElementById('file-input').addEventListener('change', function() {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function() {
img.src = reader.result;
};
reader.readAsDataURL(file);
});
var scale = 1;
canvas.addEventListener('wheel', function(e) {
var delta = Math.sign(e.deltaY);
scale += delta * 0.1;
scale = Math.max(scale, 0.1);
scale = Math.min(scale, 10);
drawImage();
});
function drawImage() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.scale(scale, scale);
ctx.translate(-canvas.width / 2, -canvas.height / 2);
ctx.drawImage(img, 0, 0);
ctx.restore();
}
function initWebGL(canvas) {
var gl = canvas.getContext('webgl');
gl.viewport(0, 0, canvas.width, canvas.height);
var vertexShaderSource = `
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main() {
gl_Position = a_position;
v_texcoord = a_texcoord;
}
`;
var fragmentShaderSource = `
precision highp float;
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main() {
gl_FragColor = texture2D(u_texture, v_texcoord);
}
`;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
var positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
var texcoordAttributeLocation = gl.getAttribLocation(program, 'a_texcoord');
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1.0, -1.0,
1.0, -1.0,
-1.0, 1.0,
1.0, 1.0,
]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
var texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(texcoordAttributeLocation);
gl.vertexAttribPointer(texcoordAttributeLocation, 2, gl.FLOAT, false, 0, 0);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
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);
function render() {
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
</script>
</body>
</html>
```
这个代码中,我们首先创建一个canvas元素并添加一个文件输入元素来允许用户选择他们的PNG文件。当用户选择文件时,我们使用FileReader API读取文件并将其加载到Image对象中。一旦图像加载完成,我们设置canvas的大小并使用CanvasRenderingContext2D将图像绘制到画布上,然后初始化WebGL以渲染图像。
当用户使用滚轮滚动时,我们更新缩放比例并重新绘制图像。通过使用WebGL,我们可以保持图像的清晰度,即使在缩放时也是如此。我们创建了一个简单的着色器程序来显示纹理,并使用gl.drawArrays绘制一个矩形,该矩形覆盖整个画布。我们使用requestAnimationFrame循环以持续渲染画布。
阅读全文