Skip to content

Commit

Permalink
feat: 添加复制粘贴元素,播放器外部控制
Browse files Browse the repository at this point in the history
  • Loading branch information
wangrongding committed Mar 31, 2024
1 parent e50b018 commit 3861c58
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 31 deletions.
69 changes: 61 additions & 8 deletions src/components/player/CanvasPlayer.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
<script setup lang="ts">
import movie from '/bird.mp4'
import { fabric } from 'fabric'
import { onMounted, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { onMounted, ref, watch } from 'vue'
import Logo from '~/assets/icons/icon-github.svg'
import { usePlayerStore } from '~/stores/player'
import emitter from '~/utils/bus'
defineProps<{
msg: string
}>()
const container = ref<HTMLElement | null>(null)
let video: HTMLVideoElement
const playerStore = usePlayerStore()
const { playStatus } = storeToRefs(playerStore)
let canvas: fabric.Canvas
let ctx: CanvasRenderingContext2D
const container = ref<HTMLElement | null>(null)
let clipboard: fabric.Object | null = null
emitter.on('element:copy', onCopy)
emitter.on('element:paste', onPaste)
watch(playStatus, () => {
if (playStatus.value) {
video.play()
} else {
video.pause()
}
})
function initCanvas() {
canvas = new fabric.Canvas('canvas', {
Expand Down Expand Up @@ -58,13 +76,10 @@ function drawStaticElements() {
// 绘制视频
// TODO 需要实现通过 webcodecs 进行视频解码后绘制
function drawVideo() {
const video = document.createElement('video')
video = document.createElement('video')
// video.src = 'https://assets.fedtop.com/picbed/movie.mp4'
video.src = movie
video.autoplay = true
video.loop = true
// 不静音就无法在未点击的情况下自动播放
video.muted = true
const canvasWidth = canvas.width!
const canvasHeight = canvas.height!
Expand All @@ -89,8 +104,6 @@ function drawVideo() {
canvas.add(videoElement)
canvas.setActiveObject(videoElement)
continuouslyRepaint()
// TODO 修改成外部控制
video.play()
})
}
Expand Down Expand Up @@ -151,6 +164,7 @@ function initControls() {
// 添加删除按钮
addDeleteButton()
}
// editor 添加删除按钮
function addDeleteButton() {
// 有些地方也有用 fabric.Object.prototype.controls.delete
Expand Down Expand Up @@ -200,6 +214,45 @@ function resizePlayer() {
function canvasOnMouseDown() {}
// 复制元素
function onCopy() {
const activeObject = canvas.getActiveObject()
if (!activeObject) return
activeObject.clone((cloned: fabric.Object) => {
clipboard = cloned
})
}
// TODO 视频元素为什么无法复制
// 粘贴元素
function onPaste() {
if (clipboard === null) return
// clone again, so you can do multiple copies.
clipboard!.clone((clonedObj: any) => {
canvas.discardActiveObject()
clonedObj.set({
left: clonedObj.left + 10,
top: clonedObj.top + 10,
evented: true
})
if (clonedObj.type === 'activeSelection') {
// active selection needs a reference to the canvas.
clonedObj.canvas = canvas
clonedObj.forEachObject((obj: any) => {
canvas.add(obj)
})
// this should solve the unselectability
clonedObj.setCoords()
} else {
canvas.add(clonedObj)
}
clipboard!.top! += 10
clipboard!.left! += 10
canvas.setActiveObject(clonedObj)
canvas.requestRenderAll()
})
}
onMounted((): void => {
// 初始化画布
initCanvas()
Expand Down
39 changes: 16 additions & 23 deletions src/components/right-panel/RightPanel.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,19 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import emitter from '~/utils/bus'
function copy() {
emitter.emit('element:copy')
}
function paste() {
emitter.emit('element:paste')
}
</script>
<template>
<div class="right-panel w-[400px] bg-[#272836] flex justify-between">
<div class="p-8">
<div role="tablist" class="tabs tabs-boxed mb-4">
<a role="tab" class="tab">Tab 1</a>
<a role="tab" class="tab tab-active overflow-hidden">Tab 2</a>
<a role="tab" class="tab">Tab 3</a>
<a role="tab" class="tab">Tab 4</a>
</div>
<div class="tooltip mb-4" data-tip="开发中...">
<button class="btn">
<span class="loading loading-spinner"></span>
loading
</button>
</div>

<div>
<input type="checkbox" class="toggle toggle-success" checked />
<input type="checkbox" class="toggle toggle-warning" checked />
<input type="checkbox" class="toggle toggle-info" checked />
<input type="checkbox" class="toggle toggle-error" checked />
</div>

<!-- Open the modal using ID.showModal() method -->
<button class="btn btn-sm" onclick="my_modal_1.showModal()">open modal</button>
<dialog id="my_modal_1" class="modal">
<button class="btn btn-sm" onclick="testModal.showModal()">open modal</button>
<dialog id="testModal" class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">Hello!</h3>
<p class="py-4">Press ESC key or click the button below to close</p>
Expand All @@ -36,6 +25,10 @@
</div>
</div>
</dialog>
<div class="my-4 flex flex-col gap-4">
<button class="btn btn-sm" @click="copy">Copy Selected Objects</button>
<button class="btn btn-sm" @click="paste">Paste Selected Objects</button>
</div>
</div>
<div class="w-[60px] bg-[#1c1c26] p-8"></div>
</div>
Expand Down

0 comments on commit 3861c58

Please sign in to comment.