# Use of wechat applet Canvas

Posted by patrick99e99 on Mon, 16 Dec 2019 17:02:07 +0100

```    This issue introduces how Canvas draws pictures, including how to draw high-definition pictures, use network pictures / local pictures, date conversion (lunar and solar calendar / week conversion), picture adaptation mobile phone model, etc.
```

## Layout introduction

There are four parts here. The picture above shows the QR Code & date of the public number in the middle. Some texts and company logo and name are shown below

## wxml page

````<canvas
canvas-id="shareImg"       style="width:{{winWidth}}px;  height:{{winHeight}}px;  background:#FFF;"
bindlongtap="createImage">
</canvas> `
```

## Date conversion GregorianCalendar.JS page

```/*
* Lunar data sheet
*
* The lunar calendar is divided into big and small months, 30 days in the big month and 29 days in the small month, but which month is the big month and which month is the small month in the year is irregular.
* There are four leap years in the lunar calendar every ten years, but it is uncertain which year is a leap year.
* In leap month, which leap month is big month and which is small month are uncertain.
*
* There are 20 lines in total, with 10 data in each line. Each data represents a year, starting from 1900.1.31 of the Gregorian calendar, which is the beginning of the first data year, that is, 1900.1.31 of the Gregorian calendar = 0.1.1 of the lunar calendar.
* 200 Data can be used to deduce the lunar calendar of 200 years, so at present, the maximum can only be calculated to 2100
*
* For each data item, 5 hex digits = 20 binary digits
* The first four digits, i.e. 0, make sense when the year is a leap year. It represents the size month of the leap month of the year. If it is 1, it will be leap big month, if it is 0, it will be leap small month.
* The middle 12 digits, i.e. 4bd, represent one month each. If it is 1, it means big month; if it is 0, it means small month.
* The last four digits, namely 8, represent the leap month of the year, and 0 means no leap. The first 4 digits should be used with the last 4 digits.
*/
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; // Minimum year that can be calculated
const maxYear = 2100; // Maximum year that can be calculated

// The number of days per month in the Gregorian calendar, plus 1 day in February in leap year
const solarMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

// Another name of lunar month
const monthName = new Array('the first month of the lunar year', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'the eleventh month of the lunar Calendar', 'December');

// twenty-four solar terms
const solarTerm = new Array(
'Slight cold', 'Great cold', 'Primula', 'rain', 'The Waking of Insects', 'Vernal equinox',
'Qingming', 'grain rain', 'Lixia', 'Grain full', 'Grain in ear', 'The summer solstice',
'Sunstroke', 'Great heat', 'Beginning of autumn', 'Heat stroke', 'Bailu', 'The autumnal equinox',
'Cold dew', 'First Frost', 'Primordial winter', 'Light snow', 'Heavy snow', 'Winter solstice'
);

// Correlation coefficient of 20 solar terms
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);

/**
* Check that the year is entered correctly
* @param year int Particular year
*/
function _checkYear(year) {
if (year < minYear) {
throw new RangeError('Year cannot be less than' + minYear + 'year');
} else if (year > maxYear) {
throw new RangeError('Year cannot be greater than' + maxYear + 'year');
}
return true;
}

/**
* Check whether the month is entered correctly
* @param month int Month
*/
function _checkMonth(month) {
if (month < 1) {
throw new RangeError('Month cannot be less than 1');
} else if (month > 12) {
throw new RangeError('Month cannot be greater than 12');
}
return true;
}

/**
* Check whether the date is entered correctly
* @param day int date
*/
function _checkDay(day) {
if (day < 1) {
throw new RangeError('Date cannot be less than 1');
} else if (day > 31) {
throw new RangeError('Date cannot be greater than 31');
}
return true;
}

/**
* Returns which month in the lunar year is a leap month, and returns 0 if there is no leap month
* @param year int Particular year
*/
function getLunarLeapMonth(year) {
if (_checkYear(year)) {
return lunarInfo[year - minYear] & 0xf;  // The last four digits represent the leap month of the year. If it is 0, there is no leap month this year
}
}

/**
* Returns the number of days in the leap month of the lunar year (0 if there is no leap month)
* @param year int Particular year
*/
function getLeapMonthDaysCount(year) {
if (getLunarLeapMonth(year)) {
return lunarInfo[year - minYear] & 0x10000 ? 30 : 29; // The first four digits, i.e. 0, only make sense when the year is a leap year, which represents the size of the leap month of the year
}
return 0;
}

/**
* Returns the total number of days in the lunar year
* @param year int Particular year
*/
function getLunarYearDaysCount(year) {
if (_checkYear(year)) {
let sum = 348;  // 29 days * 12 months = 348 days
for (let i = 0x8000; i > 0x8; i >>= 1) {
sum += (lunarInfo[year - minYear] & i ? 1 : 0);
}
return sum + getLeapMonthDaysCount(year);
}
}

/**
* Return the days of month in the year of the lunar calendar
* @param year int Particular year
* @param month int January to December
*/
function getLunarYearMonthDaysCount(year, month) {
if (_checkYear(year) && _checkMonth(month)) {
return lunarInfo[year - minYear] & (0x10000 >> month) ? 30 : 29;
}
}

/**
* Chinese string of lunar date
* @param day int date
*/
function getLunarDayString(day) {
if (_checkDay(day)) {
const nStr1 = new Array('day', 'One', 'Two', 'Three', 'Four', 'Five', 'six', 'Seven', 'Eight', 'Nine', 'Ten');
const nStr2 = new Array('first', 'Ten', 'Twenty', 'Thirty');
let str = '';
switch (day) {
case 10:
str = 'tenth day of a lunar month';
break;
case 20:
str = 'twenty';
break;
case 30:
str = 'Thirty';
break;
default:
str = nStr2[Math.floor(day / 10)];
str += nStr1[day % 10];
break;
}
return str;
}
}

/**
* How many days does the nth solar term return to a certain year (from 0 Xiaohan)
* @param year int Particular year
* @param n Solar term No. 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();
}
}

/**
* Date of lunar calendar to date of lunar calendar
* @param year int Particular year
* @param month int January to December
* @param day int Date 1-31
*/
function solarToLunar(year, month, day) {
if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
const baseDate = new Date(minYear, 0, 31);      // Base date: January 31, 1900
const objDate = new Date(year, month - 1, day); // target date
let offset = (objDate - baseDate) / 86400000;   // Offset days 60 * 60 * 24 * 1000 = 86400000, milliseconds of one day
let monCycle = 14;
let temp = 0;
let i = 0;

for (i = minYear; i < maxYear && offset > 0; i++) {
temp = getLunarYearDaysCount(i);             // Total number of days in lunar year
if (offset - temp < 0) {
break;
} else {
offset -= temp;
}
monCycle += 12;
}

const lunarYear = i;                             // Lunar year
const leap = getLunarLeapMonth(lunarYear);       // Which month is the leap month of the year
const isLeapYear = leap > 0 ? true : false;      // Is there a leap month in the current year
let isLeapMonth = false;                         // Is the current lunar month a leap month
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;        // Lunar month
const lunarDay = offset + 1; // Lunar calendar date

let monthStr = '';
if (isLeapYear) {
if (lunarMonth < leap) {
monthStr = monthName[lunarMonth - 1];
} else if (lunarMonth == leap) {
monthStr = 'Intercalation' + monthName[lunarMonth - 1];
} else {
monthStr = monthName[lunarMonth - 2];
}
} else {
monthStr = monthName[lunarMonth - 1];
}

return {
year: lunarYear,                    // Lunar year
month: lunarMonth,                  // Lunar month
day: lunarDay,                      // Lunar calendar date
isLeap: isLeapMonth,                // Leap month or not
monthStr: monthStr,                 // Month string
dayStr: getLunarDayString(lunarDay) // Date string
};
}
}

/**
* Days of a month in the Gregorian calendar
* @param year int Particular year
* @param month int January to December
*/
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];
}
}
}

/**
* Get the specified date is the day of the Gregorian year
* @param year int Particular year
* @param month int January to December
* @param day int date
*/
function getSolarDayNumber(year, month, day) {
if (_checkYear(year) && _checkMonth(month) && _checkDay(day)) {
const date = new Date(year, month - 1, day);
const d = date.getDate(); // Day of the month
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;
}
}

/**
* Calculate whether the specified date belongs to 24 solar terms
* @param year int Particular year
* @param month int January to December
* @param day int Date 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,          // Returns which month in the lunar year is a leap month, and returns 0 if there is no leap month
getLeapMonthDaysCount,      // Returns the number of days in the leap month of the lunar year (0 if there is no leap month)
getLunarYearDaysCount,      // Returns the total number of days in the lunar year
getLunarYearMonthDaysCount, // Return the days of month in the year of the lunar calendar
getLunarDayString,          // Chinese string of lunar date
getLunarTermDay,            // Returns the nth solar term of a year as the day
getSolarMonthDaysCount,     // How many days are there in a month
getSolarDayNumber,          // Get the specified date is the day of the Gregorian year
getLunar24Days,             // Calculate whether the specified date belongs to 24 solar terms
solarToLunar,               // Date of lunar calendar to date of lunar calendar
getDates: getDates,         // Day of week of date conversion
}

//Get the days after the current time and the corresponding week
function getDates(days,todate = getCurrentMonthFirst) {//The default parameter of todate is the current date. You can pass in the corresponding time
// var dateArry = [];
// for (var i = 0; i < days; i++) {
var dateObj = dateLater(days, 0);
//   dateArry.push(dateObj)
// }
return dateObj;
}
/**
* Days after transfer in time
* param: Incoming time: dates:"2018-04-02",later: how many days later
*/
function dateLater(dates,later) {
let dateObj = {};
let show_day = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
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;
}

//Get current time
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;
}

```

