本期介绍Canvas绘制图片,涉及到如何绘制高清图片丶使用网络图片/本地图片丶日期转化(阴阳历/星期换算)丶图片适配手机型号等。
布局介绍
此处分为4块,上面展示图片,中间展示公众号二维码&日期,下面展示一些文本和公司的logo和名称
wxml页面
`<canvas
canvas-id="shareImg" style="width:{{winWidth}}px; height:{{winHeight}}px; background:#FFF;"
bindlongtap="createImage">
</canvas> `
wxss页面(无)
日期转化GregorianCalendar.JS页面
/*
* 农历数据表
*
* 农历分大小月,大月30天,小月29天,但一年中哪个月为大月,哪个月为小月,是无规律的。
* 农历每十年有4个闰年,但哪一年为闰年也是不确定的。
* 而闰月中,哪个闰月为大月,哪个为小月也是不确定的。
*
* 下面共20行,每行10个数据。每个数据代表一年,从阳历1900.1.31日起,为第一个数据年的开始,即阳历1900.1.31=农历0.1.1。
* 200个数据可推200年的农历,因此目前最大只能推算到2100年
*
* 对于每一个数据项,5个十六进制数 = 20个二进制位
* 前4位,即0在这一年是闰年时才有意义,它代表这年闰月的大小月,为1则闰大月,为0则闰小月。
* 中间12位,即4bd,每位代表一个月,为1则为大月,为0则为小月。
* 最后4位,即8,代表这一年的闰月月份,为0则不闰。首4位要与末4位搭配使用。
*/
const lunarInfo = new Array(
0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900年~1909年
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910年~1919年
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920年~1929年
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930年~1939年
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940年~1949年
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950年~1959年
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960年~1969年
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, // 1970年~1979年
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980年~1989年
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, // 1990年~1999年
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000年~2009年
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010年~2019年
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020年~2029年
0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030年~2039年
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040年~2049年
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050年~2059年
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060年~2069年
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070年~2079年
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080年~2089年
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090年~2099年
0x0d520 // 2100年
);
const minYear = 1900; // 能计算的最小年份
const maxYear = 2100; // 能计算的最大年份
// 阳历每月天数,遇到闰年2月需加1天
const solarMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
// 农历月份别称
const monthName = new Array('正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '冬月', '腊月');
// 二十四节气
const solarTerm = new Array(
'小寒', '大寒', '立春', '雨水', '惊蛰', '春分',
'清明', '谷雨', '立夏', '小满', '芒种', '夏至',
'小暑', '大暑', '立秋', '处暑', '白露', '秋分',
'寒露', '霜降', '立冬', '小雪', '大雪', '冬至'
);
// 二十节气相关系数
const termInfo = new Array(
0, 21208, 42467, 63836, 85337, 107014,
128867, 150921, 173149, 195551, 218072, 240693,
263343, 285989, 308563, 331033, 353350, 375494,
397447, 419210, 440795, 462224, 483532, 504758);
/**
* 检查年份是否输入正确
* @param year int 年份
*/
function _checkYear(year) {
if (year < minYear) {
throw new RangeError('年份不能小于' + minYear + '年');
} else if (year > maxYear) {
throw new RangeError('年份不能大于' + maxYear + '年');
}
return true;
}
/**
* 检查月份是否输入正确
* @param month int 月份
*/
function _checkMonth(month) {
if (month < 1) {
throw new RangeError('月份不能小于1');
} else if (month > 12) {
throw new RangeError('月份不能大于12');
}
return true;
}
/**
* 检查日期是否输入正确
* @param day int 日期
*/
function _checkDay(day) {
if (day < 1) {
throw new RangeError('日期不能小于1');
} else if (day > 31) {
throw new RangeError('日期不能大于31');
}
return true;
}
/**
* 返回农历year年中哪个月是闰月,没有闰月返回0
* @param year int 年份
*/
function getLunarLeapMonth(year) {
if (_checkYear(year)) {
return lunarInfo[year - minYear] & 0xf; // 最后4位,代表这一年的闰月月份,为0则今年没有闰月
}
}
/**
* 返回农历year年闰月的天数(如果没有闰月则返回0)
* @param year int 年份
*/
function getLeapMonthDaysCount(year) {
if (getLunarLeapMonth(year)) {
return lunarInfo[year - minYear] & 0x10000 ? 30 : 29; // 前4位,即0在这一年是闰年时才有意义,它代表这年闰月的大小月
}
return 0;
}
/**
* 返回农历year年的总天数
* @param year int 年份
*/
function getLunarYearDaysCount(year) {
if (_checkYear(year)) {
let sum = 348; // 29天 * 12个月 = 348日
for (let i = 0x8000; i > 0x8; i >>= 1) {
sum += (lunarInfo[year - minYear] & i ? 1 : 0);
}
return sum + getLeapMonthDaysCount(year);
}
}
/**
* 返回农历year年month月的天数
* @param year int 年份
* @param month int 月份 1~12
*/
function getLunarYearMonthDaysCount(year, month) {
if (_checkYear(year) && _checkMonth(month)) {
return lunarInfo[year - minYear] & (0x10000 >> month) ? 30 : 29;
}
}
/**
* 农历日期的中文字符串
* @param day int 日期
*/
function getLunarDayString(day) {
if (_checkDay(day)) {
const nStr1 = new Array('日', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
const nStr2 = new Array('初', '十', '廿', '卅');
let str = '';
switch (day) {
case 10:
str = '初十';
break;
case 20:
str = '二十';
break;
case 30:
str = '三十';
break;
default:
str = nStr2[Math.floor(day / 10)];
str += nStr1[day % 10];
break;
}
return str;
}
}
/**
* 返回某年的第n个节气为几日(从0小寒起算)
* @param year int 年份
* @param n 节气编号 0~23
*/
function getLunarTermDay(year, n) {
if (_checkYear(year) && n <= 23 && n >= 0) {
const sTermInfo = new Array(0, 21208, 42467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758);
const offDate = new Date((31556925974.7 * (year - minYear) + sTermInfo[n] * 60000) + Date.UTC(minYear, 0, 6, 2, 5));
return offDate.getUTCDate();
}
}
/**
* 阳历日期转农历日期
* @param year int 年份
* @param month int 月份 1~12
* @param day int 日期 1~31
*/
function solarToLunar(year, month, day) {
if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
const baseDate = new Date(minYear, 0, 31); // 基础日期1900年1月31日
const objDate = new Date(year, month - 1, day); // 目标日期
let offset = (objDate - baseDate) / 86400000; // 偏移天数 60 * 60 * 24 * 1000 = 86400000,1天的毫秒数
let monCycle = 14;
let temp = 0;
let i = 0;
for (i = minYear; i < maxYear && offset > 0; i++) {
temp = getLunarYearDaysCount(i); // 农历year年的总天数
if (offset - temp < 0) {
break;
} else {
offset -= temp;
}
monCycle += 12;
}
const lunarYear = i; // 农历年份
const leap = getLunarLeapMonth(lunarYear); // 当年闰月是哪个月
const isLeapYear = leap > 0 ? true : false; // 当年是否有闰月
let isLeapMonth = false; // 当前农历月份是否是闰月
for (i = 1; i <= 12 && offset > 0; i++) {
if (leap > 0 && i == (leap + 1) && !isLeapMonth) {
--i;
isLeapMonth = true;
temp = getLeapMonthDaysCount(year);
} else {
temp = getLunarYearMonthDaysCount(year, i);
}
if (isLeapMonth && i == (leap + 1)) {
isLeapMonth = false;
}
offset -= temp;
if (!isLeapMonth) {
monCycle++;
}
}
if (offset == 0 && leap > 0 && i == leap + 1) {
if (isLeapMonth) {
isLeapMonth = false;
} else {
isLeapMonth = true;
--i;
--monCyl;
}
}
if (offset < 0) {
offset += temp;
--i;
--monCycle;
}
const lunarMonth = i; // 农历月份
const lunarDay = offset + 1; // 农历日期
let monthStr = '';
if (isLeapYear) {
if (lunarMonth < leap) {
monthStr = monthName[lunarMonth - 1];
} else if (lunarMonth == leap) {
monthStr = '闰' + monthName[lunarMonth - 1];
} else {
monthStr = monthName[lunarMonth - 2];
}
} else {
monthStr = monthName[lunarMonth - 1];
}
return {
year: lunarYear, // 农历年份
month: lunarMonth, // 农历月份
day: lunarDay, // 农历日期
isLeap: isLeapMonth, // 是否闰月
monthStr: monthStr, // 月份字符串
dayStr: getLunarDayString(lunarDay) // 日期字符串
};
}
}
/**
* 阳历某个月份天数
* @param year int 年份
* @param month int 月份 1~12
*/
function getSolarMonthDaysCount(year, month) {
if (_checkYear(year) && _checkMonth(month)) {
if (month == 2) {
return (((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)) ? 29 : 28);
} else {
return solarMonth[month - 1];
}
}
}
/**
* 获取指定日期是阳历年中的第几天
* @param year int 年份
* @param month int 月份 1-12
* @param day int 日期
*/
function getSolarDayNumber(year, month, day) {
if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
const date = new Date(year, month - 1, day);
const d = date.getDate(); // 本月第几天
const m = month - 1;
let sum = d;
for (let i = 0; i < m; i++) {
sum += solarMonth[i];
}
if (m > 1 && (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
sum += 1;
}
return sum;
}
}
/**
* 计算指定日期是否属于24节气
* @param year int 年份
* @param month int 月份 1~12
* @param day int 日期 1~31
*/
function getLunar24Days(year, month, day) {
if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
const baseDate = new Date(1900, 0, 6, 2, 5, 0);
let str = false;
for (let i = 1; i <= 24; i++) {
const num = 525948.76 * (year - 1900) + termInfo[i];
const timestamp = baseDate.getTime() + num * 60 * 1000;
const newDate = new Date(timestamp);
if (getSolarDayNumber(newDate.getFullYear(), newDate.getMonth() + 1, newDate.getDate()) ==
getSolarDayNumber(year, month, day)) {
str = solarTerm[i];
break;
}
}
return str;
}
}
module.exports = {
getLunarLeapMonth, // 返回农历year年中哪个月是闰月,没有闰月返回0
getLeapMonthDaysCount, // 返回农历year年闰月的天数(如果没有闰月则返回0)
getLunarYearDaysCount, // 返回农历year年的总天数
getLunarYearMonthDaysCount, // 返回农历year年month月的天数
getLunarDayString, // 农历日期的中文字符串
getLunarTermDay, // 返回某年的第n个节气为第几日
getSolarMonthDaysCount, // 获取阳历某个月份有多少天
getSolarDayNumber, // 获取指定日期是阳历年中的第几天
getLunar24Days, // 计算指定日期是否属于24节气
solarToLunar, // 阳历日期转农历日期
getDates: getDates, // 日期转化周几
}
//获取d当前时间多少天后的日期和对应星期
function getDates(days,todate = getCurrentMonthFirst) {//todate默认参数是当前日期,可以传入对应时间
// var dateArry = [];
// for (var i = 0; i < days; i++) {
var dateObj = dateLater(days, 0);
// dateArry.push(dateObj)
// }
return dateObj;
}
/**
* 传入时间后几天
* param:传入时间:dates:"2018-04-02",later:往后多少天
*/
function dateLater(dates,later) {
let dateObj = {};
let show_day = new Array('星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六');
let date = new Date(dates);
date.setDate(date.getDate() + later);
let day = date.getDay();
dateObj.year = date.getFullYear();
dateObj.month = ((date.getMonth() + 1) < 10 ? ("0" + (date.getMonth() + 1)) : date.getMonth() + 1);
dateObj.day = (date.getDate() < 10 ? ("0" + date.getDate()) : date.getDate());
dateObj.week = show_day[day];
return dateObj;
}
//获取当前时间
function getCurrentMonthFirst() {
var date = new Date();
var todate = date.getFullYear() + "-" + ((date.getMonth() + 1) < 10 ? ("0" + (date.getMonth() + 1)) : date.getMonth() + 1) + "-" + (date.getDate() < 10 ? ("0" + date.getDate()) : date.getDate());
return todate;
}
使用得到你想要的数据(如:农历,气,农历月份别称等)
使用起来很方便:只需要引入js,然后调用即可。例如:我要使用到阳历转阴历:
引入js:const GregorianCalendar = require('../../utils/GregorianCalendar.js');
调用相关fucntion:GregorianCalendar.solarToLunar(year, month, day)
第三点出的文本绘制类似不做过多介绍
文本xljt.js代码页面
var xljt = [{
"name": "当一个人在我们身边的时候,我们不会知道与他分别的时地。就像我们在生的时候,亦不知道死。",
"id": "1"
}, {
"name": "如果有幸福幸福只是瞬间的片段,一小段一小段缘分叵测,我们无从得知下一刻会发生一些什么。",
"id": "2"
}, {
"name": "每个人都有权利选择自己的生活方式。但换言之,人又是被拘禁的,从未曾得到权利决定自己的生活。",
"id": "3"
}, {
"name": "人生在世最大的勇气不是不怕死亡,而是坚强的活着,勇敢的面对生活带给的压力和考验!",
"id": "4"
}, {
"name": "沙砾通过不断地磨砺,让自己的棱角尽失后才会成为璀璨圆润的明珠,散发出世人所钟爱的光泽。",
"id": "5"
}, {
"name": "太多的曾经我们未曾把握,太多的机会我们一再错过。与其事竟过去之时的叹息。。。不如用心好好珍惜所有。",
"id": "6"
}, {
"name": "人生有许多选择,每一步都要慎重。一次选择不能决定一切,作出选择就不要后悔。只要我们不屈不挠地奋斗,胜利就在前方。",
"id": "7"
}, {
"name": "为了向别人、向世界证明自己而努力拼搏,而一旦你真的取得了成绩,才会明白:人无须向别人证明什么,只要你能超越自己。",
"id": "8"
}, {
"name": "朝着一定目标走去是“志”,一鼓作气中途绝不停止“气”,两者合起来就是“志气”。一切事业的成败都取决于此。",
"id": "9"
}, {
"name": "你可以忘掉失败,但不能忘掉教训;你可以忘掉苦难,但不能忘却艰辛;你可以忘掉伤疤,但不能忘却耻辱。",
"id": "10"
}, {
"name": "事物是辩证的,当你得到一些东西时,同时也会让你失去另一些东西;当你失去一些东西时,同时也会让你得到一些东西。",
"id": "11"
}, {
"name": "把懒惰放一边,把丧气的话收一收,把积极性提一提,把矫情的心放一放。所有想要的,都得靠自己的努力才能得到。",
"id": "12"
}, {
"name": "我们是活给自己看的,不必沉浸在他人的语言中,蜷缩于世外的阴影下。你若裹足不前,有人偷着笑;你若挣开束缚,前方春暖花开。",
"id": "13"
}, {
"name": "那长在石缝间的绿色尤物,它给人以鼓舞、给人以力量。任凭风霜雪雨,依然坦然面对!这就是顽劲,倔强,是生命的绚丽与辉煌!",
"id": "14"
}, {
"name": "给自己一份信心,去拥抱这个世界,让今天过得充实,让明天充满希望;光阴中的美,是来自心底的热爱和对未来的憧憬和向往。",
"id": "15"
}, {
"name": "越有故事的人越沉静简单,越肤浅单薄的人越浮躁不安。世上所有的惊喜和好运,等于你的人品乘以你的努力。",
"id": "16"
}, {
"name": "思想会变成你的言语;言语会变成你的行动;行动会变成你的习惯;习惯会变成你的性格;性格会变成你的命运。",
"id": "17"
}, {
"name": "别人所拥有的,你不必去羡慕,只要你努力,你也会拥有;自己拥有的,你不必炫耀,因为别人也在奋斗,也是会拥有。",
"id": "18"
}, {
"name": "事实上确实是当我们失去的时候,才知道自己曾经拥有;但有没有注意到当有些东西来临的时候,我们已错过。",
"id": "19"
}, {
"name": "喜欢在这里发呆的时光。喜欢那种不知不觉时间就流走的感觉。我说我活的太快。似乎一下子就要过完一生似的。",
"id": "20"
}, {
"name": "健康的才是美丽的,合适的才是最好的,常新的才是迷人的,平凡的才是伟大的,坚韧的才是长久的,真实的才是永恒的。",
"id": "21"
}, {
"name": "学会调整自己,尽快地从不幸和失意中奋起,这样得来的成功更值得自豪。即使是失败,经过了努力也值得回味。",
"id": "22"
}, {
"name": "当爱情已经渐渐地不可阻挡地淡去,谁还会在乎曾经爱过的人被一首伤心的情歌伤得不能动弹?谁还会站在原地,不离不弃?",
"id": "23"
},
{
"name": "人生之路不平坦,坦然面对很关键,谈笑风生烟云过,克难攻坚不等闲,快乐奔跑永向前,九转功成笑开颜。愿你坦然处之,努力搏之,成功等候。",
"id": "24"
}, {
"name": "有眼界才有境界,有实力才有魅力,有思路才有出路,有作为才有地位。政从正来,智从知来,财从才来,位从为来!",
"id": "25"
}, {
"name": "最常见的勇气就是在日常生活中做到诚实和正直,能够抵制诱惑,敢于讲真话,表现自己真实的一面,而不要虚伪造作。",
"id": "26"
}, {
"name": "目标的坚定是性格中最必要的力量源泉之一,也是成功的利器之一。没有它,天才会在矛盾无定的迷径中徒劳无功。",
"id": "27"
}, {
"name": "如果你失去了太阳,你还有星光的照耀;失去了金钱,还会得到友情;当生命离开你的时候,你却拥有大地的亲吻。",
"id": "28"
}, {
"name": "幸福的关键不在与找到一个完美的人,而在找到任何一个人,然后和他一起努力建立一个完美的关系。",
"id": "29"
}, {
"name": "只要认为是对的就去做,坚持去做,不要在乎别人的看法,哪怕是错,至少你有去做过证明曾经你努力过。",
"id": "30"
}, {
"name": "当你无法从一楼蹦到三楼时,不要忘记走楼梯。要记住伟大的成功往往不是一蹴而就的,必须学会分解你的目标,逐步实施。",
"id": "31"
},
]
module.exports = {
xljt
}
使用:const xljt = require('../../utils/xljt.js');
引用:var name = xljt.xljt[day].name;
util.js代码页面
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
module.exports = {
formatTime: formatTime
}
绘制图片.JS页面
// 引入配置
const GregorianCalendar = require('../../utils/GregorianCalendar.js');
const util = require('../../utils/util.js');
const xljt = require('../../utils/xljt.js');
// 显示繁忙提示
var showBusy = text => wx.showToast({
title: text,
icon: 'loading',
duration: 10000
});
Page({
/**
* 页面的初始数据
*/
data: {
url: '',
winWidth: 0,
winHeight: 0,
oneHeight: 0,// 风景图的高度
ewmWidth: 0,//二维码的高度
oneWidth: 0,//左右两边的空白
twoWidth: 0,//二维码和边框之间的距离
fontHeight: 0,
text1: '',
text2: '',
text3: '',
text4: ''
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.showLoading({
title: '图片加载中...',
});
var winWidth = 0;
var winHeight = 0;
wx.getSystemInfo({
success: function (res) {
console.log("....", res)
winWidth = res.windowWidth;
winHeight = res.windowHeight
}
})
this.setData({
winWidth: winWidth,
winHeight: winWidth * 1.25 + winWidth * 0.16 + winWidth * 0.16 * 0.8 + 100,
oneHeight: winWidth * 1.25,// 风景图的高度
ewmWidth: winWidth * 0.16,//二维码的高度
oneWidth: winWidth * 0.16,//左右两边的空白
twoWidth: winWidth * 0.04,//二维码和边框之间的距离
fontHeight: (winWidth * 0.16 + 22) * 0.5, //字体上下居中
})
console.log("fontHeight", this.data.fontHeight)
var time = util.formatTime(new Date).substring(0, 10);
var year = time.substring(0, 4);
var month = time.substring(5, 7);
var day = time.substring(8, 10);
if (month <= 9) {
month = time.substring(6, 7)
}
if (day <= 9) {
day = time.substring(9, 10);
}
var length = xljt.xljt[day].name.length;
var name = xljt.xljt[day].name;
if (this.data.winWidth <= 330) {
if (length < 19) {
this.setData({
text1: name,
})
} else if (length >= 19 && length < 38) {
this.setData({
text1: name.substring(0, 19),
text2: name.substring(19, 38),
})
} else if (length >= 38 && length < 57) {
this.setData({
text1: name.substring(0, 19),
text2: name.substring(19, 38),
text3: name.substring(38, 57),
})
} else {
this.setData({
text1: name.substring(0, 19),
text2: name.substring(19, 38),
text3: name.substring(38, 57),
text4: name.substring(57, length),
})
}
} else if (this.data.winWidth > 330 && this.data.winWidth < 400) {
if (length < 22) {
this.setData({
text1: name,
})
} else if (length >= 22 && length < 44) {
this.setData({
text1: name.substring(0, 22),
text2: name.substring(22, 44),
})
} else if (length >= 44 && length < 66) {
this.setData({
text1: name.substring(0, 22),
text2: name.substring(22, 44),
text3: name.substring(44, 66),
})
} else {
this.setData({
text1: name.substring(0, 22),
text2: name.substring(22, 44),
text3: name.substring(44, 66),
text4: name.substring(66, length),
})
}
} else {
if (length < 25) {
this.setData({
text1: name,
})
} else if (length >= 25 && length < 50) {
this.setData({
text1: name.substring(0, 25),
text2: name.substring(25, 50),
})
} else if (length >= 50 && length < 75) {
this.setData({
text1: name.substring(0, 25),
text2: name.substring(25, 50),
text3: name.substring(50, 75),
})
} else {
this.setData({
text1: name.substring(0, 25),
text2: name.substring(25, 50),
text3: name.substring(50, 75),
text4: name.substring(75, length),
})
}
}
console.log("阳历转阴历:", GregorianCalendar.solarToLunar(year, month, day));
console.log("周几", GregorianCalendar.getDates(time, time));
this.setData({
url:'../../image/11.jpg',
days: month + '/' + day,
data: GregorianCalendar.solarToLunar(year, month, day).monthStr + GregorianCalendar.solarToLunar(year, month, day).dayStr,
week: GregorianCalendar.getDates(time, time).week,
year: year
})
this.Image();
setTimeout(function () {
wx.hideLoading()
}, 2000)
},
//绘制图片
Image: function () {
var that = this;
var promise1 = new Promise(function (resolve, reject) {
wx.getImageInfo({
src: '../../image/gzhewm.png',
success: function (res) {
console.log('promise1', res)
resolve(res);
}
})
});
var promise2 = new Promise(function (resolve, reject) {
wx.getImageInfo({
src: '../../image/11.jpg',
success: function (res) {
console.log('promise2', res)
resolve(res);
}
})
});
var promise3 = new Promise(function (resolve, reject) {
wx.getImageInfo({
src: '../../image/white.jpg',
success: function (res) {
console.log('promise3', res)
resolve(res);
}
})
});
var promise4 = new Promise(function (resolve, reject) {
wx.getImageInfo({
src: '../../image/logo.png',
success: function (res) {
console.log('promise4', res)
resolve(res);
}
})
});
Promise.all([
// promise1
promise1, promise2, promise3, promise4
]).then(res => {
console.log("res", res)
const ctx = wx.createCanvasContext('shareImg')
//主要就是计算好各个图文的位置
ctx.drawImage('../../' + res[2].path, 0, 0, that.data.winWidth, that.data.winHeight)
//注意网络图片不需要加../../,本地的需要
// ctx.drawImage( res[1].path, 0, 0, that.data.winWidth, that.data.oneHeight)
ctx.drawImage('../../' +res[1].path, 0, 0, that.data.winWidth, that.data.oneHeight)
ctx.drawImage('../../' + res[0].path, that.data.oneWidth, that.data.oneHeight + 10, that.data.ewmWidth, that.data.ewmWidth)
ctx.drawImage('../../' + res[3].path, that.data.oneWidth * 0.5, that.data.oneHeight + that.data.ewmWidth + 80, that.data.winWidth - that.data.oneWidth, that.data.ewmWidth * 0.8)
ctx.setStrokeStyle('#9b4400')
//上方两根线
ctx.moveTo(that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth, that.data.oneHeight + 10)
ctx.lineTo(that.data.winWidth - that.data.oneWidth, that.data.oneHeight + 10)
ctx.moveTo(that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 5, that.data.oneHeight + 15)
ctx.lineTo(that.data.winWidth - that.data.oneWidth - 5, that.data.oneHeight + 15)
//下方两根线
ctx.moveTo(that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth, that.data.oneHeight + that.data.ewmWidth + 10)
ctx.lineTo(that.data.winWidth - that.data.oneWidth, that.data.oneHeight + that.data.ewmWidth + 10)
ctx.moveTo(that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 5, that.data.oneHeight + that.data.ewmWidth + 5)
ctx.lineTo(that.data.winWidth - that.data.oneWidth - 5, that.data.oneHeight + that.data.ewmWidth + 5)
//左边两根线
ctx.moveTo(that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth, that.data.oneHeight + 10)
ctx.lineTo(that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth, that.data.oneHeight + that.data.ewmWidth + 10)
ctx.moveTo(that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 5, that.data.oneHeight + 15)
ctx.lineTo(that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 5, that.data.oneHeight + that.data.ewmWidth + 5)
//右边两根线
ctx.moveTo(that.data.winWidth - that.data.oneWidth, that.data.oneHeight + 10)
ctx.lineTo(that.data.winWidth - that.data.oneWidth, that.data.oneHeight + that.data.ewmWidth + 10)
ctx.moveTo(that.data.winWidth - that.data.oneWidth - 5, that.data.oneHeight + 15)
ctx.lineTo(that.data.winWidth - that.data.oneWidth - 5, that.data.oneHeight + that.data.ewmWidth + 5)
ctx.setFillStyle('#9b4400')
if (that.data.winWidth < 350) {
ctx.setFontSize(30)
ctx.fillText(that.data.days, that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 10, that.data.oneHeight + that.data.fontHeight + 10)
ctx.setFontSize(16)
ctx.fillText(that.data.year, that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 86, that.data.oneHeight + that.data.fontHeight - 4)
ctx.fillText(that.data.week, that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 80, that.data.oneHeight + that.data.fontHeight + 13)
} else if (that.data.winWidth >= 350 && that.data.winWidth <= 400) {
ctx.setFontSize(32)
ctx.fillText(that.data.days, that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 10, that.data.oneHeight + that.data.fontHeight + 10)
ctx.setFontSize(20)
ctx.fillText(that.data.year, that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 96, that.data.oneHeight + that.data.fontHeight - 5)
ctx.fillText(that.data.week, that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 90, that.data.oneHeight + that.data.fontHeight + 16)
} else {
ctx.setFontSize(32)
ctx.fillText(that.data.days, that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 10, that.data.oneHeight + that.data.fontHeight + 10)
ctx.setFontSize(20)
ctx.fillText(that.data.year, that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 106, that.data.oneHeight + that.data.fontHeight - 5)
ctx.fillText(that.data.week, that.data.oneWidth + that.data.ewmWidth + that.data.twoWidth + 100, that.data.oneHeight + that.data.fontHeight + 20)
}
ctx.setFillStyle('#808080')
ctx.setFontSize(14)
if (that.data.text1.length != '') {
ctx.fillText(that.data.text1, that.data.oneWidth * 0.5, that.data.oneHeight + that.data.ewmWidth + 30)
}
if (that.data.text2 != '') {
ctx.fillText(that.data.text2, that.data.oneWidth * 0.5, that.data.oneHeight + that.data.ewmWidth + 48)
}
if (that.data.text3.length != '') {
ctx.fillText(that.data.text3, that.data.oneWidth * 0.5, that.data.oneHeight + that.data.ewmWidth + 66)
}
if (that.data.text4.length != '') {
ctx.fillText(that.data.text4, that.data.oneWidth * 0.5, that.data.oneHeight + that.data.ewmWidth + 84)
}
ctx.stroke()
ctx.draw();
})
},
//生成图片
createImage: function () {
var that = this
wx.showLoading({
title: '努力生成中...'
})
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.winWidth,
height: that.data.winHeight,
destWidth: that.data.winWidth * 2.5,
destHeight: that.data.winHeight * 2.5,
canvasId: 'shareImg',
success: function (res) {
console.log(res.tempFilePath);
that.setData({
prurl: res.tempFilePath,
//hidden: false
})
wx.hideLoading()
that.sleep(1000);
wx.getSetting({
success: (res) => {
if (res.authSetting['scope.writePhotosAlbum'] != undefined && res.authSetting['scope.writePhotosAlbum'] != true) {
//没有获取到权限
wx.openSetting({
success: function (data) {
if (data.authSetting["scope.writePhotosAlbum"] == true) {
wx.saveImageToPhotosAlbum({
filePath: that.data.prurl,
success(res) {
console.log("保存成功:", res);
wx.showModal({
content: '图片已保存到相册,赶紧晒一下吧~',
showCancel: false,
confirmText: '好的',
confirmColor: '#333',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
/* 该隐藏的隐藏 */
that.setData({
hidden: true
})
}
}
})
}
})
} else {
console.log("拒绝授权");
}
},
})
} else {
wx.saveImageToPhotosAlbum({
filePath: that.data.prurl,
success(res) {
console.log("保存成功:", res);
wx.showModal({
content: '图片已保存到相册,赶紧晒一下吧~',
showCancel: false,
confirmText: '好的',
confirmColor: '#333',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
/* 该隐藏的隐藏 */
that.setData({
hidden: true
})
}
}
})
}
})
}
}
})
},
fail: function (res) {
console.log(res)
}
})
},
sleep: function (ms) {
return new Promise(resolve => setTimeout(resolve, ms))
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
})
此处代码过多,下面拆分讲解:
适配机型代码
通过微信提供的api得到手机屏幕大小。然后赋值给要绘制的图片(wx.getSystemInfo)。
然后具体规划图片(4块区域)尺寸.注释中有关于4部分的大小。不再做描述。
var winHeight = 0;
wx.getSystemInfo({
success: function (res) {
console.log("....", res)
winWidth = res.windowWidth;
winHeight = res.windowHeight
}
})
this.setData({
winWidth: winWidth,
winHeight: winWidth * 1.25 + winWidth * 0.16 + winWidth * 0.16 * 0.8 + 100,
oneHeight: winWidth * 1.25,// 风景图的高度
ewmWidth: winWidth * 0.16,//二维码的高度
oneWidth: winWidth * 0.16,//左右两边的空白
twoWidth: winWidth * 0.04,//二维码和边框之间的距离
fontHeight: (winWidth * 0.16 + 22) * 0.5, //字体上下居中
})
注:第三部分文本适配,暂时是通过屏幕宽度来处理。先得到整个文本的长度,在更据屏幕大小来处理,通过330/400做分割线。以及文本总长度第二分割点。(有更好的解决方案可以留言哦。)
var length = xljt.xljt[day].name.length;
var name = xljt.xljt[day].name;
if (this.data.winWidth <= 330) {
if (length < 19) {
this.setData({
text1: name,
})
} else if (length >= 19 && length < 38) {
this.setData({
text1: name.substring(0, 19),
text2: name.substring(19, 38),
})
} else if (length >= 38 && length < 57) {
this.setData({
text1: name.substring(0, 19),
text2: name.substring(19, 38),
text3: name.substring(38, 57),
})
} else {
this.setData({
text1: name.substring(0, 19),
text2: name.substring(19, 38),
text3: name.substring(38, 57),
text4: name.substring(57, length),
})
}
} else if (this.data.winWidth > 330 && this.data.winWidth < 400) {
if (length < 22) {
this.setData({
text1: name,
})
} else if (length >= 22 && length < 44) {
this.setData({
text1: name.substring(0, 22),
text2: name.substring(22, 44),
})
} else if (length >= 44 && length < 66) {
this.setData({
text1: name.substring(0, 22),
text2: name.substring(22, 44),
text3: name.substring(44, 66),
})
} else {
this.setData({
text1: name.substring(0, 22),
text2: name.substring(22, 44),
text3: name.substring(44, 66),
text4: name.substring(66, length),
})
}
} else {
if (length < 25) {
this.setData({
text1: name,
})
} else if (length >= 25 && length < 50) {
this.setData({
text1: name.substring(0, 25),
text2: name.substring(25, 50),
})
} else if (length >= 50 && length < 75) {
this.setData({
text1: name.substring(0, 25),
text2: name.substring(25, 50),
text3: name.substring(50, 75),
})
} else {
this.setData({
text1: name.substring(0, 25),
text2: name.substring(25, 50),
text3: name.substring(50, 75),
text4: name.substring(75, length),
})
}
}
下面绘制图片
上面代码已经提供过这边就不重复粘贴了(上文中的绘制图片.JS页面中的那个Image方法就是绘制图片的代码),通过Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。然后绘制对应的图片,计算线条的位置绘制即可。
稍微讲解下我的思路(为啥我的代码嗨多???):
首先我是稍微适配了下手机型号:
winWidth: winWidth,
winHeight: winWidth * 1.25 + winWidth * 0.16 + winWidth * 0.16 * 0.8 + 100,
oneHeight: winWidth * 1.25,// 风景图的高度
ewmWidth: winWidth * 0.16,//二维码的高度
oneWidth: winWidth * 0.16,//左右两边的空白
twoWidth: winWidth * 0.04,//二维码和边框之间的距离
fontHeight: (winWidth * 0.16 + 22) * 0.5, //字体上下居中
然后我在绘制的时候引用先关宽高,所以代码过于繁琐,如果对适配要求不高的可以删去这些代码,问题不大哦。。。
提示:1.网络图片绘制的时候不需要相对路劲 ‘…/…/’, 而绘制本地图片需要使用的哦。2.绘制高清图片,只要在调用wx.canvasToTempFilePath的时候将destWidth和destHeight属性设置为屏幕宽高的2-2.5倍,那就可以绘制出高清图片啦
本次canvas的绘制就讲解到这边,不清楚的可以留言哈。