Javascript 调整画布图像大小,如';背景尺寸:封面';反应灵敏 我想做什么 设置背景大小:画布图像上的封面效果 调整窗口大小时重新绘制画布图像(响应) 我试过的
我试过下面两种方法。两者都不起作用 问题Javascript 调整画布图像大小,如';背景尺寸:封面';反应灵敏 我想做什么 设置背景大小:画布图像上的封面效果 调整窗口大小时重新绘制画布图像(响应) 我试过的,javascript,image,canvas,Javascript,Image,Canvas,我试过下面两种方法。两者都不起作用 问题 图像的纵横比不是固定的 我不确定,但在调整窗口大小时,图像似乎不会被重新渲染 我的代码 函数绘图(){ //得到 const canvas=document.querySelector(“#canvas”); //帆布 const ctx=canvas.getContext('2d'); const cw=画布宽度; const ch=画布高度; //形象 const img=新图像(); img.src=https://source.unsp
- 图像的纵横比不是固定的
- 我不确定,但在调整窗口大小时,图像似乎不会被重新渲染
函数绘图(){
//得到
const canvas=document.querySelector(“#canvas”);
//帆布
const ctx=canvas.getContext('2d');
const cw=画布宽度;
const ch=画布高度;
//形象
const img=新图像();
img.src=https://source.unsplash.com/WLUHO9A_xik/1600x900';
img.onload=函数(){
常数iw=img.宽度;
常数ih=img.高度;
//“背景尺寸:封面”效果
常量aspectHeight=ih*(cw/iw);
常量高度偏移=((aspectHeight-ch)/2)*-1;
ctx.drawImage(img,0,高度偏移,cw,aspectHeight);
};
}
window.addEventListener(“加载”,绘制);
window.addEventListener(“调整大小”,绘制)代码>
画布{
显示:块;
/*画布宽度取决于父窗口/窗口宽度*/
宽度:90%;
高度:300px;
保证金:0自动;
边框:1px实心#ddd;
}
画布属性不反映与CSS大小相关的实际大小。给定您的代码,cw/ch
固定在300/150
。因此,整个计算都是基于错误的值
您需要使用实际反映其可见大小的值。喜欢
一个非常简单的解决方案是在将画布宽度/高度属性用于任何计算之前更新它们。例如:
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
完整示例:
const canvas=document.querySelector('#canvas');
const ctx=canvas.getContext('2d');
//仅加载图像一次
const img=新承诺(r=>{
const img=新图像();
img.src=https://source.unsplash.com/WLUHO9A_xik/1600x900';
img.onload=()=>r(img);
});
const draw=async()=>{
//调整画布大小以匹配其可见大小
canvas.width=canvas.clientWidth;
canvas.height=canvas.clientHeight;
常量加载=等待img;
常数iw=加载的宽度;
常数ih=加载高度;
const cw=画布宽度;
const ch=画布高度;
常数f=数学最大值(cw/iw,ch/ih);
ctx.setTransform(
/*比例x*/f,
/*倾斜x*/0,
/*歪斜y*/0,
/*刻度y*/f,
/*翻译x*/(cw-f*iw)/2,
/*翻译y*/(ch-f*ih)/2,
);
ctx.drawImage(已加载,0,0);
};
window.addEventListener(“加载”,绘制);
window.addEventListener(“调整大小”,绘制)代码>
——维度{
宽度:90%;
高度:300px;
}
.——边界{
边框:3px实心#333;
}
帆布{
显示:块;
保证金:0自动;
}
#试验{
背景:url(https://source.unsplash.com/WLUHO9A_xik/1600x900)无重复中心;
背景尺寸:封面;
保证金:1rem自动0;
}
首先,仅加载一次图像,当前每次调整页面大小时都要重新加载图像
然后,您的变量cw
和ch
将始终是300
和150
,因为您没有设置画布的大小。记住,它的布局一(由CSS控制)和缓冲区一(由其.width
和.height
属性控制)。
您可以通过元素的.offsetWidth
和.offsetHeight
属性检索布局值
最后,您的代码不包含图像大小调整。要做封面,你可以参考你链接的答案,尤其是
{
//得到
const canvas=document.querySelector(“#canvas”);
//帆布
const ctx=canvas.getContext('2d');
//形象
const img=新图像();
img.src=https://source.unsplash.com/WLUHO9A_xik/1600x900';
函数绘图(){
//获取CSS计算的正确维度
//并将画布的缓冲区设置为此维度
const cw=canvas.width=canvas.offsetWidth;
const ch=canvas.height=canvas.offsetHeight;
如果(!inp.checked){
drawImageProp(ctx、img、0、0、cw、ch、0、0);
}
}
img.onload=()=>{
window.addEventListener(“调整大小”,绘制);
draw();
};
inp.oninput=绘图;
}
//肯·菲尔斯滕伯格https://stackoverflow.com/a/21961894/3702797
函数drawImageProp(ctx、img、x、y、w、h、offsetX、offsetY){
if(arguments.length==2){
x=y=0;
w=ctx.canvas.width;
h=ctx.canvas.height;
}
//默认偏移量为“中心”
offsetX=offsetX的类型==“编号”?offsetX:0.5;
offsetY=typeof offsetY==“number”?offsetY:0.5;
//保持界限[0.0,1.0]
如果(offsetX<0)offsetX=0;
如果(偏移量<0)偏移量=0;
如果(offsetX>1)offsetX=1;
如果(offsetY>1)offsetY=1;
var iw=img.width,
ih=img.高度,
r=数学最小值(w/iw,h/ih),
nw=iw*r,//新道具宽度
nh=ih*r,//新道具高度
cx,cy,cw,ch,ar=1;
//决定填补哪个空白
如果(nwiw)cw=iw;
如果(ch>ih)ch=ih;
//在目标矩形中填充图像
ctx.drawImage(img、cx、cy、cw、ch、x、y、w、h);
}
画布{
显示:块;
/*画布宽度取决于父窗口/窗口宽度*/
宽度:90%;
高度:300px;
保证金:0自动;
边框:1px实心#ddd;
背景图像:url('https://source.unsplash.com/WLUHO9A_xik/1600x900');
B