Use to get the data you want (such as lunar calendar, gas, lunar month, etc.)
Easy to use: just introduce js and call it. For example: I want to use the solar to lunar calendar:
Introduce js: const gregoriancalendar = require ('.. / utils / gregoriancalendar. js');
Call related fuction: GregorianCalendar.solarToLunar(year, month, day)

The third point is similar to the text drawing without too much introduction

## Text xljt.js code page

```var xljt = [{
"name": "When a person is around us, we will not know when we are apart from him. Just like when we are living, we don't know how to die.",
"id": "1"
}, {
"name": "If there is only a moment of happiness, a short period of bad luck, we have no way to know what will happen in the next moment.",
"id": "2"
}, {
"name": "Everyone has the right to choose their own way of life. But in other words,People are being held again,Never had the right to decide your own life.",
"id": "3"
}, {
"name": "The greatest courage in the world is not to fear death, but to live a strong life and face the pressure and test brought by life bravely!",
"id": "4"
}, {
"name": "Through continuous grinding, the gravel will become a bright and mellow pearl and give off the luster loved by the world.",
"id": "5"
}, {
"name": "Too many times we didn't grasp, too many opportunities we missed again and again. With the sigh of the past... It's better to cherish everything.",
"id": "6"
}, {
"name": "There are many choices in life,Be careful at every step. One choice is not everything,Make a choice and don't regret it. As long as we persevere in our struggle,Victory is ahead.",
"id": "7"
}, {
"name": "Strive to prove yourself to others and the world, and once you have made achievements, you will understand that people don't need to prove anything to others, as long as you can surpass yourself.",
"id": "8"
}, {
"name": "Going towards a certain goal is "ambition", never stop "Qi" in the middle of a single breath, and the combination of the two is "ambition". The success or failure of any career depends on it.",
"id": "9"
}, {
"name": "You can forget the failure, but not the lesson;You can forget the hardships, but not the hardships;You can forget the scars,But don't forget the shame.",
"id": "10"
}, {
"name": "Things are dialectical. When you get something, you lose something else;When you lose something, you get something.​",
"id": "11"
}, {
"name": "Put aside the laziness, put away the discouraged words, put forward the enthusiasm and put away the hypocritical heart. All you want, you have to rely on your own efforts to get.",
"id": "12"
}, {

"name": "We live for ourselves,Don't immerse yourself in the language of others,Crouching in the shadow of the world. If you stop,Someone is laughing;If you break free,The spring flowers are blooming ahead.",
"id": "13"
}, {
"name": "The green creature growing between the cracks,It gives people encouragement and strength. Let the wind, the frost, the snow and the rain,Still face it! This is tenacity,stubborn,It's the brilliance of life!",
"id": "14"
}, {
"name": "Give yourself confidence,To embrace the world,Let's live a full day,Let tomorrow be full of hope;Beauty in time,Is from the bottom of my heart love and vision and yearning for the future.",
"id": "15"
}, {
"name": "The more stories are told, the more quiet and simple they are, and the more superficial and thin they are, the more impetuous and restless they are. All the surprises and good luck in the world are equal to your character multiplied by your efforts.",
"id": "16"
}, {
"name": "Thoughts will become your words;Words will become your actions;Action will become your habit;Habit will become your character;Character will become your destiny.",
"id": "17"
}, {
"name": "You don't have to envy what others have, as long as you work hard, you will have it; you don't have to show off what you have, because others are struggling, and they will have it.",
"id": "18"
}, {
"name": "In fact, it's when we lose that we know we have it. But do we notice that when something comes, we have missed it.",
"id": "19"
}, {
"name": "I like to spend time here. I like the feeling that time flows away unconsciously. I said I live too fast. It seems that we are going to live our whole life in a short time.",
"id": "20"
}, {
"name": "Healthy is beautiful, suitable is the best, new is charming, ordinary is great, tough is long, real is eternal.",
"id": "21"
}, {
"name": "Learn to adjust yourself and rise up from the misfortune and disappointment as soon as possible, so that you can be more proud of your success. Even if it's a failure, it's worth remembering.",
"id": "22"
}, {
"name": "When love has been gradually irresistible fade, who will care about once loved by a sad love song hurt can not move? Who will stand in the same place and never leave?",
"id": "23"
},
{
"name": "The road of life is not smooth. It's very important to face it calmly. It's easy to talk and laugh. It's hard to overcome difficulties. It's not easy to run happily and move forward forever. It turns out to be a smile. I hope you can be calm, work hard and wait for success.",
"id": "24"
}, {
"name": "Only with vision can one have realm, only with strength can one have charm, only with ideas can one have a way out, only with actions can one have status. Politics comes from Zhenglai, wisdom from zhilai, wealth from Caicai, position from Weilai!",
"id": "25"
}, {
"name": "The most common courage is to be honest and upright in daily life, be able to resist temptation, dare to tell the truth, and show the true side of yourself, instead of hypocrisy.",
"id": "26"
}, {
"name": "Firmness of purpose is one of the most necessary sources of strength in character, and also one of the sharp weapons of success. Without it, genius would be in vain in the path of uncertainty.",
"id": "27"
}, {
"name": "If you lose the sun, you still have the light of stars; if you lose money, you will get friendship; when life leaves you, you have the kiss of the earth.",
"id": "28"
}, {
"name": "The key to happiness is not to find a perfect person, but to find anyone, and then work together with him to build a perfect relationship.",
"id": "29"
}, {
"name": "As long as you think it's right, do it. Don't care what others think. Even if it's wrong, at least you have done it to prove that you have tried.",
"id": "30"
}, {
"name": "When you can't jump from the first floor to the third floor,Don't forget to take the stairs. Remember that great success is often not achieved overnight,You have to learn to break down your goals,Step by step.",
"id": "31"
},
]
module.exports = {
xljt
}
```

