前言

闲暇时间抽个空写了个三国杀武将手册的小程序,中间有个需求设计的是合成武将皮肤图、竖排的武将姓名、以及小程序码,然后提供保存图片到相册,最终让用户可以分享到朋友圈或其他平台。合成图片应该按照 Canvas 的文档来做都没什么问题,主要是有个竖排文字的需求,这里和大家分享一下。

正文

首先放一张最终保存到相册的图片吧~

自我感觉良好,至少达到了我自己的预期吧~~~

下面让我们一步一步来看看如何实现的吧。

整个图片分为三个部分:

武将图片

小程序码

武将文字信息

先来看一下 wxml 里面的代码,主要是放了一个 canvas 标签,控制了一下高度和宽度属性。

武将图片

drawHeroImage: function (path) {

var that = this;

// 拿到canvas context

let ctx = wx.createCanvasContext('share_canvas');

// 为了保证图片比例以及绘制的位置,先要拿到图片的大小

wx.getImageInfo({

src: path,

success: function (res) {

// 计算图片占比信息

let maxWidth = Math.min(res.width, that.data.canvasWidth * 0.65);

let radio = maxWidth / res.width;

let offsetY = (that.data.canvasHeight - res.height * radio) / 2;

console.log('offsetY=' + offsetY);

that.setData({

imageWidth: res.width * radio,

imageHeight: res.height * radio,

offsetY: offsetY,

});

// 绘制canvas背景,不属于绘制图片部分

ctx.setFillStyle('white')

ctx.fillRect(0, 0, that.data.canvasWidth, that.data.canvasHeight);

// 绘制武将图片,path是本地路径,不可以传网络url,如果是网络图片需要先下载

ctx.drawImage(path, 10, offsetY, res.width * radio, res.height * radio)

// 绘制小程序码

that.drawQrCodeImage(ctx);

// 绘制势力汉字:吴

that.drawInfluence(ctx, that.data.hero.HERO.INFLUENCE);

// 绘制武将姓名:陆逊

that.drawName(ctx, that.data.hero.HERO.NAME);

// 绘制武将称号:江陵侯

that.drawHorner(ctx, that.data.hero.HERO.HORNER);

// 最终调用draw函数,生成预览图

// 一个坑点:只能调用一次,否则后面的会覆盖前面的

ctx.draw();

}

});

}

小程序码

小程序码和武将图片是一个类型,无非就是需要计算绘制的位置,这里就不再展示相关代码了。

武将文字信息

从刚刚的代码可以看出,我分了3个部分来绘制,其实 吴 和 陆逊 应该是可以放到一起的,但是我在绘制的时候发现,空格在绘制的时候会引起异常,导致空格后面的文字无法绘制出来,所以我这里 吴 和 陆逊 中间的空白是靠位置偏移来做的。

这里就展示一下如何绘制武将称号的。

// 绘制武将称号:江陵侯

drawHorner: function (ctx, text) {

// 设置字号

ctx.setFontSize(26);

// 设置字体颜色

ctx.setFillStyle("#000000");

// 计算绘制起点

let x = this.data.offsetX + 35;

let y = this.data.offsetY + 10;

console.log('drawHorner' + text);

console.log(x);

console.log(y);

// 绘制竖排文字,这里是个Util函数,具体实现请继续看

Canvas.drawTextVertical(ctx, text, x, y);

}

绘制竖排文字从网上找了个开源的代码,需要看原理的请看这里

当然我这里为了适用小程序做了些改动,函数原型是这样子的:

CanvasRenderingContext2D.prototype.letterSpacingText = function (text, x, y, letterSpacing)

原谅我不是很会 js ,完全不懂这是个什么语法,看了一会没弄懂,感觉像是给类添加新的属性,不管他。

不管白猫黑猫,能抓到耗子就是好猫

改造后的函数像下面的样子:

canvas.js

/**

* @author zhangxinxu(.com)

* @licence MIT

* @description http://www.zhangxinxu.com/wordpress/?p=7362

*/

