我写了一些代码来放大我的图像,但是当我从头开始滚动时,这张图片会跳跃一点。如何解决问题?
HTML
<canvas id="canvas"></canvas>
JS
function draw(scroll) {
scroll = (window.scrollY || window.pageYOffset) / (document.body.clientHeight - window.innerHeight) * 3000;
canvas.setAttribute('width', window.innerWidth);
canvas.setAttribute('height', window.innerHeight);
//The main formula that draws and zooms the picture
drawImageProp(ctx, forest, 0, (-scroll * 3.9) / 4, canvas.width, canvas.height + (scroll * 3.9) / 2);
}
答案 0 :(得分:1)
不是错误修复
我查看了Codepen示例,它确实跳到了顶部(有时候)。我有一个修复程序,但我没有时间找到代码问题的来源。我注意到跳转涉及一个方面改变,所以它必须在你的错误的缩放中。 (注意消极)
GPU是更好的裁剪器
此外,您的代码实际上正在执行不必要的工作,因为您正在计算图像剪裁区域。 Canvas上下文为您剪裁,尤其擅长剪裁图像。即使您提供剪辑区域,图像仍将通过剪辑,因为它是渲染管道的一部分。唯一一次你应该关注图像的剪切显示是图像的任何部分是否可见,这样你就不会发送绘图调用,只有你推动图像渲染才真正重要count(即游戏精灵计数500 +)
代码示例
无论如何我离题了。以下是我的代码。您可以添加检查和余额。 (论证审查,缩放最大分数等)。
致电功能。
// get a normalised scale 0-1 from the scroll postion
var scale = (window.scrollY || window.pageYOffset) / (document.body.clientHeight - window.innerHeight);
// call the draw function
// scale 0-1 where 0 is min scale and 1 is max scale (min max determined in function
// X and y offset are clamped but are ranged
// 0 - image.width and 0 - image.height
// where 0,0 shows top left and width,height show bottom right
drawImage(ctx, forest, scale, xOffset, yOffset);
功能。
评论应涵盖您需要了解的内容。您会注意到我所关心的是图像应该有多大以及左上角的位置。 GPU将为您进行剪辑,并且不会花费您的处理时间(即使对于未加速的显示器)。我个人喜欢使用标准化值0-1,这是一个额外的工作,但我的大脑喜欢简单,它也减少了对幻数的需要(魔法数字是代码不适应的标志)。功能适用于任何尺寸的显示和任何尺寸的图像。哦,我喜欢分而不是乘,(一个良好的数学习惯带来的错误的编码习惯)用/ 2
替换* 0.5
和所需的括号将使它更具可读性。
function drawImage(ctx, img, scale, x, y){
const MAX_SCALE = 4;
const MIN_SCALE = 1;
var w = canvas.width; // set vars just for source clarity
var h = canvas.height;
var iw = img.width;
var ih = img.height;
var fit = Math.max(w / iw, h / ih); // get the scale to fill the avalible display area
// Scale is a normalised value from 0-1 as input arg Convert to range
scale = (MAX_SCALE - MIN_SCALE) * scale + MIN_SCALE;
var idw = iw * fit * scale; // get image total display size;
var idh = ih * fit * scale;
x /= iw; // normalise offsets
y /= ih; //
x = - (idw - w) * x; // transform offsets to display coords
y = - (idh - h) * y;
x = Math.min( 0, Math.max( - (idw - w), x) ); // clamp image to display area
y = Math.min( 0, Math.max( - (idh - h), y) );
// use set transform to scale and translate
ctx.setTransform(scale, 0, 0, scale, idw / 2 + x, idh / 2 + y);
// display the image to fit;
ctx.drawImage(img, ( - iw / 2 ) * fit, (- ih / 2 ) * fit);
// restore transform.
ctx.setTransform(1, 0, 0, 1, 0, 0)
}
抱歉,我没有直接解决问题,但希望这可以帮助您重新设计您的approch。
我最近添加了一个类似的答案,包括使用你可能感兴趣的鼠标进行缩放和平移(和旋转)How to pan the canvas?它仍然有点凌乱&#34;自我注意(我清理它)& #34;没有限制。但是展示了如何设置缩放原点,以及如何将屏幕空间转换为世界空间。 (找到屏幕像素在平移/缩放/旋转显示屏上的位置)。
祝你的项目好运。