cd-aichat 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +188 -0
- package/dist/ailogo.png +0 -0
- package/dist/cd-aichat.css +1 -0
- package/dist/cd-aichat.es.js +32223 -0
- package/dist/cd-aichat.umd.js +279 -0
- package/dist/index.css +1 -0
- package/package.json +61 -0
- package/src/ailogo.png +0 -0
- package/src/components/AiChat.test.js +538 -0
- package/src/components/AiChat.vue +2206 -0
- package/src/components/AiChatWidget.test.js +312 -0
- package/src/components/AiChatWidget.vue +963 -0
- package/src/components/BurnAfterReadDialog.test.js +121 -0
- package/src/components/BurnAfterReadDialog.vue +511 -0
- package/src/components/BurnAfterReadMessage.test.js +188 -0
- package/src/components/BurnAfterReadMessage.vue +193 -0
- package/src/components/BurnIndicator.test.js +101 -0
- package/src/components/BurnIndicator.vue +164 -0
- package/src/components/ChatWindow.vue +0 -0
- package/src/components/MentionList.vue +163 -0
- package/src/components/ResourceList.vue +194 -0
- package/src/components/RichTextEditor.vue +437 -0
- package/src/components/ScheduledSendDialog.vue +476 -0
- package/src/components/ScreenshotOverlay.vue +78 -0
- package/src/components/SendButtonGroup.test.js +174 -0
- package/src/components/SendButtonGroup.vue +166 -0
- package/src/components/UserDrawer.vue +0 -0
- package/src/components/screenshot/ScreenshotsBackground/getBoundsByPoints.ts +41 -0
- package/src/components/screenshot/ScreenshotsBackground/index.scss +27 -0
- package/src/components/screenshot/ScreenshotsBackground/index.tsx +145 -0
- package/src/components/screenshot/ScreenshotsButton/index.scss +29 -0
- package/src/components/screenshot/ScreenshotsButton/index.tsx +58 -0
- package/src/components/screenshot/ScreenshotsCanvas/getBoundsByPoints.ts +55 -0
- package/src/components/screenshot/ScreenshotsCanvas/getPoints.ts +60 -0
- package/src/components/screenshot/ScreenshotsCanvas/index.scss +84 -0
- package/src/components/screenshot/ScreenshotsCanvas/index.tsx +277 -0
- package/src/components/screenshot/ScreenshotsCanvas/isPointInDraw.ts +35 -0
- package/src/components/screenshot/ScreenshotsColor/index.scss +45 -0
- package/src/components/screenshot/ScreenshotsColor/index.tsx +39 -0
- package/src/components/screenshot/ScreenshotsContext.ts +56 -0
- package/src/components/screenshot/ScreenshotsMagnifier/index.scss +61 -0
- package/src/components/screenshot/ScreenshotsMagnifier/index.tsx +126 -0
- package/src/components/screenshot/ScreenshotsOperations/index.scss +25 -0
- package/src/components/screenshot/ScreenshotsOperations/index.tsx +118 -0
- package/src/components/screenshot/ScreenshotsOption/index.scss +50 -0
- package/src/components/screenshot/ScreenshotsOption/index.tsx +150 -0
- package/src/components/screenshot/ScreenshotsSize/index.scss +28 -0
- package/src/components/screenshot/ScreenshotsSize/index.tsx +41 -0
- package/src/components/screenshot/ScreenshotsSizeColor/index.scss +8 -0
- package/src/components/screenshot/ScreenshotsSizeColor/index.tsx +25 -0
- package/src/components/screenshot/ScreenshotsTextarea/calculateNodeSize.ts +117 -0
- package/src/components/screenshot/ScreenshotsTextarea/index.scss +19 -0
- package/src/components/screenshot/ScreenshotsTextarea/index.tsx +96 -0
- package/src/components/screenshot/composeImage.ts +57 -0
- package/src/components/screenshot/exports.ts +4 -0
- package/src/components/screenshot/hooks/useBounds.ts +35 -0
- package/src/components/screenshot/hooks/useCall.ts +17 -0
- package/src/components/screenshot/hooks/useCanvasContextRef.ts +8 -0
- package/src/components/screenshot/hooks/useCanvasMousedown.ts +13 -0
- package/src/components/screenshot/hooks/useCanvasMousemove.ts +13 -0
- package/src/components/screenshot/hooks/useCanvasMouseup.ts +13 -0
- package/src/components/screenshot/hooks/useCursor.ts +34 -0
- package/src/components/screenshot/hooks/useDispatcher.ts +8 -0
- package/src/components/screenshot/hooks/useDrawSelect.ts +16 -0
- package/src/components/screenshot/hooks/useEmiter.ts +61 -0
- package/src/components/screenshot/hooks/useHistory.ts +160 -0
- package/src/components/screenshot/hooks/useLang.ts +8 -0
- package/src/components/screenshot/hooks/useOperation.ts +37 -0
- package/src/components/screenshot/hooks/useReset.ts +26 -0
- package/src/components/screenshot/hooks/useStore.ts +8 -0
- package/src/components/screenshot/icons/iconfont.scss +88 -0
- package/src/components/screenshot/icons/iconfont.ttf +0 -0
- package/src/components/screenshot/icons/iconfont.woff +0 -0
- package/src/components/screenshot/icons/iconfont.woff2 +0 -0
- package/src/components/screenshot/index.tsx +169 -0
- package/src/components/screenshot/operations/Arrow/draw.ts +56 -0
- package/src/components/screenshot/operations/Arrow/index.tsx +193 -0
- package/src/components/screenshot/operations/Brush/draw.ts +45 -0
- package/src/components/screenshot/operations/Brush/index.tsx +169 -0
- package/src/components/screenshot/operations/Cancel/index.tsx +18 -0
- package/src/components/screenshot/operations/Ellipse/draw.ts +96 -0
- package/src/components/screenshot/operations/Ellipse/index.tsx +245 -0
- package/src/components/screenshot/operations/Mosaic/index.tsx +223 -0
- package/src/components/screenshot/operations/Ok/index.tsx +37 -0
- package/src/components/screenshot/operations/Pin/index.tsx +37 -0
- package/src/components/screenshot/operations/Rectangle/draw.ts +80 -0
- package/src/components/screenshot/operations/Rectangle/index.tsx +245 -0
- package/src/components/screenshot/operations/Redo/index.tsx +22 -0
- package/src/components/screenshot/operations/Save/index.tsx +37 -0
- package/src/components/screenshot/operations/Scan/index.tsx +46 -0
- package/src/components/screenshot/operations/Search/index.tsx +39 -0
- package/src/components/screenshot/operations/Text/index.tsx +307 -0
- package/src/components/screenshot/operations/Undo/index.tsx +22 -0
- package/src/components/screenshot/operations/index.ts +34 -0
- package/src/components/screenshot/operations/utils.ts +34 -0
- package/src/components/screenshot/screenshots.scss +13 -0
- package/src/components/screenshot/types.ts +53 -0
- package/src/components/screenshot/useGetLoadedImage.ts +29 -0
- package/src/components/screenshot/var.scss +107 -0
- package/src/components/screenshot/zh_CN.ts +37 -0
- package/src/emoji/100.gif +0 -0
- package/src/emoji/101.gif +0 -0
- package/src/emoji/102.gif +0 -0
- package/src/emoji/103.gif +0 -0
- package/src/emoji/104.gif +0 -0
- package/src/emoji/105.gif +0 -0
- package/src/emoji/106.gif +0 -0
- package/src/emoji/107.gif +0 -0
- package/src/emoji/108.gif +0 -0
- package/src/emoji/109.gif +0 -0
- package/src/emoji/110.gif +0 -0
- package/src/emoji/111.gif +0 -0
- package/src/emoji/112.gif +0 -0
- package/src/emoji/113.gif +0 -0
- package/src/emoji/114.gif +0 -0
- package/src/emoji/115.gif +0 -0
- package/src/emoji/116.gif +0 -0
- package/src/emoji/117.gif +0 -0
- package/src/emoji/118.gif +0 -0
- package/src/emoji/119.gif +0 -0
- package/src/emoji/120.gif +0 -0
- package/src/emoji/121.gif +0 -0
- package/src/emoji/122.gif +0 -0
- package/src/emoji/123.gif +0 -0
- package/src/emoji/124.gif +0 -0
- package/src/emoji/125.gif +0 -0
- package/src/emoji/126.gif +0 -0
- package/src/emoji/127.gif +0 -0
- package/src/emoji/128.gif +0 -0
- package/src/emoji/129.gif +0 -0
- package/src/emoji/130.gif +0 -0
- package/src/emoji/131.gif +0 -0
- package/src/emoji/132.gif +0 -0
- package/src/emoji/133.gif +0 -0
- package/src/emoji/134.gif +0 -0
- package/src/emoji/135.gif +0 -0
- package/src/emoji/136.gif +0 -0
- package/src/emoji/137.gif +0 -0
- package/src/emoji/138.gif +0 -0
- package/src/emoji/139.gif +0 -0
- package/src/emoji/140.gif +0 -0
- package/src/emoji/141.gif +0 -0
- package/src/emoji/142.gif +0 -0
- package/src/emoji/143.gif +0 -0
- package/src/emoji/144.gif +0 -0
- package/src/emoji/145.gif +0 -0
- package/src/emoji/146.gif +0 -0
- package/src/emoji/147.gif +0 -0
- package/src/emoji/148.gif +0 -0
- package/src/emoji/149.gif +0 -0
- package/src/emoji/150.gif +0 -0
- package/src/emoji/151.gif +0 -0
- package/src/emoji/152.gif +0 -0
- package/src/emoji/153.gif +0 -0
- package/src/emoji/154.gif +0 -0
- package/src/emoji/155.gif +0 -0
- package/src/emoji/156.gif +0 -0
- package/src/emoji/157.gif +0 -0
- package/src/emoji/158.gif +0 -0
- package/src/emoji/159.gif +0 -0
- package/src/emoji/160.gif +0 -0
- package/src/emoji/161.gif +0 -0
- package/src/emoji/162.gif +0 -0
- package/src/emoji/163.gif +0 -0
- package/src/emoji/164.gif +0 -0
- package/src/emoji/165.gif +0 -0
- package/src/emoji/166.gif +0 -0
- package/src/emoji/167.gif +0 -0
- package/src/emoji/168.gif +0 -0
- package/src/emoji/169.gif +0 -0
- package/src/emoji/170.gif +0 -0
- package/src/emoji/171.gif +0 -0
- package/src/emoji/172.gif +0 -0
- package/src/emoji/173.gif +0 -0
- package/src/emoji/174.gif +0 -0
- package/src/emoji/175.gif +0 -0
- package/src/emoji/176.gif +0 -0
- package/src/emoji/177.gif +0 -0
- package/src/emoji/178.gif +0 -0
- package/src/emoji/179.gif +0 -0
- package/src/emoji/180.gif +0 -0
- package/src/emoji/181.gif +0 -0
- package/src/emoji/182.gif +0 -0
- package/src/emoji/183.gif +0 -0
- package/src/emoji/184.gif +0 -0
- package/src/emoji/185.gif +0 -0
- package/src/emoji/186.gif +0 -0
- package/src/emoji/187.gif +0 -0
- package/src/emoji/188.gif +0 -0
- package/src/emoji/189.gif +0 -0
- package/src/emoji/190.gif +0 -0
- package/src/emoji/191.gif +0 -0
- package/src/emoji/192.gif +0 -0
- package/src/emoji/193.gif +0 -0
- package/src/emoji/194.gif +0 -0
- package/src/emoji/195.gif +0 -0
- package/src/emoji/196.gif +0 -0
- package/src/emoji/197.gif +0 -0
- package/src/emoji/198.gif +0 -0
- package/src/emoji/199.gif +0 -0
- package/src/emoji/200.png +0 -0
- package/src/emoji/201.png +0 -0
- package/src/emoji/202.png +0 -0
- package/src/emoji/203.png +0 -0
- package/src/emoji/204.png +0 -0
- package/src/emoji/205.png +0 -0
- package/src/emoji/206.png +0 -0
- package/src/emoji/207.png +0 -0
- package/src/emoji/208.png +0 -0
- package/src/emoji/209.png +0 -0
- package/src/emoji/210.png +0 -0
- package/src/emoji/211.png +0 -0
- package/src/emoji/212.png +0 -0
- package/src/emoji/213.png +0 -0
- package/src/emoji/214.png +0 -0
- package/src/emoji/215.png +0 -0
- package/src/emoji/216.png +0 -0
- package/src/emoji/217.png +0 -0
- package/src/emoji/218.png +0 -0
- package/src/emoji/219.png +0 -0
- package/src/emoji2/101--Streamline-The-Team.png +0 -0
- package/src/emoji2/128--Streamline-The-Team.png +0 -0
- package/src/emoji2/134--Streamline-The-Team.png +0 -0
- package/src/emoji2/173--Streamline-The-Team.png +0 -0
- package/src/emoji2/Airplane--Streamline-Emoji.svg +24 -0
- package/src/emoji2/Alien--Streamline-Emoji.svg +21 -0
- package/src/emoji2/Amazed-Face--Streamline-Emoji.svg +16 -0
- package/src/emoji2/Amusing-Face--Streamline-Emoji.svg +20 -0
- package/src/emoji2/Anguished-Face--Streamline-Emoji.svg +19 -0
- package/src/emoji2/Anxious-Face--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Astonished-Face--Streamline-Emoji.svg +20 -0
- package/src/emoji2/Backhand-Index-Pointing-Down-1--Streamline-Emoji.svg +12 -0
- package/src/emoji2/Backhand-Index-Pointing-Left-1--Streamline-Emoji.svg +13 -0
- package/src/emoji2/Backhand-Index-Pointing-Right-1--Streamline-Emoji.svg +13 -0
- package/src/emoji2/Backhand-Index-Pointing-Up-1--Streamline-Emoji.svg +14 -0
- package/src/emoji2/Bar-Chart--Streamline-Emoji.svg +22 -0
- package/src/emoji2/Beaming-Face-With-Smiling-Eyes--Streamline-Emoji.svg +20 -0
- package/src/emoji2/Boy-1--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Boy-2--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Boy-3--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Broken-Heart--Streamline-Emoji.svg +12 -0
- package/src/emoji2/Clapping-Hands-1--Streamline-Emoji.svg +23 -0
- package/src/emoji2/Clinking-Glasses-2--Streamline-Emoji.svg +43 -0
- package/src/emoji2/Confounded-Face--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Confused-Face--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Construction-Worker--Streamline-Emoji.svg +21 -0
- package/src/emoji2/Couple-With-Heart-Woman-Man-1--Streamline-Emoji.svg +40 -0
- package/src/emoji2/Couple-With-Heart-Woman-Man-2--Streamline-Emoji.svg +40 -0
- package/src/emoji2/Cowboy-Hat-Face--Streamline-Emoji.svg +22 -0
- package/src/emoji2/Crazy-Face--Streamline-Emoji.svg +25 -0
- package/src/emoji2/Crossed-Fingers-1--Streamline-Emoji.svg +25 -0
- package/src/emoji2/Crown--Streamline-Emoji.svg +35 -0
- package/src/emoji2/Crying-Face--Streamline-Emoji.svg +26 -0
- package/src/emoji2/Delivery-Truck--Streamline-Emoji.svg +31 -0
- package/src/emoji2/Determined-Face--Streamline-Emoji.svg +25 -0
- package/src/emoji2/Disappointed-Face--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Dizzy-Face--Streamline-Emoji.svg +20 -0
- package/src/emoji2/Downcast-Face-With-Sweat--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Drooling-Face-1--Streamline-Emoji.svg +19 -0
- package/src/emoji2/Drooling-Face-2--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Ear--Streamline-Emoji.svg +14 -0
- package/src/emoji2/Exclamation-Mark--Streamline-Emoji.svg +12 -0
- package/src/emoji2/Exploding-Head--Streamline-Emoji.svg +24 -0
- package/src/emoji2/Expressionless-Face--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Face-Blowing-A-Kiss--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Face-Savoring-Food--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Face-Screaming-In-Fear--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Face-Vomiting--Streamline-Emoji.svg +28 -0
- package/src/emoji2/Face-With-Head-Bandage--Streamline-Emoji.svg +25 -0
- package/src/emoji2/Face-With-Medical-Mask--Streamline-Emoji.svg +23 -0
- package/src/emoji2/Face-With-Monocle--Streamline-Emoji.svg +26 -0
- package/src/emoji2/Face-With-Raised-Eyebrow--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Face-With-Rolling-Eyes--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Face-With-Steam-From-Nose--Streamline-Emoji.svg +19 -0
- package/src/emoji2/Face-With-Symbols-On-Mouth--Streamline-Emoji.svg +22 -0
- package/src/emoji2/Face-With-Tears-Of-Joy--Streamline-Emoji.svg +34 -0
- package/src/emoji2/Face-With-Thermometer--Streamline-Emoji.svg +31 -0
- package/src/emoji2/Face-With-Tongue--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Face-Without-Mouth--Streamline-Emoji.svg +14 -0
- package/src/emoji2/Fearful-Face--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Flexed-Biceps-1--Streamline-Emoji.svg +13 -0
- package/src/emoji2/Flushed-Face--Streamline-Emoji.svg +19 -0
- package/src/emoji2/Folded-Hands-1--Streamline-Emoji.svg +29 -0
- package/src/emoji2/Frowning-Face--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Fuel-Pump--Streamline-Emoji.svg +30 -0
- package/src/emoji2/Girl-1--Streamline-Emoji.svg +23 -0
- package/src/emoji2/Glasses-1--Streamline-Emoji.svg +27 -0
- package/src/emoji2/Grimacing-Face--Streamline-Emoji.svg +19 -0
- package/src/emoji2/Grinning-Cat-Face--Streamline-Emoji.svg +32 -0
- package/src/emoji2/Grinning-Face--Streamline-Emoji.svg +16 -0
- package/src/emoji2/Grinning-Face-With-Sweat--Streamline-Emoji.svg +19 -0
- package/src/emoji2/Grinning-Squinting-Face--Streamline-Emoji.svg +16 -0
- package/src/emoji2/Hand-With-Fingers-Splayed-1--Streamline-Emoji.svg +14 -0
- package/src/emoji2/Heart-Suit--Streamline-Emoji.svg +9 -0
- package/src/emoji2/Hushed-Face-1--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Hushed-Face-2--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Index-Pointing-Up-1--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Kissing-Face-With-Closed-Eyes--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Loudly-Crying-Face--Streamline-Emoji.svg +16 -0
- package/src/emoji2/Lying-Face--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Man-1--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Man-Facepalming-1--Streamline-Emoji.svg +21 -0
- package/src/emoji2/Man-Gesturing-No-1--Streamline-Emoji.svg +34 -0
- package/src/emoji2/Man-Gesturing-Ok-1--Streamline-Emoji.svg +25 -0
- package/src/emoji2/Man-Health-Worker-1--Streamline-Emoji.svg +41 -0
- package/src/emoji2/Man-Raising-Hand-1--Streamline-Emoji.svg +26 -0
- package/src/emoji2/Man-Shrugging-1--Streamline-Emoji.svg +31 -0
- package/src/emoji2/Money-Mouth-Face-2--Streamline-Emoji.svg +30 -0
- package/src/emoji2/Mouth--Streamline-Emoji.svg +12 -0
- package/src/emoji2/Nauseated-Face-2--Streamline-Emoji.svg +19 -0
- package/src/emoji2/Neutral-Face--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Ok-Hand-1--Streamline-Emoji.svg +14 -0
- package/src/emoji2/Old-Man-1--Streamline-Emoji.svg +27 -0
- package/src/emoji2/Old-Woman-1--Streamline-Emoji.svg +23 -0
- package/src/emoji2/Oncoming-Fist-1--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Person-Wearing-Turban-2--Streamline-Emoji.svg +20 -0
- package/src/emoji2/Pile-Of-Poo--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Police-Car-Light--Streamline-Emoji.svg +26 -0
- package/src/emoji2/Rocket--Streamline-Emoji.svg +32 -0
- package/src/emoji2/Sailboat--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Shaved-Ice--Streamline-Emoji.svg +21 -0
- package/src/emoji2/Shortcake-2--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Shushing-Face--Streamline-Emoji.svg +21 -0
- package/src/emoji2/Sign-Of-The-Horns-1--Streamline-Emoji.svg +19 -0
- package/src/emoji2/Sleeping-Face--Streamline-Emoji.svg +21 -0
- package/src/emoji2/Slightly-Smiling-Face--Streamline-Emoji.svg +15 -0
- package/src/emoji2/Smiling-Face-With-Halo--Streamline-Emoji.svg +20 -0
- package/src/emoji2/Smiling-Face-With-Heart-Eyes--Streamline-Emoji.svg +21 -0
- package/src/emoji2/Smirking-Face--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Sun-With-Face--Streamline-Emoji.svg +24 -0
- package/src/emoji2/Thumbs-Down-1--Streamline-Emoji.svg +20 -0
- package/src/emoji2/Thumbs-Up-1--Streamline-Emoji.svg +19 -0
- package/src/emoji2/Winking-Face--Streamline-Emoji.svg +18 -0
- package/src/emoji2/Woman-Gesturing-No-1--Streamline-Emoji.svg +34 -0
- package/src/emoji2/Woman-Gesturing-Ok-2--Streamline-Emoji.svg +25 -0
- package/src/emoji2/Woman-Raising-Hand-1--Streamline-Emoji.svg +26 -0
- package/src/emoji2/Womans-Sandal--Streamline-Emoji.svg +13 -0
- package/src/emoji2/Worried-Face--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Writing-Hand-1--Streamline-Emoji.svg +17 -0
- package/src/emoji2/Zipper-Mouth-Face--Streamline-Emoji.svg +21 -0
- package/src/index.js +19 -0
- package/src/services/burn-after-read-service.js +313 -0
- package/src/services/burn-after-read-service.test.js +325 -0
- package/src/services/dify-api.js +338 -0
- package/src/services/dify-api.test.js +376 -0
- package/src/services/scheduled-send-service.js +311 -0
- package/src/services/scheduled-send-service.test.js +317 -0
- package/src/styles/index.css +2368 -0
- package/src/utils/emoji.js +125 -0
- package/src/utils/emojiData.js +267 -0
- package/src/utils/eventEmitter.js +114 -0
- package/src/utils/state.js +224 -0
- package/src/utils/state.test.js +198 -0
- package/src/utils/storage.js +122 -0
- package/src/utils/storage.test.js +162 -0
- package/src/utils/validation.js +249 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="send-button-group">
|
|
3
|
+
<!-- 主发送按钮 + 下拉菜单 -->
|
|
4
|
+
<t-dropdown
|
|
5
|
+
:disabled="disabled"
|
|
6
|
+
trigger="click"
|
|
7
|
+
@click-item="handleOptionClick"
|
|
8
|
+
>
|
|
9
|
+
<template #default>
|
|
10
|
+
<button
|
|
11
|
+
class="send-btn-combined"
|
|
12
|
+
:disabled="disabled"
|
|
13
|
+
:title="disabled ? '请输入消息内容' : '发送消息 (Ctrl+Enter)'"
|
|
14
|
+
@click="handleSend"
|
|
15
|
+
>
|
|
16
|
+
<i class="ri-send-plane-line"></i>
|
|
17
|
+
<span class="send-text">发送</span>
|
|
18
|
+
<i class="ri-arrow-down-s-line dropdown-icon"></i>
|
|
19
|
+
</button>
|
|
20
|
+
</template>
|
|
21
|
+
<t-dropdown-menu>
|
|
22
|
+
<t-dropdown-item
|
|
23
|
+
v-for="option in options"
|
|
24
|
+
:key="option.id"
|
|
25
|
+
:value="option.id"
|
|
26
|
+
class="dropdown-item"
|
|
27
|
+
>
|
|
28
|
+
<i :class="option.icon"></i>
|
|
29
|
+
<span>{{ option.label }}</span>
|
|
30
|
+
</t-dropdown-item>
|
|
31
|
+
</t-dropdown-menu>
|
|
32
|
+
</t-dropdown>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script>
|
|
37
|
+
import { ref } from 'vue';
|
|
38
|
+
import { Dropdown, DropdownMenu, DropdownItem } from 'tdesign-vue-next';
|
|
39
|
+
|
|
40
|
+
export default {
|
|
41
|
+
name: 'SendButtonGroup',
|
|
42
|
+
components: {
|
|
43
|
+
TDropdown: Dropdown,
|
|
44
|
+
TDropdownMenu: DropdownMenu,
|
|
45
|
+
TDropdownItem: DropdownItem
|
|
46
|
+
},
|
|
47
|
+
props: {
|
|
48
|
+
disabled: {
|
|
49
|
+
type: Boolean,
|
|
50
|
+
default: false
|
|
51
|
+
},
|
|
52
|
+
options: {
|
|
53
|
+
type: Array,
|
|
54
|
+
default: () => [
|
|
55
|
+
{
|
|
56
|
+
id: 'screenshot',
|
|
57
|
+
label: '截屏',
|
|
58
|
+
icon: 'ri-screenshot-2-line'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: 'scheduled',
|
|
62
|
+
label: '延时发送',
|
|
63
|
+
icon: 'ri-time-line'
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'burn',
|
|
67
|
+
label: '阅后即焚',
|
|
68
|
+
icon: 'ri-fire-line'
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'priority',
|
|
72
|
+
label: '标记紧急',
|
|
73
|
+
icon: 'ri-alarm-warning-line'
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
emits: ['send', 'option-click'],
|
|
79
|
+
setup(props, { emit }) {
|
|
80
|
+
const handleSend = () => {
|
|
81
|
+
if (!props.disabled) {
|
|
82
|
+
emit('send');
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const handleOptionClick = (value) => {
|
|
87
|
+
const option = props.options.find(opt => opt.id === value);
|
|
88
|
+
if (option) {
|
|
89
|
+
emit('option-click', option);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
handleSend,
|
|
95
|
+
handleOptionClick
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
</script>
|
|
100
|
+
|
|
101
|
+
<style scoped>
|
|
102
|
+
.send-button-group {
|
|
103
|
+
display: flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.send-btn-combined {
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
gap: 6px;
|
|
111
|
+
padding: 8px 16px;
|
|
112
|
+
height: 36px;
|
|
113
|
+
border: none;
|
|
114
|
+
border-radius: 4px;
|
|
115
|
+
background-color: #1890ff;
|
|
116
|
+
color: white;
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
transition: all 0.2s ease;
|
|
119
|
+
font-size: 14px;
|
|
120
|
+
font-weight: 500;
|
|
121
|
+
white-space: nowrap;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.send-btn-combined:hover:not(:disabled) {
|
|
125
|
+
background-color: #0052a3;
|
|
126
|
+
transform: translateY(-1px);
|
|
127
|
+
box-shadow: 0 2px 8px rgba(0, 103, 204, 0.3);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.send-btn-combined:active:not(:disabled) {
|
|
131
|
+
transform: translateY(0);
|
|
132
|
+
box-shadow: 0 1px 4px rgba(0, 103, 204, 0.2);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.send-btn-combined:disabled {
|
|
136
|
+
background-color: #ccc;
|
|
137
|
+
cursor: not-allowed;
|
|
138
|
+
opacity: 0.6;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.send-text {
|
|
142
|
+
font-weight: 500;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.dropdown-icon {
|
|
146
|
+
font-size: 12px;
|
|
147
|
+
margin-left: 2px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* 响应式设计 */
|
|
151
|
+
@media (max-width: 768px) {
|
|
152
|
+
.send-btn-combined {
|
|
153
|
+
padding: 8px 12px;
|
|
154
|
+
height: 40px;
|
|
155
|
+
font-size: 15px;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.send-text {
|
|
159
|
+
display: none;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.dropdown-icon {
|
|
163
|
+
display: none;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
</style>
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Point, Bounds } from '../types'
|
|
2
|
+
|
|
3
|
+
export default function getBoundsByPoints (
|
|
4
|
+
{ x: x1, y: y1 }: Point,
|
|
5
|
+
{ x: x2, y: y2 }: Point,
|
|
6
|
+
width: number,
|
|
7
|
+
height: number
|
|
8
|
+
): Bounds {
|
|
9
|
+
// 交换值
|
|
10
|
+
if (x1 > x2) {
|
|
11
|
+
[x1, x2] = [x2, x1]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (y1 > y2) {
|
|
15
|
+
[y1, y2] = [y2, y1]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 把图形限制在元素里面
|
|
19
|
+
if (x1 < 0) {
|
|
20
|
+
x1 = 0
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (x2 > width) {
|
|
24
|
+
x2 = width
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (y1 < 0) {
|
|
28
|
+
y1 = 0
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (y2 > height) {
|
|
32
|
+
y2 = height
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
x: x1,
|
|
37
|
+
y: y1,
|
|
38
|
+
width: x2 - x1,
|
|
39
|
+
height: y2 - y1
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.screenshots-background {
|
|
2
|
+
width: 100%;
|
|
3
|
+
height: 100%;
|
|
4
|
+
position: relative;
|
|
5
|
+
|
|
6
|
+
&-image {
|
|
7
|
+
width: 100%;
|
|
8
|
+
height: 100%;
|
|
9
|
+
display: block;
|
|
10
|
+
border: none;
|
|
11
|
+
outline: none;
|
|
12
|
+
image-rendering: -webkit-optimize-contrast;
|
|
13
|
+
image-rendering: crisp-edges;
|
|
14
|
+
-webkit-font-smooting: antialiased;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
&-mask {
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
position: absolute;
|
|
21
|
+
top: 0;
|
|
22
|
+
right: 0;
|
|
23
|
+
bottom: 0;
|
|
24
|
+
left: 0;
|
|
25
|
+
background-color: rgba(0, 0, 0, 0.3);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
memo,
|
|
3
|
+
ReactElement,
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useLayoutEffect,
|
|
7
|
+
useRef,
|
|
8
|
+
useState,
|
|
9
|
+
} from "react";
|
|
10
|
+
import useBounds from "../hooks/useBounds";
|
|
11
|
+
import useStore from "../hooks/useStore";
|
|
12
|
+
import ScreenshotsMagnifier from "../ScreenshotsMagnifier";
|
|
13
|
+
import { Point, Position } from "../types";
|
|
14
|
+
import getBoundsByPoints from "./getBoundsByPoints";
|
|
15
|
+
import "./index.scss";
|
|
16
|
+
|
|
17
|
+
export default memo(function ScreenshotsBackground(): ReactElement | null {
|
|
18
|
+
const { url, image, width, height } = useStore();
|
|
19
|
+
const [bounds, boundsDispatcher] = useBounds();
|
|
20
|
+
|
|
21
|
+
const elRef = useRef<HTMLDivElement>(null);
|
|
22
|
+
const pointRef = useRef<Point | null>(null);
|
|
23
|
+
// 用来判断鼠标是否移动过
|
|
24
|
+
// 如果没有移动过位置,则mouseup时不更新
|
|
25
|
+
const isMoveRef = useRef<boolean>(false);
|
|
26
|
+
const [position, setPosition] = useState<Position | null>(null);
|
|
27
|
+
|
|
28
|
+
const updateBounds = useCallback(
|
|
29
|
+
(p1: Point, p2: Point) => {
|
|
30
|
+
if (!elRef.current) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const { x, y } = elRef.current.getBoundingClientRect();
|
|
34
|
+
|
|
35
|
+
boundsDispatcher.set(
|
|
36
|
+
getBoundsByPoints(
|
|
37
|
+
{
|
|
38
|
+
x: p1.x - x,
|
|
39
|
+
y: p1.y - y,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
x: p2.x - x,
|
|
43
|
+
y: p2.y - y,
|
|
44
|
+
},
|
|
45
|
+
width,
|
|
46
|
+
height,
|
|
47
|
+
),
|
|
48
|
+
);
|
|
49
|
+
},
|
|
50
|
+
[width, height, boundsDispatcher],
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const onMouseDown = useCallback(
|
|
54
|
+
(e: React.MouseEvent) => {
|
|
55
|
+
// e.button 鼠标左键
|
|
56
|
+
if (pointRef.current || bounds || e.button !== 0) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
pointRef.current = {
|
|
60
|
+
x: e.clientX,
|
|
61
|
+
y: e.clientY,
|
|
62
|
+
};
|
|
63
|
+
isMoveRef.current = false;
|
|
64
|
+
},
|
|
65
|
+
[bounds],
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
const onMouseMove = (e: MouseEvent) => {
|
|
70
|
+
if (elRef.current) {
|
|
71
|
+
const rect = elRef.current.getBoundingClientRect();
|
|
72
|
+
if (
|
|
73
|
+
e.clientX < rect.left ||
|
|
74
|
+
e.clientY < rect.top ||
|
|
75
|
+
e.clientX > rect.right ||
|
|
76
|
+
e.clientY > rect.bottom
|
|
77
|
+
) {
|
|
78
|
+
setPosition(null);
|
|
79
|
+
} else {
|
|
80
|
+
setPosition({
|
|
81
|
+
x: e.clientX - rect.x,
|
|
82
|
+
y: e.clientY - rect.y,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!pointRef.current) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
updateBounds(pointRef.current, {
|
|
91
|
+
x: e.clientX,
|
|
92
|
+
y: e.clientY,
|
|
93
|
+
});
|
|
94
|
+
isMoveRef.current = true;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const onMouseUp = (e: MouseEvent) => {
|
|
98
|
+
if (!pointRef.current) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (isMoveRef.current) {
|
|
103
|
+
updateBounds(pointRef.current, {
|
|
104
|
+
x: e.clientX,
|
|
105
|
+
y: e.clientY,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
pointRef.current = null;
|
|
109
|
+
isMoveRef.current = false;
|
|
110
|
+
};
|
|
111
|
+
window.addEventListener("mousemove", onMouseMove);
|
|
112
|
+
window.addEventListener("mouseup", onMouseUp);
|
|
113
|
+
|
|
114
|
+
return () => {
|
|
115
|
+
window.removeEventListener("mousemove", onMouseMove);
|
|
116
|
+
window.removeEventListener("mouseup", onMouseUp);
|
|
117
|
+
};
|
|
118
|
+
}, [updateBounds]);
|
|
119
|
+
|
|
120
|
+
useLayoutEffect(() => {
|
|
121
|
+
if (!image || bounds) {
|
|
122
|
+
// 重置位置
|
|
123
|
+
setPosition(null);
|
|
124
|
+
}
|
|
125
|
+
}, [image, bounds]);
|
|
126
|
+
|
|
127
|
+
// 没有加载完不显示图片
|
|
128
|
+
if (!url || !image) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<div
|
|
134
|
+
ref={elRef}
|
|
135
|
+
className="screenshots-background"
|
|
136
|
+
onMouseDown={onMouseDown}
|
|
137
|
+
>
|
|
138
|
+
<img className="screenshots-background-image" src={url} />
|
|
139
|
+
<div className="screenshots-background-mask" />
|
|
140
|
+
{position && !bounds && (
|
|
141
|
+
<ScreenshotsMagnifier x={position?.x} y={position?.y} />
|
|
142
|
+
)}
|
|
143
|
+
</div>
|
|
144
|
+
);
|
|
145
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
@import "../var.scss";
|
|
2
|
+
|
|
3
|
+
.screenshots-button {
|
|
4
|
+
width: $button-size;
|
|
5
|
+
height: $button-size;
|
|
6
|
+
line-height: $button-size;
|
|
7
|
+
color: #333;
|
|
8
|
+
font-size: 22px;
|
|
9
|
+
text-align: center;
|
|
10
|
+
margin: 0 3px;
|
|
11
|
+
vertical-align: middle;
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
|
|
14
|
+
&-checked,
|
|
15
|
+
&:hover {
|
|
16
|
+
background-color: #eee;
|
|
17
|
+
outline: 1px solid #777;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&-disabled {
|
|
21
|
+
color: #bbb;
|
|
22
|
+
cursor: not-allowed;
|
|
23
|
+
|
|
24
|
+
&:hover {
|
|
25
|
+
background-color: #fff;
|
|
26
|
+
outline: none;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
memo,
|
|
3
|
+
ReactElement,
|
|
4
|
+
PointerEvent,
|
|
5
|
+
ReactNode,
|
|
6
|
+
useCallback,
|
|
7
|
+
} from "react";
|
|
8
|
+
import ScreenshotsOption from "../ScreenshotsOption";
|
|
9
|
+
import "./index.scss";
|
|
10
|
+
|
|
11
|
+
export interface ScreenshotsButtonProps {
|
|
12
|
+
title: string;
|
|
13
|
+
icon: string;
|
|
14
|
+
checked?: boolean;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
option?: ReactNode;
|
|
17
|
+
onClick?: (e: PointerEvent<HTMLDivElement>) => unknown;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default memo(function ScreenshotsButton({
|
|
21
|
+
title,
|
|
22
|
+
icon,
|
|
23
|
+
checked,
|
|
24
|
+
disabled,
|
|
25
|
+
option,
|
|
26
|
+
onClick,
|
|
27
|
+
}: ScreenshotsButtonProps): ReactElement {
|
|
28
|
+
const classNames = ["screenshots-button"];
|
|
29
|
+
|
|
30
|
+
const onButtonClick = useCallback(
|
|
31
|
+
(e: PointerEvent<HTMLDivElement>) => {
|
|
32
|
+
if (disabled || !onClick) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
onClick(e);
|
|
36
|
+
},
|
|
37
|
+
[disabled, onClick],
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (checked) {
|
|
41
|
+
classNames.push("screenshots-button-checked");
|
|
42
|
+
}
|
|
43
|
+
if (disabled) {
|
|
44
|
+
classNames.push("screenshots-button-disabled");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<ScreenshotsOption open={checked} content={option}>
|
|
49
|
+
<div
|
|
50
|
+
className={classNames.join(" ")}
|
|
51
|
+
title={title}
|
|
52
|
+
onClick={onButtonClick}
|
|
53
|
+
>
|
|
54
|
+
<span className={icon} />
|
|
55
|
+
</div>
|
|
56
|
+
</ScreenshotsOption>
|
|
57
|
+
);
|
|
58
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Bounds, Point } from '../types'
|
|
2
|
+
|
|
3
|
+
export default function getBoundsByPoints (
|
|
4
|
+
{ x: x1, y: y1 }: Point,
|
|
5
|
+
{ x: x2, y: y2 }: Point,
|
|
6
|
+
bounds: Bounds,
|
|
7
|
+
width: number,
|
|
8
|
+
height: number,
|
|
9
|
+
resizeOrMove: string
|
|
10
|
+
): Bounds {
|
|
11
|
+
// 交换值
|
|
12
|
+
if (x1 > x2) {
|
|
13
|
+
[x1, x2] = [x2, x1]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (y1 > y2) {
|
|
17
|
+
[y1, y2] = [y2, y1]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// 把图形限制在元素里面
|
|
21
|
+
if (x1 < 0) {
|
|
22
|
+
x1 = 0
|
|
23
|
+
if (resizeOrMove === 'move') {
|
|
24
|
+
x2 = bounds.width
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (x2 > width) {
|
|
29
|
+
x2 = width
|
|
30
|
+
if (resizeOrMove === 'move') {
|
|
31
|
+
x1 = x2 - bounds.width
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (y1 < 0) {
|
|
36
|
+
y1 = 0
|
|
37
|
+
if (resizeOrMove === 'move') {
|
|
38
|
+
y2 = bounds.height
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (y2 > height) {
|
|
43
|
+
y2 = height
|
|
44
|
+
if (resizeOrMove === 'move') {
|
|
45
|
+
y1 = y2 - bounds.height
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
x: x1,
|
|
51
|
+
y: y1,
|
|
52
|
+
width: Math.max(x2 - x1, 1),
|
|
53
|
+
height: Math.max(y2 - y1, 1)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Point, Bounds } from '../types'
|
|
2
|
+
|
|
3
|
+
export default function getBoundsByPoints (e: MouseEvent, resizeOrMove: string, point: Point, bounds: Bounds): Point[] {
|
|
4
|
+
const x = e.clientX - point.x
|
|
5
|
+
const y = e.clientY - point.y
|
|
6
|
+
let x1 = bounds.x
|
|
7
|
+
let y1 = bounds.y
|
|
8
|
+
let x2 = bounds.x + bounds.width
|
|
9
|
+
let y2 = bounds.y + bounds.height
|
|
10
|
+
|
|
11
|
+
switch (resizeOrMove) {
|
|
12
|
+
case 'top':
|
|
13
|
+
y1 += y
|
|
14
|
+
break
|
|
15
|
+
case 'top-right':
|
|
16
|
+
x2 += x
|
|
17
|
+
y1 += y
|
|
18
|
+
break
|
|
19
|
+
case 'right':
|
|
20
|
+
x2 += x
|
|
21
|
+
break
|
|
22
|
+
case 'right-bottom':
|
|
23
|
+
x2 += x
|
|
24
|
+
y2 += y
|
|
25
|
+
break
|
|
26
|
+
case 'bottom':
|
|
27
|
+
y2 += y
|
|
28
|
+
break
|
|
29
|
+
case 'bottom-left':
|
|
30
|
+
x1 += x
|
|
31
|
+
y2 += y
|
|
32
|
+
break
|
|
33
|
+
case 'left':
|
|
34
|
+
x1 += x
|
|
35
|
+
break
|
|
36
|
+
case 'left-top':
|
|
37
|
+
x1 += x
|
|
38
|
+
y1 += y
|
|
39
|
+
break
|
|
40
|
+
case 'move':
|
|
41
|
+
x1 += x
|
|
42
|
+
y1 += y
|
|
43
|
+
x2 += x
|
|
44
|
+
y2 += y
|
|
45
|
+
break
|
|
46
|
+
default:
|
|
47
|
+
break
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return [
|
|
51
|
+
{
|
|
52
|
+
x: x1,
|
|
53
|
+
y: y1
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
x: x2,
|
|
57
|
+
y: y2
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
@import "../var.scss";
|
|
2
|
+
|
|
3
|
+
.screenshots-canvas {
|
|
4
|
+
position: absolute;
|
|
5
|
+
left: 0;
|
|
6
|
+
top: 0;
|
|
7
|
+
will-change: width, height, transform;
|
|
8
|
+
|
|
9
|
+
&-body,
|
|
10
|
+
&-mask {
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 100%;
|
|
13
|
+
position: absolute;
|
|
14
|
+
top: 0;
|
|
15
|
+
right: 0;
|
|
16
|
+
bottom: 0;
|
|
17
|
+
left: 0;
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&-image {
|
|
22
|
+
display: block;
|
|
23
|
+
border: none;
|
|
24
|
+
outline: none;
|
|
25
|
+
will-change: transform;
|
|
26
|
+
max-width: unset;
|
|
27
|
+
image-rendering: -webkit-optimize-contrast;
|
|
28
|
+
image-rendering: crisp-edges;
|
|
29
|
+
-webkit-font-smooting: antialiased;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&-panel {
|
|
33
|
+
width: 100%;
|
|
34
|
+
height: 100%;
|
|
35
|
+
position: absolute;
|
|
36
|
+
left: 0;
|
|
37
|
+
top: 0;
|
|
38
|
+
right: 0;
|
|
39
|
+
bottom: 0;
|
|
40
|
+
will-change: width, height;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&-size {
|
|
44
|
+
position: absolute;
|
|
45
|
+
bottom: 0;
|
|
46
|
+
left: 50%;
|
|
47
|
+
transform: translateX(-50%);
|
|
48
|
+
background-color: rgba(0, 0, 0, 0.8);
|
|
49
|
+
color: #fff;
|
|
50
|
+
font-size: 12px;
|
|
51
|
+
padding: 3px 4px;
|
|
52
|
+
border-radius: 2px;
|
|
53
|
+
white-space: nowrap;
|
|
54
|
+
pointer-events: none;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@each $border in $borders {
|
|
58
|
+
@each $key, $value in $border {
|
|
59
|
+
&-border-#{$key} {
|
|
60
|
+
@each $j, $val in $value {
|
|
61
|
+
#{$j}: $val;
|
|
62
|
+
}
|
|
63
|
+
position: absolute;
|
|
64
|
+
background-color: $border-color;
|
|
65
|
+
pointer-events: none;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
@each $point in $points {
|
|
70
|
+
@each $key, $value in $point {
|
|
71
|
+
&-point-#{$key} {
|
|
72
|
+
@each $j, $val in $value {
|
|
73
|
+
#{$j}: $val;
|
|
74
|
+
}
|
|
75
|
+
width: 8px;
|
|
76
|
+
height: 8px;
|
|
77
|
+
position: absolute;
|
|
78
|
+
background-color: $point-color;
|
|
79
|
+
border-radius: 50%;
|
|
80
|
+
transform: translate(-50%, -50%);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|