Use: const xljt = require ('.. / utils / xljt. JS');
Reference: var name = xljt.xljt[day].name;

## util.js code page

```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
}

```

## Draw picture.JS page

```
// Import configuration

const GregorianCalendar = require('../../utils/GregorianCalendar.js');

const util = require('../../utils/util.js');
const xljt = require('../../utils/xljt.js');
// Show busy tips
var showBusy = text => wx.showToast({
title: text,
icon: 'loading',
duration: 10000
});

Page({

/**
* Initial data of the page
*/
data: {
url: '',
winWidth: 0,
winHeight: 0,
oneHeight: 0,// Height of landscape
ewmWidth: 0,//Height of QR code

oneWidth: 0,//Left and right margins
twoWidth: 0,//Distance between QR code and border
fontHeight: 0,
text1: '',
text2: '',
text3: '',
text4: ''
},

/**
* Life cycle function -- listening to page loading
*/
onLoad: function (options) {

wx.showLoading({
title: 'Picture loading...',
});
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,// Height of landscape
ewmWidth: winWidth * 0.16,//Height of QR code
oneWidth: winWidth * 0.16,//Left and right margins
twoWidth: winWidth * 0.04,//Distance between QR code and border
fontHeight: (winWidth * 0.16 + 22) * 0.5, //Center font up and down
})
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("Solar to lunar:", GregorianCalendar.solarToLunar(year, month, day));
console.log("Zhou Ji", 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)
},
//Draw picture
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')

//It is mainly to calculate the location of each picture and text
ctx.drawImage('../../' + res[2].path, 0, 0, that.data.winWidth, that.data.winHeight)
//Note that network pictures do not need to add.. /.. /, local needs
//  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')

//Two lines above
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)
//Two lines below
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)
//Two lines on the left
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)
//Two lines on the right
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();

})

},
//Generate picture
createImage: function () {
var that = this
wx.showLoading({
title: 'Trying to generate...'
})
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) {
//No permission obtained
wx.openSetting({
success: function (data) {
if (data.authSetting["scope.writePhotosAlbum"] == true) {
wx.saveImageToPhotosAlbum({
filePath: that.data.prurl,
success(res) {
console.log("Saved successfully:", res);
wx.showModal({
content: 'The picture has been saved to the album. Let's have a quick sun exposure~',
showCancel: false,
confirmText: 'Well',
confirmColor: '#333',
success: function (res) {
if (res.confirm) {
console.log('User click OK');
/* The hidden */
that.setData({
hidden: true
})
}
}
})
}
})

} else {
console.log("Deny authorization");
}

},

})
} else {
wx.saveImageToPhotosAlbum({
filePath: that.data.prurl,
success(res) {
console.log("Saved successfully:", res);
wx.showModal({
content: 'The picture has been saved to the album. Let's have a quick sun exposure~',
showCancel: false,
confirmText: 'Well',
confirmColor: '#333',
success: function (res) {
if (res.confirm) {
console.log('User click OK');
/* The hidden */
that.setData({
hidden: true
})
}
}
})
}
})
}
}

})

},
fail: function (res) {
console.log(res)
}
})

},

sleep: function (ms) {
return new Promise(resolve => setTimeout(resolve, ms))
},
/**
* Life cycle function -- listen to the completion of the first rendering of the page
*/
onReady: function () {
},

/**
* Life cycle function -- monitor page display
*/
onShow: function () {
},
/**
* Life cycle function -- monitor page hidden
*/
onHide: function () {
},
/**
* Life cycle function -- monitor page unloading
*/
onUnload: function () {
},
/**
* Page related event processing function -- listening to user pull-down action
*/
onPullDownRefresh: function () {
},
/**
* Handling function of page pull bottom event
*/
onReachBottom: function () {
},
})
```

