| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- import { fabric } from 'fabric';
- import { ref } from 'vue';
- import cameraImg from '@/assets/camera/camera.png';
- import {
- CameraImage,
- MapData,
- OnMoving,
- OnRightClick,
- OnSelect,
- isCanvas,
- OnRotating,
- } from './types';
- import { fabricSetting } from './fabricSetting';
- import { getRandomPosition } from './utils';
- fabricSetting();
- interface Props {
- onSelect: OnSelect;
- onRightClick: OnRightClick;
- onMoving: OnMoving;
- onRotating: OnRotating;
- }
- function useCameraMap(props: Props) {
- let canvas;
- const createMap = (canvasId: string) => {
- canvas = new fabric.Canvas(canvasId, {
- fireRightClick: true, // 启用右键,button的数字为3
- stopContextMenu: true, // 禁止默认右键菜单
- });
- addListener();
- window.canvas = canvas;
- };
- /** 监听点击事件 */
- const addListener = () => {
- if (!isCanvas(canvas)) return;
- canvas.on('mouse:down', (options) => {
- if (!canvas) return;
- const target = options.target as CameraImage;
- const cameraId = target?.cameraId;
- // console.log('当前选中的id是', cameraId);
- console.log('mouse:down');
- console.log(options);
- // 判断:右键,且在元素上右键
- // opt.button: 1-左键;2-中键;3-右键
- // 在画布上点击:opt.target 为 null
- if (options.button === 3 && options.target) {
- props.onRightClick(options);
- return;
- }
- if (!cameraId || !target) {
- props.onSelect(null);
- return;
- }
- props.onSelect(target);
- });
- canvas.on('object:moving', (e) => {
- // console.log('object moving', e);
- props.onMoving(e);
- });
- canvas.on('object:rotating', function (e) {
- props.onRotating(e);
- });
- };
- /** 上传背景图 */
- const uploadBg = (imgUrl: string) => {
- if (!isCanvas(canvas)) return;
- fabric.Image.fromURL(imgUrl, (img) => {
- const refImg = ref(img);
- console.log('image', img);
- canvas!.setWidth(img.width!);
- canvas!.setHeight(img.height!);
- refImg.value.lockScalingX = true;
- refImg.value.lockScalingY = true;
- // 设置背景图
- canvas?.setBackgroundImage(refImg.value, canvas!.renderAll.bind(canvas));
- });
- };
- /** 增加一个摄像头 */
- const addCamera = (cameraId: string): Promise<CameraImage> => {
- if (!isCanvas(canvas)) return Promise.reject();
- // eslint-disable-next-line @typescript-eslint/no-this-alias
- return new Promise((resolve) => {
- fabric.Image.fromURL(cameraImg, (img) => {
- const cImg = ref(img as unknown as CameraImage);
- cImg.value.set({
- left: getRandomPosition(),
- top: getRandomPosition(),
- cameraId,
- });
- cImg.value.lockScalingX = true;
- cImg.value.lockScalingY = true;
- canvas?.add(cImg.value);
- canvas?.setActiveObject(cImg.value);
- // cImg.value.on('moving', function (e) {
- // props.onMoving(e);
- // });
- // cImg.value.on('rotating', function (e) {
- // props.onRotating(e);
- // });
- resolve(cImg.value);
- });
- });
- };
- /** 删除一个摄像头 */
- const removeActiveCamera = () => {
- if (!isCanvas(canvas)) return;
- const activeObject = canvas?.getActiveObject();
- if (!activeObject) return;
- canvas.remove(activeObject);
- const objects = canvas.getObjects();
- if (objects.length > 0) {
- canvas.setActiveObject(objects[0]);
- }
- };
- /** 导出JSON格式 */
- const toJSON = () => {
- if (!isCanvas(canvas)) return;
- const initialJSON = canvas.toJSON(['cameraId']);
- /** toJSON返回值的类型它写错了,应该是有backgroundImage的 */
- const { src, type, version, width, height, left, top, angle } =
- (initialJSON as any).backgroundImage || {};
- const newObjects = initialJSON.objects.map((item) => {
- return {
- type: item.type,
- width: item.width,
- height: item.height,
- left: item.left,
- top: item.top,
- angle: item.angle,
- cameraId: (item as CameraImage).cameraId,
- };
- });
- const newJson = {
- version: initialJSON.version,
- backgroundImage: { src, type, version, width, height, left, top, angle },
- objects: newObjects,
- };
- return newJson;
- };
- /** 从json中加载 */
- const loadFromJSON = (json: MapData): Promise<void> => {
- if (!isCanvas(canvas)) return Promise.reject();
- canvas.clear();
- return new Promise((resolve) => {
- const { width, height } = json.backgroundImage;
- canvas?.setWidth(width);
- canvas?.setHeight(height);
- const objects = json.objects.map((item) => {
- return {
- ...item,
- src: cameraImg,
- };
- });
- canvas?.loadFromJSON({ ...json, objects }, () => {
- resolve();
- });
- });
- };
- /** 更新摄像头的渲染 */
- const renderCamera = () => {
- canvas?.renderAll();
- };
- /** */
- const clear = () => {
- canvas?.clear();
- };
- /** 是否已经存在这个cameraId */
- const hasCamera = (cameraId: string) => {
- const cameraIds =
- canvas?.toJSON(['cameraId']).objects.map((item) => (item as CameraImage).cameraId) || [];
- return cameraIds.includes(cameraId);
- };
- const getObjects = () => {
- return canvas?.getObjects() as CameraImage[];
- };
- /** 根据cameraId查找某个元素 */
- const getCameraById = (cameraId: string) => {
- return canvas
- ?.getObjects()
- .find((x) => (x as CameraImage).cameraId === cameraId) as CameraImage;
- };
- return {
- canvas,
- createMap,
- uploadBg,
- addCamera,
- removeActiveCamera,
- toJSON,
- loadFromJSON,
- renderCamera,
- clear,
- hasCamera,
- getCameraById,
- getObjects,
- };
- }
- export default useCameraMap;
|