function drawTextVertical(context, text, x, y) {

var arrText = text.split('');

var arrWidth = arrText.map(function (letter) {

return 26;

// 这里为了找到那个空格的 bug 做了许多努力,不过似乎是白费力了

// const metrics = context.measureText(letter);

// console.log(metrics);

// const width = metrics.width;

// return width;

});

var align = context.textAlign;

var baseline = context.textBaseline;

if (align == 'left') {

x = x + Math.max.apply(null, arrWidth) / 2;

} else if (align == 'right') {

x = x - Math.max.apply(null, arrWidth) / 2;

}

if (baseline == 'bottom' || baseline == 'alphabetic' || baseline == 'ideographic') {

y = y - arrWidth[0] / 2;

} else if (baseline == 'top' || baseline == 'hanging') {

y = y + arrWidth[0] / 2;

}

context.textAlign = 'center';

context.textBaseline = 'middle';

// 开始逐字绘制

arrText.forEach(function (letter, index) {

// 确定下一个字符的纵坐标位置

var letterWidth = arrWidth[index];

// 是否需要旋转判断

var code = letter.charCodeAt(0);

if (code <= 256) {

context.translate(x, y);

// 英文字符,旋转90°

context.rotate(90 * Math.PI / 180);

context.translate(-x, -y);

} else if (index > 0 && text.charCodeAt(index - 1) < 256) {

// y修正

y = y + arrWidth[index - 1] / 2;

}

context.fillText(letter, x, y);

// 旋转坐标系还原成初始态

context.setTransform(1, 0, 0, 1, 0, 0);

// 确定下一个字符的纵坐标位置

var letterWidth = arrWidth[index];

y = y + letterWidth;

});

// 水平垂直对齐方式还原

context.textAlign = align;

context.textBaseline = baseline;

}

module.exports = {

drawTextVertical: drawTextVertical

}

绘制网络图片

由于网络图片无法直接绘制,所以需要先下载到本地,然后再按住本地图片绘制的流程走一遍。

downloadHeroImage: function () {

// 微信不支持非https的图片下载,这里了个替换

let url = this.data.hero.HERO.ICON.replace(/http/, "https");

var that = this;

wx.downloadFile({

url: url,

success: function (res) {

// 下载成功后拿到图片的路径,然后开始绘制

var path = res.tempFilePath;

that.drawHeroImage(path);

}, fail: function (res) {

console.log(res)

}

});

}

保存图片

说了这么多,自然少不了最终的一步,将绘制到 canvas 的图片保存到手机相册,这里需要用户授权,你需要自己处理。

用的是微信给我们提供的接口 wx.canvasToTempFilePath 。需要我们传入起点坐标 (x, y)和画布大小 (width, height) 以及 canvasId 。

saveShareImage: function () {

wx.showLoading({

title: '正在保存图片..',

});

let that = this;

wx.canvasToTempFilePath({

x: 0,

y: 0,

width: that.data.canvasWidth,

height: that.data.canvasHeight,

canvasId: 'share_canvas',

success: function (res) {

wx.saveImageToPhotosAlbum({

filePath: res.tempFilePath,

success(res) {

console.log(res);

wx.showToast({

title: '保存到相册成功',

duration: 1500,

})

},

fail(res) {

console.log(res)

wx.showToast({

title: '保存到相册失败',

icon: 'fail'

})

},

complete(res) {

console.log(res)

}

})

}

})

}

开源

本着开源的精神,源码已经放在 Github 上,大家可以去上面查看具体代码。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

