Апплетыcanvas
Создавайте плакаты - устраните искажение изображений на экране и устраните невозможность использования изображений из внешней сети.
исходный код внизу
Окончательные результаты
Элемент холста (холст) используется для рисования графики на странице. Холст - это прямоугольная область, вы можете контролировать каждый из пикселей. Рисование холста имеет множество путей, прямоугольников, кругов, персонажей, изображений и многое другое.
Уведомление
Следует отметить, что текущее полотно можно просто разделить на два типа. Один — это холст на традиционной веб-странице, а другой — это холст в апплете. Функции обоих абсолютно одинаковы. просто стиль этикетки, иapi
Только немного другой. В настоящее время мы в основном объясняем холст в апплете.
Сценарии применения холста
-
рекламировать
-
синтез изображений Обычное дело в небольших программах
-
нажмите на меня, чтобы ускорить
-
красный флаг аватара
-
плакат календарь
-
разное
-
Простой опыт
Нарисуем прямую линию
В холсте этапы рисования прямой линии разбиваются на следующие этапы:
- написать теги
- получить экземпляр холста
- установить отправную точку
- конечная точка соединения
- Линии (также называемые штрихами)
- цвет
написать теги
Ширина и высота по умолчанию 300px * 150px.
В отличие от обычных тегов, атрибут должен быть указан
canvas-id
, используемый для получения этого объекта в js (не объект dom!!!)
<canvas canvas-id="firstCanvas"></canvas>
получить экземпляр холста
Получить по идентификатору холста
Этот экземпляр не является элементом dom, его можно понимать как другой объект, такой как Math Date String и т. д.
index.js
Page({
onLoad() {
// 1 获取画布上下文对象
const context = wx.createCanvasContext("firstCanvas");
console.log(context);
}
})
Начальная точка
На холсте есть система координат, как показано ниже:
Координаты, о которых мы говорим в холсте, относятся к внутренним координатам холста.
установить отправную точку
// 定起点
context.moveTo(10, 10);
конечная точка
// 定终点
context.lineTo(300,150);
соединять
// 连线
context.stroke();
цвет
// 上色
context.draw();
полный код
index.wxml
<!-- 1 写标签 -->
<canvas canvas-id="firstCanvas"></canvas>
index.js
Page({
onLoad() {
// 2 获取画布上下文对象
const context = wx.createCanvasContext("firstCanvas");
// 3 定起点
context.moveTo(10, 10);
// 4 定终点
context.lineTo(300,150);
// 5 连线
context.stroke();
// 6 上色
context.draw();
}
})
Эффект
Встроенная другая обычная графика
Холст также инкапсулирует метод рисования обычной графики, такой как:
нарисовать прямоугольник
CanvasContext.strokeRect(number x, number y, number width, number height)
CanvasContext.strokeRect (рисовать по X холста, рисовать по Y холста, насколько широк рисунок, насколько высок рисунок)
// 1 获取画布上下文对象
const context = wx.createCanvasContext("firstCanvas");
// 2 调用canvas内置的画“矩形”的方法
context.strokeRect(10, 10, 100, 100);
// 3 上色
context.draw();
Эффект
нарисовать дугу
CanvasContext.arc(number x, number y, number r, number sAngle, number eAngle, boolean counterclockwise)
CanvasContext.arc (абсцисса центра окружности X, ордината центра окружности Y, длина радиуса, начальный радиан, конечный радиан, рисовать ли наоборот)
код
drawArc() {
// 1 获取画布上下文对象
const context = wx.createCanvasContext("firstCanvas");
// context.arc(圆心的横坐标X,圆心的纵坐标Y, 半径的长度, 开始的弧度, 结束的弧度);
// 2 调用内置的画 “圆弧” 的方法
context.arc(100, 100, 100, this.angleToArc(0), this.angleToArc(90));
// 3 开始描边
context.stroke();
// 4 上色
context.draw();
},
/**
* 将角度转为弧度
* @param {number} angle 角度
*/
angleToArc(angle) {
return angle * Math.PI / 180;
}
Эффект
нарисовать сплошной прямоугольник
CanvasContext.fillRect(number x, number y, number width, number height)
// 1 获取画布上下文对象
const context = wx.createCanvasContext("firstCanvas");
// 2 调用canvas内置的 画填充 “矩形”的方法
context.fillRect(10, 10, 100, 100);
// 3 上色
context.draw();
Эффект
рисовать текст
CanvasContext.strokeText(string text, number x, number y, number maxWidth)
CanvasContext.strokeText (текст для рисования, координата по оси x начальной точки текста, число y, максимальная ширина для рисования, необязательно)
код
// 1 获取画布上下文对象
const context = wx.createCanvasContext("firstCanvas");
// 2 画 “文字”
context.strokeText("hello world", 100, 100);
// 3 上色
context.draw();
Эффект
задать стиль
После приведенной выше демонстрации мы также обнаружили, что цвет линии всегда был черным, чего определенно недостаточно, чтобы удовлетворить наше бьющееся сердце. Теперь давайте узнаем об API, связанном с настройкой стиля линии холста.
- установить цвет линии
- установить толщину линии
- установить цвет заливки
- установить размер текста
установить цвет линии
**Особое внимание**,setStrokeStyle
Это функция.После версии 1.9.90 обслуживание остановлено, и для ее изменения используются следующие методы.
-
Устарело и не рекомендуетсяCanvasContext.setStrokeStyle("red")
-
CanvasContext.strokeStyle="red";
правильный
код
const context = wx.createCanvasContext("firstCanvas");
context.moveTo(10, 10);
context.lineTo(300, 150);
// 5 修改颜色 需要在stroke之前修改
context.strokeStyle = "red";
context.stroke();
context.draw();
Эффект
установить толщину линии
**Особое внимание**,setLineWidth
Это функция.После версии 1.9.90 обслуживание остановлено, и для ее изменения используются следующие методы.
-
Устарело и не рекомендуетсяCanvasContext.setLineWidth(20)
-
CanvasContext.lineWidth=20;
правильный
код
const context = wx.createCanvasContext("firstCanvas");
context.moveTo(10, 10);
context.lineTo(300, 150);
// 设置线条宽度
context.lineWidth = 20;
context.stroke();
context.draw();
Эффект
установить цвет заливки
**Особое внимание**,setFillStyle
Это функция.После версии 1.9.90 обслуживание остановлено, и для ее изменения используются следующие методы.
-
Устарело и не рекомендуетсяCanvasContext.setFillStyle("red")
-
CanvasContext.fillStyle="red";
правильный
код
const context = wx.createCanvasContext("firstCanvas");
// 设置填充颜色
context.fillStyle = "red";
context.fillRect(10, 10, 100, 100);
context.draw();
Эффект
установить размер текста
**Особое внимание**,setFontSize
Это функция.После версии 1.9.90 обслуживание остановлено, и для ее изменения используются следующие методы.
-
Устарело и не рекомендуетсяCanvasContext.setFontSize("20")
-
CanvasContext.font="sans-serif";
правильный -
font
Свойства текущего стиля шрифта. соответствоватьСинтаксис шрифта CSSСтрока DOMString, по крайней мере, должна указать размер шрифта и имя семейства шрифтов. По умолчанию используется шрифт без засечек размером 10 пикселей.
код
const context = wx.createCanvasContext("firstCanvas");
// 必须要同时提供 字号 和 字体
context.font="10px sans-serif";
context.strokeText("10px", 10, 10);
// 必须要同时提供 字号 和 字体
context.font="50px sans-serif";
context.strokeText("50px", 50, 100);
// 必须要同时提供 字号 和 字体
context.font="80px sans-serif";
context.strokeText("80px", 80, 180);
context.draw();
Эффект
Передовой
В этом разделе мы в основном объясним несколько более сложные функции. Для достижения следующих функций
Но сначала нужно провести техническую подготовку.
Основные используемые API:
- Получить информацию о системе
- Выберите изображение альбома
- Получить информацию о сетевом изображении
- холст рисует картину на холсте
- Сохраните холст как изображение
- Загрузить фотографии на локальный
Базовый API
Для достижения вышеуказанного случая требуется следующий API
Получить информацию о системе
Получите размер экрана, соотношение пикселей устройства и т. д.
код
wx.getSystemInfo({
success (res) {
console.log(res.model)
console.log(res.pixelRatio)
console.log(res.windowWidth)
console.log(res.windowHeight)
console.log(res.language)
console.log(res.version)
console.log(res.platform)
}
})
Выберите изображение альбома
Выберите картинку из локального альбома или сделайте снимок камерой
код
wx.chooseImage({
count: 1,// 最多可以选择的图片张数
sizeType: ['original', 'compressed'],// 所选的图片的尺寸
sourceType: ['album', 'camera'],// 选择图片的来源
success (res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFilePaths
}
})
код
wx.getSystemInfo({
success (res) {
console.log(res.model)
console.log(res.pixelRatio)
console.log(res.windowWidth)
console.log(res.windowHeight)
console.log(res.language)
console.log(res.version)
console.log(res.platform)
}
})
Получить информацию о сетевом изображении
Получить информацию о картинке. Сетевые образы должны быть настроены с именем домена загрузки, прежде чем они смогут вступить в силу.
Canvas предоставляет функцию рисования изображений на холсте, но требует, чтобы предоставленные изображения были изображениями из внешней сети.
Таким образом, сетевое изображение может быть преобразовано этим методом в локальное изображение, и в то же время может быть возвращена информация об изображении.
код
wx.getImageInfo({
src: 'cloud://c-73e071.632d-c-73e071/92637.jpg',
success (res) {
console.log(res.width)
console.log(res.height)
}
})
нарисовать изображение на холсте
Вы не можете использовать локальные изображения, вы должны сначала использовать фотографии из внешней сети
wx.getImageInfo
скачать на локальный
Существует три варианта написания:
- drawImage(imageResource, dx, dy)
- drawImage(imageResource, dx, dy, dWidth, dHeight)
- drawImage(imageResource, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
- Описание drawImage (путь к изображению, x исходного изображения, y исходного изображения, ширина исходного изображения, высота исходного изображения, x холста, y холста, ширина рисунка, высота рисунок)
код
context.drawImage('xxxx.jpg', 0, 0,100, 100);
Сохраните холст как изображение
существуетdraw()Этот метод вызывается в обратном вызове, чтобы убедиться, что изображение успешно экспортировано.
код
wx.canvasToTempFilePath({
x: 100,
y: 200,
width: 50,
height: 50,
destWidth: 100,
destHeight: 100,
canvasId: 'myCanvas',
success(res) {
console.log(res.tempFilePath)
}
})
Загрузить фотографии на локальный
Сохранить картинку в системный альбом
код
wx.saveImageToPhotosAlbum({
success(res) { }
})
Реализация кейса
На самом деле для реализации одного и того же случая самое хлопотное не вызовы этих API, а как по разным картинкам синтезировать разные картинки.Соответствующийизнеразмытые картинки;
Почему соотношение правильное?
Потому что в холсте поддерживается толькоpx
единиц, затем с помощьюjavascript
чтобы нарисовать картину, ее не существуетrpx
,vw
,%
Это относительные единицы. Его можно рассчитать только вручную. Например, на холстеНарисовать прямоугольник в половину ширины экрана и в половину высоты экрана?
почему не расплывчато
Причина проблемы в том, что все экраны мобильных телефонов являются экранами высокой четкости. Конкретные причины см.Связь
Если мы хотим сгенерировать изображение размером 100 пикселей * 100 пикселей, нам нужно установить размер холста наwidth = 图片的宽度 * 设备像素比
height = 图片的高度 * 设备像素比
Каталог файлов
-
index
титульная страница -
result
страница с составными изображениями
Домашний индекс
index
pages/index/index.wxml
<!-- 用来显示 被选择的图片的 -->
<image mode="widthFix" src="{{src}}"></image>
<!-- 选择相册图片 -->
<button bindtap="handleTap">选择图片</button>
<!-- 跳转到 结果页面 -->
<button bindtap="handleCreateFlag">生成小红旗</button>
pages/index/index.js
В основном реализовать 3 функции
- Нажмите «Выбрать изображение», чтобы распечатать выбранное изображение на странице.
- Выбранное изображение будет отображаться на странице
- Нажмите «Создать красный флаг» и перейти на страницу результатов (завершено на странице результата)
Page({
data: {
src: ""
},
// 选择图片
handleTap() {
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (result) => {
this.setData({
src: result.tempFilePaths[0]
})
// 保存图片路径
wx.setStorageSync('src', this.data.src);
}
});
},
// 生成红旗
handleCreateFlag() {
// 跳转到结果页面
wx.navigateTo({
url: '/pages/result/index'
});
}
})
результат страницы результатов
result
result/index.wxml
3 вкладки
- тег холста, скройте его, расположив
- тег изображения, используемый для отображения составного изображения
- тег кнопки, используемый для загрузки изображения по клику
<!-- canvas 标签-->
<canvas class="cas" style="width:{{canvasWidth}};height:{{canvasHeight}};" canvas-id="firstCanvas"></canvas>
<!-- 用来显示 合成成功的图片 -->
<image class="res_image" mode="widthFix" src="{{resSrc}}"></image>
<!-- 点击下载图片 -->
<button bindtap="handleSave">下载图片</button>
result/index.wxss
два стиля
- скрыть холст (потому что онРодной компонент, значит его уровень выше общей метки (позиционирование + zindex не решает))
- Установите стиль метки изображения
page {
overflow-x: hidden;
overflow-y: auto;
width: 100vw;
height: 100vh;
}
.cas {
position: absolute;
top: 1000vw;
left: 1000vh;
z-index: -1;
opacity: 0;
}
.res_image {
width: 100%;
display: block;
}
result/index.js
Склонен к ошибкам:
- Для изображений из внешней сети необходимо сначала добавить сервер изображений в белый список (иначе реальная отладка машины не удастся)
- Ширина и высота холста не задаются динамически (см. строки 29 и 31).
import regeneratorRuntime from '../../lib/runtime/runtime';
import { getImageInfo, canvasToTempFilePath, saveImageToPhotosAlbum } from "../../wxAsync/index.js";
Page({
data: {
// 默认的canvas的宽度
canvasWidth: 1,
// 默认的canvas高度
canvasHeight: 1,
// 最终生成的图片路径
resSrc: ""
},
// 全局变量
saveImgSrc: "",
async onLoad() {
// 红旗图片
const flagSrc = "https://632d-c-73e071-1252056196.tcb.qcloud.la/3434.jpg?sign=a4f1c2106d1e61551829c2f99820c0ba&t=1569678566";
// const baseSrc = "https://632d-c-73e071-1252056196.tcb.qcloud.la/92637.jpg?sign=8952d1eaa69a35510418fe25dc25d6c5&t=1569678606";
// 上个页面选择的图片路径 柯南图片
const baseSrc = wx.getStorageSync("src");
// 设备像素比
const { pixelRatio } = wx.getSystemInfoSync();
// 获取 画布实例
const context = wx.createCanvasContext('firstCanvas');
console.log(context);
// 下载到本地的 柯南图片
const baseImg = await getImageInfo(baseSrc);
// 下载到本地的 红旗图片
const flagImg = await getImageInfo(flagSrc);
// 将canvas的宽度设置中 图片的宽度
const canvasWidth = baseImg.width + "px";
// 将canvas的宽度设置中 图片的高度
const canvasHeight = baseImg.height + "px";
// setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。
// 因此需要将 描绘 图片的步骤写在回调中,否则 真机调试有bug!
this.setData({ canvasWidth, canvasHeight }, () => {
// 如果个别机型出现图片失败错误,可以加上定时器。
setTimeout(() => {
// 先将柯南 描绘到画布上
context.drawImage(baseImg.path, 0, 0, baseImg.width, baseImg.height);
// 把红旗 描绘到画布上
context.drawImage(flagImg.path, baseImg.width - (pixelRatio * 50), baseImg.height - (pixelRatio * 50), (pixelRatio * 50), (pixelRatio * 50));
context.draw(true, async () => {
// 将 画布生成 成图片
const res1 = await canvasToTempFilePath({
canvasId: "firstCanvas"
});
// 让图片显示 合成后的效果
this.setData({ resSrc: res1.tempFilePath })
// 保存起来,当点击保存图片时调用
this.saveImgSrc = res1.tempFilePath;
});
}, 100);
});
},
// 点击保存图片
handleSave() {
saveImageToPhotosAlbum(this.saveImgSrc);
}
})
гитхаб-адрес
https://github.com/itcastWsy/AppletPoster.git