解决 canvas隐藏后出现滚动条的问题

现在的 canvas 不能像 h5的 canvas 一样把 画布大小 和 显示大小分别设置,且 canvas 不能 `display:none`。

分享下我的处理方法:

把 canvas 包裹在一个 view 中, 然后把这个 view 高度变成 0,`overflow: hidden` 掉, 也可以把它定位出去。总之就是利用类似的方法把 canvas 隐藏。然后在绘制 canvas 结束后把 canvas 导出到 tempfile,用 img src 去加载。这样可以设置一个较大的画布,但展示成想要的尺寸。 缺点是不能实时渲染展示,导出操作比较消耗性能。 另外还有一个坑: context.draw 的 callback 虽然执行了,但在 android 下不能直接导出 tempfile, 可以 setTimeout 下再导出。直接导出将会导致画布的内容不稳定出错。 另外注意画布的内容大小,和内存占用。

适配全尺寸公司Logo的处理

微信小程序的image组件中,有一个mode属性,其设置如下:

mode 有 13 种模式,其中 4 种是缩放模式,9 种是裁剪模式。

模式说明
缩放scaleToFill.不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
缩放aspectFit保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
缩放aspectFill保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
缩放widthFix宽度不变,高度自动变化,保持原图宽高比不变
裁剪top不缩放图片,只显示图片的顶部区域
裁剪bottom不缩放图片,只显示图片的底部区域
裁剪center不缩放图片,只显示图片的中间区域
裁剪left不缩放图片,只显示图片的左边区域
裁剪right不缩放图片,只显示图片的右边区域
裁剪top left不缩放图片,只显示图片的左上边区域
裁剪top right不缩放图片,只显示图片的右上边区域
裁剪bottom left不缩放图片,只显示图片的左下边区域
裁剪bottom right不缩放图片,只显示图片的右下边区域

原图


scaleToFill

不保持纵横比缩放图片,使图片完全适应


aspectFit

保持纵横比缩放图片,使图片的长边能完全显示出来(图片可完整显示,背景区域有留空)


aspectFill

保持纵横比缩放图片,只保证图片的短边能完全显示出来(图片被剪裁,丢失部分内容)

为什么要仿造一个微信小程序的aspectFitImg算法?

在微信小程序页面开发时,以绘制公司logo为例,

我希望得到的显示效果如下:

(Logo和公司名称在视觉上完美左对齐)

对于公司Logo这样的图案,是必须完整显示并保持比例的,任何对内容的剪裁或比例失调都是无法令人接受的。

为实现这个效果,我们通常的做法是:直接指定图片元素的显示模式为aspectFit模式,然后将公司Logo和公司名称左对齐。

但是这样会产生排版上的瑕疵,例如:

假设图片的缺省占位宽高为:100px * 40px;
但是从网络加载的图片实际只有40px * 40px

那么实际图片的水平中心点将在占位宽度(100px)的水平正中间对齐显示,看起来就好像实际图片左边被留出了30px的宽度,即:(100-40)/2,而这种情况不是我们想要的,因为我们想要的是从视觉上看,图片和底下的元素应该可以左对齐,而不是仅从CSS的视角来看两个元素是左对齐的;

此时,肉眼看见的效果如下:

logo图片占位和公司名称在CSS的层面左对齐,但是从视觉上来看,logo和公司名称并没有左对齐;


在微信小程序中,我解决这个问题的方法是:

(1)首先,在CSS中使用默认的占位宽高来设定图片的显示属性,打比方:{100px,40px},并设置数据绑定属性;
(2)从网络下载图片,然后根据{100,40}这个初始限定来计算将实际图片(可能是400px * 400px)缩放到刚好能塞进这个占位框中时图片应该被显示的尺寸,即(40px * 40px);
(3)使用微信小程序中css属性绑定的机制来修改占位框的宽度和高度;即将{100px * 40px}动态修改为 {40px * 40px};


在微信小程序中设置css属性绑定、下载图片并获取图片的宽高信息等都有现成的方法和完善的API说明文档,不再言表,仅列出那个aspectFitImg的方法。

/**
 * imgSourceWidth,imgSourceHeight : 图片的原始高度;
 * fitWidth,fitHeight: 图片保持比例缩放后,要能够塞进这个大小范围内;
 * 返回对象为适配处理后的图片尺寸,该尺寸是刚刚好可以装到fitWidth和fitHeight中的,不多一个像素,也不少一个像素,并且保持原始的图片宽高显示比例;
 * 返回示例:{width:100,height:100}
 * 如果计算失败,返回null
 */
function aspectFitImg(imgSourceWidth, imgSourceHeight, fitWidth, fitHeight) {
  if (isNull(imgSourceWidth) || isNull(imgSourceHeight) || isNull(fitWidth) || isNull(fitHeight)) {
    return null;
  }
  if (imgSourceWidth > fitWidth) {
    let d = imgSourceWidth / fitWidth;
    let th = imgSourceHeight / d;
    return this.aspectFitImg(fitWidth, th, fitWidth, fitHeight);
  } else if (imgSourceHeight > fitHeight) {
    let d = imgSourceHeight / fitHeight;
    let tw = imgSourceWidth / d;
    return this.aspectFitImg(tw, fitHeight, fitWidth, fitHeight);
  } else if (imgSourceWidth <= fitWidth && imgSourceHeight <= fitHeight) {
    return { width: imgSourceWidth, height: imgSourceHeight };
  } else {
    return this.aspectFitImg(imgSourceWidth, imgSourceWidth, fitWidth, fitHeight);
  }
}

作者:zhangyin

以上内容来自于:

链接:https://www.jianshu.com/p/a6014e968598/
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值