提交 62facd69 编写于 作者: fxy060608's avatar fxy060608

feat(h5): canvas 高清处理

上级 849687ff
const pixelRatio = (function () {
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')
const backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1
return (window.devicePixelRatio || 1) / backingStore
})()
const forEach = function (obj, func) {
for (let key in obj) {
if (obj.hasOwnProperty(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]
}
if (pixelRatio !== 1) {
const proto = CanvasRenderingContext2D.prototype
forEach(ratioArgs, function (value, key) {
proto[key] = (function (_super) {
return function () {
if (this.__ignore__) {
return _super.apply(this, arguments)
}
let args = Array.prototype.slice.call(arguments)
if (value === 'all') {
args = args.map(function (a) {
return a * pixelRatio
})
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
args[value[i]] *= pixelRatio
}
}
return _super.apply(this, args)
}
})(proto[key])
})
proto.stroke = (function (_super) {
return function () {
if (this.__ignore__) {
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.__ignore__) {
return _super.apply(this, arguments)
}
const args = Array.prototype.slice.call(arguments)
args[1] *= pixelRatio
args[2] *= pixelRatio
this.font = this.font.replace(
/(\d+)(px|em|rem|pt)/g,
function (w, m, u) {
return (m * pixelRatio) + u
}
)
_super.apply(this, args)
this.font = this.font.replace(
/(\d+)(px|em|rem|pt)/g,
function (w, m, u) {
return (m / pixelRatio) + u
}
)
}
})(proto.fillText)
proto.strokeText = (function (_super) {
return function () {
if (this.__ignore__) {
return _super.apply(this, arguments)
}
var args = Array.prototype.slice.call(arguments)
args[1] *= pixelRatio // x
args[2] *= pixelRatio // y
this.font = this.font.replace(
/(\d+)(px|em|rem|pt)/g,
function (w, m, u) {
return (m * pixelRatio) + u
}
)
_super.apply(this, args)
this.font = this.font.replace(
/(\d+)(px|em|rem|pt)/g,
function (w, m, u) {
return (m / pixelRatio) + u
}
)
}
})(proto.strokeText)
proto.drawImageByCanvas = (function (_super) {
return function (canvas, srcx, srcy, srcw, srch, desx, desy, desw, desh, isScale) {
if (this.__ignore__) {
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)
proto.drawImage = (function (_super) {
return function () {
if (this.__ignore__) {
return _super.apply(this, arguments)
}
this.scale(pixelRatio, pixelRatio)
_super.apply(this, arguments)
this.scale(1 / pixelRatio, 1 / pixelRatio)
}
})(proto.drawImage)
}
export function wrapper (canvas) {
canvas.style.height = canvas.height + 'px'
canvas.style.width = canvas.width + 'px'
canvas.width *= pixelRatio
canvas.height *= pixelRatio
console.log(canvas.width)
console.log(canvas.height)
}
<template>
<template>
<uni-canvas
:canvas-id="canvasId"
:disable-scroll="disableScroll"
v-on="_listeners">
v-on="_listeners">
<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"/>
</uni-canvas>
</template>
<script>
import {
subscriber
} from 'uni-mixins'
function resolveColor (color) {
color = color.slice(0)
color[3] = color[3] / 255
return 'rgba(' + color.join(',') + ')'
}
function processTouches (target, touches) {
return ([]).map.call(touches, (touche) => {
var boundingClientRect = target.getBoundingClientRect()
return {
identifier: touche.identifier,
x: touche.clientX - boundingClientRect.x,
y: touche.clientY - boundingClientRect.y
}
})
}
export default {
name: 'Canvas',
mixins: [subscriber],
props: {
canvasId: {
type: String,
default: ''
},
disableScroll: {
type: [Boolean, String],
default: false
}
},
data () {
return {
actionsWaiting: false
}
},
computed: {
id () {
return this.canvasId
},
_listeners () {
var $listeners = Object.assign({}, this.$listeners)
var events = ['touchstart', 'touchmove', 'touchend']
events.forEach(event => {
var existing = $listeners[event]
var eventHandler = []
if (existing) {
eventHandler.push(($event) => {
this.$trigger(event, Object.assign({}, $event, {
touches: processTouches($event.currentTarget, $event.touches),
changedTouches: processTouches($event.currentTarget, $event.changedTouches)
}))
})
}
if (this.disableScroll && event === 'touchmove') {
eventHandler.push(this._touchmove)
}
$listeners[event] = eventHandler
})
return $listeners
}
},
created () {
this._actionsDefer = []
this._images = {}
},
mounted () {
this._resize({
width: this.$refs.sensor.$el.offsetWidth,
height: this.$refs.sensor.$el.offsetHeight
})
},
methods: {
_handleSubscribe ({
type,
data = {}
}) {
var method = this[type]
if (type.indexOf('_') !== 0 && typeof method === 'function') {
method(data)
}
},
_resize ({ width, height }) {
var canvas = this.$refs.canvas
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width
canvas.height = height
}
},
_touchmove (event) {
event.preventDefault()
},
actionsChanged ({
actions,
reserve,
callbackId
}) {
var self = this
if (!actions) {
return
}
if (this.actionsWaiting) {
this._actionsDefer.push([actions, reserve, callbackId])
return
}
var canvas = this.$refs.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)
}
this.preloadImage(actions)
for (let index = 0; index < actions.length; index++) {
let action = actions[index]
let method = action.method
let data = action.data
if (/^set/.test(method) && method !== 'setTransform') {
let 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') {
let LinearGradient = c2d.createLinearGradient(...data[1])
data[2].forEach(function (data2) {
let offset = data2[0]
let color = resolveColor(data2[1])
LinearGradient.addColorStop(offset, color)
})
} else if (data[0] === 'radial') {
let x = data[1][0]
let y = data[1][1]
let r = data[1][2]
let LinearGradient = c2d.createRadialGradient(x, y, 0, x, y, r)
data[2].forEach(function (data2) {
let offset = data2[0]
let color = resolveColor(data2[1])
LinearGradient.addColorStop(offset, color)
})
} else if (data[0] === 'pattern') {
let loaded = this.checkImageLoaded(data[1], actions.slice(index + 1), callbackId, function (image) {
if (image) {
c2d[method1] = c2d.createPattern(image, data[2])
}
})
if (!loaded) {
break
}
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_
})
} 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 (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
}
} else {
if (method === 'clip') {
data.forEach(function (data_) {
c2d[data_.method].apply(c2d, data_.data)
})
c2d.clip()
} else {
c2d[method].apply(c2d, data)
}
}
}
if (!this.actionsWaiting && callbackId) {
UniViewJSBridge.publishHandler('onDrawCanvas', {
callbackId,
data: {
errMsg: 'drawCanvas:ok'
}
}, this.$page.id)
}
},
preloadImage: function (actions) {
var sefl = this
actions.forEach(function (action) {
var method = action.method
var data = action.data
var src = ''
if (method === 'drawImage') {
src = data[0]
src = sefl.$getRealPath(src)
data[0] = src
} else if (method === 'setFillStyle' && data[0] === 'pattern') {
src = data[1]
src = sefl.$getRealPath(src)
data[1] = src
}
if (src && !sefl._images[src]) {
loadImage()
}
/**
* 加载图像
*/
function loadImage () {
sefl._images[src] = new Image()
sefl._images[src].onload = function () {
sefl._images[src].ready = true
}
/**
* 从Blob加载
* @param {Blob} blob
*/
function loadBlob (blob) {
sefl._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 () {
sefl._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 {
sefl._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 () {
sefl._images[src].src = src
}
xhr.send()
}
if (window.plus && (!window.webkit || !window.webkit.messageHandlers)) {
sefl._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) {
loadFile(src)
} else if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(src)) {
sefl._images[src].src = src
} else {
loadUrl(src)
}
}
}
})
},
checkImageLoaded: function (src, actions, callbackId, fn) {
var self = this
var image = this._images[src]
if (image.ready) {
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;) {
self.actionsChanged({
actions: action[0],
reserve: action[1],
callbackId
})
action = actions.shift()
}
}
return false
}
},
getImageData ({
x,
y,
width,
height,
callbackId
}) {
var imgData
var canvas = this.$refs.canvas
if (!width) {
width = canvas.width
}
if (!height) {
height = canvas.height
}
try {
imgData = canvas.getContext('2d').getImageData(x, y, width, height)
} catch (error) {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasGetImageData:fail'
}
}, this.$page.id)
return
}
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasGetImageData:ok',
data: [...imgData.data],
width,
height
}
}, this.$page.id)
},
putImageData ({
data,
x,
y,
width,
height,
callbackId
}) {
try {
if (!height) {
height = Math.round(data.length / 4 / width)
}
this.$refs.canvas.getContext('2d').putImageData(new ImageData(new Uint8ClampedArray(data), width, height), x, y)
} catch (error) {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasPutImageData:fail'
}
}, this.$page.id)
return
}
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasPutImageData:ok'
}
}, this.$page.id)
}
}
}
</script>
<style>
uni-canvas {
width: 300px;
height: 150px;
display: block;
position: relative;
}
uni-canvas > canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
height="150" />
<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden;">
<slot />
</div>
</uni-canvas>
</template>
<script>
import {
subscriber
} from 'uni-mixins'
import {
wrapper
} from './hidpi'
function resolveColor (color) {
color = color.slice(0)
color[3] = color[3] / 255
return 'rgba(' + color.join(',') + ')'
}
function processTouches (target, touches) {
return ([]).map.call(touches, (touche) => {
var boundingClientRect = target.getBoundingClientRect()
return {
identifier: touche.identifier,
x: touche.clientX - boundingClientRect.x,
y: touche.clientY - boundingClientRect.y
}
})
}
export default {
name: 'Canvas',
mixins: [subscriber],
props: {
canvasId: {
type: String,
default: ''
},
disableScroll: {
type: [Boolean, String],
default: false
}
},
data () {
return {
actionsWaiting: false
}
},
computed: {
id () {
return this.canvasId
},
_listeners () {
var $listeners = Object.assign({}, this.$listeners)
var events = ['touchstart', 'touchmove', 'touchend']
events.forEach(event => {
var existing = $listeners[event]
var eventHandler = []
if (existing) {
eventHandler.push(($event) => {
this.$trigger(event, Object.assign({}, $event, {
touches: processTouches($event.currentTarget, $event.touches),
changedTouches: processTouches($event.currentTarget, $event
.changedTouches)
}))
})
}
if (this.disableScroll && event === 'touchmove') {
eventHandler.push(this._touchmove)
}
$listeners[event] = eventHandler
})
return $listeners
}
},
created () {
this._actionsDefer = []
this._images = {}
},
mounted () {
this._resize({
width: this.$el.offsetWidth,
height: this.$el.offsetHeight
})
},
methods: {
_handleSubscribe ({
type,
data = {}
}) {
var method = this[type]
if (type.indexOf('_') !== 0 && typeof method === 'function') {
method(data)
}
},
_resize ({
width,
height
}) {
var canvas = this.$refs.canvas
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width
canvas.height = height
}
wrapper(canvas)
},
_touchmove (event) {
event.preventDefault()
},
actionsChanged ({
actions,
reserve,
callbackId
}) {
var self = this
if (!actions) {
return
}
if (this.actionsWaiting) {
this._actionsDefer.push([actions, reserve, callbackId])
return
}
var canvas = this.$refs.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)
}
this.preloadImage(actions)
for (let index = 0; index < actions.length; index++) {
let action = actions[index]
let method = action.method
let data = action.data
if (/^set/.test(method) && method !== 'setTransform') {
let 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') {
let LinearGradient = c2d.createLinearGradient(...data[1])
data[2].forEach(function (data2) {
let offset = data2[0]
let color = resolveColor(data2[1])
LinearGradient.addColorStop(offset, color)
})
} else if (data[0] === 'radial') {
let x = data[1][0]
let y = data[1][1]
let r = data[1][2]
let LinearGradient = c2d.createRadialGradient(x, y, 0, x, y, r)
data[2].forEach(function (data2) {
let offset = data2[0]
let color = resolveColor(data2[1])
LinearGradient.addColorStop(offset, color)
})
} else if (data[0] === 'pattern') {
let loaded = this.checkImageLoaded(data[1], actions.slice(index + 1), callbackId,
function (image) {
if (image) {
c2d[method1] = c2d.createPattern(image, data[2])
}
})
if (!loaded) {
break
}
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_
})
} 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 (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
}
} else {
if (method === 'clip') {
data.forEach(function (data_) {
c2d[data_.method].apply(c2d, data_.data)
})
c2d.clip()
} else {
c2d[method].apply(c2d, data)
}
}
}
if (!this.actionsWaiting && callbackId) {
UniViewJSBridge.publishHandler('onDrawCanvas', {
callbackId,
data: {
errMsg: 'drawCanvas:ok'
}
}, this.$page.id)
}
},
preloadImage: function (actions) {
var sefl = this
actions.forEach(function (action) {
var method = action.method
var data = action.data
var src = ''
if (method === 'drawImage') {
src = data[0]
src = sefl.$getRealPath(src)
data[0] = src
} else if (method === 'setFillStyle' && data[0] === 'pattern') {
src = data[1]
src = sefl.$getRealPath(src)
data[1] = src
}
if (src && !sefl._images[src]) {
loadImage()
}
/**
* 加载图像
*/
function loadImage () {
sefl._images[src] = new Image()
sefl._images[src].onload = function () {
sefl._images[src].ready = true
}
/**
* 从Blob加载
* @param {Blob} blob
*/
function loadBlob (blob) {
sefl._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 () {
sefl._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 {
sefl._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 () {
sefl._images[src].src = src
}
xhr.send()
}
if (window.plus && (!window.webkit || !window.webkit.messageHandlers)) {
sefl._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) {
loadFile(src)
} else if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(src)) {
sefl._images[src].src = src
} else {
loadUrl(src)
}
}
}
})
},
checkImageLoaded: function (src, actions, callbackId, fn) {
var self = this
var image = this._images[src]
if (image.ready) {
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;) {
self.actionsChanged({
actions: action[0],
reserve: action[1],
callbackId
})
action = actions.shift()
}
}
return false
}
},
getImageData ({
x,
y,
width,
height,
callbackId
}) {
var imgData
var canvas = this.$refs.canvas
if (!width) {
width = canvas.width
}
if (!height) {
height = canvas.height
}
try {
imgData = canvas.getContext('2d').getImageData(x, y, width, height)
} catch (error) {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasGetImageData:fail'
}
}, this.$page.id)
return
}
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasGetImageData:ok',
data: [...imgData.data],
width,
height
}
}, this.$page.id)
},
putImageData ({
data,
x,
y,
width,
height,
callbackId
}) {
try {
if (!height) {
height = Math.round(data.length / 4 / width)
}
this.$refs.canvas.getContext('2d').putImageData(new ImageData(new Uint8ClampedArray(data), width,
height), x, y)
} catch (error) {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasPutImageData:fail'
}
}, this.$page.id)
return
}
UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId,
data: {
errMsg: 'canvasPutImageData:ok'
}
}, this.$page.id)
}
}
}
</script>
<style>
uni-canvas {
width: 300px;
height: 150px;
display: block;
position: relative;
}
uni-canvas>canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册