8 changed files with 301 additions and 24 deletions
@ -0,0 +1,51 @@ |
|||
<template> |
|||
<Card class='DeviceControl' title="设备管控"> |
|||
TODO |
|||
</Card> |
|||
</template> |
|||
|
|||
<script> |
|||
import Card from "@screen/components/Card2/Card.vue";; |
|||
|
|||
import { merge } from "lodash"; |
|||
import { provideMixin } from "./../../mixin" |
|||
|
|||
|
|||
|
|||
export default { |
|||
name: 'DeviceControl', |
|||
mixins: [provideMixin], |
|||
components: { |
|||
Card |
|||
}, |
|||
data() { |
|||
return { |
|||
data: null |
|||
} |
|||
}, |
|||
watch: { |
|||
data() { |
|||
|
|||
} |
|||
}, |
|||
mounted() { |
|||
|
|||
}, |
|||
methods: { |
|||
|
|||
}, |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss' scoped> |
|||
.DeviceControl { |
|||
::v-deep { |
|||
.content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
} |
|||
|
|||
} |
|||
</style> |
@ -0,0 +1,207 @@ |
|||
export function getQuadrant(angle) { |
|||
angle %= 360.0; |
|||
if (angle < 0) angle += 360.0; |
|||
var quadrant = Math.floor(angle / 90) + 1; |
|||
return quadrant; |
|||
} |
|||
|
|||
export function calcPoint(x0, y0, width, height, angle) { |
|||
const parseAngle = parseFloat(angle); |
|||
|
|||
angle = (Math.PI / 180) * parseFloat(parseAngle); |
|||
|
|||
x0 += width / 2; |
|||
y0 += height / 2; |
|||
|
|||
const hypotenuse = width / 2 > height / 2 ? width / 2 : height / 2; |
|||
|
|||
// 对边
|
|||
let oppositeEdge = Math.abs(hypotenuse * Math.sin(angle)); |
|||
|
|||
// 邻边
|
|||
let adjacentEdge = Math.abs(hypotenuse * Math.cos(angle)); |
|||
|
|||
let point0 = [], |
|||
point1 = []; |
|||
|
|||
switch (parseFloat(parseAngle) % 360.0) { |
|||
case 180: |
|||
oppositeEdge = adjacentEdge; |
|||
adjacentEdge = 0; |
|||
break; |
|||
case 90: |
|||
case 270: |
|||
adjacentEdge = oppositeEdge; |
|||
oppositeEdge = 0; |
|||
break; |
|||
} |
|||
|
|||
switch (getQuadrant(parseAngle)) { |
|||
case 1: |
|||
point0 = [x0 - adjacentEdge, y0 + oppositeEdge]; |
|||
point1 = [x0 + adjacentEdge, y0 - oppositeEdge]; |
|||
break; |
|||
case 2: |
|||
point0 = [x0 - adjacentEdge, y0 - oppositeEdge]; |
|||
point1 = [x0 + adjacentEdge, y0 + oppositeEdge]; |
|||
break; |
|||
case 3: |
|||
point0 = [x0 + adjacentEdge, y0 - oppositeEdge]; |
|||
point1 = [x0 - adjacentEdge, y0 + oppositeEdge]; |
|||
break; |
|||
case 4: |
|||
point0 = [x0 + adjacentEdge, y0 + oppositeEdge]; |
|||
point1 = [x0 - adjacentEdge, y0 - oppositeEdge]; |
|||
break; |
|||
} |
|||
|
|||
return angle > 0 ? [point0, point1] : [point1, point0]; |
|||
} |
|||
|
|||
export class CanvasFlow { |
|||
canvas = null; |
|||
context = null; |
|||
zoom = 3; |
|||
constructor(canvas) { |
|||
this.canvas = canvas; |
|||
this.context = canvas.getContext("2d"); |
|||
|
|||
this.canvas.width = canvas.clientWidth * this.zoom; |
|||
this.canvas.height = canvas.clientHeight * this.zoom; |
|||
} |
|||
|
|||
drawRectangle({ |
|||
x, |
|||
y, |
|||
width, |
|||
height, |
|||
borderWidth, |
|||
borderColor, |
|||
backgroundColor, |
|||
radius, |
|||
}) { |
|||
this.context.beginPath(); |
|||
|
|||
if (backgroundColor) this.context.fillStyle = backgroundColor; |
|||
|
|||
x *= this.zoom; |
|||
y *= this.zoom; |
|||
width *= this.zoom; |
|||
height *= this.zoom; |
|||
|
|||
if (radius) { |
|||
this.context.roundRect(x, y, width, height, radius); |
|||
this.context.fill(); |
|||
} else { |
|||
this.context.fillRect(x, y, width, height); |
|||
} |
|||
|
|||
if (typeof borderWidth === "number") { |
|||
borderWidth *= this.zoom; |
|||
|
|||
this.context.lineWidth = borderWidth; |
|||
this.context.strokeStyle = borderColor; |
|||
|
|||
this.context.stroke(); |
|||
} |
|||
} |
|||
|
|||
transformCssLinearGradient(x, y, width, height, linearGradient) { |
|||
const [_, deg, ...stopStrings] = linearGradient.match(/[^,()]+/g); |
|||
|
|||
const stops = stopStrings.map((stop) => { |
|||
const [color, offset] = stop.trim().split(" "); |
|||
|
|||
return { |
|||
color, |
|||
offset: parseFloat(offset) * 0.01, |
|||
}; |
|||
}); |
|||
|
|||
const [point0, point1] = calcPoint(x, y, width, height, deg); |
|||
|
|||
return [ |
|||
{ |
|||
x0: point0[0], |
|||
y0: point0[1], |
|||
x1: point1[0], |
|||
y1: point1[1], |
|||
}, |
|||
stops, |
|||
]; |
|||
} |
|||
|
|||
setLinearGradient({ x0, y0, x1, y1 }, stops) { |
|||
x0 *= this.zoom; |
|||
x1 *= this.zoom; |
|||
y0 *= this.zoom; |
|||
y1 *= this.zoom; |
|||
|
|||
const gradient = this.context.createLinearGradient(x0, y0, x1, y1); |
|||
|
|||
stops.forEach(({ offset, color }) => { |
|||
gradient.addColorStop(offset, color); |
|||
}); |
|||
|
|||
this.context.fillStyle = gradient; |
|||
} |
|||
|
|||
drawLine({ x, y, color, lineWidth = 1 }, vertices) { |
|||
x *= this.zoom; |
|||
y *= this.zoom; |
|||
|
|||
this.context.beginPath(); |
|||
|
|||
this.context.moveTo(x, y); |
|||
|
|||
vertices.forEach(({ x, y }) => { |
|||
this.context.lineTo(x * this.zoom, y * this.zoom); |
|||
}); |
|||
|
|||
this.context.strokeStyle = color; |
|||
|
|||
this.context.lineWidth = lineWidth; |
|||
|
|||
this.context.stroke(); |
|||
} |
|||
|
|||
fillText( |
|||
text, |
|||
{ |
|||
x, |
|||
y, |
|||
fontSize = 15, |
|||
color, |
|||
align = "center", |
|||
fontWeight = "normal", |
|||
fontFamily = "微软雅黑", |
|||
} = {}, |
|||
{ width: rectWidth = 0, height: rectHeight = 0 } = {} |
|||
) { |
|||
this.context.beginPath(); |
|||
|
|||
this.context.font = `${fontWeight} ${fontSize * this.zoom}px ${fontFamily}`; |
|||
|
|||
this.context.textBaseline = "middle"; |
|||
|
|||
const textWidth = this.context.measureText(text).width; |
|||
|
|||
x *= this.zoom; |
|||
|
|||
switch (align) { |
|||
case "center": |
|||
x += (rectWidth * this.zoom - textWidth) / 2; |
|||
|
|||
y += rectHeight / 2; |
|||
break; |
|||
} |
|||
|
|||
this.context.fillStyle = color; |
|||
|
|||
this.context.fillText(text, x, y * this.zoom); |
|||
} |
|||
|
|||
clear() { |
|||
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); |
|||
} |
|||
} |
After Width: | Height: | Size: 2.0 KiB |
Loading…
Reference in new issue