|
@@ -8,11 +8,40 @@
|
|
@mousedown="handleMouseDown"
|
|
@mousedown="handleMouseDown"
|
|
@mousemove="handleMouseMove"
|
|
@mousemove="handleMouseMove"
|
|
@mouseup="handleMouseUp"
|
|
@mouseup="handleMouseUp"
|
|
- @mouseleave="handleMouseUp"
|
|
|
|
@touchstart="handleTouchStart"
|
|
@touchstart="handleTouchStart"
|
|
@touchmove="handleTouchMove"
|
|
@touchmove="handleTouchMove"
|
|
@touchend="handleTouchEnd"
|
|
@touchend="handleTouchEnd"
|
|
></canvas>
|
|
></canvas>
|
|
|
|
+
|
|
|
|
+ <canvas
|
|
|
|
+ ref="canvas2"
|
|
|
|
+ class="drawing-canvas"
|
|
|
|
+ v-show="showCanvas2"
|
|
|
|
+ @mousedown="handleMouseDown"
|
|
|
|
+ @mousemove="handleMouseMove"
|
|
|
|
+ @mouseup="handleMouseUp"
|
|
|
|
+ @touchstart="handleTouchStart"
|
|
|
|
+ @touchmove="handleTouchMove"
|
|
|
|
+ @touchend="handleTouchEnd"
|
|
|
|
+ ></canvas>
|
|
|
|
+
|
|
|
|
+ <!-- <canvas
|
|
|
|
+ ref="canvas3"
|
|
|
|
+ class="drawing-canvas screenshotCanvas"
|
|
|
|
+ v-show="mode==='screenshot'"
|
|
|
|
+ @mousedown="screenshotMouseDown"
|
|
|
|
+ @mousemove="screenshotMouseMove"
|
|
|
|
+ @mouseup="screenshotMouseUp"
|
|
|
|
+ @touchstart="screenshotTouchStart"
|
|
|
|
+ @touchmove="screenshotTouchMove"
|
|
|
|
+ @touchend="screenshotTouchEnd"
|
|
|
|
+ ></canvas>
|
|
|
|
+
|
|
|
|
+ <div class="screenshotBox" v-show="showCanvas4">
|
|
|
|
+ <canvas ref="canvas4" :style="`position:absolute;left:${startX}px;top:${startY}px`">
|
|
|
|
+
|
|
|
|
+ </canvas>
|
|
|
|
+ </div> -->
|
|
</el-col>
|
|
</el-col>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row
|
|
<el-row
|
|
@@ -28,12 +57,21 @@
|
|
:class="{ active: mode === 'draw' }"
|
|
:class="{ active: mode === 'draw' }"
|
|
>画笔</el-button
|
|
>画笔</el-button
|
|
> -->
|
|
> -->
|
|
- <el-tooltip class="item" effect="light" content="画笔" placement="top">
|
|
|
|
|
|
+ <el-tooltip
|
|
|
|
+ class="item"
|
|
|
|
+ effect="light"
|
|
|
|
+ content="画笔"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
<svg
|
|
<svg
|
|
width="24"
|
|
width="24"
|
|
height="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
viewBox="0 0 24 24"
|
|
- :style="mode === 'draw' ? `background-color:${brushColor}` : ''"
|
|
|
|
|
|
+ :style="
|
|
|
|
+ mode === 'draw' && canDraw
|
|
|
|
+ ? `background-color:${brushColor}`
|
|
|
|
+ : ''
|
|
|
|
+ "
|
|
fill="none"
|
|
fill="none"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
@click.stop="setMode('draw')"
|
|
@click.stop="setMode('draw')"
|
|
@@ -42,13 +80,25 @@
|
|
fill-rule="evenodd"
|
|
fill-rule="evenodd"
|
|
clip-rule="evenodd"
|
|
clip-rule="evenodd"
|
|
d="M12 6.75C12.2508 6.75 12.4849 6.87533 12.624 7.08397L15.624 11.584C15.7062 11.7072 15.75 11.8519 15.75 12V21C15.75 21.4142 15.4142 21.75 15 21.75C14.5858 21.75 14.25 21.4142 14.25 21V12.75H9.75V21C9.75 21.4142 9.41421 21.75 9 21.75C8.58579 21.75 8.25 21.4142 8.25 21V12C8.25 11.8519 8.29383 11.7072 8.37596 11.584L11.376 7.08397C11.5151 6.87533 11.7492 6.75 12 6.75ZM10.4014 11.25H13.5986L12 8.85208L10.4014 11.25Z"
|
|
d="M12 6.75C12.2508 6.75 12.4849 6.87533 12.624 7.08397L15.624 11.584C15.7062 11.7072 15.75 11.8519 15.75 12V21C15.75 21.4142 15.4142 21.75 15 21.75C14.5858 21.75 14.25 21.4142 14.25 21V12.75H9.75V21C9.75 21.4142 9.41421 21.75 9 21.75C8.58579 21.75 8.25 21.4142 8.25 21V12C8.25 11.8519 8.29383 11.7072 8.37596 11.584L11.376 7.08397C11.5151 6.87533 11.7492 6.75 12 6.75ZM10.4014 11.25H13.5986L12 8.85208L10.4014 11.25Z"
|
|
- :fill="mode === 'draw' ? brushColor==='#FFFFFF'?'black':'#fff' : '#3681FC'"
|
|
|
|
|
|
+ :fill="
|
|
|
|
+ mode === 'draw' && canDraw
|
|
|
|
+ ? brushColor === '#FFFFFF'
|
|
|
|
+ ? 'black'
|
|
|
|
+ : '#fff'
|
|
|
|
+ : '#3681FC'
|
|
|
|
+ "
|
|
/>
|
|
/>
|
|
<path
|
|
<path
|
|
fill-rule="evenodd"
|
|
fill-rule="evenodd"
|
|
clip-rule="evenodd"
|
|
clip-rule="evenodd"
|
|
d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM12 22.5C17.799 22.5 22.5 17.799 22.5 12C22.5 6.20101 17.799 1.5 12 1.5C6.20101 1.5 1.5 6.20101 1.5 12C1.5 17.799 6.20101 22.5 12 22.5Z"
|
|
d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM12 22.5C17.799 22.5 22.5 17.799 22.5 12C22.5 6.20101 17.799 1.5 12 1.5C6.20101 1.5 1.5 6.20101 1.5 12C1.5 17.799 6.20101 22.5 12 22.5Z"
|
|
- :fill="mode === 'draw' ? brushColor==='#FFFFFF'?'black':'#fff' : 'black'"
|
|
|
|
|
|
+ :fill="
|
|
|
|
+ mode === 'draw' && canDraw
|
|
|
|
+ ? brushColor === '#FFFFFF'
|
|
|
|
+ ? 'black'
|
|
|
|
+ : '#fff'
|
|
|
|
+ : 'black'
|
|
|
|
+ "
|
|
fill-opacity="0.9"
|
|
fill-opacity="0.9"
|
|
/>
|
|
/>
|
|
</svg>
|
|
</svg>
|
|
@@ -57,7 +107,7 @@
|
|
<el-tooltip
|
|
<el-tooltip
|
|
class="item"
|
|
class="item"
|
|
effect="light"
|
|
effect="light"
|
|
- content="切换颜色"
|
|
|
|
|
|
+ content="切换颜色与大小"
|
|
placement="top"
|
|
placement="top"
|
|
>
|
|
>
|
|
<el-button
|
|
<el-button
|
|
@@ -68,8 +118,15 @@
|
|
"
|
|
"
|
|
></el-button>
|
|
></el-button>
|
|
</el-tooltip>
|
|
</el-tooltip>
|
|
- <div class="brushBtn_colorBox" v-if="openBrushColorBox">
|
|
|
|
- <span
|
|
|
|
|
|
+ <div class="brushBtn_colorBox" v-if="openBrushColorBox" v-click-outside="handleBlur">
|
|
|
|
+ <div class="bb_cb_drawSize">
|
|
|
|
+ <div>大小</div>
|
|
|
|
+ <el-slider v-model="drawSize" :min="1" :max="20"></el-slider>
|
|
|
|
+ <div>颜色</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="bb_cb_drawColor">
|
|
|
|
+
|
|
|
|
+ <span
|
|
v-for="(item, index) in colorList"
|
|
v-for="(item, index) in colorList"
|
|
:key="index"
|
|
:key="index"
|
|
:style="`background-color: ${item};${
|
|
:style="`background-color: ${item};${
|
|
@@ -77,24 +134,217 @@
|
|
}`"
|
|
}`"
|
|
@click="setColor(item)"
|
|
@click="setColor(item)"
|
|
></span>
|
|
></span>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
- <div>
|
|
|
|
- <el-slider
|
|
|
|
- v-model="brushSize"
|
|
|
|
- :min="1"
|
|
|
|
- :max="20"
|
|
|
|
- style="width: 100px"
|
|
|
|
- ></el-slider>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
<!-- <div>
|
|
<!-- <div>
|
|
<el-color-picker
|
|
<el-color-picker
|
|
v-model="brushColor"
|
|
v-model="brushColor"
|
|
@active-change="setColor"
|
|
@active-change="setColor"
|
|
></el-color-picker>
|
|
></el-color-picker>
|
|
</div> -->
|
|
</div> -->
|
|
|
|
+<!--
|
|
|
|
+ <div>
|
|
|
|
+ <el-slider v-model="drawSize" :min="1" :max="20" style="width: 100px;"></el-slider>
|
|
|
|
+ </div> -->
|
|
|
|
+
|
|
|
|
+ <div class="shape">
|
|
|
|
+ <div
|
|
|
|
+ :class="[
|
|
|
|
+ ['line', 'circle', 'arrow', 'rect'].includes(shape) && canShape
|
|
|
|
+ ? 'shapeActive'
|
|
|
|
+ : '',
|
|
|
|
+ ]"
|
|
|
|
+ @click.stop="setShape('open')"
|
|
|
|
+ >
|
|
|
|
+ <svg
|
|
|
|
+ v-if="shape === 'line'"
|
|
|
|
+ t="1723428738446"
|
|
|
|
+ class="icon"
|
|
|
|
+ viewBox="0 0 1024 1024"
|
|
|
|
+ version="1.1"
|
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
|
+ p-id="5383"
|
|
|
|
+ width="200"
|
|
|
|
+ height="200"
|
|
|
|
+ fill="black"
|
|
|
|
+ >
|
|
|
|
+ <path
|
|
|
|
+ d="M195.584 866.816l-38.4-38.4c-12.288-12.288-12.288-31.744 0-43.52L784.384 157.184c12.288-12.288 31.744-12.288 43.52 0l38.4 38.4c12.288 12.288 12.288 31.744 0 43.52L239.104 866.816c-11.776 12.288-31.232 12.288-43.52 0z"
|
|
|
|
+ p-id="5384"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ <svg
|
|
|
|
+ v-else-if="shape === 'circle'"
|
|
|
|
+ t="1723428969048"
|
|
|
|
+ class="icon"
|
|
|
|
+ viewBox="0 0 1024 1024"
|
|
|
|
+ version="1.1"
|
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
|
+ p-id="6395"
|
|
|
|
+ width="200"
|
|
|
|
+ height="200"
|
|
|
|
+ fill="black"
|
|
|
|
+ >
|
|
|
|
+ <path
|
|
|
|
+ d="M512 928C282.624 928 96 741.376 96 512S282.624 96 512 96s416 186.624 416 416-186.624 416-416 416z m0-768C317.92 160 160 317.92 160 512s157.92 352 352 352 352-157.92 352-352S706.08 160 512 160z"
|
|
|
|
+ p-id="6396"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ <svg
|
|
|
|
+ v-else-if="shape === 'arrow'"
|
|
|
|
+ t="1723429061277"
|
|
|
|
+ class="icon"
|
|
|
|
+ viewBox="0 0 1024 1024"
|
|
|
|
+ version="1.1"
|
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
|
+ p-id="7359"
|
|
|
|
+ width="200"
|
|
|
|
+ height="200"
|
|
|
|
+ >
|
|
|
|
+ <path
|
|
|
|
+ d="M708.864 343.872l4.48 3.84 146.112 146.176a25.6 25.6 0 0 1 0 36.224l-146.112 146.112a40 40 0 0 1-60.416-52.032l3.84-4.48 67.584-67.712H168a40 40 0 1 1 0-80h556.48l-67.712-67.648a40 40 0 0 1-3.84-52.096l3.84-4.48a40 40 0 0 1 52.096-3.84z"
|
|
|
|
+ p-id="7360"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ <svg
|
|
|
|
+ v-else
|
|
|
|
+ t="1723428698910"
|
|
|
|
+ class="icon"
|
|
|
|
+ viewBox="0 0 1024 1024"
|
|
|
|
+ version="1.1"
|
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
|
+ p-id="4240"
|
|
|
|
+ width="200"
|
|
|
|
+ height="200"
|
|
|
|
+ fill="black"
|
|
|
|
+ >
|
|
|
|
+ <path
|
|
|
|
+ d="M864 896H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h704a32 32 0 0 1 32 32v704a32 32 0 0 1-32 32zM192 832h640V192H192v640z"
|
|
|
|
+ p-id="4241"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ </div>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ class="item"
|
|
|
|
+ effect="light"
|
|
|
|
+ content="切换形状"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
|
|
+ <el-button
|
|
|
|
+ class="selectBox"
|
|
|
|
+ @click.stop="changeOpenShape(!openShapeBox)"
|
|
|
|
+ :icon="openShapeBox ? 'el-icon-arrow-down' : 'el-icon-arrow-up'"
|
|
|
|
+ ></el-button>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ <div class="shapeBox" v-if="openShapeBox" v-click-outside="handleBlur">
|
|
|
|
+ <div
|
|
|
|
+ class="shapeItem"
|
|
|
|
+ :class="{ shapeItemActive: shape === 'line' }"
|
|
|
|
+ @click.stop="setShape('line')"
|
|
|
|
+ >
|
|
|
|
+ <svg
|
|
|
|
+ t="1723428738446"
|
|
|
|
+ class="icon"
|
|
|
|
+ viewBox="0 0 1024 1024"
|
|
|
|
+ version="1.1"
|
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
|
+ p-id="5383"
|
|
|
|
+ width="200"
|
|
|
|
+ height="200"
|
|
|
|
+ fill="black"
|
|
|
|
+ >
|
|
|
|
+ <path
|
|
|
|
+ d="M195.584 866.816l-38.4-38.4c-12.288-12.288-12.288-31.744 0-43.52L784.384 157.184c12.288-12.288 31.744-12.288 43.52 0l38.4 38.4c12.288 12.288 12.288 31.744 0 43.52L239.104 866.816c-11.776 12.288-31.232 12.288-43.52 0z"
|
|
|
|
+ p-id="5384"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ <span>直线</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ class="shapeItem"
|
|
|
|
+ :class="{ shapeItemActive: shape === 'circle' }"
|
|
|
|
+ @click.stop="setShape('circle')"
|
|
|
|
+ >
|
|
|
|
+ <svg
|
|
|
|
+ t="1723428969048"
|
|
|
|
+ class="icon"
|
|
|
|
+ viewBox="0 0 1024 1024"
|
|
|
|
+ version="1.1"
|
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
|
+ p-id="6395"
|
|
|
|
+ width="200"
|
|
|
|
+ height="200"
|
|
|
|
+ fill="black"
|
|
|
|
+ >
|
|
|
|
+ <path
|
|
|
|
+ d="M512 928C282.624 928 96 741.376 96 512S282.624 96 512 96s416 186.624 416 416-186.624 416-416 416z m0-768C317.92 160 160 317.92 160 512s157.92 352 352 352 352-157.92 352-352S706.08 160 512 160z"
|
|
|
|
+ p-id="6396"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ <span>圆形</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ class="shapeItem"
|
|
|
|
+ :class="{ shapeItemActive: shape === 'arrow' }"
|
|
|
|
+ @click.stop="setShape('arrow')"
|
|
|
|
+ >
|
|
|
|
+ <svg
|
|
|
|
+ t="1723429061277"
|
|
|
|
+ class="icon"
|
|
|
|
+ viewBox="0 0 1024 1024"
|
|
|
|
+ version="1.1"
|
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
|
+ p-id="7359"
|
|
|
|
+ width="200"
|
|
|
|
+ height="200"
|
|
|
|
+ >
|
|
|
|
+ <path
|
|
|
|
+ d="M708.864 343.872l4.48 3.84 146.112 146.176a25.6 25.6 0 0 1 0 36.224l-146.112 146.112a40 40 0 0 1-60.416-52.032l3.84-4.48 67.584-67.712H168a40 40 0 1 1 0-80h556.48l-67.712-67.648a40 40 0 0 1-3.84-52.096l3.84-4.48a40 40 0 0 1 52.096-3.84z"
|
|
|
|
+ p-id="7360"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ <span>箭头</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ class="shapeItem"
|
|
|
|
+ :class="{ shapeItemActive: shape === 'rect' }"
|
|
|
|
+ @click.stop="setShape('rect')"
|
|
|
|
+ >
|
|
|
|
+ <svg
|
|
|
|
+ t="1723428698910"
|
|
|
|
+ class="icon"
|
|
|
|
+ viewBox="0 0 1024 1024"
|
|
|
|
+ version="1.1"
|
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
|
+ p-id="4240"
|
|
|
|
+ width="200"
|
|
|
|
+ height="200"
|
|
|
|
+ fill="black"
|
|
|
|
+ >
|
|
|
|
+ <path
|
|
|
|
+ d="M864 896H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h704a32 32 0 0 1 32 32v704a32 32 0 0 1-32 32zM192 832h640V192H192v640z"
|
|
|
|
+ p-id="4241"
|
|
|
|
+ ></path>
|
|
|
|
+ </svg>
|
|
|
|
+ <span>矩形</span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <!-- <div class="brushBtn_colorBox" v-if="openShapeBox">
|
|
|
|
+ <span
|
|
|
|
+ v-for="(item, index) in colorList"
|
|
|
|
+ :key="index"
|
|
|
|
+ :style="`background-color: ${item};${
|
|
|
|
+ item === '#FFFFFF' ? 'border:solid 2px #E2E1E5' : ''
|
|
|
|
+ }`"
|
|
|
|
+ @click="setShapeColor(item)"
|
|
|
|
+ ></span>
|
|
|
|
+ <div class="bb_cb_drawSize">
|
|
|
|
+ <el-slider v-model="shapeSize" :min="1" :max="20"></el-slider>
|
|
|
|
+ </div>
|
|
|
|
+ </div> -->
|
|
|
|
+ </div>
|
|
|
|
|
|
<div class="eraserBtn">
|
|
<div class="eraserBtn">
|
|
<el-tooltip
|
|
<el-tooltip
|
|
@@ -108,7 +358,7 @@
|
|
height="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
fill="none"
|
|
- :class="{ eraserBtnActive: mode === 'erase' }"
|
|
|
|
|
|
+ :class="{ eraserBtnActive: mode === 'erase' && canDraw }"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
@click.stop="setMode('erase')"
|
|
@click.stop="setMode('erase')"
|
|
>
|
|
>
|
|
@@ -116,26 +366,63 @@
|
|
fill-rule="evenodd"
|
|
fill-rule="evenodd"
|
|
clip-rule="evenodd"
|
|
clip-rule="evenodd"
|
|
d="M13.6464 6.14645C13.8417 5.95118 14.1583 5.95118 14.3536 6.14645L17.8536 9.64645C18.0488 9.84171 18.0488 10.1583 17.8536 10.3536L11.2071 17H17.5V18H10C9.86739 18 9.74021 17.9473 9.64645 17.8536L6.14645 14.3536C5.95118 14.1583 5.95118 13.8417 6.14645 13.6464L13.6464 6.14645ZM10 16.7929L7.20711 14L9 12.2071L11.7929 15L10 16.7929ZM12.5 14.2929L16.7929 10L14 7.20711L9.70711 11.5L12.5 14.2929Z"
|
|
d="M13.6464 6.14645C13.8417 5.95118 14.1583 5.95118 14.3536 6.14645L17.8536 9.64645C18.0488 9.84171 18.0488 10.1583 17.8536 10.3536L11.2071 17H17.5V18H10C9.86739 18 9.74021 17.9473 9.64645 17.8536L6.14645 14.3536C5.95118 14.1583 5.95118 13.8417 6.14645 13.6464L13.6464 6.14645ZM10 16.7929L7.20711 14L9 12.2071L11.7929 15L10 16.7929ZM12.5 14.2929L16.7929 10L14 7.20711L9.70711 11.5L12.5 14.2929Z"
|
|
- fill="black"
|
|
|
|
|
|
+ :fill="mode === 'erase' && canDraw ? '#fff' : 'black'"
|
|
fill-opacity="0.9"
|
|
fill-opacity="0.9"
|
|
/>
|
|
/>
|
|
</svg>
|
|
</svg>
|
|
|
|
+
|
|
</el-tooltip>
|
|
</el-tooltip>
|
|
- <!-- <el-button
|
|
|
|
- @click="setMode('erase')"
|
|
|
|
|
|
+ <el-tooltip
|
|
|
|
+ class="item"
|
|
|
|
+ effect="light"
|
|
|
|
+ content="选择大小"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
|
|
+ <el-button
|
|
|
|
+ class="selectBox"
|
|
|
|
+ @click.stop="changeOpenEraser(!openEraserBox)"
|
|
|
|
+ :icon="openEraserBox ? 'el-icon-arrow-down' : 'el-icon-arrow-up'"
|
|
|
|
+ ></el-button>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ <div class="eb_changeSize" v-if="openEraserBox" v-click-outside="handleBlur">
|
|
|
|
+ <el-slider v-model="eraserSize" :min="5" :max="30" style="width: 150px;"></el-slider>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- <el-button
|
|
|
|
+ @click="screenshot()"
|
|
icon="el-icon-connection"
|
|
icon="el-icon-connection"
|
|
- :class="{ active: mode === 'erase' }"
|
|
|
|
- >橡皮擦</el-button
|
|
|
|
|
|
+ :class="{ active: mode === 'screenshot' }"
|
|
|
|
+ >截图</el-button
|
|
> -->
|
|
> -->
|
|
- </div>
|
|
|
|
- <!-- <el-button @click="setMode('line')" :class="{ active: mode === 'line' }">直线</el-button>
|
|
|
|
- <el-button @click="setMode('rect')" :class="{ active: mode === 'rect' }">矩形</el-button>
|
|
|
|
- <el-button @click="setMode('circle')" :class="{ active: mode === 'circle' }">圆圈</el-button> -->
|
|
|
|
|
|
+
|
|
|
|
+ <!-- <el-button @click="setMode('line')" :class="{ active: mode === 'line' }"
|
|
|
|
+ >直线</el-button
|
|
|
|
+ >
|
|
|
|
+ <el-button @click="setMode('rect')" :class="{ active: mode === 'rect' }"
|
|
|
|
+ >矩形</el-button
|
|
|
|
+ >
|
|
|
|
+ <el-button
|
|
|
|
+ @click="setMode('circle')"
|
|
|
|
+ :class="{ active: mode === 'circle' }"
|
|
|
|
+ >圆圈</el-button
|
|
|
|
+ >
|
|
|
|
+
|
|
|
|
+ <el-button
|
|
|
|
+ @click="setMode('arrow')"
|
|
|
|
+ :class="{ active: mode === 'arrow' }"
|
|
|
|
+ >箭头</el-button
|
|
|
|
+ > -->
|
|
<div class="clearScreenBtn">
|
|
<div class="clearScreenBtn">
|
|
<!-- <el-button @click="clearCanvas" icon="el-icon-refresh-left"
|
|
<!-- <el-button @click="clearCanvas" icon="el-icon-refresh-left"
|
|
>清空画布</el-button
|
|
>清空画布</el-button
|
|
> -->
|
|
> -->
|
|
- <el-tooltip class="item" effect="light" content="清空" placement="top">
|
|
|
|
|
|
+ <el-tooltip
|
|
|
|
+ class="item"
|
|
|
|
+ effect="light"
|
|
|
|
+ content="清空"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
<svg
|
|
<svg
|
|
width="24"
|
|
width="24"
|
|
height="24"
|
|
height="24"
|
|
@@ -258,20 +545,56 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
-// import html2canvas from "html2canvas";
|
|
|
|
|
|
+import html2canvas from "html2canvas";
|
|
import "element-ui/lib/theme-chalk/index.css";
|
|
import "element-ui/lib/theme-chalk/index.css";
|
|
-
|
|
|
|
|
|
+// 自定义指令,用于处理点击外部区域的事件
|
|
|
|
+const clickOutside = {
|
|
|
|
+ bind(el, binding) {
|
|
|
|
+ // 在元素上绑定一个点击事件监听器
|
|
|
|
+ el.clickOutsideEvent = function (event) {
|
|
|
|
+ // 检查点击事件是否发生在元素的内部
|
|
|
|
+ if (!(el === event.target || el.contains(event.target))) {
|
|
|
|
+ // 如果点击事件发生在元素的外部,则触发指令绑定的方法,将点击的event数据传过去
|
|
|
|
+ binding.value(event);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ // 在文档上添加点击事件监听器
|
|
|
|
+ document.addEventListener("mousedown", el.clickOutsideEvent);
|
|
|
|
+ },
|
|
|
|
+ unbind(el) {
|
|
|
|
+ // 在元素上解除点击事件监听器
|
|
|
|
+ document.removeEventListener("mousedown", el.clickOutsideEvent);
|
|
|
|
+ },
|
|
|
|
+};
|
|
export default {
|
|
export default {
|
|
emits: ["close"],
|
|
emits: ["close"],
|
|
|
|
+ directives: {
|
|
|
|
+ "click-outside": clickOutside, // 注册自定义指令
|
|
|
|
+ },
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
show: false,
|
|
show: false,
|
|
showTool: false,
|
|
showTool: false,
|
|
canvas: null,
|
|
canvas: null,
|
|
|
|
+ showCanvas2: false,
|
|
|
|
+ showCanvas3: false,
|
|
|
|
+ showCanvas4: false,
|
|
|
|
+ canvas2: null,
|
|
|
|
+ ctx2: null,
|
|
|
|
+ // canvas3: null,
|
|
|
|
+ // ctx3: null,
|
|
|
|
+ // canvas4:null,
|
|
|
|
+ // ctx4:null,
|
|
ctx: null,
|
|
ctx: null,
|
|
brushColor: "#000000",
|
|
brushColor: "#000000",
|
|
- brushSize: 5,
|
|
|
|
|
|
+ shapeColor:"#000000",
|
|
|
|
+ drawSize: 5,
|
|
|
|
+ shapeSize:5,
|
|
|
|
+ eraserSize:5,
|
|
mode: "draw",
|
|
mode: "draw",
|
|
|
|
+ canDraw: true,
|
|
|
|
+ canShape: false,
|
|
|
|
+ shape: "rect",
|
|
history: [],
|
|
history: [],
|
|
historyStep: -1,
|
|
historyStep: -1,
|
|
startX: 0,
|
|
startX: 0,
|
|
@@ -280,6 +603,8 @@ export default {
|
|
tempShape: null,
|
|
tempShape: null,
|
|
tempCtx: null,
|
|
tempCtx: null,
|
|
openBrushColorBox: false,
|
|
openBrushColorBox: false,
|
|
|
|
+ openShapeBox: false,
|
|
|
|
+ openEraserBox:false,
|
|
colorList: [
|
|
colorList: [
|
|
"#000000",
|
|
"#000000",
|
|
"#E2E1E5",
|
|
"#E2E1E5",
|
|
@@ -333,13 +658,70 @@ export default {
|
|
},
|
|
},
|
|
initCanvas() {
|
|
initCanvas() {
|
|
this.canvas = this.$refs.canvas;
|
|
this.canvas = this.$refs.canvas;
|
|
|
|
+ this.canvas2 = this.$refs.canvas2;
|
|
|
|
+ // this.canvas3 = this.$refs.canvas3;
|
|
|
|
+ // this.canvas4 = this.$refs.canvas4;
|
|
|
|
+
|
|
this.ctx = this.canvas.getContext("2d");
|
|
this.ctx = this.canvas.getContext("2d");
|
|
|
|
+ this.ctx2 = this.canvas2.getContext("2d");
|
|
|
|
+ // this.ctx3 = this.canvas3.getContext("2d");
|
|
|
|
+ // this.ctx4 = this.canvas4.getContext("2d");
|
|
|
|
+
|
|
this.canvas.width = window.innerWidth;
|
|
this.canvas.width = window.innerWidth;
|
|
this.canvas.height = window.innerHeight;
|
|
this.canvas.height = window.innerHeight;
|
|
|
|
+
|
|
|
|
+ this.canvas2.width = window.innerWidth;
|
|
|
|
+ this.canvas2.height = window.innerHeight;
|
|
|
|
+
|
|
|
|
+ // this.canvas3.width = window.innerWidth;
|
|
|
|
+ // this.canvas3.height = window.innerHeight;
|
|
|
|
+
|
|
|
|
+ // this.canvas4.width = window.innerWidth;
|
|
|
|
+ // this.canvas4.height = window.innerHeight;
|
|
this.saveState();
|
|
this.saveState();
|
|
},
|
|
},
|
|
- setMode(mode) {
|
|
|
|
|
|
+ setMode(mode,type=true) {
|
|
|
|
+ this.openBrushColorBox = false;
|
|
|
|
+ this.openShapeBox = false;
|
|
|
|
+ this.openEraserBox = false;
|
|
|
|
+ if (this.mode == mode && this.canDraw && type) return (this.canDraw = false);
|
|
|
|
+ this.canDraw = true;
|
|
this.mode = mode;
|
|
this.mode = mode;
|
|
|
|
+ this.canShape = false;
|
|
|
|
+
|
|
|
|
+ // this.mode = mode;
|
|
|
|
+ // this.openShapeBox = false;
|
|
|
|
+ // if(this.mode==="screenshot"){
|
|
|
|
+ // this.ctx3.fillStyle = '#00000044';
|
|
|
|
+ // this.ctx3.fillRect(0, 0, this.canvas3.width, this.canvas3.height);
|
|
|
|
+ // }
|
|
|
|
+ },
|
|
|
|
+ setShape(shape) {
|
|
|
|
+ this.openBrushColorBox = false;
|
|
|
|
+ this.openShapeBox = false;
|
|
|
|
+ this.openEraserBox = false;
|
|
|
|
+ if (this.shape == shape && this.canShape) return (this.canShape = false);
|
|
|
|
+ if (shape === "open") {
|
|
|
|
+ if (this.canShape) this.canShape = false;
|
|
|
|
+ else this.canShape = true;
|
|
|
|
+ return (this.canDraw = false);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ this.canShape = true;
|
|
|
|
+ this.shape = shape;
|
|
|
|
+ this.canDraw = false;
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ setShapeColor(newColor){
|
|
|
|
+ this.shapeColor = newColor;
|
|
|
|
+ this.openShapeColorBox = false;
|
|
|
|
+ },
|
|
|
|
+ changeOpenShape(newValue) {
|
|
|
|
+ this.openShapeBox = newValue;
|
|
|
|
+ },
|
|
|
|
+ changeOpenEraser(newValue){
|
|
|
|
+ this.openEraserBox = newValue
|
|
},
|
|
},
|
|
clearCanvas() {
|
|
clearCanvas() {
|
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
@@ -403,11 +785,16 @@ export default {
|
|
this.ctx.drawImage(img, 0, 0);
|
|
this.ctx.drawImage(img, 0, 0);
|
|
};
|
|
};
|
|
},
|
|
},
|
|
|
|
+ handleBlur(){
|
|
|
|
+ this.openEraserBox = false;
|
|
|
|
+ this.openShapeBox = false;
|
|
|
|
+ this.openBrushColorBox = false;
|
|
|
|
+ },
|
|
handleMouseDown(event) {
|
|
handleMouseDown(event) {
|
|
- if (this.mode === "erase" || this.mode === "draw") {
|
|
|
|
|
|
+ if (["erase", "draw"].includes(this.mode) && this.canDraw) {
|
|
this.ctx.strokeStyle =
|
|
this.ctx.strokeStyle =
|
|
this.mode === "erase" ? "white" : this.brushColor;
|
|
this.mode === "erase" ? "white" : this.brushColor;
|
|
- this.ctx.lineWidth = this.brushSize;
|
|
|
|
|
|
+ this.ctx.lineWidth = this.mode=='draw'?this.drawSize:this.eraserSize;
|
|
this.ctx.lineCap = "round";
|
|
this.ctx.lineCap = "round";
|
|
this.ctx.lineJoin = "round";
|
|
this.ctx.lineJoin = "round";
|
|
this.isDrawing = true;
|
|
this.isDrawing = true;
|
|
@@ -416,68 +803,90 @@ export default {
|
|
this.startX = event.clientX - rect.left;
|
|
this.startX = event.clientX - rect.left;
|
|
this.startY = event.clientY - rect.top;
|
|
this.startY = event.clientY - rect.top;
|
|
this.ctx.moveTo(this.startX, this.startY);
|
|
this.ctx.moveTo(this.startX, this.startY);
|
|
- } else if (["line", "rect", "circle"].includes(this.mode)) {
|
|
|
|
- this.tempShape = document.createElement("canvas");
|
|
|
|
- this.tempShape.width = this.canvas.width;
|
|
|
|
- this.tempShape.height = this.canvas.height;
|
|
|
|
- this.tempCtx = this.tempShape.getContext("2d");
|
|
|
|
- this.tempCtx.strokeStyle = this.brushColor;
|
|
|
|
- this.tempCtx.lineWidth = this.brushSize;
|
|
|
|
- this.tempCtx.fillStyle = this.brushColor;
|
|
|
|
|
|
+ } else if (
|
|
|
|
+ ["line", "rect", "circle", "arrow"].includes(this.shape) &&
|
|
|
|
+ this.canShape
|
|
|
|
+ ) {
|
|
|
|
+ this.showCanvas2 = true;
|
|
|
|
+ // this.ctx2.strokeStyle = this.brushColor;
|
|
|
|
+ this.ctx2.strokeStyle = "#000000";
|
|
|
|
+
|
|
|
|
+ // this.ctx2.lineWidth = this.drawSize;
|
|
|
|
+ this.ctx2.lineWidth = 5;
|
|
|
|
+
|
|
|
|
+ // this.ctx2.fillStyle = this.brushColor;
|
|
|
|
+ this.ctx2.fillStyle = "#000000";
|
|
this.isDrawing = true;
|
|
this.isDrawing = true;
|
|
- const rect = this.canvas.getBoundingClientRect();
|
|
|
|
|
|
+ const rect = this.canvas2.getBoundingClientRect();
|
|
this.startX = event.clientX - rect.left;
|
|
this.startX = event.clientX - rect.left;
|
|
this.startY = event.clientY - rect.top;
|
|
this.startY = event.clientY - rect.top;
|
|
}
|
|
}
|
|
},
|
|
},
|
|
handleMouseMove(event) {
|
|
handleMouseMove(event) {
|
|
if (!this.isDrawing) return;
|
|
if (!this.isDrawing) return;
|
|
|
|
+
|
|
const rect = this.canvas.getBoundingClientRect();
|
|
const rect = this.canvas.getBoundingClientRect();
|
|
const x = event.clientX - rect.left;
|
|
const x = event.clientX - rect.left;
|
|
const y = event.clientY - rect.top;
|
|
const y = event.clientY - rect.top;
|
|
- // this.drawPreviewSize(x,y)
|
|
|
|
|
|
|
|
- if (this.mode === "draw") {
|
|
|
|
|
|
+ if (this.mode === "draw" && this.canDraw) {
|
|
this.ctx.lineTo(x, y);
|
|
this.ctx.lineTo(x, y);
|
|
this.ctx.stroke();
|
|
this.ctx.stroke();
|
|
- } else if (this.mode === "erase") {
|
|
|
|
|
|
+ } else if (this.mode === "erase" && this.canDraw) {
|
|
this.ctx.beginPath();
|
|
this.ctx.beginPath();
|
|
this.ctx.clearRect(
|
|
this.ctx.clearRect(
|
|
- x - this.brushSize / 2,
|
|
|
|
- y - this.brushSize / 2,
|
|
|
|
- this.brushSize * 3,
|
|
|
|
- this.brushSize * 3
|
|
|
|
|
|
+ x - this.eraserSize / 2,
|
|
|
|
+ y - this.eraserSize / 2,
|
|
|
|
+ this.eraserSize * 3,
|
|
|
|
+ this.eraserSize * 3
|
|
);
|
|
);
|
|
- } else if (this.tempShape) {
|
|
|
|
- this.tempCtx.clearRect(
|
|
|
|
- 0,
|
|
|
|
- 0,
|
|
|
|
- this.tempShape.width,
|
|
|
|
- this.tempShape.height
|
|
|
|
- );
|
|
|
|
- if (this.mode === "line") {
|
|
|
|
- this.tempCtx.beginPath();
|
|
|
|
- this.tempCtx.moveTo(this.startX, this.startY);
|
|
|
|
- this.tempCtx.lineTo(x, y);
|
|
|
|
- this.tempCtx.stroke();
|
|
|
|
- } else if (this.mode === "rect") {
|
|
|
|
- this.tempCtx.strokeRect(
|
|
|
|
|
|
+ } else if (this.showCanvas2) {
|
|
|
|
+ // 清除临时画布上的内容
|
|
|
|
+ this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height);
|
|
|
|
+
|
|
|
|
+ if (this.shape === "line" && this.canShape) {
|
|
|
|
+ this.ctx2.beginPath();
|
|
|
|
+ this.ctx2.moveTo(this.startX, this.startY);
|
|
|
|
+ this.ctx2.lineTo(x, y);
|
|
|
|
+ this.ctx2.stroke();
|
|
|
|
+ } else if (this.shape === "rect" && this.canShape) {
|
|
|
|
+ this.ctx2.strokeRect(
|
|
this.startX,
|
|
this.startX,
|
|
this.startY,
|
|
this.startY,
|
|
x - this.startX,
|
|
x - this.startX,
|
|
y - this.startY
|
|
y - this.startY
|
|
);
|
|
);
|
|
- } else if (this.mode === "circle") {
|
|
|
|
|
|
+ } else if (this.shape === "circle" && this.canShape) {
|
|
const radius = Math.sqrt(
|
|
const radius = Math.sqrt(
|
|
Math.pow(x - this.startX, 2) + Math.pow(y - this.startY, 2)
|
|
Math.pow(x - this.startX, 2) + Math.pow(y - this.startY, 2)
|
|
);
|
|
);
|
|
- this.tempCtx.beginPath();
|
|
|
|
- this.tempCtx.arc(this.startX, this.startY, radius, 0, Math.PI * 2);
|
|
|
|
- this.tempCtx.stroke();
|
|
|
|
|
|
+ this.ctx2.beginPath();
|
|
|
|
+ this.ctx2.arc(this.startX, this.startY, radius, 0, Math.PI * 2);
|
|
|
|
+ this.ctx2.stroke();
|
|
|
|
+ } else if (this.shape === "arrow" && this.canShape) {
|
|
|
|
+ // 计算箭头的角度
|
|
|
|
+ const headlen = 5 * 5; // 箭头的长度
|
|
|
|
+ const angle = Math.atan2(y - this.startY, x - this.startX);
|
|
|
|
+
|
|
|
|
+ // 画箭头的主线
|
|
|
|
+ this.ctx2.beginPath();
|
|
|
|
+ this.ctx2.moveTo(this.startX, this.startY);
|
|
|
|
+ this.ctx2.lineTo(x, y);
|
|
|
|
+ this.ctx2.stroke();
|
|
|
|
+
|
|
|
|
+ // 画箭头的两条边
|
|
|
|
+ this.ctx2.moveTo(x - 1, y);
|
|
|
|
+ this.ctx2.lineTo(
|
|
|
|
+ x - headlen * Math.cos(angle - Math.PI / 6),
|
|
|
|
+ y - headlen * Math.sin(angle - Math.PI / 6)
|
|
|
|
+ );
|
|
|
|
+ this.ctx2.moveTo(x + 1, y);
|
|
|
|
+ this.ctx2.lineTo(
|
|
|
|
+ x - headlen * Math.cos(angle + Math.PI / 6),
|
|
|
|
+ y - headlen * Math.sin(angle + Math.PI / 6)
|
|
|
|
+ );
|
|
|
|
+ this.ctx2.stroke();
|
|
}
|
|
}
|
|
- this.ctx.drawImage(this.tempShape, 0, 0);
|
|
|
|
- // this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
|
|
- this.restoreState();
|
|
|
|
}
|
|
}
|
|
},
|
|
},
|
|
drawPreviewSize(x, y) {
|
|
drawPreviewSize(x, y) {
|
|
@@ -502,12 +911,15 @@ export default {
|
|
},
|
|
},
|
|
handleMouseUp() {
|
|
handleMouseUp() {
|
|
if (!this.isDrawing) return;
|
|
if (!this.isDrawing) return;
|
|
|
|
+
|
|
this.isDrawing = false;
|
|
this.isDrawing = false;
|
|
this.ctx.closePath();
|
|
this.ctx.closePath();
|
|
- if (this.tempShape) {
|
|
|
|
- this.ctx.drawImage(this.tempShape, 0, 0);
|
|
|
|
- this.tempShape = null;
|
|
|
|
- this.tempCtx = null;
|
|
|
|
|
|
+ if (this.showCanvas2) {
|
|
|
|
+ this.showCanvas2 = false;
|
|
|
|
+ this.ctx.drawImage(this.canvas2, 0, 0);
|
|
|
|
+ this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height);
|
|
|
|
+ // // this.tempShape = null;
|
|
|
|
+ // // this.tempCtx = null;
|
|
}
|
|
}
|
|
this.saveState();
|
|
this.saveState();
|
|
},
|
|
},
|
|
@@ -534,11 +946,129 @@ export default {
|
|
setColor(newColor) {
|
|
setColor(newColor) {
|
|
this.brushColor = newColor;
|
|
this.brushColor = newColor;
|
|
this.openBrushColorBox = false;
|
|
this.openBrushColorBox = false;
|
|
- this.setMode("draw");
|
|
|
|
|
|
+ this.setMode("draw",false);
|
|
},
|
|
},
|
|
changeOpenBrushColorBox(newValue) {
|
|
changeOpenBrushColorBox(newValue) {
|
|
this.openBrushColorBox = newValue;
|
|
this.openBrushColorBox = newValue;
|
|
},
|
|
},
|
|
|
|
+ screenshotMouseDown(e) {
|
|
|
|
+ this.isDrawing = true;
|
|
|
|
+ this.ctx3.fillStyle = "#00000044";
|
|
|
|
+ this.startX = e.clientX;
|
|
|
|
+ this.startY = e.clientY;
|
|
|
|
+ },
|
|
|
|
+ screenshotMouseMove(e) {
|
|
|
|
+ if (!this.isDrawing) return;
|
|
|
|
+ this.ctx3.clearRect(0, 0, this.canvas3.width, this.canvas3.height);
|
|
|
|
+ this.ctx3.fillStyle = "#00000044";
|
|
|
|
+ this.ctx3.fillRect(0, 0, this.canvas3.width, this.canvas3.height);
|
|
|
|
+
|
|
|
|
+ const width = e.clientX - this.startX;
|
|
|
|
+ const height = e.clientY - this.startY;
|
|
|
|
+
|
|
|
|
+ this.ctx3.globalCompositeOperation = "destination-out";
|
|
|
|
+ this.ctx3.clearRect(this.startX, this.startY, width, height);
|
|
|
|
+ this.ctx3.globalCompositeOperation = "source-over";
|
|
|
|
+ },
|
|
|
|
+ screenshotMouseUp(e) {
|
|
|
|
+ if (!this.isDrawing) return;
|
|
|
|
+ console.log("👇");
|
|
|
|
+ console.log(this.startX, this.startY);
|
|
|
|
+ console.log(e.clientX, e.clientY);
|
|
|
|
+ console.log("👆");
|
|
|
|
+ this.isDrawing = false;
|
|
|
|
+ // 截取指定区域
|
|
|
|
+ const rect = {
|
|
|
|
+ x: Math.min(this.startX, e.clientX),
|
|
|
|
+ y: Math.min(this.startY, e.clientY),
|
|
|
|
+ width: Math.abs(e.clientX - this.startX),
|
|
|
|
+ height: Math.abs(e.clientY - this.startY),
|
|
|
|
+ };
|
|
|
|
+ console.log(rect);
|
|
|
|
+ html2canvas(document.body, {
|
|
|
|
+ x: rect.x,
|
|
|
|
+ y: rect.y,
|
|
|
|
+ width: rect.width,
|
|
|
|
+ height: rect.height,
|
|
|
|
+ windowWidth: document.body.scrollWidth,
|
|
|
|
+ windowHeight: document.body.scrollHeight,
|
|
|
|
+ scale: window.devicePixelRatio,
|
|
|
|
+ }).then((result) => {
|
|
|
|
+ this.mode = "";
|
|
|
|
+ this.showCanvas4 = true;
|
|
|
|
+ this.canvas4.width = rect.width;
|
|
|
|
+ this.canvas4.height = rect.height;
|
|
|
|
+ this.ctx4.drawImage(result, 0, 0, rect.width, rect.height);
|
|
|
|
+ // 移除覆盖的 canvas
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ screenshotTouchStart(e) {
|
|
|
|
+ e.preventDefault();
|
|
|
|
+ const touch = e.touches[0];
|
|
|
|
+ this.screenshotMouseDown({
|
|
|
|
+ clientX: touch.clientX,
|
|
|
|
+ clientY: touch.clientY,
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ screenshotTouchMove(e) {
|
|
|
|
+ e.preventDefault();
|
|
|
|
+ const touch = e.touches[0];
|
|
|
|
+ this.screenshotMouseMove({
|
|
|
|
+ clientX: touch.clientX,
|
|
|
|
+ clientY: touch.clientY,
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ screenshotTouchEnd(e) {
|
|
|
|
+ e.preventDefault();
|
|
|
|
+ this.screenshotMouseUp();
|
|
|
|
+ },
|
|
|
|
+ screenshot(){
|
|
|
|
+ // return console.log(document.clientWidth,document.clientHeight)
|
|
|
|
+ html2canvas(document.body, {
|
|
|
|
+ x: 0,
|
|
|
|
+ y: 0,
|
|
|
|
+ width: document.documentElement.clientWidth,
|
|
|
|
+ height: document.documentElement.clientHeight,
|
|
|
|
+ useCORS:true,
|
|
|
|
+ windowWidth: 0,
|
|
|
|
+ windowHeight: 0,
|
|
|
|
+ scale: window.devicePixelRatio,
|
|
|
|
+ }).then((result) => {
|
|
|
|
+ console.log(result);
|
|
|
|
+ // this.mode = "";
|
|
|
|
+ // this.showCanvas4 = true;
|
|
|
|
+ // this.canvas4.width = result.width/2;
|
|
|
|
+ // this.canvas4.height = result.height/2;
|
|
|
|
+ // this.ctx4.drawImage(
|
|
|
|
+ // result,
|
|
|
|
+ // 0,
|
|
|
|
+ // 0,
|
|
|
|
+ // document.clientWidth,
|
|
|
|
+ // document.clientHeight
|
|
|
|
+ // );
|
|
|
|
+ // return
|
|
|
|
+ var imgURL = result.toDataURL({
|
|
|
|
+ format: "image/png",
|
|
|
|
+ quality: 1,
|
|
|
|
+ width: result.width,
|
|
|
|
+ height: result.height,
|
|
|
|
+ });
|
|
|
|
+ var dlLink = document.createElement("a");
|
|
|
|
+ dlLink.download = "fileName";
|
|
|
|
+ dlLink.href = imgURL;
|
|
|
|
+ dlLink.dataset.downloadurl = [
|
|
|
|
+ "png",
|
|
|
|
+ dlLink.download,
|
|
|
|
+ dlLink.href,
|
|
|
|
+ ].join(":");
|
|
|
|
+ document.body.appendChild(dlLink);
|
|
|
|
+ dlLink.click();
|
|
|
|
+ document.body.removeChild(dlLink);
|
|
|
|
+ // 移除覆盖的 canvas
|
|
|
|
+ });
|
|
|
|
+ // this.ctx3.fillStyle = '#00000044';
|
|
|
|
+ // this.ctx3.fillRect(0, 0, this.canvas3.width, this.canvas3.height);
|
|
|
|
+ }
|
|
},
|
|
},
|
|
watch: {
|
|
watch: {
|
|
brushColor(newColor) {
|
|
brushColor(newColor) {
|
|
@@ -561,6 +1091,20 @@ export default {
|
|
background-color: rgba(255, 255, 255, 0);
|
|
background-color: rgba(255, 255, 255, 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+.screenshotBox {
|
|
|
|
+ position: fixed;
|
|
|
|
+ top: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ width: 100vw;
|
|
|
|
+ height: 100vh;
|
|
|
|
+ background-color: #00000044;
|
|
|
|
+ z-index: 12;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.screenshotCanvas {
|
|
|
|
+ z-index: 11;
|
|
|
|
+}
|
|
|
|
+
|
|
.toolbar {
|
|
.toolbar {
|
|
position: fixed;
|
|
position: fixed;
|
|
bottom: 0;
|
|
bottom: 0;
|
|
@@ -576,6 +1120,7 @@ export default {
|
|
box-shadow: 0px 6px 30px 5px #0000000d;
|
|
box-shadow: 0px 6px 30px 5px #0000000d;
|
|
transform: translateX(-50%);
|
|
transform: translateX(-50%);
|
|
max-width: 100vw;
|
|
max-width: 100vw;
|
|
|
|
+ z-index: 10;
|
|
}
|
|
}
|
|
|
|
|
|
.toolbar-container {
|
|
.toolbar-container {
|
|
@@ -616,6 +1161,10 @@ export default {
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+.eraserBtn{
|
|
|
|
+ position: relative;
|
|
|
|
+}
|
|
|
|
+
|
|
.eraserBtn > svg {
|
|
.eraserBtn > svg {
|
|
width: 40px;
|
|
width: 40px;
|
|
height: 40px;
|
|
height: 40px;
|
|
@@ -648,8 +1197,18 @@ export default {
|
|
justify-content: center;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
flex-wrap: wrap;
|
|
}
|
|
}
|
|
|
|
+.bb_cb_drawColor{
|
|
|
|
+ width: 250px;
|
|
|
|
+ height: auto;
|
|
|
|
+ background-color: #ffffff;
|
|
|
|
+ padding: 4px, 8px, 4px, 8px;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
+}
|
|
|
|
|
|
-.brushBtn_colorBox > span {
|
|
|
|
|
|
+.bb_cb_drawColor > span {
|
|
width: 25px;
|
|
width: 25px;
|
|
height: 25px;
|
|
height: 25px;
|
|
border-radius: 100%;
|
|
border-radius: 100%;
|
|
@@ -667,4 +1226,123 @@ export default {
|
|
padding: 5px !important;
|
|
padding: 5px !important;
|
|
margin-left: 5px;
|
|
margin-left: 5px;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+.shape {
|
|
|
|
+ position: relative;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shape > div {
|
|
|
|
+ width: 40px;
|
|
|
|
+ height: 40px;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ border-radius: 8px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shape > div > svg {
|
|
|
|
+ width: 80%;
|
|
|
|
+ height: 80%;
|
|
|
|
+}
|
|
|
|
+.shapeActive {
|
|
|
|
+ background-color: #3681fc;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shapeActive > svg {
|
|
|
|
+ fill: #fff;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shapeBox {
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: 0;
|
|
|
|
+ bottom: calc(100% + 10px);
|
|
|
|
+ width: auto !important;
|
|
|
|
+ height: auto !important;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ box-shadow: 0px 4px 10px 0px #1d398314;
|
|
|
|
+ box-shadow: 1px 1px 20px 4px #1d39830d;
|
|
|
|
+ border-radius: 6px;
|
|
|
|
+ padding: 8px;
|
|
|
|
+ cursor: default;
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shapeItem {
|
|
|
|
+ width: auto;
|
|
|
|
+ height: auto;
|
|
|
|
+ padding: 5px;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ border-radius: 8px;
|
|
|
|
+ color: black;
|
|
|
|
+ margin-bottom: 5px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shapeItem > span {
|
|
|
|
+ width: 2em;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shapeItem > svg {
|
|
|
|
+ width: 25px;
|
|
|
|
+ height: 25px;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shapeItem:hover {
|
|
|
|
+ background-color: #e6e6e6;
|
|
|
|
+ color: black;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shapeItemActive {
|
|
|
|
+ background-color: #3681fc !important;
|
|
|
|
+ color: #fff !important;
|
|
|
|
+ fill: #fff !important;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.shapeItemActive > svg {
|
|
|
|
+ fill: #fff !important;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.eraserBtnActive {
|
|
|
|
+ background-color: #3681fc !important;
|
|
|
|
+ color: #fff !important;
|
|
|
|
+ fill: #fff !important;
|
|
|
|
+ border-radius: 8px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.bb_cb_drawSize {
|
|
|
|
+ width: 100%;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ padding: 5px 20px;
|
|
|
|
+ color: black;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.eb_changeSize{
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: 0;
|
|
|
|
+ bottom: calc(100% + 10px);
|
|
|
|
+ width: auto !important;
|
|
|
|
+ height: auto !important;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ box-shadow: 0px 4px 10px 0px #1d398314;
|
|
|
|
+ box-shadow: 1px 1px 20px 4px #1d39830d;
|
|
|
|
+ border-radius: 6px;
|
|
|
|
+ padding: 8px 15px 8px 15px;
|
|
|
|
+ cursor: default;
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.selectBox{
|
|
|
|
+ border: none;
|
|
|
|
+ background-color: none;
|
|
|
|
+}
|
|
</style>
|
|
</style>
|