@tomiaa/canvas-graffiti
Version:
166 lines (165 loc) • 5.23 kB
JavaScript
var r = Object.defineProperty;
var h = (s, t, e) => t in s ? r(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
var o = (s, t, e) => (h(s, typeof t != "symbol" ? t + "" : t, e), e);
import * as a from "./utils/index.js";
class l {
constructor(t) {
o(this, "options", {
currentTool: "Marker",
createBufferCanvasStyle: {},
allowType: ["pen", "mouse", "touch"],
allowButton: [0]
});
// canvas 容器
o(this, "el");
// 起点
o(this, "beginPoint", { x: 0, y: 0 });
// 终点
o(this, "endPoint");
// 移动轨迹
o(this, "points", []);
// 工具名
o(this, "currentTool", "Marker");
// 离屏渲染画布
o(this, "bufferCanvas");
// 允许绘图方式
o(this, "allowType");
// 鼠标允许绘图方式
o(this, "allowButton");
Object.assign(this.options, t), typeof this.options.el == "string" ? this.el = document.querySelector(this.options.el) : this.el = this.options.el, this.currentTool = this.options.currentTool, this.allowType = this.options.allowType, this.allowButton = this.options.allowButton, this.init();
}
// color
get color() {
return this.ctx.fillStyle;
}
set color(t) {
this.ctx.strokeStyle = t, this.ctx.fillStyle = t;
}
// 线宽
get lineWidth() {
return this.ctx.lineWidth;
}
set lineWidth(t) {
this.ctx.lineWidth = t;
}
// 当前工具
get tool() {
return a[this.currentTool];
}
set tool(t) {
this.currentTool = t;
}
// 上下文
get ctx() {
return this.el.getContext("2d");
}
// 离屏渲染画布上下文
get bufferCtx() {
var t;
return (t = this.bufferCanvas) == null ? void 0 : t.getContext("2d");
}
/**
* 初始化
*/
init() {
this.pointerdown = this.pointerdown.bind(this), this.pointermove = this.pointermove.bind(this), this.pointerup = this.pointerup.bind(this), this.bindCanvasEventListener();
}
// 绑定事件
bindCanvasEventListener() {
this.el.addEventListener("pointerdown", this.pointerdown);
}
// 解绑事件
removeEventListener(t = ["pointerdown", "pointermove", "pointerup"]) {
t.forEach((e) => {
this.el.removeEventListener(e, this[e]), document.removeEventListener(e, this[e]);
});
}
// 按下
pointerdown(t) {
var e, i;
this.allowType.includes(t.pointerType) && (t.pointerType === "mouse" && !this.allowButton.includes(t.button) || (this.el.style.touchAction = "none", this.beginPoint = { x: t.offsetX, y: t.offsetY }, t.preventDefault(), this.tool.buffer && this.createBufferCanvas(), this.tool && ((i = (e = this.tool) == null ? void 0 : e.pointerdown) == null || i.call(this, t)), this.el.addEventListener("pointermove", this.pointermove), document.addEventListener("pointerup", this.pointerup)));
}
// 移动
pointermove(t) {
var e, i;
t.preventDefault(), this.allowType.includes(t.pointerType) && ((i = (e = this.tool) == null ? void 0 : e.pointermove) == null || i.call(this, t));
}
// 抬起
pointerup(t) {
var e, i, n;
this.el.style.touchAction = "auto", this.allowType.includes(t.pointerType) && (~~this.beginPoint.x === ~~t.offsetX && ~~this.beginPoint.y === ~~t.offsetY && (this.ctx.beginPath(), this.ctx.arc(t.offsetX, t.offsetY, 1, 0, 2 * Math.PI, !1), this.ctx.stroke(), this.ctx.fill()), t.preventDefault(), (i = (e = this.tool) == null ? void 0 : e.pointerup) == null || i.call(this, t), this.removeEventListener(["pointermove", "pointerup"]), this.beginPoint = { x: 0, y: 0 }, this.endPoint = void 0, this.points = [], (n = this.bufferCanvas) == null || n.remove());
}
// 清除画布
clear() {
this.ctx.clearRect(0, 0, this.el.width, this.el.height);
}
// 创建离屏渲染画布
createBufferCanvas() {
const t = this.el.cloneNode();
t.style.zIndex += 100, t.style.pointerEvents = "none", t.style.position = "absolute", t.style.left = this.el.offsetLeft + "px", t.style.top = this.el.offsetTop + "px";
const e = this.options.createBufferCanvasStyle;
if (e)
for (const i in e)
t.setAttribute(i, e[i]);
this.el.parentElement.appendChild(t), this.bufferCanvas = t, this.bufferCtx.fillStyle = this.color, this.bufferCtx.strokeStyle = this.color, this.bufferCtx.lineWidth = this.lineWidth;
}
// 销毁
destroy(t) {
this.removeEventListener(), t && this.el.remove();
}
// 获取 canvas.toDataURL
toDataURL(t = "image/png", e = 0.92) {
return this.el.toDataURL(t, e);
}
// 获取 canvas 的图片文件
toPicFile(t = "0.png") {
return new Promise((e) => {
this.el.toBlob((i) => {
i && e(new File([i], t));
});
});
}
}
o(l, "toolList", [
{
label: "记号笔",
value: "Marker"
},
{
label: "直线",
value: "Line"
},
{
label: "空心矩形",
value: "Rect"
},
{
label: "实心矩形",
value: "FillRect"
},
{
label: "空心圆",
value: "Arc"
},
{
label: "实心圆",
value: "FillArc"
}
]), o(l, "allowTypes", [
{
label: "鼠标",
value: "mouse"
},
{
label: "手写",
value: "touch"
},
{
label: "笔写",
value: "pen"
}
]);
export {
l as CanvasGraffiti,
l as default
};