There are too many codes here. Let's break them up and explain:

Adapter code
Get the screen size of mobile phone through the api provided by wechat. It is then assigned to the picture to be drawn (wx.getSystemInfo).
Then plan the size of the picture (4 areas). The note has about the size of 4 parts. No more description.

```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,// Height of landscape
ewmWidth: winWidth * 0.16,//Height of QR code
oneWidth: winWidth * 0.16,//Left and right margins
twoWidth: winWidth * 0.04,//Distance between QR code and border
fontHeight: (winWidth * 0.16 + 22) * 0.5, //Center font up and down
})
```

Note: the third part of text adaptation is temporarily handled by screen width. First, get the length of the whole text, and then process it according to the screen size. Use 330 / 400 as the dividing line. And the second dividing point of the total length of the text. (there is a better solution to leave a message. )

```  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),
})
}
}

```

Draw a picture below
The above code has been provided so that it will not be pasted repeatedly (the Image method in the above page of drawing picture. JS is the code of drawing picture). The Promise.all method is used to package multiple Promise instances into a new Promise instance. Then draw the corresponding picture and calculate the position of the line.
Explain my ideas a little bit (why is my code so much??? ):
First of all, I slightly adapted the following mobile phone models:

```  winWidth: winWidth,
winHeight: winWidth * 1.25 + winWidth * 0.16 + winWidth * 0.16 * 0.8 + 100,
oneHeight: winWidth * 1.25,// Height of landscape
ewmWidth: winWidth * 0.16,//Height of QR code
oneWidth: winWidth * 0.16,//Left and right margins
twoWidth: winWidth * 0.04,//Distance between QR code and border
fontHeight: (winWidth * 0.16 + 22) * 0.5, //Center font up and down
```

Then when I draw, I first turn off the width and height, so the code is too cumbersome. If the adaptation requirements are not high, you can delete these codes, which is not a big problem...
Tips: 1. When drawing network pictures, you don't need relative strength ... /', which is used to draw local pictures. 2. Draw high-definition pictures. As long as the destWidth and destHeight properties are set to 2-2.5 times the screen width and height when wx.canvasToTempFilePath is called, you can draw high-definition pictures
This canvas painting is explained here. If it is unclear, you can leave a message.

Topics: network Mobile less Spring