canvas绘制竖排的数字_微信小程序利用Canvas绘制图片和竖排文字详解相关推荐

  1. html5绘制图形幸运大转盘,微信小程序利用canvas 绘制幸运大转盘功能

    小程序对 canvas api 跟h5的不太一致 ,所以这个搞的比较久,不多说,先贴代码 Page({ /** * 页面的初始数据 */ data: { awardsConfig: {}, resta ...

  2. wxss 点击样式_微信小程序点击控件修改样式实例详解

    微信小程序点击控件修改样式实例详解 现在要在微信小程序中实现点击控件修改样式,如下: 微信小程序中不支持直接操作dom,要实现这种效果,我们需要通过设置data,然后利用数据和界面的双向绑定来实现它. ...

  3. 微信小程序点击带id参数跳转_微信小程序页面跳转方法和携带参数详解

    1.页面跳转方式 (1)标签跳转 open-type的属性值对应api里的用法即wx.的用法 1 跳转到新页面 (2)wx.navigateTo 方法跳转 此方法能够从跳转的页面会回到当前页面 1 w ...

  4. api 定位 微信小程序 精度_微信小程序3种位置API的使用方法详解

    获取位置 获取当前的地理位置.速度.当用户离开小程序后,此接口无法调用:当用户点击"显示在聊天顶部"时,此接口可继续调用. wx.getLocation(object) 获取位置 ...

  5. 微信小程序利用canvas实现六边形蜘蛛图

    微信小程序利用canvas实现六边形蜘蛛图 发布时间:2018-01-24 14:30:29 1..wxml <canvas style="width: 200px; height: ...

  6. 微信小程序云开发入门(二)-数据库详解

    微信小程序云开发入门(二)-数据库详解 接上一篇:微信小程序云开发入门(一) 摘要: 因为微信小程序云数据库有点类似传统的关系型数据库,但又有所不同.所以刚入手的时候会有点困扰,经过一段时间的学习和摸 ...

  7. php微信小程序物流进度推送,微信小程序 消息推送php服务器验证实例详解

    微信小程序 消息推送php服务器验证实例详解 设置页面("设置">>"开发设置"): 1.设置服务器域名 注意http和https协议的不同. 2. ...

  8. 微信小程序图片转换成文字_微信小程序中用canvas将文字转成图片,文字自动换行...

    onReady: function () { wx.showLoading({ title: '生成图片中...', }) var that = this const ctx = wx.createC ...

  9. 微信小程序进度条组件自定义数字_微信小程序之圆形进度条(自定义组件)

    前言 昨天在微信小程序实现了圆形进度条,今天想把这个圆形进度条做成一个组件,方便以后直接拿来用. 根据官方文档自定义组件一步一步来 创建自定义组遇新是直朋能到件 第一步创建项遇新是直朋能到分览目结构 ...

  10. 微信小程序利用canvas画出根据文字自适应的边框

    1.需求 生成海需要画出一个中空带边框的的tag,如下图.众所周知,微信小程序里的canvas画图都是需要自己一点点画出来,不想html有htmlToCanvas,直接写HTML就可以转成canvas ...

最新文章

  1. Jquery实现的Tabs页签
  2. 两次服务器灾难事故的反思
  3. 我司那产品经理丨第一期
  4. 聚合链路出现Destination host unreachable
  5. RSA openssl_public_encrypt false
  6. 数据库工作笔记/设计思路-通过增加索引表为某库中其他表添加索引(描述信息)
  7. The Pragmatic Programmer 读书笔记之中的一个 DRY-Don’t Repeat Youself
  8. gamma分布_RAW和Gamma
  9. python open 函数漏洞_Python系列之——编写已知漏洞exp实现批量getshell
  10. 13、细说装饰器与闭包
  11. springAOP(Aspect)权限访问页面
  12. Jmeter及JDK下载安装配置教程
  13. 互联网晚报 | 11月10日 星期三 | 华为捐赠欧拉开源操作系统;微信支持导出个人信息;12306上线铁水联运服务...
  14. java中的字符串常量池_java字符串常量池
  15. 用HTML+CSS实现百度静态页面
  16. 无效的证书、相同的序列号、SEC_ERROR_REUSED_ISSUER_AND_SERIAL
  17. 顺序表——有序顺序表的插入
  18. LeetCode:逆波兰式;
  19. 仲至信息与Cornet Solutions签订日本经销合同
  20. 更好的确保企业数据安全,华为云数据灾备解决方案更便捷

热门文章

  1. SQL SERVER 2016安装Microsoft R Open和Microsoft R Server问题
  2. Navicat 将 psc备份文件还原
  3. 如果你读不完凯文凯利的《必然》,至少读完这120条书摘
  4. 结构建模设计——Solidworks软件之特征成型中拉伸凸台基体与设计树应用实战总结
  5. PHP工程师接私单操作流程
  6. linux解压rar.gz,Linux tar.gz 、zip、rar 解压 压缩命令
  7. 什么是前端开发工程师
  8. 毕索大学计算机科学怎么样,毕索大学与麦吉尔大学哪个好
  9. Vue报错:Invalid prop: type check failed for prop .... Expected String with value 1, got Number 1
  10. VUE博客模板----FXBLOG