mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-16 17:46:17 -08:00
- Removed the assignment of Artplayer to the global window object in index.js of the artplayer package. - Eliminated the window export for the template plugin in index.js, streamlining the code and reducing global scope pollution.
140 lines
3.6 KiB
JavaScript
140 lines
3.6 KiB
JavaScript
export default function artplayerProxyCanvas(callback) {
|
|
return (art) => {
|
|
const { constructor } = art
|
|
const { createElement } = constructor.utils
|
|
|
|
const canvas = createElement('canvas')
|
|
const video = createElement('video')
|
|
const ctx = canvas.getContext('2d')
|
|
|
|
let animationId = null
|
|
|
|
const originalCanvasMethods = {}
|
|
for (const prop in canvas) {
|
|
if (typeof canvas[prop] === 'function') {
|
|
originalCanvasMethods[prop] = canvas[prop].bind(canvas)
|
|
}
|
|
}
|
|
|
|
for (const prop in video) {
|
|
if (!(prop in canvas)) {
|
|
Object.defineProperty(canvas, prop, {
|
|
get() {
|
|
const value = video[prop]
|
|
return typeof value === 'function' ? value.bind(video) : value
|
|
},
|
|
set(value) {
|
|
video[prop] = value
|
|
},
|
|
configurable: true,
|
|
enumerable: true,
|
|
})
|
|
}
|
|
}
|
|
|
|
for (const prop in originalCanvasMethods) {
|
|
canvas[prop] = function (...args) {
|
|
if (prop in originalCanvasMethods) {
|
|
return originalCanvasMethods[prop](...args)
|
|
}
|
|
return video[prop](...args)
|
|
}
|
|
}
|
|
|
|
setupEventListeners()
|
|
setupArtPlayerEvents()
|
|
|
|
return canvas
|
|
|
|
function setupEventListeners() {
|
|
const { events } = constructor.config
|
|
setTimeout(() => {
|
|
events.forEach((event) => {
|
|
art.proxy(video, event, (event) => {
|
|
art.emit(`video:${event.type}`, event)
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
async function draw() {
|
|
try {
|
|
if (typeof createImageBitmap !== 'undefined') {
|
|
const bitmap = await createImageBitmap(video)
|
|
ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height)
|
|
bitmap.close()
|
|
}
|
|
else {
|
|
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
|
|
}
|
|
callback && callback(ctx, video)
|
|
art.emit('artplayerProxyCanvas:draw', ctx, video)
|
|
}
|
|
catch (error) {
|
|
art.emit('artplayerProxyCanvas:error', error)
|
|
}
|
|
}
|
|
|
|
async function animation() {
|
|
await draw()
|
|
animationId = requestAnimationFrame(animation)
|
|
}
|
|
|
|
function resize() {
|
|
const player = art.template?.$player
|
|
if (!player || art.option.autoSize)
|
|
return
|
|
|
|
const aspectRatio = video.videoWidth / video.videoHeight
|
|
const containerWidth = player.clientWidth
|
|
const containerHeight = player.clientHeight
|
|
const containerRatio = containerWidth / containerHeight
|
|
|
|
let canvasWidth, canvasHeight
|
|
if (containerRatio > aspectRatio) {
|
|
canvasHeight = containerHeight
|
|
canvasWidth = canvasHeight * aspectRatio
|
|
}
|
|
else {
|
|
canvasWidth = containerWidth
|
|
canvasHeight = canvasWidth / aspectRatio
|
|
}
|
|
|
|
canvas.width = canvasWidth
|
|
canvas.height = canvasHeight
|
|
|
|
const paddingLeft = (containerWidth - canvasWidth) / 2
|
|
const paddingTop = (containerHeight - canvasHeight) / 2
|
|
|
|
Object.assign(canvas.style, {
|
|
padding: `${paddingTop}px ${paddingLeft}px`,
|
|
})
|
|
}
|
|
|
|
function setupArtPlayerEvents() {
|
|
art.on('video:loadedmetadata', () => {
|
|
canvas.width = video.videoWidth
|
|
canvas.height = video.videoHeight
|
|
})
|
|
|
|
art.on('video:play', () => {
|
|
cancelAnimationFrame(animationId)
|
|
animation()
|
|
})
|
|
|
|
art.on('video:pause', () => {
|
|
cancelAnimationFrame(animationId)
|
|
})
|
|
|
|
art.on('resize', () => {
|
|
resize()
|
|
draw()
|
|
})
|
|
|
|
art.on('destroy', () => {
|
|
cancelAnimationFrame(animationId)
|
|
})
|
|
}
|
|
}
|
|
}
|