提交 94f0776e 编写于 作者: D DCloud_LXH

feat: canvas、createCanvasContext、canvasGetImageData、canvasPutImageData、canvasToTempFilePath

上级 eba81dfe
......@@ -4,6 +4,7 @@ export * from './service/base/interceptor'
export * from './service/context/createVideoContext'
export * from './service/context/createMapContext'
export * from './service/context/canvas'
export * from './service/ui/createIntersectionObserver'
export * from './service/ui/createSelectorQuery'
......@@ -13,6 +14,7 @@ export * from './service/ui/tabBar'
export * from './protocols/base/canIUse'
export * from './protocols/context/context'
export * from './protocols/context/canvas'
export * from './protocols/device/makePhoneCall'
export * from './protocols/device/setClipboardData'
......
......@@ -12,6 +12,8 @@ function getInt(name: string, defaultValue?: number) {
const formatWidth = getInt('width')
const formatHeight = getInt('height')
//#region getImageDataOptions
export const API_CANVAS_GET_IMAGE_DATA = 'canvasGetImageData'
export type API_TYPE_CANVAS_GET_IMAGE_DATA = typeof uni.canvasGetImageData
export const CanvasGetImageDataOptions: ApiOptions<API_TYPE_CANVAS_GET_IMAGE_DATA> = {
......@@ -22,7 +24,6 @@ export const CanvasGetImageDataOptions: ApiOptions<API_TYPE_CANVAS_GET_IMAGE_DAT
height: formatHeight,
},
}
export const CanvasGetImageDataProtocol: ApiProtocol<API_TYPE_CANVAS_GET_IMAGE_DATA> = {
canvasId: {
type: String,
......@@ -45,11 +46,12 @@ export const CanvasGetImageDataProtocol: ApiProtocol<API_TYPE_CANVAS_GET_IMAGE_D
required: true,
},
}
//#endregion
//#region putImageData
export const API_CANVAS_PUT_IMAGE_DATA = 'canvasPutImageData'
export type API_TYPE_CANVAS_PUT_IMAGE_DATA = typeof uni.canvasPutImageData
export const CanvasPutImageDataOptions = CanvasGetImageDataOptions
export const CanvasPutImageDataProtocol: ApiProtocol<API_TYPE_CANVAS_PUT_IMAGE_DATA> = /*#__PURE__*/ extend(
{
data: {
......@@ -59,7 +61,9 @@ export const CanvasPutImageDataProtocol: ApiProtocol<API_TYPE_CANVAS_PUT_IMAGE_D
},
CanvasGetImageDataProtocol
)
//#endregion
//#region toTempFilePath
const fileTypes = {
PNG: 'png',
JPG: 'jpg',
......@@ -67,7 +71,6 @@ const fileTypes = {
}
export const API_CANVAS_TO_TEMP_FILE_PATH = 'canvasToTempFilePath'
export type API_TYPE_CANVAS_TO_TEMP_FILE_PATH = typeof uni.canvasToTempFilePath
export const CanvasToTempFilePathOptions: ApiOptions<API_TYPE_CANVAS_TO_TEMP_FILE_PATH> = {
formatArgs: {
x: getInt('x', 0),
......@@ -89,7 +92,6 @@ export const CanvasToTempFilePathOptions: ApiOptions<API_TYPE_CANVAS_TO_TEMP_FIL
},
},
}
export const CanvasToTempFilePathProtocol: ApiProtocol<API_TYPE_CANVAS_TO_TEMP_FILE_PATH> = {
x: Number,
y: Number,
......@@ -104,6 +106,7 @@ export const CanvasToTempFilePathProtocol: ApiProtocol<API_TYPE_CANVAS_TO_TEMP_F
fileType: String,
quality: Number,
}
//#endregion
export const DrawCanvasProtocol: ApiProtocol<any> = {
canvasId: {
......
declare var __WEEX_DEVTOOL__: any
//#region import
import {
API_CREATE_CANVAS_CONTEXT,
CreateCanvasContextProtocol,
} from '../../protocols/context/context'
import {
API_CANVAS_GET_IMAGE_DATA,
API_CANVAS_PUT_IMAGE_DATA,
API_CANVAS_TO_TEMP_FILE_PATH,
CanvasGetImageDataOptions,
CanvasGetImageDataProtocol,
CanvasPutImageDataOptions,
CanvasPutImageDataProtocol,
CanvasToTempFilePathOptions,
CanvasToTempFilePathProtocol,
} from '../../protocols/context/canvas'
import { defineSyncApi, defineAsyncApi } from '../../helpers/api'
import type {
API_TYPE_CREATE_CANVAS_CONTEXT,
API_TYPE_CANVAS_GET_IMAGE_DATA,
API_TYPE_CANVAS_PUT_IMAGE_DATA,
API_TYPE_CANVAS_TO_TEMP_FILE_PATH,
} from '@dcloudio/uni-api'
import { hasOwn } from '@vue/shared'
import {
getCurrentPageId,
createCallbacks,
ServiceJSBridge,
} from '@dcloudio/uni-core'
import { TEMP_PATH } from '@dcloudio/uni-platform'
// import pako from 'pako'
//#endregion
//#region UniServiceJSBridge
const canvasEventCallbacks = createCallbacks('canvasEvent')
ServiceJSBridge.subscribe!(
'onCanvasMethodCallback',
({ callbackId, data }: { callbackId: number | string; data: any }) => {
const callback = canvasEventCallbacks.pop(callbackId)
if (callback) {
callback(data)
}
}
)
function operateCanvas(
canvasId: string,
pageId: number,
type: unknown,
data: any
) {
ServiceJSBridge.publishHandler!(
'canvas.' + canvasId,
{
canvasId,
type,
data,
},
pageId
)
}
//#endregion
//#region methods
var methods1 = ['scale', 'rotate', 'translate', 'setTransform', 'transform']
var methods2 = [
'drawImage',
'fillText',
'fill',
'stroke',
'fillRect',
'strokeRect',
'clearRect',
'strokeText',
]
var methods3 = [
'setFillStyle',
'setTextAlign',
'setStrokeStyle',
'setGlobalAlpha',
'setShadow',
'setFontSize',
'setLineCap',
'setLineJoin',
'setLineWidth',
'setMiterLimit',
'setTextBaseline',
'setLineDash',
]
function measureText(text: string, font: string) {
const canvas = document.createElement('canvas')
const c2d = canvas.getContext('2d')!
c2d.font = font
return c2d.measureText(text).width || 0
}
//#endregion
//#region checkColor
const predefinedColor = {
aliceblue: '#f0f8ff',
antiquewhite: '#faebd7',
aqua: '#00ffff',
aquamarine: '#7fffd4',
azure: '#f0ffff',
beige: '#f5f5dc',
bisque: '#ffe4c4',
black: '#000000',
blanchedalmond: '#ffebcd',
blue: '#0000ff',
blueviolet: '#8a2be2',
brown: '#a52a2a',
burlywood: '#deb887',
cadetblue: '#5f9ea0',
chartreuse: '#7fff00',
chocolate: '#d2691e',
coral: '#ff7f50',
cornflowerblue: '#6495ed',
cornsilk: '#fff8dc',
crimson: '#dc143c',
cyan: '#00ffff',
darkblue: '#00008b',
darkcyan: '#008b8b',
darkgoldenrod: '#b8860b',
darkgray: '#a9a9a9',
darkgrey: '#a9a9a9',
darkgreen: '#006400',
darkkhaki: '#bdb76b',
darkmagenta: '#8b008b',
darkolivegreen: '#556b2f',
darkorange: '#ff8c00',
darkorchid: '#9932cc',
darkred: '#8b0000',
darksalmon: '#e9967a',
darkseagreen: '#8fbc8f',
darkslateblue: '#483d8b',
darkslategray: '#2f4f4f',
darkslategrey: '#2f4f4f',
darkturquoise: '#00ced1',
darkviolet: '#9400d3',
deeppink: '#ff1493',
deepskyblue: '#00bfff',
dimgray: '#696969',
dimgrey: '#696969',
dodgerblue: '#1e90ff',
firebrick: '#b22222',
floralwhite: '#fffaf0',
forestgreen: '#228b22',
fuchsia: '#ff00ff',
gainsboro: '#dcdcdc',
ghostwhite: '#f8f8ff',
gold: '#ffd700',
goldenrod: '#daa520',
gray: '#808080',
grey: '#808080',
green: '#008000',
greenyellow: '#adff2f',
honeydew: '#f0fff0',
hotpink: '#ff69b4',
indianred: '#cd5c5c',
indigo: '#4b0082',
ivory: '#fffff0',
khaki: '#f0e68c',
lavender: '#e6e6fa',
lavenderblush: '#fff0f5',
lawngreen: '#7cfc00',
lemonchiffon: '#fffacd',
lightblue: '#add8e6',
lightcoral: '#f08080',
lightcyan: '#e0ffff',
lightgoldenrodyellow: '#fafad2',
lightgray: '#d3d3d3',
lightgrey: '#d3d3d3',
lightgreen: '#90ee90',
lightpink: '#ffb6c1',
lightsalmon: '#ffa07a',
lightseagreen: '#20b2aa',
lightskyblue: '#87cefa',
lightslategray: '#778899',
lightslategrey: '#778899',
lightsteelblue: '#b0c4de',
lightyellow: '#ffffe0',
lime: '#00ff00',
limegreen: '#32cd32',
linen: '#faf0e6',
magenta: '#ff00ff',
maroon: '#800000',
mediumaquamarine: '#66cdaa',
mediumblue: '#0000cd',
mediumorchid: '#ba55d3',
mediumpurple: '#9370db',
mediumseagreen: '#3cb371',
mediumslateblue: '#7b68ee',
mediumspringgreen: '#00fa9a',
mediumturquoise: '#48d1cc',
mediumvioletred: '#c71585',
midnightblue: '#191970',
mintcream: '#f5fffa',
mistyrose: '#ffe4e1',
moccasin: '#ffe4b5',
navajowhite: '#ffdead',
navy: '#000080',
oldlace: '#fdf5e6',
olive: '#808000',
olivedrab: '#6b8e23',
orange: '#ffa500',
orangered: '#ff4500',
orchid: '#da70d6',
palegoldenrod: '#eee8aa',
palegreen: '#98fb98',
paleturquoise: '#afeeee',
palevioletred: '#db7093',
papayawhip: '#ffefd5',
peachpuff: '#ffdab9',
peru: '#cd853f',
pink: '#ffc0cb',
plum: '#dda0dd',
powderblue: '#b0e0e6',
purple: '#800080',
rebeccapurple: '#663399',
red: '#ff0000',
rosybrown: '#bc8f8f',
royalblue: '#4169e1',
saddlebrown: '#8b4513',
salmon: '#fa8072',
sandybrown: '#f4a460',
seagreen: '#2e8b57',
seashell: '#fff5ee',
sienna: '#a0522d',
silver: '#c0c0c0',
skyblue: '#87ceeb',
slateblue: '#6a5acd',
slategray: '#708090',
slategrey: '#708090',
snow: '#fffafa',
springgreen: '#00ff7f',
steelblue: '#4682b4',
tan: '#d2b48c',
teal: '#008080',
thistle: '#d8bfd8',
tomato: '#ff6347',
turquoise: '#40e0d0',
violet: '#ee82ee',
wheat: '#f5deb3',
white: '#ffffff',
whitesmoke: '#f5f5f5',
yellow: '#ffff00',
yellowgreen: '#9acd32',
transparent: '#00000000',
}
function checkColor(e: string | undefined) {
// 其他开发者适配的echarts会传入一个undefined到这里
e = e || '#000000'
var t = null
if ((t = /^#([0-9|A-F|a-f]{6})$/.exec(e)) != null) {
const n = parseInt(t[1].slice(0, 2), 16)
const o = parseInt(t[1].slice(2, 4), 16)
const r = parseInt(t[1].slice(4), 16)
return [n, o, r, 255]
}
if ((t = /^#([0-9|A-F|a-f]{3})$/.exec(e)) != null) {
let n: string | number = t[1].slice(0, 1)
let o: string | number = t[1].slice(1, 2)
let r: string | number = t[1].slice(2, 3)
n = parseInt(n + n, 16)
o = parseInt(o + o, 16)
r = parseInt(r + r, 16)
return [n, o, r, 255]
}
if ((t = /^rgb\((.+)\)$/.exec(e)) != null) {
return t[1]
.split(',')
.map(function (e) {
return Math.min(255, parseInt(e.trim()))
})
.concat(255)
}
if ((t = /^rgba\((.+)\)$/.exec(e)) != null) {
return t[1].split(',').map(function (e, t) {
return t === 3
? Math.floor(255 * parseFloat(e.trim()))
: Math.min(255, parseInt(e.trim()))
})
}
var i = e.toLowerCase()
if (hasOwn(predefinedColor, i)) {
t = /^#([0-9|A-F|a-f]{6,8})$/.exec(predefinedColor[i])
const n = parseInt(t![1].slice(0, 2), 16)
const o = parseInt(t![1].slice(2, 4), 16)
const r = parseInt(t![1].slice(4, 6), 16)
let a = parseInt(t![1].slice(6, 8), 16)
a = a >= 0 ? a : 255
return [n, o, r, a]
}
console.error('unsupported color:' + e)
return [0, 0, 0, 255]
}
type CheckColor = typeof checkColor
//#endregion
//#region Class
class CanvasGradient {
type: string
data: Array<number>
colorStop: Array<[number, ReturnType<CheckColor>]>
constructor(type: string, data: Array<number>) {
this.type = type
this.data = data
this.colorStop = []
}
addColorStop(position: number, color: string) {
this.colorStop.push([position, checkColor(color)])
}
}
class Pattern {
image: string
repetition: string
constructor(image: string, repetition: string) {
this.image = image
this.repetition = repetition
}
}
class TextMetrics {
width: number
constructor(width: number) {
this.width = width
}
}
//#endregion
const defaultState = {
lineDash: [0, 0],
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 0,
shadowColor: [0, 0, 0, 0],
font: '10px sans-serif',
fontSize: 10,
fontWeight: 'normal',
fontStyle: 'normal',
fontFamily: 'sans-serif',
}
type ActionsItem = {
method: string
data: Array<string | number | boolean>
}
type DefaultState = typeof defaultState
type Callback = (result: any) => void | undefined
type LineCapType = 'butt' | 'round' | 'square'
type LineJoinType = 'bevel' | 'round' | 'miter'
type TextAlignType = 'left' | 'center' | 'right'
type TextBaselineType = 'top' | 'bottom' | 'middle' | 'normal'
export class CanvasContext implements UniApp.CanvasContext {
id: string
pageId: number
actions: Array<ActionsItem>
path: Array<ActionsItem>
subpath: Array<ActionsItem['data']>
state: DefaultState
drawingState: Array<DefaultState>
constructor(id: string, pageId: number) {
this.id = id
this.pageId = pageId
this.actions = []
this.path = []
this.subpath = []
// this.currentTransform = []
// this.currentStepAnimates = []
this.drawingState = []
this.state = {
lineDash: [0, 0],
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 0,
shadowColor: [0, 0, 0, 0],
font: '10px sans-serif',
fontSize: 10,
fontWeight: 'normal',
fontStyle: 'normal',
fontFamily: 'sans-serif',
}
}
draw(reserve: boolean = false, callback: Callback) {
var actions = [...this.actions]
this.actions = []
this.path = []
var callbackId
if (typeof callback === 'function') {
callbackId = canvasEventCallbacks.push(callback)
}
operateCanvas(this.id, this.pageId, 'actionsChanged', {
actions,
reserve,
callbackId,
})
}
createLinearGradient(x0: number, y0: number, x1: number, y1: number) {
return new CanvasGradient('linear', [x0, y0, x1, y1])
}
createCircularGradient(x: number, y: number, r: number) {
return new CanvasGradient('radial', [x, y, r])
}
createPattern(image: string, repetition: string) {
if (undefined === repetition) {
console.error(
"Failed to execute 'createPattern' on 'CanvasContext': 2 arguments required, but only 1 present."
)
} else if (
['repeat', 'repeat-x', 'repeat-y', 'no-repeat'].indexOf(repetition) < 0
) {
console.error(
"Failed to execute 'createPattern' on 'CanvasContext': The provided type ('" +
repetition +
"') is not one of 'repeat', 'no-repeat', 'repeat-x', or 'repeat-y'."
)
} else {
return new Pattern(image, repetition)
}
}
measureText(text: string) {
const font = this.state.font
let width = 0
if (__PLATFORM__ === 'h5') {
width = measureText(text, font)
} else {
const webview = plus.webview
.all()
.find((webview) => webview.getURL().endsWith('www/__uniappview.html'))
if (webview) {
width = Number(
webview.evalJSSync(
`(${measureText.toString()})(${JSON.stringify(
text
)},${JSON.stringify(font)})`
)
)
}
}
return new TextMetrics(width)
}
save() {
this.actions.push({
method: 'save',
data: [],
})
this.drawingState.push(this.state)
}
restore() {
this.actions.push({
method: 'restore',
data: [],
})
this.state = this.drawingState.pop() || {
lineDash: [0, 0],
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 0,
shadowColor: [0, 0, 0, 0],
font: '10px sans-serif',
fontSize: 10,
fontWeight: 'normal',
fontStyle: 'normal',
fontFamily: 'sans-serif',
}
}
beginPath() {
this.path = []
this.subpath = []
}
moveTo(x: number, y: number) {
this.path.push({
method: 'moveTo',
data: [x, y],
})
this.subpath = [[x, y]]
}
lineTo(x: number, y: number) {
if (this.path.length === 0 && this.subpath.length === 0) {
this.path.push({
method: 'moveTo',
data: [x, y],
})
} else {
this.path.push({
method: 'lineTo',
data: [x, y],
})
}
this.subpath.push([x, y])
}
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number) {
this.path.push({
method: 'quadraticCurveTo',
data: [cpx, cpy, x, y],
})
this.subpath.push([x, y])
}
bezierCurveTo(
cp1x: number,
cp1y: number,
cp2x: number,
cp2y: number,
x: number,
y: number
) {
this.path.push({
method: 'bezierCurveTo',
data: [cp1x, cp1y, cp2x, cp2y, x, y],
})
this.subpath.push([x, y])
}
arc(
x: number,
y: number,
r: number,
sAngle: number,
eAngle: number,
counterclockwise: boolean = false
) {
this.path.push({
method: 'arc',
data: [x, y, r, sAngle, eAngle, counterclockwise],
})
this.subpath.push([x, y])
}
rect(x: number, y: number, width: number, height: number) {
this.path.push({
method: 'rect',
data: [x, y, width, height],
})
this.subpath = [[x, y]]
}
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number) {
this.path.push({
method: 'arcTo',
data: [x1, y1, x2, y2, radius],
})
this.subpath.push([x2, y2])
}
clip() {
this.actions.push({
method: 'clip',
data: [...(this.path as any)],
})
}
closePath() {
this.path.push({
method: 'closePath',
data: [],
})
if (this.subpath.length) {
this.subpath = [this.subpath.shift()!]
}
}
clearActions() {
this.actions = []
this.path = []
this.subpath = []
}
getActions() {
var actions = [...this.actions]
this.clearActions()
return actions
}
set lineDashOffset(value: number) {
this.actions.push({
method: 'setLineDashOffset',
data: [value],
})
}
set globalCompositeOperation(type: string) {
this.actions.push({
method: 'setGlobalCompositeOperation',
data: [type],
})
}
set shadowBlur(level: number) {
this.actions.push({
method: 'setShadowBlur',
data: [level],
})
}
set shadowColor(color: string) {
this.actions.push({
method: 'setShadowColor',
data: [color],
})
}
set shadowOffsetX(x: number) {
this.actions.push({
method: 'setShadowOffsetX',
data: [x],
})
}
set shadowOffsetY(y: number) {
this.actions.push({
method: 'setShadowOffsetY',
data: [y],
})
}
set font(value: string) {
var self = this
this.state.font = value
// eslint-disable-next-line
var fontFormat = value.match(
/^(([\w\-]+\s)*)(\d+r?px)(\/(\d+\.?\d*(r?px)?))?\s+(.*)/
)
if (fontFormat) {
var style = fontFormat[1].trim().split(/\s/)
var fontSize = parseFloat(fontFormat[3])
var fontFamily = fontFormat[7]
var actions: Array<ActionsItem> = []
style.forEach(function (value, index) {
if (['italic', 'oblique', 'normal'].indexOf(value) > -1) {
actions.push({
method: 'setFontStyle',
data: [value],
})
self.state.fontStyle = value
} else if (['bold', 'normal'].indexOf(value) > -1) {
actions.push({
method: 'setFontWeight',
data: [value],
})
self.state.fontWeight = value
} else if (index === 0) {
actions.push({
method: 'setFontStyle',
data: ['normal'],
})
self.state.fontStyle = 'normal'
} else if (index === 1) {
pushAction()
}
})
if (style.length === 1) {
pushAction()
}
style = actions
.map(function (action) {
return action.data[0]
})
.join(' ') as any
this.state.fontSize = fontSize
this.state.fontFamily = fontFamily
this.actions.push({
method: 'setFont',
data: [`${style} ${fontSize}px ${fontFamily}`],
})
} else {
console.warn("Failed to set 'font' on 'CanvasContext': invalid format.")
}
function pushAction() {
actions.push({
method: 'setFontWeight',
data: ['normal'],
})
self.state.fontWeight = 'normal'
}
}
get font() {
return this.state.font
}
set fillStyle(color: string) {
this.setFillStyle(color)
}
set strokeStyle(color: string) {
this.setStrokeStyle(color)
}
set globalAlpha(value: number) {
value = Math.floor(255 * parseFloat((value as unknown) as string))
this.actions.push({
method: 'setGlobalAlpha',
data: [value],
})
}
set textAlign(align: string) {
this.actions.push({
method: 'setTextAlign',
data: [align],
})
}
set lineCap(type: LineCapType) {
this.actions.push({
method: 'setLineCap',
data: [type],
})
}
set lineJoin(type: LineJoinType) {
this.actions.push({
method: 'setLineJoin',
data: [type],
})
}
set lineWidth(value: number) {
this.actions.push({
method: 'setLineWidth',
data: [value],
})
}
set miterLimit(value: number) {
this.actions.push({
method: 'setMiterLimit',
data: [value],
})
}
set textBaseline(type: TextBaselineType) {
this.actions.push({
method: 'setTextBaseline',
data: [type],
})
}
'setFillStyle': UniApp.CanvasContext['setFillStyle']
'setStrokeStyle': UniApp.CanvasContext['setStrokeStyle']
'setGlobalAlpha': UniApp.CanvasContext['setGlobalAlpha']
'setShadow': UniApp.CanvasContext['setShadow']
'addColorStop': UniApp.CanvasContext['addColorStop']
'setLineWidth': UniApp.CanvasContext['setLineWidth']
'setLineCap': UniApp.CanvasContext['setLineCap']
'setLineJoin': UniApp.CanvasContext['setLineJoin']
'setLineDash': UniApp.CanvasContext['setLineDash']
'setMiterLimit': UniApp.CanvasContext['setMiterLimit']
'fillRect': UniApp.CanvasContext['fillRect']
'strokeRect': UniApp.CanvasContext['strokeRect']
'clearRect': UniApp.CanvasContext['clearRect']
'fill': UniApp.CanvasContext['fill']
'stroke': UniApp.CanvasContext['stroke']
'scale': UniApp.CanvasContext['scale']
'rotate': UniApp.CanvasContext['rotate']
'translate': UniApp.CanvasContext['translate']
'setFontSize': UniApp.CanvasContext['setFontSize']
'fillText': UniApp.CanvasContext['fillText']
'setTextAlign': UniApp.CanvasContext['setTextAlign']
'setTextBaseline': UniApp.CanvasContext['setTextBaseline']
'drawImage': UniApp.CanvasContext['drawImage']
'strokeText': UniApp.CanvasContext['strokeText']
'setTransform': UniApp.CanvasContext['setTransform']
}
;[...methods1, ...methods2].forEach(function (method) {
function get(method: string) {
switch (method) {
case 'fill':
case 'stroke':
return function () {
// @ts-ignore
this.actions.push({
method: method + 'Path',
// @ts-ignore
data: [...this.path],
})
}
case 'fillRect':
return function (x: number, y: number, width: number, height: number) {
// @ts-ignore
this.actions.push({
method: 'fillPath',
data: [
{
method: 'rect',
data: [x, y, width, height],
},
],
})
}
case 'strokeRect':
return function (x: number, y: number, width: number, height: number) {
// @ts-ignore
this.actions.push({
method: 'strokePath',
data: [
{
method: 'rect',
data: [x, y, width, height],
},
],
})
}
case 'fillText':
case 'strokeText':
return function (text: string, x: number, y: number, maxWidth: number) {
var data = [text.toString(), x, y]
if (typeof maxWidth === 'number') {
data.push(maxWidth)
}
// @ts-ignore
this.actions.push({
method,
data,
})
}
case 'drawImage':
return function (
imageResource: string,
dx: number | undefined,
dy: number | undefined,
dWidth: number | undefined,
dHeight: number | undefined,
sx: number | undefined,
sy: number | undefined,
sWidth: number | undefined,
sHeight: number | undefined
) {
if (sHeight === undefined) {
sx = dx
sy = dy
sWidth = dWidth
sHeight = dHeight
dx = undefined
dy = undefined
dWidth = undefined
dHeight = undefined
}
var data
function isNumber(e: any) {
return typeof e === 'number'
}
data =
isNumber(dx) &&
isNumber(dy) &&
isNumber(dWidth) &&
isNumber(dHeight)
? [
imageResource,
sx,
sy,
sWidth,
sHeight,
dx,
dy,
dWidth,
dHeight,
]
: isNumber(sWidth) && isNumber(sHeight)
? [imageResource, sx, sy, sWidth, sHeight]
: [imageResource, sx, sy]
// @ts-ignore
this.actions.push({
method,
data,
})
}
default:
return function (...data: any) {
// @ts-ignore
this.actions.push({
method,
data,
})
}
}
}
;(CanvasContext.prototype as any)[method] = get(method)
})
methods3.forEach(function (method) {
function get(method: string) {
switch (method) {
case 'setFillStyle':
case 'setStrokeStyle':
return function (color: string | Data) {
if (typeof color !== 'object') {
// @ts-ignore
this.actions.push({
method,
data: ['normal', checkColor(color)],
})
} else {
// @ts-ignore
this.actions.push({
method,
data: [color.type, color.data, color.colorStop],
})
}
}
case 'setGlobalAlpha':
return function (alpha: number) {
alpha = Math.floor(255 * parseFloat((alpha as unknown) as string))
// @ts-ignore
this.actions.push({
method,
data: [alpha],
})
}
case 'setShadow':
return function (
offsetX: number,
offsetY: number,
blur: number,
color: string
) {
color = checkColor(color) as any
// @ts-ignore
this.actions.push({
method,
data: [offsetX, offsetY, blur, color],
})
// @ts-ignore
this.state.shadowBlur = blur
// @ts-ignore
this.state.shadowColor = color
// @ts-ignore
this.state.shadowOffsetX = offsetX
// @ts-ignore
this.state.shadowOffsetY = offsetY
}
case 'setLineDash':
return function (pattern: Array<number> | undefined, offset: number) {
pattern = pattern || [0, 0]
offset = offset || 0
// @ts-ignore
this.actions.push({
method,
data: [pattern, offset],
})
// @ts-ignore
this.state.lineDash = pattern
}
case 'setFontSize':
return function (fontSize: number) {
// @ts-ignore
this.state.font = this.state.font.replace(
/\d+\.?\d*px/,
fontSize + 'px'
)
// @ts-ignore
this.state.fontSize = fontSize
// @ts-ignore
this.actions.push({
method,
data: [fontSize],
})
}
default:
return function (...data: any) {
// @ts-ignore
this.actions.push({
method,
data,
})
}
}
}
;(CanvasContext.prototype as any)[method] = get(method)
})
export const createCanvasContext = defineSyncApi<API_TYPE_CREATE_CANVAS_CONTEXT>(
API_CREATE_CANVAS_CONTEXT,
(canvasId, componentInstance): any => {
if (componentInstance) {
return new CanvasContext(canvasId, componentInstance.$page.id)
}
const pageId = getCurrentPageId()
if (pageId) {
return new CanvasContext(canvasId, pageId)
} else {
UniServiceJSBridge.emit('onError', 'createCanvasContext:fail')
}
},
CreateCanvasContextProtocol
)
export const canvasGetImageData = defineAsyncApi<API_TYPE_CANVAS_GET_IMAGE_DATA>(
API_CANVAS_GET_IMAGE_DATA,
({ canvasId, x, y, width, height }, { resolve, reject }) => {
const pageId = getCurrentPageId()
if (!pageId) {
reject()
return
}
const cId = canvasEventCallbacks.push(async function (
data: UniApp.CanvasGetImageDataRes & { compressed?: boolean }
) {
let imgData = data.data
if (imgData && imgData.length) {
if (__PLATFORM__ === 'app' && data.compressed) {
const pako = await import('pako')
imgData = pako.inflateRaw(imgData) as any
delete data.compressed
}
data.data = new Uint8ClampedArray(imgData) as any
}
resolve(data)
})
operateCanvas(canvasId, pageId, 'getImageData', {
x,
y,
width,
height,
callbackId: cId,
})
},
CanvasGetImageDataProtocol,
CanvasGetImageDataOptions
)
export const canvasPutImageData = defineAsyncApi<API_TYPE_CANVAS_PUT_IMAGE_DATA>(
API_CANVAS_PUT_IMAGE_DATA,
async ({ canvasId, data, x, y, width, height }, { resolve, reject }) => {
var pageId = getCurrentPageId()
if (!pageId) {
reject()
return
}
var cId = canvasEventCallbacks.push(function (
data: UniApp.CanvasGetImageDataRes
) {
resolve(data)
})
let compressed
// iOS真机非调试模式压缩太慢暂时排除
if (
__PLATFORM__ === 'app' &&
(plus.os.name !== 'iOS' || typeof __WEEX_DEVTOOL__ === 'boolean')
) {
const pako = await import('pako')
data = pako.deflateRaw(data as any, { to: 'string' }) as any
compressed = true
} else {
// fix ...
data = Array.prototype.slice.call(data)
}
operateCanvas(canvasId, pageId, 'putImageData', {
data,
x,
y,
width,
height,
compressed,
callbackId: cId,
})
},
CanvasPutImageDataProtocol,
CanvasPutImageDataOptions
)
export const canvasToTempFilePath = defineAsyncApi<API_TYPE_CANVAS_TO_TEMP_FILE_PATH>(
API_CANVAS_TO_TEMP_FILE_PATH,
(
{
x = 0,
y = 0,
width,
height,
destWidth,
destHeight,
canvasId,
fileType,
quality,
},
{ resolve, reject }
) => {
var pageId = getCurrentPageId()
if (!pageId) {
reject()
return
}
const cId = canvasEventCallbacks.push(function (
res: UniApp.CanvasToTempFilePathRes
) {
resolve(res)
})
const dirname = `${TEMP_PATH}/canvas`
operateCanvas(canvasId, pageId, 'toTempFilePath', {
x,
y,
width,
height,
destWidth,
destHeight,
fileType,
quality,
dirname,
callbackId: cId,
})
},
CanvasToTempFilePathProtocol,
CanvasToTempFilePathOptions
)
<template>
<uni-canvas :canvas-id="canvasId" :disable-scroll="disableScroll" v-on="_listeners">
<canvas ref="canvas" width="300" height="150" />
<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden;">
<uni-canvas
:canvas-id="canvasId"
:disable-scroll="disableScroll"
v-bind="{ ...Attrs, ...ExcludeAttrs }"
v-on="_listeners"
>
<canvas class="uni-canvas-canvas" ref="canvas" width="300" height="150" />
<div
style="
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
"
>
<slot />
</div>
<v-uni-resize-sensor ref="sensor" @resize="_resize" />
<ResizeSensor ref="sensor" @resize="_resize" />
</uni-canvas>
</template>
<script>
import {
subscriber
} from '../../mixins'
<script lang="ts">
import { ref } from "vue";
import { useAttrs, useSubscribe, withWebEvent } from "@dcloudio/uni-components";
import { getCurrentPageVm, getCurrentPageId, onEventPrevent } from "@dcloudio/uni-core";
import { saveImage, getSameOriginUrl } from "@dcloudio/uni-platform";
import ResizeSensor from "../resize-sensor";
import { useNativeEvent } from "../../helpers/useEvent";
import { pixelRatio, wrapper, initHidpi } from "../../helpers/hidpi";
import {
pixelRatio,
wrapper,
initHidpi
} from '../../helpers/hidpi'
!__NODE_JS__ && /*#__PURE__*/ initHidpi()
!__NODE_JS__ && initHidpi();
function resolveColor(color) {
color = color.slice(0)
color[3] = color[3] / 255
return 'rgba(' + color.join(',') + ')'
color = color.slice(0);
color[3] = color[3] / 255;
return "rgba(" + color.join(",") + ")";
}
function processTouches(target, touches) {
return ([]).map.call(touches, (touch) => {
var boundingClientRect = target.getBoundingClientRect()
return [].map.call(touches, (touch) => {
var boundingClientRect = target.getBoundingClientRect();
return {
identifier: touch.identifier,
x: touch.clientX - boundingClientRect.left,
y: touch.clientY - boundingClientRect.top
}
})
y: touch.clientY - boundingClientRect.top,
};
});
}
var tempCanvas
var tempCanvas;
function getTempCanvas(width = 0, height = 0) {
if (!tempCanvas) {
tempCanvas = document.createElement('canvas')
tempCanvas = document.createElement("canvas");
}
tempCanvas.width = width
tempCanvas.height = height
return tempCanvas
tempCanvas.width = width;
tempCanvas.height = height;
return tempCanvas;
}
export default {
name: 'Canvas',
mixins: [subscriber],
name: "Canvas",
inheritAttrs: false,
components: {
ResizeSensor,
},
props: {
canvasId: {
type: String,
default: ''
default: "",
},
disableScroll: {
type: [Boolean, String],
default: false
}
default: false,
},
},
data() {
return {
actionsWaiting: false
}
actionsWaiting: false,
};
},
computed: {
id() {
return this.canvasId
return this.canvasId;
},
_listeners() {
var $listeners = Object.assign({}, this.$listeners)
var events = ['touchstart', 'touchmove', 'touchend']
events.forEach(event => {
var existing = $listeners[event]
var eventHandler = []
let events = ["touchstart", "touchmove", "touchend"];
let _$listeners = this.Listeners;
let $listeners = Object.assign(
{},
(() => {
let obj = {};
for (const key in _$listeners) {
if (Object.prototype.hasOwnProperty.call(_$listeners, key)) {
const event = _$listeners[key];
obj[key.replace("on", "").toLowerCase()] = event;
}
}
return obj;
})()
);
events.forEach((event) => {
let existing = $listeners[event];
let eventHandler = [];
if (existing) {
eventHandler.push(($event) => {
this.$trigger(event, Object.assign({}, $event, {
touches: processTouches($event.currentTarget, $event.touches),
changedTouches: processTouches($event.currentTarget, $event
.changedTouches)
}))
})
eventHandler.push(
withWebEvent(($event) => {
this.$trigger(
event,
Object.assign(
{},
// $event无法直接assign
(() => {
let obj = {};
for (const key in $event) {
obj[key] = $event[key];
}
return obj;
})(),
{
touches: processTouches($event.currentTarget, $event.touches),
changedTouches: processTouches(
$event.currentTarget,
$event.changedTouches
),
}
)
);
})
);
}
if (this.disableScroll && event === 'touchmove') {
eventHandler.push(this._touchmove)
if (this.disableScroll && event === "touchmove") {
eventHandler.push(onEventPrevent);
}
$listeners[event] = eventHandler
})
return $listeners
}
$listeners[event] = eventHandler;
});
return $listeners;
},
},
created() {
this._actionsDefer = []
this._images = {}
this._actionsDefer = [];
this._images = {};
useSubscribe(this._handleSubscribe);
},
mounted() {
this._resize({
width: this.$refs.sensor.$el.offsetWidth,
height: this.$refs.sensor.$el.offsetHeight
})
this.$trigger = useNativeEvent(this.$emit);
this._resize();
},
beforeDestroy() {
const canvas = this.$refs.canvas
canvas.height = canvas.width = 0
beforeUnmount() {
const canvas = this.canvas;
canvas.height = canvas.width = 0;
},
methods: {
_handleSubscribe({
type,
data = {}
}) {
var method = this[type]
if (type.indexOf('_') !== 0 && typeof method === 'function') {
method(data)
_handleSubscribe(type, data = {}) {
var method = this[type];
if (type.indexOf("_") !== 0 && typeof method === "function") {
method(data);
}
},
_resize() {
var canvas = this.$refs.canvas
var canvas = this.canvas;
if (canvas.width > 0 && canvas.height > 0) {
var context = canvas.getContext('2d')
var imageData = context.getImageData(0, 0, canvas.width, canvas.height)
wrapper(this.$refs.canvas)
context.putImageData(imageData, 0, 0)
var context = canvas.getContext("2d");
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
wrapper(canvas);
context.putImageData(imageData, 0, 0);
} else {
wrapper(this.$refs.canvas)
wrapper(canvas);
}
},
_touchmove(event) {
event.preventDefault()
},
actionsChanged({
actions,
reserve,
callbackId
}) {
var self = this
actionsChanged({ actions, reserve, callbackId }) {
var self = this;
if (!actions) {
return
return;
}
if (this.actionsWaiting) {
this._actionsDefer.push([actions, reserve, callbackId])
return
this._actionsDefer.push([actions, reserve, callbackId]);
return;
}
var canvas = this.$refs.canvas
var c2d = canvas.getContext('2d')
var canvas = this.canvas;
var c2d = canvas.getContext("2d");
if (!reserve) {
c2d.fillStyle = '#000000'
c2d.strokeStyle = '#000000'
c2d.shadowColor = '#000000'
c2d.shadowBlur = 0
c2d.shadowOffsetX = 0
c2d.shadowOffsetY = 0
c2d.setTransform(1, 0, 0, 1, 0, 0)
c2d.clearRect(0, 0, canvas.width, canvas.height)
c2d.fillStyle = "#000000";
c2d.strokeStyle = "#000000";
c2d.shadowColor = "#000000";
c2d.shadowBlur = 0;
c2d.shadowOffsetX = 0;
c2d.shadowOffsetY = 0;
c2d.setTransform(1, 0, 0, 1, 0, 0);
c2d.clearRect(0, 0, canvas.width, canvas.height);
}
this.preloadImage(actions)
this.preloadImage(actions);
for (let index = 0; index < actions.length; index++) {
const action = actions[index]
let method = action.method
const data = action.data
if (/^set/.test(method) && method !== 'setTransform') {
const method1 = method[3].toLowerCase() + method.slice(4)
let color
if (method1 === 'fillStyle' || method1 === 'strokeStyle') {
if (data[0] === 'normal') {
color = resolveColor(data[1])
} else if (data[0] === 'linear') {
const LinearGradient = c2d.createLinearGradient(...data[1])
data[2].forEach(function(data2) {
const offset = data2[0]
const color = resolveColor(data2[1])
LinearGradient.addColorStop(offset, color)
})
color = LinearGradient
} else if (data[0] === 'radial') {
const x = data[1][0]
const y = data[1][1]
const r = data[1][2]
const LinearGradient = c2d.createRadialGradient(x, y, 0, x, y, r)
data[2].forEach(function(data2) {
const offset = data2[0]
const color = resolveColor(data2[1])
LinearGradient.addColorStop(offset, color)
})
color = LinearGradient
} else if (data[0] === 'pattern') {
const loaded = this.checkImageLoaded(data[1], actions.slice(index + 1), callbackId,
function(image) {
const action = actions[index];
let method = action.method;
const data = action.data;
if (/^set/.test(method) && method !== "setTransform") {
const method1 = method[3].toLowerCase() + method.slice(4);
let color;
if (method1 === "fillStyle" || method1 === "strokeStyle") {
if (data[0] === "normal") {
color = resolveColor(data[1]);
} else if (data[0] === "linear") {
const LinearGradient = c2d.createLinearGradient(...data[1]);
data[2].forEach(function (data2) {
const offset = data2[0];
const color = resolveColor(data2[1]);
LinearGradient.addColorStop(offset, color);
});
color = LinearGradient;
} else if (data[0] === "radial") {
const x = data[1][0];
const y = data[1][1];
const r = data[1][2];
const LinearGradient = c2d.createRadialGradient(x, y, 0, x, y, r);
data[2].forEach(function (data2) {
const offset = data2[0];
const color = resolveColor(data2[1]);
LinearGradient.addColorStop(offset, color);
});
color = LinearGradient;
} else if (data[0] === "pattern") {
const loaded = this.checkImageLoaded(
data[1],
actions.slice(index + 1),
callbackId,
function (image) {
if (image) {
c2d[method1] = c2d.createPattern(image, data[2])
c2d[method1] = c2d.createPattern(image, data[2]);
}
})
}
);
if (!loaded) {
break
break;
}
continue
continue;
}
c2d[method1] = color
} else if (method1 === 'globalAlpha') {
c2d[method1] = data[0] / 255
} else if (method1 === 'shadow') {
var _ = ['shadowOffsetX', 'shadowOffsetY', 'shadowBlur', 'shadowColor']
data.forEach(function(color_, method_) {
c2d[_[method_]] = _[method_] === 'shadowColor' ? resolveColor(color_) : color_
})
c2d[method1] = color;
} else if (method1 === "globalAlpha") {
c2d[method1] = data[0] / 255;
} else if (method1 === "shadow") {
var _ = ["shadowOffsetX", "shadowOffsetY", "shadowBlur", "shadowColor"];
data.forEach(function (color_, method_) {
c2d[_[method_]] =
_[method_] === "shadowColor" ? resolveColor(color_) : color_;
});
} else if (method1 === "fontSize") {
const font = c2d.__font__ || c2d.font;
c2d.__font__ = c2d.font = font.replace(/\d+\.?\d*px/, data[0] + "px");
} else if (method1 === "lineDash") {
c2d.setLineDash(data[0]);
c2d.lineDashOffset = data[1] || 0;
} else if (method1 === "textBaseline") {
if (data[0] === "normal") {
data[0] = "alphabetic";
}
c2d[method1] = data[0];
} else if (method1 === "font") {
c2d.__font__ = c2d.font = data[0];
} else {
if (method1 === 'fontSize') {
c2d.font = c2d.font.replace(/\d+\.?\d*px/, data[0] + 'px')
} else {
if (method1 === 'lineDash') {
c2d.setLineDash(data[0])
c2d.lineDashOffset = data[1] || 0
} else {
if (method1 === 'textBaseline') {
if (data[0] === 'normal') {
data[0] = 'alphabetic'
c2d[method1] = data[0];
}
} else if (method === "fillPath" || method === "strokePath") {
method = method.replace(/Path/, "");
c2d.beginPath();
data.forEach(function (data_) {
c2d[data_.method].apply(c2d, data_.data);
});
c2d[method]();
} else if (method === "fillText") {
c2d.fillText.apply(c2d, data);
} else if (method === "drawImage") {
var A = (function () {
var dataArray = [...data];
var url = dataArray[0];
var otherData = dataArray.slice(1);
self._images = self._images || {};
if (
!self.checkImageLoaded(
url,
actions.slice(index + 1),
callbackId,
function (image) {
if (image) {
c2d.drawImage.apply(
c2d,
[image].concat(
[...otherData.slice(4, 8)],
[...otherData.slice(0, 4)]
)
);
}
c2d[method1] = data[0]
} else {
c2d[method1] = data[0]
}
}
}
}
} else if (method === 'fillPath' || method === 'strokePath') {
method = method.replace(/Path/, '')
c2d.beginPath()
data.forEach(function(data_) {
c2d[data_.method].apply(c2d, data_.data)
})
c2d[method]()
} else if (method === 'fillText') {
c2d.fillText.apply(c2d, data)
} else if (method === 'drawImage') {
var A = (function() {
var dataArray = [...data]
var url = dataArray[0]
var otherData = dataArray.slice(1)
self._images = self._images || {}
if (!self.checkImageLoaded(url, actions.slice(index + 1), callbackId, function(
image) {
if (image) {
c2d.drawImage.apply(c2d, [image].concat([...otherData.slice(4, 8)],
[...otherData.slice(0, 4)]))
}
})) return 'break'
}())
if (A === 'break') {
break
)
)
return "break";
})();
if (A === "break") {
break;
}
} else {
if (method === 'clip') {
data.forEach(function(data_) {
c2d[data_.method].apply(c2d, data_.data)
})
c2d.clip()
if (method === "clip") {
data.forEach(function (data_) {
c2d[data_.method].apply(c2d, data_.data);
});
c2d.clip();
} else {
c2d[method].apply(c2d, data)
c2d[method].apply(c2d, data);
}
}
}
if (!this.actionsWaiting && callbackId) {
UniViewJSBridge.publishHandler('onDrawCanvas', {
callbackId,
data: {
errMsg: 'drawCanvas:ok'
}
}, this.$page.id)
UniViewJSBridge.publishHandler(
"onCanvasMethodCallback",
{
callbackId,
data: {
errMsg: "drawCanvas:ok",
},
},
getCurrentPageId()
);
}
},
preloadImage: function(actions) {
var self = this
actions.forEach(function(action) {
var method = action.method
var data = action.data
var src = ''
if (method === 'drawImage') {
src = data[0]
src = self.$getRealPath(src)
data[0] = src
} else if (method === 'setFillStyle' && data[0] === 'pattern') {
src = data[1]
src = self.$getRealPath(src)
data[1] = src
preloadImage: function (actions) {
var self = this;
actions.forEach(function (action) {
var method = action.method;
var data = action.data;
var src = "";
if (method === "drawImage") {
src = data[0];
src = self.$getRealPath(src);
data[0] = src;
} else if (method === "setFillStyle" && data[0] === "pattern") {
src = data[1];
src = self.$getRealPath(src);
data[1] = src;
}
if (src && !self._images[src]) {
loadImage()
loadImage();
}
/**
* 加载图像
*/
function loadImage() {
self._images[src] = new Image()
self._images[src].onload = function() {
self._images[src].ready = true
}
/**
* 从Blob加载
* @param {Blob} blob
*/
function loadBlob(blob) {
self._images[src].src = (window.URL || window.webkitURL).createObjectURL(blob)
}
/**
* 从本地文件加载
* @param {string} path 文件路径
*/
function loadFile(path) {
var bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
bitmap.load(path, function() {
self._images[src].src = bitmap.toBase64Data()
bitmap.clear()
}, function() {
bitmap.clear()
console.error('preloadImage error')
})
}
/**
* 从网络加载
* @param {string} url 文件地址
*/
function loadUrl(url) {
function plusDownload() {
plus.downloader.createDownload(url, {
filename: '_doc/uniapp_temp/download/'
}, function(d, status) {
if (status === 200) {
loadFile(d.filename)
} else {
self._images[src].src = src
}
}).start()
}
var xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.responseType = 'blob'
xhr.onload = function() {
if (this.status === 200) {
loadBlob(this.response)
}
}
xhr.onerror = window.plus ? plusDownload : function() {
self._images[src].src = src
}
xhr.send()
}
const image = (self._images[src] = new Image());
image.onload = function () {
image.ready = true;
};
if (window.plus && (!window.webkit || !window.webkit.messageHandlers)) {
self._images[src].src = src
} else {
// 解决 PLUS-APP(wkwebview)以及 H5 图像跨域问题(H5图像响应头需包含access-control-allow-origin)
if (window.plus && src.indexOf('http://') !== 0 && src.indexOf('https://') !==
0 && !/^data:.*,.*/.test(src)) {
loadFile(src)
} else if (/^data:.*,.*/.test(src)) {
self._images[src].src = src
} else {
loadUrl(src)
// 安卓 WebView 除本地路径无跨域问题
if (__PLATFORM__ === "app-plus" && navigator.vendor === "Google Inc.") {
if (src.indexOf("file://") === 0) {
image.crossOrigin = "anonymous";
}
image.src = src;
return;
}
getSameOriginUrl(src)
.then((src) => {
image.src = src;
})
.catch(() => {
image.src = src;
});
}
})
});
},
checkImageLoaded: function(src, actions, callbackId, fn) {
var self = this
var image = this._images[src]
checkImageLoaded: function (src, actions, callbackId, fn) {
var self = this;
var image = this._images[src];
if (image.ready) {
fn(image)
return true
fn(image);
return true;
} else {
this._actionsDefer.unshift([actions, true])
this.actionsWaiting = true
image.onload = function() {
image.ready = true
fn(image)
self.actionsWaiting = false
var actions = self._actionsDefer.slice(0)
self._actionsDefer = []
for (var action = actions.shift(); action;) {
this._actionsDefer.unshift([actions, true]);
this.actionsWaiting = true;
image.onload = function () {
image.ready = true;
fn(image);
self.actionsWaiting = false;
var actions = self._actionsDefer.slice(0);
self._actionsDefer = [];
for (var action = actions.shift(); action; ) {
self.actionsChanged({
actions: action[0],
reserve: action[1],
callbackId
})
action = actions.shift()
callbackId,
});
action = actions.shift();
}
}
return false
};
return false;
}
},
getImageData({
......@@ -398,112 +404,146 @@ export default {
destWidth,
destHeight,
hidpi = true,
callbackId
dataType,
quality = 1,
type = "png",
callbackId,
}) {
var imgData
var canvas = this.$refs.canvas
if (!width) {
width = canvas.offsetWidth - x
const canvas = this.canvas;
let data;
const maxWidth = canvas.offsetWidth - x;
width = width ? Math.min(width, maxWidth) : maxWidth;
const maxHeight = canvas.offsetHeight - y;
height = height ? Math.min(height, maxHeight) : maxHeight;
if (!hidpi) {
if (!destWidth && !destHeight) {
destWidth = Math.round(width * pixelRatio);
destHeight = Math.round(height * pixelRatio);
} else if (!destWidth) {
destWidth = Math.round((width / height) * destHeight);
} else if (!destHeight) {
destHeight = Math.round((height / width) * destWidth);
}
} else {
destWidth = width;
destHeight = height;
}
if (!height) {
height = canvas.offsetHeight - y
const newCanvas = getTempCanvas(destWidth, destHeight);
const context = newCanvas.getContext("2d");
if (type === "jpeg" || type === "jpg") {
type = "jpeg";
context.fillStyle = "#fff";
context.fillRect(0, 0, destWidth, destHeight);
}
context.__hidpi__ = true;
context.drawImageByCanvas(
canvas,
x,
y,
width,
height,
0,
0,
destWidth,
destHeight,
false
);
let result;
try {
if (!hidpi) {
if (!destWidth && !destHeight) {
destWidth = Math.round(width * pixelRatio)
destHeight = Math.round(height * pixelRatio)
} else if (!destWidth) {
destWidth = Math.round(width / height * destHeight)
} else if (!destHeight) {
destHeight = Math.round(height / width * destWidth)
}
let compressed;
if (dataType === "base64") {
data = newCanvas.toDataURL(`image/${type}`, quality);
} else {
destWidth = width
destHeight = height
const imgData = context.getImageData(0, 0, destWidth, destHeight);
if (__PLATFORM__ === "app-plus") {
const pako = require("pako");
data = pako.deflateRaw(imgData.data, { to: "string" });
compressed = true;
} else {
// fix [...]展开TypedArray在低版本手机报错的问题,使用Array.prototype.slice
data = Array.prototype.slice.call(imgData.data);
}
}
const newCanvas = getTempCanvas(destWidth, destHeight)
const context = newCanvas.getContext('2d')
context.__hidpi__ = true
context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false)
imgData = context.getImageData(0, 0, destWidth, destHeight)
newCanvas.height = newCanvas.width = 0
context.__hidpi__ = false
result = {
errMsg: "canvasGetImageData:ok",
data,
compressed,
width: destWidth,
height: destHeight,
};
} catch (error) {
if (!callbackId) {
return
}
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasGetImageData:fail'
}
}, this.$page.id)
return
result = {
errMsg: `canvasGetImageData:fail ${error}`,
};
}
newCanvas.height = newCanvas.width = 0;
context.__hidpi__ = false;
if (!callbackId) {
// fix [...]展开TypedArray在低版本手机报错的问题,使用Array.prototype.slice
return {
data: Array.prototype.slice.call(imgData.data),
width: destWidth,
height: destHeight
}
return result;
} else {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasGetImageData:ok',
data: [...imgData.data],
width: destWidth,
height: destHeight
}
}, this.$page.id)
UniViewJSBridge.publishHandler(
"onCanvasMethodCallback",
{
callbackId,
data: result,
},
getCurrentPageId()
);
}
},
putImageData({
data,
x,
y,
width,
height,
callbackId
}) {
putImageData({ data, x, y, width, height, compressed, callbackId }) {
try {
if (!height) {
height = Math.round(data.length / 4 / width)
height = Math.round(data.length / 4 / width);
}
const canvas = getTempCanvas(width, height);
const context = canvas.getContext("2d");
if (__PLATFORM__ === "app-plus" && compressed) {
const pako = require("pako");
data = pako.inflateRaw(data);
}
const canvas = getTempCanvas(width, height)
const context = canvas.getContext('2d')
context.putImageData(new ImageData(new Uint8ClampedArray(data), width, height), 0, 0)
this.$refs.canvas.getContext('2d').drawImage(canvas, x, y, width, height)
canvas.height = canvas.width = 0
context.putImageData(
new ImageData(new Uint8ClampedArray(data), width, height),
0,
0
);
this.canvas.getContext("2d").drawImage(canvas, x, y, width, height);
canvas.height = canvas.width = 0;
} catch (error) {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
UniViewJSBridge.publishHandler(
"onCanvasMethodCallback",
{
callbackId,
data: {
errMsg: "canvasPutImageData:fail",
},
},
getCurrentPageId()
);
return;
}
UniViewJSBridge.publishHandler(
"onCanvasMethodCallback",
{
callbackId,
data: {
errMsg: 'canvasPutImageData:fail'
}
}, this.$page.id)
return
}
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasPutImageData:ok'
}
}, this.$page.id)
errMsg: "canvasPutImageData:ok",
},
},
getCurrentPageId()
);
},
getDataUrl({
toTempFilePath({
x = 0,
y = 0,
width,
height,
destWidth,
destHeight,
hidpi = true,
fileType,
qualit,
callbackId
quality,
dirname,
callbackId,
}) {
const res = this.getImageData({
x,
......@@ -512,57 +552,61 @@ export default {
height,
destWidth,
destHeight,
hidpi
})
hidpi: false,
dataType: "base64",
type: fileType,
quality,
});
if (!res.data || !res.data.length) {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasGetDataUrl:fail'
}
}, this.$page.id)
return
}
let imgData
try {
imgData = new ImageData(new Uint8ClampedArray(res.data), res.width, res.height)
} catch (error) {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasGetDataUrl:fail'
}
}, this.$page.id)
return
UniViewJSBridge.publishHandler(
"onCanvasMethodCallback",
{
callbackId,
data: {
errMsg: res.errMsg.replace("canvasPutImageData", "toTempFilePath"),
},
},
getCurrentPageId()
);
return;
}
destWidth = res.width
destHeight = res.height
const canvas = getTempCanvas(destWidth, destHeight)
const c2d = canvas.getContext('2d')
c2d.putImageData(imgData, 0, 0)
let base64 = canvas.toDataURL('image/png')
canvas.height = canvas.width = 0
const img = new Image()
img.onload = () => {
const canvas = getTempCanvas(destWidth, destHeight)
if (fileType === 'jpeg' || fileType === 'jpg') {
fileType = 'jpeg'
c2d.fillStyle = '#fff'
c2d.fillRect(0, 0, destWidth, destHeight)
saveImage(res.data, dirname, (error, tempFilePath) => {
let errMsg = `toTempFilePath:${error ? "fail" : "ok"}`;
if (error) {
errMsg += ` ${error.message}`;
}
c2d.drawImage(img, 0, 0)
base64 = canvas.toDataURL(`image/${fileType}`, qualit)
canvas.height = canvas.width = 0
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasGetDataUrl:ok',
base64: base64
}
}, this.$page.id)
}
img.src = base64
}
}
}
UniViewJSBridge.publishHandler(
"onCanvasMethodCallback",
{
callbackId,
data: {
errMsg,
tempFilePath: tempFilePath,
},
},
getCurrentPageId()
);
});
},
},
setup() {
const canvas = ref(null);
const sensor = ref(null);
const {
$attrs: Attrs,
$excludeAttrs: ExcludeAttrs,
$listeners: Listeners,
} = useAttrs({
excludeListeners: true,
});
return {
canvas,
sensor,
Attrs,
ExcludeAttrs,
Listeners,
};
},
};
</script>
import { Ref, SetupContext, EmitsOptions } from 'vue'
import { normalizeTarget } from '@dcloudio/uni-shared'
import { createNativeEvent } from '@dcloudio/uni-core'
type EventDetail = Record<string, any>
export type CustomEventTrigger = ReturnType<typeof useCustomEvent>
export type NativeEventTrigger = ReturnType<typeof useNativeEvent>
export type EmitEvent<E extends (...args: any) => any> = [Parameters<E>[0]]
export function withWebEvent(fn: Function) {
......@@ -21,6 +23,14 @@ export function useCustomEvent<E extends EmitsOptions>(
}
}
export function useNativeEvent<E extends EmitsOptions>(
emit: SetupContext<E>['emit']
) {
return (name: string, evt: Event) => {
emit(name, createNativeEvent(evt))
}
}
function normalizeCustomEvent(
name: string,
domEvt: Event,
......
export * from './components'
export { useOn, useSubscribe } from './helpers/useSubscribe'
export { withWebEvent, useCustomEvent } from './helpers/useEvent'
export type { CustomEventTrigger, EmitEvent } from './helpers/useEvent'
export {
withWebEvent,
useCustomEvent,
useNativeEvent,
} from './helpers/useEvent'
export type {
CustomEventTrigger,
NativeEventTrigger,
EmitEvent,
} from './helpers/useEvent'
export { useUserAction } from './helpers/useUserAction'
export { useAttrs } from './helpers/useAttrs'
......@@ -5,7 +5,7 @@ uni-canvas {
position: relative;
}
uni-canvas > canvas {
uni-canvas > .uni-canvas-canvas {
position: absolute;
top: 0;
left: 0;
......
const callbacks = {}
export function createCallbacks(namespace: string) {
let scopedCallbacks = (callbacks as any)[namespace]
if (!scopedCallbacks) {
scopedCallbacks = {
id: 1,
callbacks: Object.create(null),
}
;(callbacks as any)[namespace] = scopedCallbacks
}
return {
get(id: any) {
return scopedCallbacks.callbacks[id]
},
pop(id: any) {
const callback = scopedCallbacks.callbacks[id]
if (callback) {
delete scopedCallbacks.callbacks[id]
}
return callback
},
push(callback: Function) {
const id = scopedCallbacks.id++
scopedCallbacks.callbacks[id] = callback
return id
},
}
}
......@@ -4,3 +4,4 @@ export * from './icon'
export * from './page'
export * from './scroll'
export * from './getRealRoute'
export * from './callbacks'
......@@ -33,7 +33,7 @@ export function $nne(this: ComponentPublicInstance, evt: Event) {
return res
}
function createNativeEvent(evt: Event) {
export function createNativeEvent(evt: Event | TouchEvent) {
const { type, timeStamp, currentTarget } = evt
const target = normalizeTarget(currentTarget as HTMLElement)
const event = {
......@@ -43,6 +43,10 @@ function createNativeEvent(evt: Event) {
detail: {},
currentTarget: target,
}
if (evt.type.startsWith('touch')) {
;(event as any).touches = (evt as TouchEvent).touches
;(event as any).changedTouches = (evt as TouchEvent).changedTouches
}
if (__PLATFORM__ === 'h5') {
extend(event, {
preventDefault() {
......
......@@ -13,3 +13,5 @@ export function initView(app: App) {
initAppConfig(app._context.config)
// TODO wxs,behaviors
}
export { createNativeEvent } from './componentInstance'
"use strict";
var __defProp = Object.defineProperty;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value;
var __assign = (a2, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a2, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a2, prop, b[prop]);
}
return a2;
};
Object.defineProperty(exports, "__esModule", {value: true});
exports[Symbol.toStringTag] = "Module";
var shared = require("@vue/shared");
......@@ -144,6 +160,8 @@ function initBridge(namespace) {
}
const ViewJSBridge = /* @__PURE__ */ initBridge("view");
uniShared.passive(true);
const onEventPrevent = /* @__PURE__ */ vue.withModifiers(() => {
}, ["prevent"]);
function updateCssVar(cssVars) {
const style = document.documentElement.style;
Object.keys(cssVars).forEach((name) => {
......@@ -216,6 +234,66 @@ function getRealRoute(fromRoute, toRoute) {
fromRouteArray.splice(fromRouteArray.length - i2 - 1, i2 + 1);
return "/" + fromRouteArray.concat(toRouteArray).join("/");
}
const callbacks$1 = {};
function createCallbacks(namespace) {
let scopedCallbacks = callbacks$1[namespace];
if (!scopedCallbacks) {
scopedCallbacks = {
id: 1,
callbacks: Object.create(null)
};
callbacks$1[namespace] = scopedCallbacks;
}
return {
get(id) {
return scopedCallbacks.callbacks[id];
},
pop(id) {
const callback = scopedCallbacks.callbacks[id];
if (callback) {
delete scopedCallbacks.callbacks[id];
}
return callback;
},
push(callback) {
const id = scopedCallbacks.id++;
scopedCallbacks.callbacks[id] = callback;
return id;
}
};
}
function createNativeEvent(evt) {
const {type, timeStamp, currentTarget} = evt;
const target = uniShared.normalizeTarget(currentTarget);
const event = {
type,
timeStamp,
target,
detail: {},
currentTarget: target
};
if (evt.type.startsWith("touch")) {
event.touches = evt.touches;
event.changedTouches = evt.changedTouches;
}
{
shared.extend(event, {
preventDefault() {
if (process.env.NODE_ENV !== "production") {
console.warn("preventDefault is only supported in h5, use `.prevent` instead.");
}
return evt.preventDefault();
},
stopPropagation() {
if (process.env.NODE_ENV !== "production") {
console.warn("stopPropagation is only supported in h5, use `.stop` instead.");
}
return evt.stopPropagation();
}
});
}
return event;
}
const ServiceJSBridge = /* @__PURE__ */ shared.extend(initBridge("service"), {
invokeOnCallback(name, res) {
return UniServiceJSBridge.emit("api." + name, res);
......@@ -228,6 +306,19 @@ function getCurrentPage() {
return pages[len - 1];
}
}
function getCurrentPageMeta() {
const page = getCurrentPage();
if (page) {
return page.$page.meta;
}
}
function getCurrentPageId() {
const meta = getCurrentPageMeta();
if (meta) {
return meta.id;
}
return -1;
}
function getCurrentPageVm() {
const page = getCurrentPage();
if (page) {
......@@ -708,7 +799,94 @@ function getRealPath(filePath) {
}
return filePath;
}
function saveImage(base64, dirname, callback) {
callback(null, base64);
}
const files = {};
function urlToFile(url, local) {
const file = files[url];
if (file) {
return Promise.resolve(file);
}
if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(url)) {
return Promise.resolve(base64ToFile(url));
}
if (local) {
return Promise.reject(new Error("not find"));
}
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function() {
resolve(this.response);
};
xhr.onerror = reject;
xhr.send();
});
}
function base64ToFile(base64) {
const base64Array = base64.split(",");
const res = base64Array[0].match(/:(.*?);/);
const type = res ? res[1] : "";
const str = atob(base64Array[1]);
let n = str.length;
const array = new Uint8Array(n);
while (n--) {
array[n] = str.charCodeAt(n);
}
return blobToFile(array, type);
}
function getExtname(type) {
const extname = type.split("/")[1];
return extname ? `.${extname}` : "";
}
function blobToFile(blob, type) {
let file;
if (blob instanceof File) {
file = blob;
} else {
type = type || blob.type || "";
const filename = `${Date.now()}${getExtname(type)}`;
try {
file = new File([blob], filename, {type});
} catch (error) {
blob = blob instanceof Blob ? blob : new Blob([blob], {type});
file = blob;
file.name = file.name || filename;
}
}
return file;
}
function fileToUrl(file) {
for (const key in files) {
if (shared.hasOwn(files, key)) {
const oldFile = files[key];
if (oldFile === file) {
return key;
}
}
}
var url = (window.URL || window.webkitURL).createObjectURL(file);
files[url] = file;
return url;
}
function getSameOriginUrl(url) {
const a2 = document.createElement("a");
a2.href = url;
if (a2.origin === location.origin) {
return Promise.resolve(url);
}
return urlToFile(url).then(fileToUrl);
}
const API_ON_TAB_BAR_MID_BUTTON_TAP = "onTabBarMidButtonTap";
const canvasEventCallbacks = createCallbacks("canvasEvent");
ServiceJSBridge.subscribe("onCanvasMethodCallback", ({callbackId, data}) => {
const callback = canvasEventCallbacks.pop(callbackId);
if (callback) {
callback(data);
}
});
const API_GET_STORAGE = "getStorage";
const GetStorageProtocol = {
key: {
......@@ -1517,6 +1695,82 @@ var index$k = /* @__PURE__ */ vue.defineComponent({
};
}
});
var ResizeSensor = /* @__PURE__ */ vue.defineComponent({
name: "ResizeSensor",
props: {
initial: {
type: Boolean,
default: false
}
},
emits: ["resize"],
setup(props2, {
emit: emit2
}) {
const rootRef = vue.ref(null);
const reset = useResizeSensorReset(rootRef);
const update = useResizeSensorUpdate(rootRef, emit2, reset);
return () => vue.createVNode("uni-resize-sensor", {
ref: rootRef,
onAnimationstartOnce: update
}, [vue.createVNode("div", {
onScroll: update
}, [vue.createVNode("div", null, null)], 40, ["onScroll"]), vue.createVNode("div", {
onScroll: update
}, [vue.createVNode("div", null, null)], 40, ["onScroll"])], 40, ["onAnimationstartOnce"]);
}
});
function useResizeSensorUpdate(rootRef, emit2, reset) {
const size = vue.reactive({
width: -1,
height: -1
});
vue.watch(() => shared.extend({}, size), (value) => emit2("resize", value));
return () => {
const {
offsetWidth,
offsetHeight
} = rootRef.value;
size.width = offsetWidth;
size.height = offsetHeight;
reset();
};
}
function useResizeSensorReset(rootRef) {
return () => {
const {
firstElementChild,
lastElementChild
} = rootRef.value;
firstElementChild.scrollLeft = 1e5;
firstElementChild.scrollTop = 1e5;
lastElementChild.scrollLeft = 1e5;
lastElementChild.scrollTop = 1e5;
};
}
function withWebEvent(fn) {
return fn.__wwe = true, fn;
}
function useCustomEvent(ref, emit2) {
return (name, evt, detail) => {
emit2(name, normalizeCustomEvent(name, evt, ref.value, detail || {}));
};
}
function useNativeEvent(emit2) {
return (name, evt) => {
emit2(name, createNativeEvent(evt));
};
}
function normalizeCustomEvent(name, domEvt, el, detail) {
const target = uniShared.normalizeTarget(el);
return {
type: detail.type || name,
timeStamp: domEvt.timeStamp || 0,
target,
currentTarget: target,
detail
};
}
const pixelRatio = 1;
function wrapper(canvas) {
canvas.width = canvas.offsetWidth * pixelRatio;
......@@ -1547,9 +1801,12 @@ function getTempCanvas(width = 0, height = 0) {
tempCanvas.height = height;
return tempCanvas;
}
const _sfc_main$8 = {
var _sfc_main$8 = {
name: "Canvas",
mixins: [subscriber],
inheritAttrs: false,
components: {
ResizeSensor
},
props: {
canvasId: {
type: String,
......@@ -1570,21 +1827,37 @@ const _sfc_main$8 = {
return this.canvasId;
},
_listeners() {
var $listeners = Object.assign({}, this.$listeners);
var events = ["touchstart", "touchmove", "touchend"];
let events = ["touchstart", "touchmove", "touchend"];
let _$listeners = this.Listeners;
let $listeners = Object.assign({}, (() => {
let obj = {};
for (const key in _$listeners) {
if (Object.prototype.hasOwnProperty.call(_$listeners, key)) {
const event = _$listeners[key];
obj[key.replace("on", "").toLowerCase()] = event;
}
}
return obj;
})());
events.forEach((event) => {
var existing = $listeners[event];
var eventHandler = [];
let existing = $listeners[event];
let eventHandler = [];
if (existing) {
eventHandler.push(($event) => {
this.$trigger(event, Object.assign({}, $event, {
eventHandler.push(withWebEvent(($event) => {
this.$trigger(event, Object.assign({}, (() => {
let obj = {};
for (const key in $event) {
obj[key] = $event[key];
}
return obj;
})(), {
touches: processTouches($event.currentTarget, $event.touches),
changedTouches: processTouches($event.currentTarget, $event.changedTouches)
}));
});
}));
}
if (this.disableScroll && event === "touchmove") {
eventHandler.push(this._touchmove);
eventHandler.push(onEventPrevent);
}
$listeners[event] = eventHandler;
});
......@@ -1594,46 +1867,35 @@ const _sfc_main$8 = {
created() {
this._actionsDefer = [];
this._images = {};
useSubscribe(this._handleSubscribe);
},
mounted() {
this._resize({
width: this.$refs.sensor.$el.offsetWidth,
height: this.$refs.sensor.$el.offsetHeight
});
this.$trigger = useNativeEvent(this.$emit);
this._resize();
},
beforeDestroy() {
const canvas = this.$refs.canvas;
beforeUnmount() {
const canvas = this.canvas;
canvas.height = canvas.width = 0;
},
methods: {
_handleSubscribe({
type,
data = {}
}) {
_handleSubscribe(type, data = {}) {
var method = this[type];
if (type.indexOf("_") !== 0 && typeof method === "function") {
method(data);
}
},
_resize() {
var canvas = this.$refs.canvas;
var canvas = this.canvas;
if (canvas.width > 0 && canvas.height > 0) {
var context = canvas.getContext("2d");
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
wrapper(this.$refs.canvas);
wrapper(canvas);
context.putImageData(imageData, 0, 0);
} else {
wrapper(this.$refs.canvas);
wrapper(canvas);
}
},
_touchmove(event) {
event.preventDefault();
},
actionsChanged({
actions,
reserve,
callbackId
}) {
actionsChanged({actions, reserve, callbackId}) {
var self = this;
if (!actions) {
return;
......@@ -1642,7 +1904,7 @@ const _sfc_main$8 = {
this._actionsDefer.push([actions, reserve, callbackId]);
return;
}
var canvas = this.$refs.canvas;
var canvas = this.canvas;
var c2d = canvas.getContext("2d");
if (!reserve) {
c2d.fillStyle = "#000000";
......@@ -1703,24 +1965,21 @@ const _sfc_main$8 = {
data.forEach(function(color_, method_) {
c2d[_[method_]] = _[method_] === "shadowColor" ? resolveColor(color_) : color_;
});
} else {
if (method1 === "fontSize") {
c2d.font = c2d.font.replace(/\d+\.?\d*px/, data[0] + "px");
} else {
if (method1 === "lineDash") {
c2d.setLineDash(data[0]);
c2d.lineDashOffset = data[1] || 0;
} else {
if (method1 === "textBaseline") {
if (data[0] === "normal") {
data[0] = "alphabetic";
}
c2d[method1] = data[0];
} else {
c2d[method1] = data[0];
}
}
} else if (method1 === "fontSize") {
const font = c2d.__font__ || c2d.font;
c2d.__font__ = c2d.font = font.replace(/\d+\.?\d*px/, data[0] + "px");
} else if (method1 === "lineDash") {
c2d.setLineDash(data[0]);
c2d.lineDashOffset = data[1] || 0;
} else if (method1 === "textBaseline") {
if (data[0] === "normal") {
data[0] = "alphabetic";
}
c2d[method1] = data[0];
} else if (method1 === "font") {
c2d.__font__ = c2d.font = data[0];
} else {
c2d[method1] = data[0];
}
} else if (method === "fillPath" || method === "strokePath") {
method = method.replace(/Path/, "");
......@@ -1759,12 +2018,12 @@ const _sfc_main$8 = {
}
}
if (!this.actionsWaiting && callbackId) {
UniViewJSBridge.publishHandler("onDrawCanvas", {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "drawCanvas:ok"
}
}, this.$page.id);
}, getCurrentPageId());
}
},
preloadImage: function(actions) {
......@@ -1786,59 +2045,15 @@ const _sfc_main$8 = {
loadImage();
}
function loadImage() {
self._images[src] = new Image();
self._images[src].onload = function() {
self._images[src].ready = true;
const image = self._images[src] = new Image();
image.onload = function() {
image.ready = true;
};
function loadBlob(blob) {
self._images[src].src = (window.URL || window.webkitURL).createObjectURL(blob);
}
function loadFile(path) {
var bitmap = new plus.nativeObj.Bitmap("bitmap" + Date.now());
bitmap.load(path, function() {
self._images[src].src = bitmap.toBase64Data();
bitmap.clear();
}, function() {
bitmap.clear();
console.error("preloadImage error");
});
}
function loadUrl(url) {
function plusDownload() {
plus.downloader.createDownload(url, {
filename: "_doc/uniapp_temp/download/"
}, function(d, status) {
if (status === 200) {
loadFile(d.filename);
} else {
self._images[src].src = src;
}
}).start();
}
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function() {
if (this.status === 200) {
loadBlob(this.response);
}
};
xhr.onerror = window.plus ? plusDownload : function() {
self._images[src].src = src;
};
xhr.send();
}
if (window.plus && (!window.webkit || !window.webkit.messageHandlers)) {
self._images[src].src = src;
} else {
if (window.plus && src.indexOf("http://") !== 0 && src.indexOf("https://") !== 0 && !/^data:.*,.*/.test(src)) {
loadFile(src);
} else if (/^data:.*,.*/.test(src)) {
self._images[src].src = src;
} else {
loadUrl(src);
}
}
getSameOriginUrl(src).then((src2) => {
image.src = src2;
}).catch(() => {
image.src = src;
});
}
});
},
......@@ -1877,83 +2092,86 @@ const _sfc_main$8 = {
destWidth,
destHeight,
hidpi = true,
dataType: dataType2,
quality = 1,
type = "png",
callbackId
}) {
var imgData;
var canvas = this.$refs.canvas;
if (!width) {
width = canvas.offsetWidth - x;
}
if (!height) {
height = canvas.offsetHeight - y;
}
const canvas = this.canvas;
let data;
const maxWidth = canvas.offsetWidth - x;
width = width ? Math.min(width, maxWidth) : maxWidth;
const maxHeight = canvas.offsetHeight - y;
height = height ? Math.min(height, maxHeight) : maxHeight;
if (!hidpi) {
if (!destWidth && !destHeight) {
destWidth = Math.round(width * pixelRatio);
destHeight = Math.round(height * pixelRatio);
} else if (!destWidth) {
destWidth = Math.round(width / height * destHeight);
} else if (!destHeight) {
destHeight = Math.round(height / width * destWidth);
}
} else {
destWidth = width;
destHeight = height;
}
const newCanvas = getTempCanvas(destWidth, destHeight);
const context = newCanvas.getContext("2d");
if (type === "jpeg" || type === "jpg") {
type = "jpeg";
context.fillStyle = "#fff";
context.fillRect(0, 0, destWidth, destHeight);
}
context.__hidpi__ = true;
context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false);
let result;
try {
if (!hidpi) {
if (!destWidth && !destHeight) {
destWidth = Math.round(width * pixelRatio);
destHeight = Math.round(height * pixelRatio);
} else if (!destWidth) {
destWidth = Math.round(width / height * destHeight);
} else if (!destHeight) {
destHeight = Math.round(height / width * destWidth);
}
let compressed;
if (dataType2 === "base64") {
data = newCanvas.toDataURL(`image/${type}`, quality);
} else {
destWidth = width;
destHeight = height;
}
const newCanvas = getTempCanvas(destWidth, destHeight);
const context = newCanvas.getContext("2d");
context.__hidpi__ = true;
context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false);
imgData = context.getImageData(0, 0, destWidth, destHeight);
newCanvas.height = newCanvas.width = 0;
context.__hidpi__ = false;
} catch (error) {
if (!callbackId) {
return;
}
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetImageData:fail"
const imgData = context.getImageData(0, 0, destWidth, destHeight);
if (false)
;
else {
data = Array.prototype.slice.call(imgData.data);
}
}, this.$page.id);
return;
}
if (!callbackId) {
return {
data: Array.prototype.slice.call(imgData.data),
}
result = {
errMsg: "canvasGetImageData:ok",
data,
compressed,
width: destWidth,
height: destHeight
};
} catch (error) {
result = {
errMsg: `canvasGetImageData:fail ${error}`
};
}
newCanvas.height = newCanvas.width = 0;
context.__hidpi__ = false;
if (!callbackId) {
return result;
} else {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetImageData:ok",
data: [...imgData.data],
width: destWidth,
height: destHeight
}
}, this.$page.id);
data: result
}, getCurrentPageId());
}
},
putImageData({
data,
x,
y,
width,
height,
callbackId
}) {
putImageData({data, x, y, width, height, compressed, callbackId}) {
try {
if (!height) {
height = Math.round(data.length / 4 / width);
}
const canvas = getTempCanvas(width, height);
const context = canvas.getContext("2d");
if (false)
;
context.putImageData(new ImageData(new Uint8ClampedArray(data), width, height), 0, 0);
this.$refs.canvas.getContext("2d").drawImage(canvas, x, y, width, height);
this.canvas.getContext("2d").drawImage(canvas, x, y, width, height);
canvas.height = canvas.width = 0;
} catch (error) {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
......@@ -1961,7 +2179,7 @@ const _sfc_main$8 = {
data: {
errMsg: "canvasPutImageData:fail"
}
}, this.$page.id);
}, getCurrentPageId());
return;
}
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
......@@ -1969,18 +2187,18 @@ const _sfc_main$8 = {
data: {
errMsg: "canvasPutImageData:ok"
}
}, this.$page.id);
}, getCurrentPageId());
},
getDataUrl({
toTempFilePath({
x = 0,
y = 0,
width,
height,
destWidth,
destHeight,
hidpi = true,
fileType,
qualit,
quality,
dirname,
callbackId
}) {
const res = this.getImageData({
......@@ -1990,100 +2208,78 @@ const _sfc_main$8 = {
height,
destWidth,
destHeight,
hidpi
hidpi: false,
dataType: "base64",
type: fileType,
quality
});
if (!res.data || !res.data.length) {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetDataUrl:fail"
errMsg: res.errMsg.replace("canvasPutImageData", "toTempFilePath")
}
}, this.$page.id);
}, getCurrentPageId());
return;
}
let imgData;
try {
imgData = new ImageData(new Uint8ClampedArray(res.data), res.width, res.height);
} catch (error) {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetDataUrl:fail"
}
}, this.$page.id);
return;
}
destWidth = res.width;
destHeight = res.height;
const canvas = getTempCanvas(destWidth, destHeight);
const c2d = canvas.getContext("2d");
c2d.putImageData(imgData, 0, 0);
let base64 = canvas.toDataURL("image/png");
canvas.height = canvas.width = 0;
const img = new Image();
img.onload = () => {
const canvas2 = getTempCanvas(destWidth, destHeight);
if (fileType === "jpeg" || fileType === "jpg") {
fileType = "jpeg";
c2d.fillStyle = "#fff";
c2d.fillRect(0, 0, destWidth, destHeight);
saveImage(res.data, dirname, (error, tempFilePath) => {
let errMsg = `toTempFilePath:${error ? "fail" : "ok"}`;
if (error) {
errMsg += ` ${error.message}`;
}
c2d.drawImage(img, 0, 0);
base64 = canvas2.toDataURL(`image/${fileType}`, qualit);
canvas2.height = canvas2.width = 0;
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetDataUrl:ok",
base64
errMsg,
tempFilePath
}
}, this.$page.id);
};
img.src = base64;
}, getCurrentPageId());
});
}
},
setup() {
const canvas = vue.ref(null);
const sensor = vue.ref(null);
const {
$attrs: Attrs,
$excludeAttrs: ExcludeAttrs,
$listeners: Listeners
} = useAttrs({
excludeListeners: true
});
return {
canvas,
sensor,
Attrs,
ExcludeAttrs,
Listeners
};
}
};
const _hoisted_1$5 = {
class: "uni-canvas-canvas",
ref: "canvas",
width: "300",
height: "150"
};
const _hoisted_2$2 = {style: {position: "absolute", top: "0", left: "0", width: "100%", height: "100%", overflow: "hidden"}};
function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
const _component_v_uni_resize_sensor = vue.resolveComponent("v-uni-resize-sensor");
const _component_ResizeSensor = vue.resolveComponent("ResizeSensor");
return vue.openBlock(), vue.createBlock("uni-canvas", vue.mergeProps({
"canvas-id": $props.canvasId,
"disable-scroll": $props.disableScroll
}, vue.toHandlers($options._listeners)), [
}, __assign(__assign({}, $setup.Attrs), $setup.ExcludeAttrs), vue.toHandlers($options._listeners)), [
vue.createVNode("canvas", _hoisted_1$5, null, 512),
vue.createVNode("div", _hoisted_2$2, [
vue.renderSlot(_ctx.$slots, "default")
]),
vue.createVNode(_component_v_uni_resize_sensor, {
vue.createVNode(_component_ResizeSensor, {
ref: "sensor",
onResize: $options._resize
}, null, 8, ["onResize"])
], 16, ["canvas-id", "disable-scroll"]);
}
_sfc_main$8.render = _sfc_render$8;
function withWebEvent(fn) {
return fn.__wwe = true, fn;
}
function useCustomEvent(ref, emit2) {
return (name, evt, detail) => {
emit2(name, normalizeCustomEvent(name, evt, ref.value, detail || {}));
};
}
function normalizeCustomEvent(name, domEvt, el, detail) {
const target = uniShared.normalizeTarget(el);
return {
type: detail.type || name,
timeStamp: domEvt.timeStamp || 0,
target,
currentTarget: target,
detail
};
}
const uniCheckGroupKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniCheckGroup" : "ucg");
const props$k = {
name: {
......@@ -2571,59 +2767,6 @@ var index$f = /* @__PURE__ */ vue.defineComponent({
return () => vue.createVNode("uni-icon", null, [path.value.d && createSvgIconVNode(path.value.d, props2.color || path.value.c, rpx2px(props2.size))]);
}
});
var ResizeSensor = /* @__PURE__ */ vue.defineComponent({
name: "ResizeSensor",
props: {
initial: {
type: Boolean,
default: false
}
},
emits: ["resize"],
setup(props2, {
emit: emit2
}) {
const rootRef = vue.ref(null);
const reset = useResizeSensorReset(rootRef);
const update = useResizeSensorUpdate(rootRef, emit2, reset);
return () => vue.createVNode("uni-resize-sensor", {
ref: rootRef,
onAnimationstartOnce: update
}, [vue.createVNode("div", {
onScroll: update
}, [vue.createVNode("div", null, null)], 40, ["onScroll"]), vue.createVNode("div", {
onScroll: update
}, [vue.createVNode("div", null, null)], 40, ["onScroll"])], 40, ["onAnimationstartOnce"]);
}
});
function useResizeSensorUpdate(rootRef, emit2, reset) {
const size = vue.reactive({
width: -1,
height: -1
});
vue.watch(() => shared.extend({}, size), (value) => emit2("resize", value));
return () => {
const {
offsetWidth,
offsetHeight
} = rootRef.value;
size.width = offsetWidth;
size.height = offsetHeight;
reset();
};
}
function useResizeSensorReset(rootRef) {
return () => {
const {
firstElementChild,
lastElementChild
} = rootRef.value;
firstElementChild.scrollLeft = 1e5;
firstElementChild.scrollTop = 1e5;
lastElementChild.scrollLeft = 1e5;
lastElementChild.scrollTop = 1e5;
};
}
const props$f = {
src: {
type: String,
......@@ -9445,6 +9588,7 @@ exports.setupPage = setupPage;
exports.uni = uni$1;
exports.useAttrs = useAttrs;
exports.useCustomEvent = useCustomEvent;
exports.useNativeEvent = useNativeEvent;
exports.useOn = useOn;
exports.useSubscribe = useSubscribe;
exports.useUserAction = useUserAction;
......
var __defProp = Object.defineProperty;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value;
var __assign = (a2, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a2, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a2, prop, b[prop]);
}
return a2;
};
import {isFunction, extend, hyphenate, isPlainObject, isString, isArray, hasOwn, isObject, capitalize, toRawType, makeMap as makeMap$1, isPromise, invokeArrayFns as invokeArrayFns$1} from "@vue/shared";
import {injectHook, withModifiers, createVNode, getCurrentInstance, inject, provide, reactive, computed, nextTick, onBeforeMount, onMounted, onBeforeActivate, onBeforeDeactivate, openBlock, createBlock, mergeProps, toDisplayString, ref, defineComponent, resolveComponent, toHandlers, renderSlot, watch, onUnmounted, onBeforeUnmount, onActivated, withDirectives, vShow, createCommentVNode, createTextVNode, shallowRef, watchEffect, renderList, onDeactivated, Fragment, Teleport, createApp, Transition, withCtx, KeepAlive, resolveDynamicComponent} from "vue";
import {injectHook, withModifiers, createVNode, getCurrentInstance, inject, provide, reactive, computed, nextTick, onBeforeMount, onMounted, onBeforeActivate, onBeforeDeactivate, openBlock, createBlock, mergeProps, toDisplayString, ref, defineComponent, watch, onActivated, resolveComponent, toHandlers, renderSlot, onUnmounted, onBeforeUnmount, withDirectives, vShow, createCommentVNode, createTextVNode, shallowRef, watchEffect, renderList, onDeactivated, Fragment, Teleport, createApp, Transition, withCtx, KeepAlive, resolveDynamicComponent} from "vue";
import {once, passive, normalizeTarget, isBuiltInComponent, invokeArrayFns, NAVBAR_HEIGHT, parseQuery, PRIMARY_COLOR, removeLeadingSlash, getLen, ON_REACH_BOTTOM_DISTANCE, decodedQuery, debounce, plusReady, updateElementStyle, addFont, scrollTo} from "@dcloudio/uni-shared";
import {initVueI18n, LOCALE_EN, LOCALE_ES, LOCALE_FR, LOCALE_ZH_HANS, LOCALE_ZH_HANT} from "@dcloudio/uni-i18n";
import {useRoute, createRouter, createWebHistory, createWebHashHistory, useRouter, isNavigationFailure, RouterView} from "vue-router";
......@@ -405,14 +421,14 @@ function attrChange(attr2) {
style[attr3] = elementComputedStyle[attr3];
});
changeAttrs.length = 0;
callbacks$2.forEach(function(callback2) {
callbacks$3.forEach(function(callback2) {
callback2(style);
});
}, 0);
}
changeAttrs.push(attr2);
}
var callbacks$2 = [];
var callbacks$3 = [];
function onChange(callback2) {
if (!getSupport()) {
return;
......@@ -421,13 +437,13 @@ function onChange(callback2) {
init();
}
if (typeof callback2 === "function") {
callbacks$2.push(callback2);
callbacks$3.push(callback2);
}
}
function offChange(callback2) {
var index2 = callbacks$2.indexOf(callback2);
var index2 = callbacks$3.indexOf(callback2);
if (index2 >= 0) {
callbacks$2.splice(index2, 1);
callbacks$3.splice(index2, 1);
}
}
var safeAreaInsets = {
......@@ -449,7 +465,7 @@ var safeAreaInsets = {
onChange,
offChange
};
var out = safeAreaInsets;
var D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out = safeAreaInsets;
const onEventPrevent = /* @__PURE__ */ withModifiers(() => {
}, ["prevent"]);
const onEventStop = /* @__PURE__ */ withModifiers(() => {
......@@ -461,10 +477,10 @@ function getWindowOffset() {
const left = parseInt(style.getPropertyValue("--window-left"));
const right = parseInt(style.getPropertyValue("--window-right"));
return {
top: top ? top + out.top : 0,
bottom: bottom ? bottom + out.bottom : 0,
left: left ? left + out.left : 0,
right: right ? right + out.right : 0
top: top ? top + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top : 0,
bottom: bottom ? bottom + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.bottom : 0,
left: left ? left + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.left : 0,
right: right ? right + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.right : 0
};
}
function updateCssVar(cssVars) {
......@@ -640,6 +656,34 @@ function getRealRoute(fromRoute, toRoute) {
fromRouteArray.splice(fromRouteArray.length - i2 - 1, i2 + 1);
return "/" + fromRouteArray.concat(toRouteArray).join("/");
}
const callbacks$2 = {};
function createCallbacks(namespace) {
let scopedCallbacks = callbacks$2[namespace];
if (!scopedCallbacks) {
scopedCallbacks = {
id: 1,
callbacks: Object.create(null)
};
callbacks$2[namespace] = scopedCallbacks;
}
return {
get(id2) {
return scopedCallbacks.callbacks[id2];
},
pop(id2) {
const callback2 = scopedCallbacks.callbacks[id2];
if (callback2) {
delete scopedCallbacks.callbacks[id2];
}
return callback2;
},
push(callback2) {
const id2 = scopedCallbacks.id++;
scopedCallbacks.callbacks[id2] = callback2;
return id2;
}
};
}
const isClickEvent = (val) => val.type === "click";
const isMouseEvent = (val) => val.type.indexOf("mouse") === 0;
function $nne(evt) {
......@@ -672,6 +716,10 @@ function createNativeEvent(evt) {
detail: {},
currentTarget: target
};
if (evt.type.startsWith("touch")) {
event.touches = evt.touches;
event.changedTouches = evt.changedTouches;
}
{
extend(event, {
preventDefault() {
......@@ -731,7 +779,8 @@ function normalizeTouchEvent(touches, top) {
var instance = /* @__PURE__ */ Object.freeze({
__proto__: null,
[Symbol.toStringTag]: "Module",
$nne
$nne,
createNativeEvent
});
const CLASS_RE = /^\s+|\s+$/g;
const WXS_CLASS_RE = /\s+/;
......@@ -1115,7 +1164,7 @@ function normalizePageMeta(pageMeta) {
let offset = rpx2px(refreshOptions.offset);
const {type} = navigationBar;
if (type !== "transparent" && type !== "none") {
offset += NAVBAR_HEIGHT + out.top;
offset += NAVBAR_HEIGHT + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top;
}
refreshOptions.offset = offset;
refreshOptions.height = rpx2px(refreshOptions.height);
......@@ -1701,6 +1750,97 @@ function removeIntersectionObserver({reqId, component}, _pageId) {
delete $el.__io[reqId];
}
}
function saveImage(base64, dirname, callback2) {
callback2(null, base64);
}
const TEMP_PATH = "";
const files = {};
function urlToFile(url, local) {
const file = files[url];
if (file) {
return Promise.resolve(file);
}
if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(url)) {
return Promise.resolve(base64ToFile(url));
}
if (local) {
return Promise.reject(new Error("not find"));
}
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function() {
resolve(this.response);
};
xhr.onerror = reject;
xhr.send();
});
}
function base64ToFile(base64) {
const base64Array = base64.split(",");
const res = base64Array[0].match(/:(.*?);/);
const type = res ? res[1] : "";
const str = atob(base64Array[1]);
let n = str.length;
const array = new Uint8Array(n);
while (n--) {
array[n] = str.charCodeAt(n);
}
return blobToFile(array, type);
}
function getExtname(type) {
const extname = type.split("/")[1];
return extname ? `.${extname}` : "";
}
function getFileName(url) {
url = url.split("#")[0].split("?")[0];
const array = url.split("/");
return array[array.length - 1];
}
function blobToFile(blob, type) {
let file;
if (blob instanceof File) {
file = blob;
} else {
type = type || blob.type || "";
const filename = `${Date.now()}${getExtname(type)}`;
try {
file = new File([blob], filename, {type});
} catch (error) {
blob = blob instanceof Blob ? blob : new Blob([blob], {type});
file = blob;
file.name = file.name || filename;
}
}
return file;
}
function fileToUrl(file) {
for (const key in files) {
if (hasOwn(files, key)) {
const oldFile = files[key];
if (oldFile === file) {
return key;
}
}
}
var url = (window.URL || window.webkitURL).createObjectURL(file);
files[url] = file;
return url;
}
function getSameOriginUrl(url) {
const a2 = document.createElement("a");
a2.href = url;
if (a2.origin === location.origin) {
return Promise.resolve(url);
}
return urlToFile(url).then(fileToUrl);
}
function revokeObjectURL(url) {
const URL = window.URL || window.webkitURL;
URL.revokeObjectURL(url);
delete files[url];
}
const API_UPX2PX = "upx2px";
const Upx2pxProtocol = [
{
......@@ -1833,6 +1973,18 @@ const validator = [
const API_CREATE_VIDEO_CONTEXT = "createVideoContext";
const API_CREATE_MAP_CONTEXT = "createMapContext";
const CreateMapContextProtocol = validator;
const API_CREATE_CANVAS_CONTEXT = "createCanvasContext";
const CreateCanvasContextProtocol = [
{
name: "canvasId",
type: String,
required: true
},
{
name: "componentInstance",
type: Object
}
];
const API_CREATE_INNER_AUDIO_CONTEXT = "createInnerAudioContext";
const RATES = [0.5, 0.8, 1, 1.25, 1.5, 2];
class VideoContext {
......@@ -1994,6 +2146,913 @@ const createSelectorQuery = () => {
const API_ON_TAB_BAR_MID_BUTTON_TAP = "onTabBarMidButtonTap";
const onTabBarMidButtonTap = /* @__PURE__ */ defineOnApi(API_ON_TAB_BAR_MID_BUTTON_TAP, () => {
});
function getInt(name, defaultValue) {
return function(value, params) {
if (value) {
params[name] = Math.round(value);
} else if (typeof defaultValue !== "undefined") {
params[name] = defaultValue;
}
};
}
const formatWidth = getInt("width");
const formatHeight = getInt("height");
const API_CANVAS_GET_IMAGE_DATA = "canvasGetImageData";
const CanvasGetImageDataOptions = {
formatArgs: {
x: getInt("x"),
y: getInt("y"),
width: formatWidth,
height: formatHeight
}
};
const CanvasGetImageDataProtocol = {
canvasId: {
type: String,
required: true
},
x: {
type: Number,
required: true
},
y: {
type: Number,
required: true
},
width: {
type: Number,
required: true
},
height: {
type: Number,
required: true
}
};
const API_CANVAS_PUT_IMAGE_DATA = "canvasPutImageData";
const CanvasPutImageDataOptions = CanvasGetImageDataOptions;
const CanvasPutImageDataProtocol = /* @__PURE__ */ extend({
data: {
type: Uint8ClampedArray,
required: true
}
}, CanvasGetImageDataProtocol);
const fileTypes = {
PNG: "png",
JPG: "jpg",
JPEG: "jpg"
};
const API_CANVAS_TO_TEMP_FILE_PATH = "canvasToTempFilePath";
const CanvasToTempFilePathOptions = {
formatArgs: {
x: getInt("x", 0),
y: getInt("y", 0),
width: formatWidth,
height: formatHeight,
destWidth: getInt("destWidth"),
destHeight: getInt("destHeight"),
fileType(value, params) {
value = (value || "").toUpperCase();
let type = fileTypes[value];
if (!type) {
type = fileTypes.PNG;
}
params.fileType = type;
},
quality(value, params) {
params.quality = value && value > 0 && value < 1 ? value : 1;
}
}
};
const CanvasToTempFilePathProtocol = {
x: Number,
y: Number,
width: Number,
height: Number,
destWidth: Number,
destHeight: Number,
canvasId: {
type: String,
required: true
},
fileType: String,
quality: Number
};
const canvasEventCallbacks = createCallbacks("canvasEvent");
ServiceJSBridge.subscribe("onCanvasMethodCallback", ({callbackId, data}) => {
const callback2 = canvasEventCallbacks.pop(callbackId);
if (callback2) {
callback2(data);
}
});
function operateCanvas(canvasId, pageId, type, data) {
ServiceJSBridge.publishHandler("canvas." + canvasId, {
canvasId,
type,
data
}, pageId);
}
var methods1 = ["scale", "rotate", "translate", "setTransform", "transform"];
var methods2 = [
"drawImage",
"fillText",
"fill",
"stroke",
"fillRect",
"strokeRect",
"clearRect",
"strokeText"
];
var methods3 = [
"setFillStyle",
"setTextAlign",
"setStrokeStyle",
"setGlobalAlpha",
"setShadow",
"setFontSize",
"setLineCap",
"setLineJoin",
"setLineWidth",
"setMiterLimit",
"setTextBaseline",
"setLineDash"
];
function measureText(text2, font2) {
const canvas = document.createElement("canvas");
const c2d = canvas.getContext("2d");
c2d.font = font2;
return c2d.measureText(text2).width || 0;
}
const predefinedColor = {
aliceblue: "#f0f8ff",
antiquewhite: "#faebd7",
aqua: "#00ffff",
aquamarine: "#7fffd4",
azure: "#f0ffff",
beige: "#f5f5dc",
bisque: "#ffe4c4",
black: "#000000",
blanchedalmond: "#ffebcd",
blue: "#0000ff",
blueviolet: "#8a2be2",
brown: "#a52a2a",
burlywood: "#deb887",
cadetblue: "#5f9ea0",
chartreuse: "#7fff00",
chocolate: "#d2691e",
coral: "#ff7f50",
cornflowerblue: "#6495ed",
cornsilk: "#fff8dc",
crimson: "#dc143c",
cyan: "#00ffff",
darkblue: "#00008b",
darkcyan: "#008b8b",
darkgoldenrod: "#b8860b",
darkgray: "#a9a9a9",
darkgrey: "#a9a9a9",
darkgreen: "#006400",
darkkhaki: "#bdb76b",
darkmagenta: "#8b008b",
darkolivegreen: "#556b2f",
darkorange: "#ff8c00",
darkorchid: "#9932cc",
darkred: "#8b0000",
darksalmon: "#e9967a",
darkseagreen: "#8fbc8f",
darkslateblue: "#483d8b",
darkslategray: "#2f4f4f",
darkslategrey: "#2f4f4f",
darkturquoise: "#00ced1",
darkviolet: "#9400d3",
deeppink: "#ff1493",
deepskyblue: "#00bfff",
dimgray: "#696969",
dimgrey: "#696969",
dodgerblue: "#1e90ff",
firebrick: "#b22222",
floralwhite: "#fffaf0",
forestgreen: "#228b22",
fuchsia: "#ff00ff",
gainsboro: "#dcdcdc",
ghostwhite: "#f8f8ff",
gold: "#ffd700",
goldenrod: "#daa520",
gray: "#808080",
grey: "#808080",
green: "#008000",
greenyellow: "#adff2f",
honeydew: "#f0fff0",
hotpink: "#ff69b4",
indianred: "#cd5c5c",
indigo: "#4b0082",
ivory: "#fffff0",
khaki: "#f0e68c",
lavender: "#e6e6fa",
lavenderblush: "#fff0f5",
lawngreen: "#7cfc00",
lemonchiffon: "#fffacd",
lightblue: "#add8e6",
lightcoral: "#f08080",
lightcyan: "#e0ffff",
lightgoldenrodyellow: "#fafad2",
lightgray: "#d3d3d3",
lightgrey: "#d3d3d3",
lightgreen: "#90ee90",
lightpink: "#ffb6c1",
lightsalmon: "#ffa07a",
lightseagreen: "#20b2aa",
lightskyblue: "#87cefa",
lightslategray: "#778899",
lightslategrey: "#778899",
lightsteelblue: "#b0c4de",
lightyellow: "#ffffe0",
lime: "#00ff00",
limegreen: "#32cd32",
linen: "#faf0e6",
magenta: "#ff00ff",
maroon: "#800000",
mediumaquamarine: "#66cdaa",
mediumblue: "#0000cd",
mediumorchid: "#ba55d3",
mediumpurple: "#9370db",
mediumseagreen: "#3cb371",
mediumslateblue: "#7b68ee",
mediumspringgreen: "#00fa9a",
mediumturquoise: "#48d1cc",
mediumvioletred: "#c71585",
midnightblue: "#191970",
mintcream: "#f5fffa",
mistyrose: "#ffe4e1",
moccasin: "#ffe4b5",
navajowhite: "#ffdead",
navy: "#000080",
oldlace: "#fdf5e6",
olive: "#808000",
olivedrab: "#6b8e23",
orange: "#ffa500",
orangered: "#ff4500",
orchid: "#da70d6",
palegoldenrod: "#eee8aa",
palegreen: "#98fb98",
paleturquoise: "#afeeee",
palevioletred: "#db7093",
papayawhip: "#ffefd5",
peachpuff: "#ffdab9",
peru: "#cd853f",
pink: "#ffc0cb",
plum: "#dda0dd",
powderblue: "#b0e0e6",
purple: "#800080",
rebeccapurple: "#663399",
red: "#ff0000",
rosybrown: "#bc8f8f",
royalblue: "#4169e1",
saddlebrown: "#8b4513",
salmon: "#fa8072",
sandybrown: "#f4a460",
seagreen: "#2e8b57",
seashell: "#fff5ee",
sienna: "#a0522d",
silver: "#c0c0c0",
skyblue: "#87ceeb",
slateblue: "#6a5acd",
slategray: "#708090",
slategrey: "#708090",
snow: "#fffafa",
springgreen: "#00ff7f",
steelblue: "#4682b4",
tan: "#d2b48c",
teal: "#008080",
thistle: "#d8bfd8",
tomato: "#ff6347",
turquoise: "#40e0d0",
violet: "#ee82ee",
wheat: "#f5deb3",
white: "#ffffff",
whitesmoke: "#f5f5f5",
yellow: "#ffff00",
yellowgreen: "#9acd32",
transparent: "#00000000"
};
function checkColor(e2) {
e2 = e2 || "#000000";
var t2 = null;
if ((t2 = /^#([0-9|A-F|a-f]{6})$/.exec(e2)) != null) {
const n = parseInt(t2[1].slice(0, 2), 16);
const o2 = parseInt(t2[1].slice(2, 4), 16);
const r = parseInt(t2[1].slice(4), 16);
return [n, o2, r, 255];
}
if ((t2 = /^#([0-9|A-F|a-f]{3})$/.exec(e2)) != null) {
let n = t2[1].slice(0, 1);
let o2 = t2[1].slice(1, 2);
let r = t2[1].slice(2, 3);
n = parseInt(n + n, 16);
o2 = parseInt(o2 + o2, 16);
r = parseInt(r + r, 16);
return [n, o2, r, 255];
}
if ((t2 = /^rgb\((.+)\)$/.exec(e2)) != null) {
return t2[1].split(",").map(function(e22) {
return Math.min(255, parseInt(e22.trim()));
}).concat(255);
}
if ((t2 = /^rgba\((.+)\)$/.exec(e2)) != null) {
return t2[1].split(",").map(function(e22, t22) {
return t22 === 3 ? Math.floor(255 * parseFloat(e22.trim())) : Math.min(255, parseInt(e22.trim()));
});
}
var i2 = e2.toLowerCase();
if (hasOwn(predefinedColor, i2)) {
t2 = /^#([0-9|A-F|a-f]{6,8})$/.exec(predefinedColor[i2]);
const n = parseInt(t2[1].slice(0, 2), 16);
const o2 = parseInt(t2[1].slice(2, 4), 16);
const r = parseInt(t2[1].slice(4, 6), 16);
let a2 = parseInt(t2[1].slice(6, 8), 16);
a2 = a2 >= 0 ? a2 : 255;
return [n, o2, r, a2];
}
console.error("unsupported color:" + e2);
return [0, 0, 0, 255];
}
class CanvasGradient {
constructor(type, data) {
this.type = type;
this.data = data;
this.colorStop = [];
}
addColorStop(position, color) {
this.colorStop.push([position, checkColor(color)]);
}
}
class Pattern {
constructor(image2, repetition) {
this.image = image2;
this.repetition = repetition;
}
}
class TextMetrics {
constructor(width) {
this.width = width;
}
}
class CanvasContext {
constructor(id2, pageId) {
this.id = id2;
this.pageId = pageId;
this.actions = [];
this.path = [];
this.subpath = [];
this.drawingState = [];
this.state = {
lineDash: [0, 0],
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 0,
shadowColor: [0, 0, 0, 0],
font: "10px sans-serif",
fontSize: 10,
fontWeight: "normal",
fontStyle: "normal",
fontFamily: "sans-serif"
};
}
draw(reserve = false, callback2) {
var actions = [...this.actions];
this.actions = [];
this.path = [];
var callbackId;
if (typeof callback2 === "function") {
callbackId = canvasEventCallbacks.push(callback2);
}
operateCanvas(this.id, this.pageId, "actionsChanged", {
actions,
reserve,
callbackId
});
}
createLinearGradient(x0, y0, x1, y1) {
return new CanvasGradient("linear", [x0, y0, x1, y1]);
}
createCircularGradient(x, y, r) {
return new CanvasGradient("radial", [x, y, r]);
}
createPattern(image2, repetition) {
if (repetition === void 0) {
console.error("Failed to execute 'createPattern' on 'CanvasContext': 2 arguments required, but only 1 present.");
} else if (["repeat", "repeat-x", "repeat-y", "no-repeat"].indexOf(repetition) < 0) {
console.error("Failed to execute 'createPattern' on 'CanvasContext': The provided type ('" + repetition + "') is not one of 'repeat', 'no-repeat', 'repeat-x', or 'repeat-y'.");
} else {
return new Pattern(image2, repetition);
}
}
measureText(text2) {
const font2 = this.state.font;
let width = 0;
{
width = measureText(text2, font2);
}
return new TextMetrics(width);
}
save() {
this.actions.push({
method: "save",
data: []
});
this.drawingState.push(this.state);
}
restore() {
this.actions.push({
method: "restore",
data: []
});
this.state = this.drawingState.pop() || {
lineDash: [0, 0],
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 0,
shadowColor: [0, 0, 0, 0],
font: "10px sans-serif",
fontSize: 10,
fontWeight: "normal",
fontStyle: "normal",
fontFamily: "sans-serif"
};
}
beginPath() {
this.path = [];
this.subpath = [];
}
moveTo(x, y) {
this.path.push({
method: "moveTo",
data: [x, y]
});
this.subpath = [[x, y]];
}
lineTo(x, y) {
if (this.path.length === 0 && this.subpath.length === 0) {
this.path.push({
method: "moveTo",
data: [x, y]
});
} else {
this.path.push({
method: "lineTo",
data: [x, y]
});
}
this.subpath.push([x, y]);
}
quadraticCurveTo(cpx, cpy, x, y) {
this.path.push({
method: "quadraticCurveTo",
data: [cpx, cpy, x, y]
});
this.subpath.push([x, y]);
}
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
this.path.push({
method: "bezierCurveTo",
data: [cp1x, cp1y, cp2x, cp2y, x, y]
});
this.subpath.push([x, y]);
}
arc(x, y, r, sAngle, eAngle, counterclockwise = false) {
this.path.push({
method: "arc",
data: [x, y, r, sAngle, eAngle, counterclockwise]
});
this.subpath.push([x, y]);
}
rect(x, y, width, height) {
this.path.push({
method: "rect",
data: [x, y, width, height]
});
this.subpath = [[x, y]];
}
arcTo(x1, y1, x2, y2, radius) {
this.path.push({
method: "arcTo",
data: [x1, y1, x2, y2, radius]
});
this.subpath.push([x2, y2]);
}
clip() {
this.actions.push({
method: "clip",
data: [...this.path]
});
}
closePath() {
this.path.push({
method: "closePath",
data: []
});
if (this.subpath.length) {
this.subpath = [this.subpath.shift()];
}
}
clearActions() {
this.actions = [];
this.path = [];
this.subpath = [];
}
getActions() {
var actions = [...this.actions];
this.clearActions();
return actions;
}
set lineDashOffset(value) {
this.actions.push({
method: "setLineDashOffset",
data: [value]
});
}
set globalCompositeOperation(type) {
this.actions.push({
method: "setGlobalCompositeOperation",
data: [type]
});
}
set shadowBlur(level) {
this.actions.push({
method: "setShadowBlur",
data: [level]
});
}
set shadowColor(color) {
this.actions.push({
method: "setShadowColor",
data: [color]
});
}
set shadowOffsetX(x) {
this.actions.push({
method: "setShadowOffsetX",
data: [x]
});
}
set shadowOffsetY(y) {
this.actions.push({
method: "setShadowOffsetY",
data: [y]
});
}
set font(value) {
var self = this;
this.state.font = value;
var fontFormat = value.match(/^(([\w\-]+\s)*)(\d+r?px)(\/(\d+\.?\d*(r?px)?))?\s+(.*)/);
if (fontFormat) {
var style = fontFormat[1].trim().split(/\s/);
var fontSize = parseFloat(fontFormat[3]);
var fontFamily = fontFormat[7];
var actions = [];
style.forEach(function(value2, index2) {
if (["italic", "oblique", "normal"].indexOf(value2) > -1) {
actions.push({
method: "setFontStyle",
data: [value2]
});
self.state.fontStyle = value2;
} else if (["bold", "normal"].indexOf(value2) > -1) {
actions.push({
method: "setFontWeight",
data: [value2]
});
self.state.fontWeight = value2;
} else if (index2 === 0) {
actions.push({
method: "setFontStyle",
data: ["normal"]
});
self.state.fontStyle = "normal";
} else if (index2 === 1) {
pushAction();
}
});
if (style.length === 1) {
pushAction();
}
style = actions.map(function(action) {
return action.data[0];
}).join(" ");
this.state.fontSize = fontSize;
this.state.fontFamily = fontFamily;
this.actions.push({
method: "setFont",
data: [`${style} ${fontSize}px ${fontFamily}`]
});
} else {
console.warn("Failed to set 'font' on 'CanvasContext': invalid format.");
}
function pushAction() {
actions.push({
method: "setFontWeight",
data: ["normal"]
});
self.state.fontWeight = "normal";
}
}
get font() {
return this.state.font;
}
set fillStyle(color) {
this.setFillStyle(color);
}
set strokeStyle(color) {
this.setStrokeStyle(color);
}
set globalAlpha(value) {
value = Math.floor(255 * parseFloat(value));
this.actions.push({
method: "setGlobalAlpha",
data: [value]
});
}
set textAlign(align2) {
this.actions.push({
method: "setTextAlign",
data: [align2]
});
}
set lineCap(type) {
this.actions.push({
method: "setLineCap",
data: [type]
});
}
set lineJoin(type) {
this.actions.push({
method: "setLineJoin",
data: [type]
});
}
set lineWidth(value) {
this.actions.push({
method: "setLineWidth",
data: [value]
});
}
set miterLimit(value) {
this.actions.push({
method: "setMiterLimit",
data: [value]
});
}
set textBaseline(type) {
this.actions.push({
method: "setTextBaseline",
data: [type]
});
}
}
[...methods1, ...methods2].forEach(function(method) {
function get(method2) {
switch (method2) {
case "fill":
case "stroke":
return function() {
this.actions.push({
method: method2 + "Path",
data: [...this.path]
});
};
case "fillRect":
return function(x, y, width, height) {
this.actions.push({
method: "fillPath",
data: [
{
method: "rect",
data: [x, y, width, height]
}
]
});
};
case "strokeRect":
return function(x, y, width, height) {
this.actions.push({
method: "strokePath",
data: [
{
method: "rect",
data: [x, y, width, height]
}
]
});
};
case "fillText":
case "strokeText":
return function(text2, x, y, maxWidth) {
var data = [text2.toString(), x, y];
if (typeof maxWidth === "number") {
data.push(maxWidth);
}
this.actions.push({
method: method2,
data
});
};
case "drawImage":
return function(imageResource, dx, dy, dWidth, dHeight, sx, sy, sWidth, sHeight) {
if (sHeight === void 0) {
sx = dx;
sy = dy;
sWidth = dWidth;
sHeight = dHeight;
dx = void 0;
dy = void 0;
dWidth = void 0;
dHeight = void 0;
}
var data;
function isNumber(e2) {
return typeof e2 === "number";
}
data = isNumber(dx) && isNumber(dy) && isNumber(dWidth) && isNumber(dHeight) ? [
imageResource,
sx,
sy,
sWidth,
sHeight,
dx,
dy,
dWidth,
dHeight
] : isNumber(sWidth) && isNumber(sHeight) ? [imageResource, sx, sy, sWidth, sHeight] : [imageResource, sx, sy];
this.actions.push({
method: method2,
data
});
};
default:
return function(...data) {
this.actions.push({
method: method2,
data
});
};
}
}
CanvasContext.prototype[method] = get(method);
});
methods3.forEach(function(method) {
function get(method2) {
switch (method2) {
case "setFillStyle":
case "setStrokeStyle":
return function(color) {
if (typeof color !== "object") {
this.actions.push({
method: method2,
data: ["normal", checkColor(color)]
});
} else {
this.actions.push({
method: method2,
data: [color.type, color.data, color.colorStop]
});
}
};
case "setGlobalAlpha":
return function(alpha) {
alpha = Math.floor(255 * parseFloat(alpha));
this.actions.push({
method: method2,
data: [alpha]
});
};
case "setShadow":
return function(offsetX, offsetY, blur, color) {
color = checkColor(color);
this.actions.push({
method: method2,
data: [offsetX, offsetY, blur, color]
});
this.state.shadowBlur = blur;
this.state.shadowColor = color;
this.state.shadowOffsetX = offsetX;
this.state.shadowOffsetY = offsetY;
};
case "setLineDash":
return function(pattern, offset) {
pattern = pattern || [0, 0];
offset = offset || 0;
this.actions.push({
method: method2,
data: [pattern, offset]
});
this.state.lineDash = pattern;
};
case "setFontSize":
return function(fontSize) {
this.state.font = this.state.font.replace(/\d+\.?\d*px/, fontSize + "px");
this.state.fontSize = fontSize;
this.actions.push({
method: method2,
data: [fontSize]
});
};
default:
return function(...data) {
this.actions.push({
method: method2,
data
});
};
}
}
CanvasContext.prototype[method] = get(method);
});
const createCanvasContext = /* @__PURE__ */ defineSyncApi(API_CREATE_CANVAS_CONTEXT, (canvasId, componentInstance) => {
if (componentInstance) {
return new CanvasContext(canvasId, componentInstance.$page.id);
}
const pageId = getCurrentPageId();
if (pageId) {
return new CanvasContext(canvasId, pageId);
} else {
UniServiceJSBridge.emit("onError", "createCanvasContext:fail");
}
}, CreateCanvasContextProtocol);
const canvasGetImageData = /* @__PURE__ */ defineAsyncApi(API_CANVAS_GET_IMAGE_DATA, ({canvasId, x, y, width, height}, {resolve, reject}) => {
const pageId = getCurrentPageId();
if (!pageId) {
reject();
return;
}
const cId = canvasEventCallbacks.push(async function(data) {
let imgData = data.data;
if (imgData && imgData.length) {
data.data = new Uint8ClampedArray(imgData);
}
resolve(data);
});
operateCanvas(canvasId, pageId, "getImageData", {
x,
y,
width,
height,
callbackId: cId
});
}, CanvasGetImageDataProtocol, CanvasGetImageDataOptions);
const canvasPutImageData = /* @__PURE__ */ defineAsyncApi(API_CANVAS_PUT_IMAGE_DATA, async ({canvasId, data, x, y, width, height}, {resolve, reject}) => {
var pageId = getCurrentPageId();
if (!pageId) {
reject();
return;
}
var cId = canvasEventCallbacks.push(function(data2) {
resolve(data2);
});
let compressed;
{
data = Array.prototype.slice.call(data);
}
operateCanvas(canvasId, pageId, "putImageData", {
data,
x,
y,
width,
height,
compressed,
callbackId: cId
});
}, CanvasPutImageDataProtocol, CanvasPutImageDataOptions);
const canvasToTempFilePath = /* @__PURE__ */ defineAsyncApi(API_CANVAS_TO_TEMP_FILE_PATH, ({
x = 0,
y = 0,
width,
height,
destWidth,
destHeight,
canvasId,
fileType,
quality
}, {resolve, reject}) => {
var pageId = getCurrentPageId();
if (!pageId) {
reject();
return;
}
const cId = canvasEventCallbacks.push(function(res) {
resolve(res);
});
const dirname = `${TEMP_PATH}/canvas`;
operateCanvas(canvasId, pageId, "toTempFilePath", {
x,
y,
width,
height,
destWidth,
destHeight,
fileType,
quality,
dirname,
callbackId: cId
});
}, CanvasToTempFilePathProtocol, CanvasToTempFilePathOptions);
const API_CAN_I_USE = "canIUse";
const CanIUseProtocol = [
{
......@@ -4224,6 +5283,98 @@ var index$k = /* @__PURE__ */ defineComponent({
};
}
});
var ResizeSensor = /* @__PURE__ */ defineComponent({
name: "ResizeSensor",
props: {
initial: {
type: Boolean,
default: false
}
},
emits: ["resize"],
setup(props2, {
emit: emit2
}) {
const rootRef = ref(null);
const reset = useResizeSensorReset(rootRef);
const update = useResizeSensorUpdate(rootRef, emit2, reset);
useResizeSensorLifecycle(rootRef, props2, update, reset);
return () => createVNode("uni-resize-sensor", {
ref: rootRef,
onAnimationstartOnce: update
}, [createVNode("div", {
onScroll: update
}, [createVNode("div", null, null)], 40, ["onScroll"]), createVNode("div", {
onScroll: update
}, [createVNode("div", null, null)], 40, ["onScroll"])], 40, ["onAnimationstartOnce"]);
}
});
function useResizeSensorUpdate(rootRef, emit2, reset) {
const size = reactive({
width: -1,
height: -1
});
watch(() => extend({}, size), (value) => emit2("resize", value));
return () => {
const {
offsetWidth,
offsetHeight
} = rootRef.value;
size.width = offsetWidth;
size.height = offsetHeight;
reset();
};
}
function useResizeSensorReset(rootRef) {
return () => {
const {
firstElementChild,
lastElementChild
} = rootRef.value;
firstElementChild.scrollLeft = 1e5;
firstElementChild.scrollTop = 1e5;
lastElementChild.scrollLeft = 1e5;
lastElementChild.scrollTop = 1e5;
};
}
function useResizeSensorLifecycle(rootRef, props2, update, reset) {
onActivated(reset);
onMounted(() => {
if (props2.initial) {
nextTick(update);
}
const rootEl = rootRef.value;
if (rootEl.offsetParent !== rootEl.parentElement) {
rootEl.parentElement.style.position = "relative";
}
if (!("AnimationEvent" in window)) {
reset();
}
});
}
function withWebEvent(fn) {
return fn.__wwe = true, fn;
}
function useCustomEvent(ref2, emit2) {
return (name, evt, detail) => {
emit2(name, normalizeCustomEvent(name, evt, ref2.value, detail || {}));
};
}
function useNativeEvent(emit2) {
return (name, evt) => {
emit2(name, createNativeEvent(evt));
};
}
function normalizeCustomEvent(name, domEvt, el, detail) {
const target = normalizeTarget(el);
return {
type: detail.type || name,
timeStamp: domEvt.timeStamp || 0,
target,
currentTarget: target,
detail
};
}
const pixelRatio = /* @__PURE__ */ function() {
const canvas = document.createElement("canvas");
canvas.height = canvas.width = 0;
......@@ -4236,6 +5387,130 @@ function wrapper(canvas) {
canvas.height = canvas.offsetHeight * pixelRatio;
canvas.getContext("2d").__hidpi__ = true;
}
let isHidpi = false;
function initHidpi() {
if (isHidpi) {
return;
}
isHidpi = true;
const forEach = function(obj, func) {
for (const key in obj) {
if (hasOwn(obj, key)) {
func(obj[key], key);
}
}
};
const ratioArgs = {
fillRect: "all",
clearRect: "all",
strokeRect: "all",
moveTo: "all",
lineTo: "all",
arc: [0, 1, 2],
arcTo: "all",
bezierCurveTo: "all",
isPointinPath: "all",
isPointinStroke: "all",
quadraticCurveTo: "all",
rect: "all",
translate: "all",
createRadialGradient: "all",
createLinearGradient: "all",
setTransform: [4, 5]
};
const proto = CanvasRenderingContext2D.prototype;
proto.drawImageByCanvas = function(_super) {
return function(canvas, srcx, srcy, srcw, srch, desx, desy, desw, desh, isScale) {
if (!this.__hidpi__) {
return _super.apply(this, arguments);
}
srcx *= pixelRatio;
srcy *= pixelRatio;
srcw *= pixelRatio;
srch *= pixelRatio;
desx *= pixelRatio;
desy *= pixelRatio;
desw = isScale ? desw * pixelRatio : desw;
desh = isScale ? desh * pixelRatio : desh;
_super.call(this, canvas, srcx, srcy, srcw, srch, desx, desy, desw, desh);
};
}(proto.drawImage);
if (pixelRatio !== 1) {
forEach(ratioArgs, function(value, key) {
proto[key] = function(_super) {
return function() {
if (!this.__hidpi__) {
return _super.apply(this, arguments);
}
let args = Array.prototype.slice.call(arguments);
if (value === "all") {
args = args.map(function(a2) {
return a2 * pixelRatio;
});
} else if (Array.isArray(value)) {
for (let i2 = 0; i2 < value.length; i2++) {
args[value[i2]] *= pixelRatio;
}
}
return _super.apply(this, args);
};
}(proto[key]);
});
proto.stroke = function(_super) {
return function() {
if (!this.__hidpi__) {
return _super.apply(this, arguments);
}
this.lineWidth *= pixelRatio;
_super.apply(this, arguments);
this.lineWidth /= pixelRatio;
};
}(proto.stroke);
proto.fillText = function(_super) {
return function() {
if (!this.__hidpi__) {
return _super.apply(this, arguments);
}
const args = Array.prototype.slice.call(arguments);
args[1] *= pixelRatio;
args[2] *= pixelRatio;
var font2 = this.font;
this.font = font2.replace(/(\d+\.?\d*)(px|em|rem|pt)/g, function(w, m, u) {
return m * pixelRatio + u;
});
_super.apply(this, args);
this.font = font2;
};
}(proto.fillText);
proto.strokeText = function(_super) {
return function() {
if (!this.__hidpi__) {
return _super.apply(this, arguments);
}
var args = Array.prototype.slice.call(arguments);
args[1] *= pixelRatio;
args[2] *= pixelRatio;
var font2 = this.font;
this.font = font2.replace(/(\d+\.?\d*)(px|em|rem|pt)/g, function(w, m, u) {
return m * pixelRatio + u;
});
_super.apply(this, args);
this.font = font2;
};
}(proto.strokeText);
proto.drawImage = function(_super) {
return function() {
if (!this.__hidpi__) {
return _super.apply(this, arguments);
}
this.scale(pixelRatio, pixelRatio);
_super.apply(this, arguments);
this.scale(1 / pixelRatio, 1 / pixelRatio);
};
}(proto.drawImage);
}
}
initHidpi();
function resolveColor(color) {
color = color.slice(0);
color[3] = color[3] / 255;
......@@ -4260,9 +5535,12 @@ function getTempCanvas(width = 0, height = 0) {
tempCanvas.height = height;
return tempCanvas;
}
const _sfc_main$8 = {
var _sfc_main$8 = {
name: "Canvas",
mixins: [subscriber],
inheritAttrs: false,
components: {
ResizeSensor
},
props: {
canvasId: {
type: String,
......@@ -4283,21 +5561,37 @@ const _sfc_main$8 = {
return this.canvasId;
},
_listeners() {
var $listeners = Object.assign({}, this.$listeners);
var events = ["touchstart", "touchmove", "touchend"];
let events = ["touchstart", "touchmove", "touchend"];
let _$listeners = this.Listeners;
let $listeners = Object.assign({}, (() => {
let obj = {};
for (const key in _$listeners) {
if (Object.prototype.hasOwnProperty.call(_$listeners, key)) {
const event = _$listeners[key];
obj[key.replace("on", "").toLowerCase()] = event;
}
}
return obj;
})());
events.forEach((event) => {
var existing = $listeners[event];
var eventHandler = [];
let existing = $listeners[event];
let eventHandler = [];
if (existing) {
eventHandler.push(($event) => {
this.$trigger(event, Object.assign({}, $event, {
eventHandler.push(withWebEvent(($event) => {
this.$trigger(event, Object.assign({}, (() => {
let obj = {};
for (const key in $event) {
obj[key] = $event[key];
}
return obj;
})(), {
touches: processTouches($event.currentTarget, $event.touches),
changedTouches: processTouches($event.currentTarget, $event.changedTouches)
}));
});
}));
}
if (this.disableScroll && event === "touchmove") {
eventHandler.push(this._touchmove);
eventHandler.push(onEventPrevent);
}
$listeners[event] = eventHandler;
});
......@@ -4307,46 +5601,35 @@ const _sfc_main$8 = {
created() {
this._actionsDefer = [];
this._images = {};
useSubscribe(this._handleSubscribe);
},
mounted() {
this._resize({
width: this.$refs.sensor.$el.offsetWidth,
height: this.$refs.sensor.$el.offsetHeight
});
this.$trigger = useNativeEvent(this.$emit);
this._resize();
},
beforeDestroy() {
const canvas = this.$refs.canvas;
beforeUnmount() {
const canvas = this.canvas;
canvas.height = canvas.width = 0;
},
methods: {
_handleSubscribe({
type,
data = {}
}) {
_handleSubscribe(type, data = {}) {
var method = this[type];
if (type.indexOf("_") !== 0 && typeof method === "function") {
method(data);
}
},
_resize() {
var canvas = this.$refs.canvas;
var canvas = this.canvas;
if (canvas.width > 0 && canvas.height > 0) {
var context = canvas.getContext("2d");
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
wrapper(this.$refs.canvas);
wrapper(canvas);
context.putImageData(imageData, 0, 0);
} else {
wrapper(this.$refs.canvas);
wrapper(canvas);
}
},
_touchmove(event) {
event.preventDefault();
},
actionsChanged({
actions,
reserve,
callbackId
}) {
actionsChanged({actions, reserve, callbackId}) {
var self = this;
if (!actions) {
return;
......@@ -4355,7 +5638,7 @@ const _sfc_main$8 = {
this._actionsDefer.push([actions, reserve, callbackId]);
return;
}
var canvas = this.$refs.canvas;
var canvas = this.canvas;
var c2d = canvas.getContext("2d");
if (!reserve) {
c2d.fillStyle = "#000000";
......@@ -4416,24 +5699,21 @@ const _sfc_main$8 = {
data.forEach(function(color_, method_) {
c2d[_[method_]] = _[method_] === "shadowColor" ? resolveColor(color_) : color_;
});
} else {
if (method1 === "fontSize") {
c2d.font = c2d.font.replace(/\d+\.?\d*px/, data[0] + "px");
} else {
if (method1 === "lineDash") {
c2d.setLineDash(data[0]);
c2d.lineDashOffset = data[1] || 0;
} else {
if (method1 === "textBaseline") {
if (data[0] === "normal") {
data[0] = "alphabetic";
}
c2d[method1] = data[0];
} else {
c2d[method1] = data[0];
}
}
} else if (method1 === "fontSize") {
const font2 = c2d.__font__ || c2d.font;
c2d.__font__ = c2d.font = font2.replace(/\d+\.?\d*px/, data[0] + "px");
} else if (method1 === "lineDash") {
c2d.setLineDash(data[0]);
c2d.lineDashOffset = data[1] || 0;
} else if (method1 === "textBaseline") {
if (data[0] === "normal") {
data[0] = "alphabetic";
}
c2d[method1] = data[0];
} else if (method1 === "font") {
c2d.__font__ = c2d.font = data[0];
} else {
c2d[method1] = data[0];
}
} else if (method === "fillPath" || method === "strokePath") {
method = method.replace(/Path/, "");
......@@ -4472,12 +5752,12 @@ const _sfc_main$8 = {
}
}
if (!this.actionsWaiting && callbackId) {
UniViewJSBridge.publishHandler("onDrawCanvas", {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "drawCanvas:ok"
}
}, this.$page.id);
}, getCurrentPageId());
}
},
preloadImage: function(actions) {
......@@ -4499,59 +5779,15 @@ const _sfc_main$8 = {
loadImage();
}
function loadImage() {
self._images[src] = new Image();
self._images[src].onload = function() {
self._images[src].ready = true;
const image2 = self._images[src] = new Image();
image2.onload = function() {
image2.ready = true;
};
function loadBlob(blob) {
self._images[src].src = (window.URL || window.webkitURL).createObjectURL(blob);
}
function loadFile(path) {
var bitmap = new plus.nativeObj.Bitmap("bitmap" + Date.now());
bitmap.load(path, function() {
self._images[src].src = bitmap.toBase64Data();
bitmap.clear();
}, function() {
bitmap.clear();
console.error("preloadImage error");
});
}
function loadUrl(url) {
function plusDownload() {
plus.downloader.createDownload(url, {
filename: "_doc/uniapp_temp/download/"
}, function(d, status) {
if (status === 200) {
loadFile(d.filename);
} else {
self._images[src].src = src;
}
}).start();
}
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function() {
if (this.status === 200) {
loadBlob(this.response);
}
};
xhr.onerror = window.plus ? plusDownload : function() {
self._images[src].src = src;
};
xhr.send();
}
if (window.plus && (!window.webkit || !window.webkit.messageHandlers)) {
self._images[src].src = src;
} else {
if (window.plus && src.indexOf("http://") !== 0 && src.indexOf("https://") !== 0 && !/^data:.*,.*/.test(src)) {
loadFile(src);
} else if (/^data:.*,.*/.test(src)) {
self._images[src].src = src;
} else {
loadUrl(src);
}
}
getSameOriginUrl(src).then((src2) => {
image2.src = src2;
}).catch(() => {
image2.src = src;
});
}
});
},
......@@ -4590,83 +5826,86 @@ const _sfc_main$8 = {
destWidth,
destHeight,
hidpi = true,
dataType: dataType2,
quality = 1,
type = "png",
callbackId
}) {
var imgData;
var canvas = this.$refs.canvas;
if (!width) {
width = canvas.offsetWidth - x;
}
if (!height) {
height = canvas.offsetHeight - y;
}
const canvas = this.canvas;
let data;
const maxWidth = canvas.offsetWidth - x;
width = width ? Math.min(width, maxWidth) : maxWidth;
const maxHeight = canvas.offsetHeight - y;
height = height ? Math.min(height, maxHeight) : maxHeight;
if (!hidpi) {
if (!destWidth && !destHeight) {
destWidth = Math.round(width * pixelRatio);
destHeight = Math.round(height * pixelRatio);
} else if (!destWidth) {
destWidth = Math.round(width / height * destHeight);
} else if (!destHeight) {
destHeight = Math.round(height / width * destWidth);
}
} else {
destWidth = width;
destHeight = height;
}
const newCanvas = getTempCanvas(destWidth, destHeight);
const context = newCanvas.getContext("2d");
if (type === "jpeg" || type === "jpg") {
type = "jpeg";
context.fillStyle = "#fff";
context.fillRect(0, 0, destWidth, destHeight);
}
context.__hidpi__ = true;
context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false);
let result;
try {
if (!hidpi) {
if (!destWidth && !destHeight) {
destWidth = Math.round(width * pixelRatio);
destHeight = Math.round(height * pixelRatio);
} else if (!destWidth) {
destWidth = Math.round(width / height * destHeight);
} else if (!destHeight) {
destHeight = Math.round(height / width * destWidth);
}
let compressed;
if (dataType2 === "base64") {
data = newCanvas.toDataURL(`image/${type}`, quality);
} else {
destWidth = width;
destHeight = height;
}
const newCanvas = getTempCanvas(destWidth, destHeight);
const context = newCanvas.getContext("2d");
context.__hidpi__ = true;
context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false);
imgData = context.getImageData(0, 0, destWidth, destHeight);
newCanvas.height = newCanvas.width = 0;
context.__hidpi__ = false;
} catch (error) {
if (!callbackId) {
return;
}
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetImageData:fail"
const imgData = context.getImageData(0, 0, destWidth, destHeight);
if (false)
;
else {
data = Array.prototype.slice.call(imgData.data);
}
}, this.$page.id);
return;
}
if (!callbackId) {
return {
data: Array.prototype.slice.call(imgData.data),
}
result = {
errMsg: "canvasGetImageData:ok",
data,
compressed,
width: destWidth,
height: destHeight
};
} catch (error) {
result = {
errMsg: `canvasGetImageData:fail ${error}`
};
}
newCanvas.height = newCanvas.width = 0;
context.__hidpi__ = false;
if (!callbackId) {
return result;
} else {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetImageData:ok",
data: [...imgData.data],
width: destWidth,
height: destHeight
}
}, this.$page.id);
data: result
}, getCurrentPageId());
}
},
putImageData({
data,
x,
y,
width,
height,
callbackId
}) {
putImageData({data, x, y, width, height, compressed, callbackId}) {
try {
if (!height) {
height = Math.round(data.length / 4 / width);
}
const canvas = getTempCanvas(width, height);
const context = canvas.getContext("2d");
if (false)
;
context.putImageData(new ImageData(new Uint8ClampedArray(data), width, height), 0, 0);
this.$refs.canvas.getContext("2d").drawImage(canvas, x, y, width, height);
this.canvas.getContext("2d").drawImage(canvas, x, y, width, height);
canvas.height = canvas.width = 0;
} catch (error) {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
......@@ -4674,7 +5913,7 @@ const _sfc_main$8 = {
data: {
errMsg: "canvasPutImageData:fail"
}
}, this.$page.id);
}, getCurrentPageId());
return;
}
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
......@@ -4682,18 +5921,18 @@ const _sfc_main$8 = {
data: {
errMsg: "canvasPutImageData:ok"
}
}, this.$page.id);
}, getCurrentPageId());
},
getDataUrl({
toTempFilePath({
x = 0,
y = 0,
width,
height,
destWidth,
destHeight,
hidpi = true,
fileType,
qualit,
quality,
dirname,
callbackId
}) {
const res = this.getImageData({
......@@ -4703,76 +5942,72 @@ const _sfc_main$8 = {
height,
destWidth,
destHeight,
hidpi
hidpi: false,
dataType: "base64",
type: fileType,
quality
});
if (!res.data || !res.data.length) {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetDataUrl:fail"
}
}, this.$page.id);
return;
}
let imgData;
try {
imgData = new ImageData(new Uint8ClampedArray(res.data), res.width, res.height);
} catch (error) {
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetDataUrl:fail"
errMsg: res.errMsg.replace("canvasPutImageData", "toTempFilePath")
}
}, this.$page.id);
}, getCurrentPageId());
return;
}
destWidth = res.width;
destHeight = res.height;
const canvas = getTempCanvas(destWidth, destHeight);
const c2d = canvas.getContext("2d");
c2d.putImageData(imgData, 0, 0);
let base64 = canvas.toDataURL("image/png");
canvas.height = canvas.width = 0;
const img = new Image();
img.onload = () => {
const canvas2 = getTempCanvas(destWidth, destHeight);
if (fileType === "jpeg" || fileType === "jpg") {
fileType = "jpeg";
c2d.fillStyle = "#fff";
c2d.fillRect(0, 0, destWidth, destHeight);
}
c2d.drawImage(img, 0, 0);
base64 = canvas2.toDataURL(`image/${fileType}`, qualit);
canvas2.height = canvas2.width = 0;
saveImage(res.data, dirname, (error, tempFilePath) => {
let errMsg = `toTempFilePath:${error ? "fail" : "ok"}`;
if (error) {
errMsg += ` ${error.message}`;
}
UniViewJSBridge.publishHandler("onCanvasMethodCallback", {
callbackId,
data: {
errMsg: "canvasGetDataUrl:ok",
base64
errMsg,
tempFilePath
}
}, this.$page.id);
};
img.src = base64;
}, getCurrentPageId());
});
}
},
setup() {
const canvas = ref(null);
const sensor = ref(null);
const {
$attrs: Attrs,
$excludeAttrs: ExcludeAttrs,
$listeners: Listeners
} = useAttrs({
excludeListeners: true
});
return {
canvas,
sensor,
Attrs,
ExcludeAttrs,
Listeners
};
}
};
const _hoisted_1$5 = {
class: "uni-canvas-canvas",
ref: "canvas",
width: "300",
height: "150"
};
const _hoisted_2$2 = {style: {position: "absolute", top: "0", left: "0", width: "100%", height: "100%", overflow: "hidden"}};
function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
const _component_v_uni_resize_sensor = resolveComponent("v-uni-resize-sensor");
const _component_ResizeSensor = resolveComponent("ResizeSensor");
return openBlock(), createBlock("uni-canvas", mergeProps({
"canvas-id": $props.canvasId,
"disable-scroll": $props.disableScroll
}, toHandlers($options._listeners)), [
}, __assign(__assign({}, $setup.Attrs), $setup.ExcludeAttrs), toHandlers($options._listeners)), [
createVNode("canvas", _hoisted_1$5, null, 512),
createVNode("div", _hoisted_2$2, [
renderSlot(_ctx.$slots, "default")
]),
createVNode(_component_v_uni_resize_sensor, {
createVNode(_component_ResizeSensor, {
ref: "sensor",
onResize: $options._resize
}, null, 8, ["onResize"])
......@@ -4833,24 +6068,6 @@ function _removeListeners(id2, listeners, watch2) {
}
});
}
function withWebEvent(fn) {
return fn.__wwe = true, fn;
}
function useCustomEvent(ref2, emit2) {
return (name, evt, detail) => {
emit2(name, normalizeCustomEvent(name, evt, ref2.value, detail || {}));
};
}
function normalizeCustomEvent(name, domEvt, el, detail) {
const target = normalizeTarget(el);
return {
type: detail.type || name,
timeStamp: domEvt.timeStamp || 0,
target,
currentTarget: target,
detail
};
}
const uniCheckGroupKey = PolySymbol(process.env.NODE_ENV !== "production" ? "uniCheckGroup" : "ucg");
const props$m = {
name: {
......@@ -5923,75 +7140,6 @@ var index$f = /* @__PURE__ */ defineComponent({
return () => createVNode("uni-icon", null, [path.value.d && createSvgIconVNode(path.value.d, props2.color || path.value.c, rpx2px(props2.size))]);
}
});
var ResizeSensor = /* @__PURE__ */ defineComponent({
name: "ResizeSensor",
props: {
initial: {
type: Boolean,
default: false
}
},
emits: ["resize"],
setup(props2, {
emit: emit2
}) {
const rootRef = ref(null);
const reset = useResizeSensorReset(rootRef);
const update = useResizeSensorUpdate(rootRef, emit2, reset);
useResizeSensorLifecycle(rootRef, props2, update, reset);
return () => createVNode("uni-resize-sensor", {
ref: rootRef,
onAnimationstartOnce: update
}, [createVNode("div", {
onScroll: update
}, [createVNode("div", null, null)], 40, ["onScroll"]), createVNode("div", {
onScroll: update
}, [createVNode("div", null, null)], 40, ["onScroll"])], 40, ["onAnimationstartOnce"]);
}
});
function useResizeSensorUpdate(rootRef, emit2, reset) {
const size = reactive({
width: -1,
height: -1
});
watch(() => extend({}, size), (value) => emit2("resize", value));
return () => {
const {
offsetWidth,
offsetHeight
} = rootRef.value;
size.width = offsetWidth;
size.height = offsetHeight;
reset();
};
}
function useResizeSensorReset(rootRef) {
return () => {
const {
firstElementChild,
lastElementChild
} = rootRef.value;
firstElementChild.scrollLeft = 1e5;
firstElementChild.scrollTop = 1e5;
lastElementChild.scrollLeft = 1e5;
lastElementChild.scrollTop = 1e5;
};
}
function useResizeSensorLifecycle(rootRef, props2, update, reset) {
onActivated(reset);
onMounted(() => {
if (props2.initial) {
nextTick(update);
}
const rootEl = rootRef.value;
if (rootEl.offsetParent !== rootEl.parentElement) {
rootEl.parentElement.style.position = "relative";
}
if (!("AnimationEvent" in window)) {
reset();
}
});
}
const props$h = {
src: {
type: String,
......@@ -12073,7 +13221,7 @@ const getSystemInfoSync = /* @__PURE__ */ defineSyncApi("getSystemInfoSync", ()
const windowWidth = getWindowWidth(screenWidth);
let windowHeight = window.innerHeight;
const language = navigator.language;
const statusBarHeight = out.top;
const statusBarHeight = D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top;
let osname;
let osversion;
let model;
......@@ -12186,12 +13334,12 @@ const getSystemInfoSync = /* @__PURE__ */ defineSyncApi("getSystemInfoSync", ()
const system = `${osname} ${osversion}`;
const platform = osname.toLocaleLowerCase();
const safeArea = {
left: out.left,
right: windowWidth - out.right,
top: out.top,
bottom: windowHeight - out.bottom,
width: windowWidth - out.left - out.right,
height: windowHeight - out.top - out.bottom
left: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.left,
right: windowWidth - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.right,
top: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top,
bottom: windowHeight - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.bottom,
width: windowWidth - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.left - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.right,
height: windowHeight - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.bottom
};
const {top: windowTop, bottom: windowBottom} = getWindowOffset();
windowHeight -= windowTop;
......@@ -12211,10 +13359,10 @@ const getSystemInfoSync = /* @__PURE__ */ defineSyncApi("getSystemInfoSync", ()
model,
safeArea,
safeAreaInsets: {
top: out.top,
right: out.right,
bottom: out.bottom,
left: out.left
top: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top,
right: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.right,
bottom: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.bottom,
left: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.left
}
};
});
......@@ -12485,85 +13633,6 @@ const getStorageInfoSync = /* @__PURE__ */ defineSyncApi("getStorageInfoSync", (
const getStorageInfo = /* @__PURE__ */ defineAsyncApi("getStorageInfo", (_, {resolve}) => {
resolve(getStorageInfoSync());
});
const files = {};
function urlToFile(url, local) {
const file = files[url];
if (file) {
return Promise.resolve(file);
}
if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(url)) {
return Promise.resolve(base64ToFile(url));
}
if (local) {
return Promise.reject(new Error("not find"));
}
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function() {
resolve(this.response);
};
xhr.onerror = reject;
xhr.send();
});
}
function base64ToFile(base64) {
const base64Array = base64.split(",");
const res = base64Array[0].match(/:(.*?);/);
const type = res ? res[1] : "";
const str = atob(base64Array[1]);
let n = str.length;
const array = new Uint8Array(n);
while (n--) {
array[n] = str.charCodeAt(n);
}
return blobToFile(array, type);
}
function getExtname(type) {
const extname = type.split("/")[1];
return extname ? `.${extname}` : "";
}
function getFileName(url) {
url = url.split("#")[0].split("?")[0];
const array = url.split("/");
return array[array.length - 1];
}
function blobToFile(blob, type) {
let file;
if (blob instanceof File) {
file = blob;
} else {
type = type || blob.type || "";
const filename = `${Date.now()}${getExtname(type)}`;
try {
file = new File([blob], filename, {type});
} catch (error) {
blob = blob instanceof Blob ? blob : new Blob([blob], {type});
file = blob;
file.name = file.name || filename;
}
}
return file;
}
function fileToUrl(file) {
for (const key in files) {
if (hasOwn(files, key)) {
const oldFile = files[key];
if (oldFile === file) {
return key;
}
}
}
var url = (window.URL || window.webkitURL).createObjectURL(file);
files[url] = file;
return url;
}
function revokeObjectURL(url) {
const URL = window.URL || window.webkitURL;
URL.revokeObjectURL(url);
delete files[url];
}
const getFileInfo = /* @__PURE__ */ defineAsyncApi(API_GET_FILE_INFO, ({filePath}, {resolve, reject}) => {
urlToFile(filePath).then((res) => {
resolve({
......@@ -14010,6 +15079,10 @@ var api = /* @__PURE__ */ Object.freeze({
createVideoContext,
createMapContext,
onTabBarMidButtonTap,
createCanvasContext,
canvasGetImageData,
canvasPutImageData,
canvasToTempFilePath,
cssVar,
cssEnv,
cssConstant,
......@@ -15698,4 +16771,4 @@ var index = /* @__PURE__ */ defineComponent({
return openBlock(), createBlock("div", clazz, [loadingVNode]);
}
});
export {index$1 as AsyncErrorComponent, index as AsyncLoadingComponent, _sfc_main$9 as Audio, index$k as Button, _sfc_main$8 as Canvas, index$h as Checkbox, index$j as CheckboxGroup, _sfc_main$1 as CoverImage, _sfc_main$2 as CoverView, index$g as Editor, index$l as Form, index$f as Icon, index$e as Image, Input, index$i as Label, LayoutComponent, index$3 as Map, _sfc_main$7 as MovableView, _sfc_main$6 as Navigator, index$2 as PageComponent, index$d as Progress, index$b as Radio, index$c as RadioGroup, ResizeSensor, _sfc_main$5 as RichText, _sfc_main$4 as ScrollView, index$a as Slider, _sfc_main$3 as SwiperItem, index$9 as Switch, index$8 as Text, index$7 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, index$5 as Video, index$6 as View, index$4 as WebView, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, chooseFile, chooseImage, chooseVideo, clearStorage, clearStorageSync, closeSocket, connectSocket, createInnerAudioContext, createIntersectionObserver, createMapContext, createSelectorQuery, createVideoContext, cssBackdropFilter, cssConstant, cssEnv, cssVar, downloadFile, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getFileInfo, getImageInfo, getLocation, getNetworkType, getStorage, getStorageInfo, getStorageInfoSync, getStorageSync, getSystemInfo, getSystemInfoSync, getVideoInfo, hideKeyboard, hideLoading, hideNavigationBarLoading, hideTabBar, hideTabBarRedDot, hideToast, loadFontFace, makePhoneCall, navigateBack, navigateTo, offAccelerometerChange, offCompassChange, offNetworkStatusChange, onAccelerometerChange, onCompassChange, onNetworkStatusChange, onSocketClose, onSocketError, onSocketMessage, onSocketOpen, onTabBarMidButtonTap, openDocument, pageScrollTo, index$m as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, removeStorage, removeStorageSync, removeTabBarBadge, request, sendSocketMessage, setNavigationBarColor, setNavigationBarTitle, setStorage, setStorageSync, setTabBarBadge, setTabBarItem, setTabBarStyle, setupApp, setupPage, showLoading, showModal, showNavigationBarLoading, showTabBar, showTabBarRedDot, showToast, startAccelerometer, startCompass, startPullDownRefresh, stopAccelerometer, stopCompass, stopPullDownRefresh, switchTab, uni$1 as uni, uploadFile, upx2px, useAttrs, useCustomEvent, useOn, useSubscribe, useUserAction, vibrateLong, vibrateShort, withWebEvent};
export {index$1 as AsyncErrorComponent, index as AsyncLoadingComponent, _sfc_main$9 as Audio, index$k as Button, _sfc_main$8 as Canvas, index$h as Checkbox, index$j as CheckboxGroup, _sfc_main$1 as CoverImage, _sfc_main$2 as CoverView, index$g as Editor, index$l as Form, index$f as Icon, index$e as Image, Input, index$i as Label, LayoutComponent, index$3 as Map, _sfc_main$7 as MovableView, _sfc_main$6 as Navigator, index$2 as PageComponent, index$d as Progress, index$b as Radio, index$c as RadioGroup, ResizeSensor, _sfc_main$5 as RichText, _sfc_main$4 as ScrollView, index$a as Slider, _sfc_main$3 as SwiperItem, index$9 as Switch, index$8 as Text, index$7 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, index$5 as Video, index$6 as View, index$4 as WebView, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, canvasGetImageData, canvasPutImageData, canvasToTempFilePath, chooseFile, chooseImage, chooseVideo, clearStorage, clearStorageSync, closeSocket, connectSocket, createCanvasContext, createInnerAudioContext, createIntersectionObserver, createMapContext, createSelectorQuery, createVideoContext, cssBackdropFilter, cssConstant, cssEnv, cssVar, downloadFile, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getFileInfo, getImageInfo, getLocation, getNetworkType, getStorage, getStorageInfo, getStorageInfoSync, getStorageSync, getSystemInfo, getSystemInfoSync, getVideoInfo, hideKeyboard, hideLoading, hideNavigationBarLoading, hideTabBar, hideTabBarRedDot, hideToast, loadFontFace, makePhoneCall, navigateBack, navigateTo, offAccelerometerChange, offCompassChange, offNetworkStatusChange, onAccelerometerChange, onCompassChange, onNetworkStatusChange, onSocketClose, onSocketError, onSocketMessage, onSocketOpen, onTabBarMidButtonTap, openDocument, pageScrollTo, index$m as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, removeStorage, removeStorageSync, removeTabBarBadge, request, sendSocketMessage, setNavigationBarColor, setNavigationBarTitle, setStorage, setStorageSync, setTabBarBadge, setTabBarItem, setTabBarStyle, setupApp, setupPage, showLoading, showModal, showNavigationBarLoading, showTabBar, showTabBarRedDot, showToast, startAccelerometer, startCompass, startPullDownRefresh, stopAccelerometer, stopCompass, stopPullDownRefresh, switchTab, uni$1 as uni, uploadFile, upx2px, useAttrs, useCustomEvent, useNativeEvent, useOn, useSubscribe, useUserAction, vibrateLong, vibrateShort, withWebEvent};
......@@ -6,3 +6,6 @@ export {
addIntersectionObserver,
removeIntersectionObserver,
} from '../service/api/ui/intersectionObserver'
export * from './saveImage'
export * from './constants'
export { getSameOriginUrl } from '../helpers/file'
export function saveImage(base64: string, dirname: string, callback: Function) {
callback(null, base64)
}
......@@ -67,5 +67,9 @@ export {
createVideoContext,
createMapContext,
onTabBarMidButtonTap,
createCanvasContext,
canvasGetImageData,
canvasPutImageData,
canvasToTempFilePath,
} from '@dcloudio/uni-api'
//#endif
......@@ -5,6 +5,7 @@ import vue from '@vitejs/plugin-vue'
import jscc from 'rollup-plugin-jscc'
import strip from '@rollup/plugin-strip'
import replace from '@rollup/plugin-replace'
import minimatch from 'minimatch'
import { stripOptions } from '@dcloudio/uni-cli-shared'
import { isCustomElement } from '../uni-shared'
......@@ -39,6 +40,8 @@ const rollupPlugins = [
// 该插件限制了不能以__开头
_NODE_JS_: FORMAT === 'cjs' ? 1 : 0,
},
// exclude: ['pako.esm.mjs'],
exclude: [resolve('../../node_modules/pako/**')],
}),
]
if (FORMAT === 'cjs') {
......
......@@ -3,3 +3,6 @@ export function operateVideoPlayer() {}
export function operateMap() {}
export function addIntersectionObserver() {}
export function removeIntersectionObserver() {}
export function saveImage() {}
export function getSameOriginUrl() {}
export const TEMP_PATH = ''
......@@ -967,6 +967,11 @@
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
"@types/pako@^1.0.1":
version "1.0.1"
resolved "https://registry.nlark.com/@types/pako/download/@types/pako-1.0.1.tgz#33b237f3c9aff44d0f82fe63acffa4a365ef4a61"
integrity sha1-M7I388mv9E0Pgv5jrP+ko2XvSmE=
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
......@@ -5010,6 +5015,11 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
pako@^2.0.3:
version "2.0.3"
resolved "https://registry.nlark.com/pako/download/pako-2.0.3.tgz#cdf475e31b678565251406de9e759196a0ea7a43"
integrity sha1-zfR14xtnhWUlFAbennWRlqDqekM=
parchment@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/parchment/-/parchment-1.1.4.tgz#aeded7ab938fe921d4c34bc339ce1168bc2ffde5"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册