@ -0,0 +1,45 @@ |
|||||
|
/** |
||||
|
* |
||||
|
* @param {HTMLElement} container |
||||
|
* @param {{ target: HTMLElement }} param1 |
||||
|
*/ |
||||
|
export function moveable(container, { target } = {}) { |
||||
|
if (!target) target = container; |
||||
|
|
||||
|
target.style.cursor = "move"; |
||||
|
|
||||
|
/** |
||||
|
* @type { { clientX: number; clientY: number } } |
||||
|
*/ |
||||
|
let lastPosition = { clientX: 0, clientY: 0 }; |
||||
|
|
||||
|
const down = (e) => { |
||||
|
const { clientX: x, clientY: y } = e; |
||||
|
|
||||
|
const move = (e) => { |
||||
|
const { clientX, clientY } = e; |
||||
|
|
||||
|
console.log(clientX, clientY, "move"); |
||||
|
|
||||
|
container.style.transform = `translate3d(${ |
||||
|
clientX - x + lastPosition.clientX |
||||
|
}px, ${clientY - y + lastPosition.clientY}px, 0)`;
|
||||
|
}; |
||||
|
|
||||
|
const up = (e) => { |
||||
|
const { clientX, clientY } = e; |
||||
|
lastPosition.clientX += clientX - x; |
||||
|
lastPosition.clientY += clientY - y; |
||||
|
|
||||
|
document.removeEventListener("pointermove", move); |
||||
|
document.removeEventListener("pointerup", up); |
||||
|
}; |
||||
|
|
||||
|
document.addEventListener("pointermove", move); |
||||
|
document.addEventListener("pointerup", up); |
||||
|
}; |
||||
|
|
||||
|
target.addEventListener("pointerdown", down); |
||||
|
|
||||
|
return () => target.removeEventListener("pointerdown", down); |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
<template> |
||||
|
<video controls autoplay muted class="video-stream" v-bind="$attrs" ref="videoContainerRef" /> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { HttpLivePlayer } from "./videoStream.js" |
||||
|
|
||||
|
export default { |
||||
|
name: 'Video', |
||||
|
props: { |
||||
|
camId: { |
||||
|
type: String, |
||||
|
default: null |
||||
|
}, |
||||
|
url: { |
||||
|
type: String, |
||||
|
default: null |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
const player = new HttpLivePlayer(this.$refs.videoContainerRef, { camId: this.camId, url: this.url }); |
||||
|
|
||||
|
this.$once("hook:beforeDestroy", () => player.destroy()); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang='scss' scoped> |
||||
|
.video-stream { |
||||
|
background-color: #000; |
||||
|
} |
||||
|
</style> |
After Width: | Height: | Size: 994 B |
Before Width: | Height: | Size: 950 B |
Before Width: | Height: | Size: 572 B |
Before Width: | Height: | Size: 584 B |
Before Width: | Height: | Size: 595 B |
After Width: | Height: | Size: 2.4 KiB |
@ -0,0 +1,193 @@ |
|||||
|
<template> |
||||
|
<Dialog v-model="modelVisible" title="广播发布"> |
||||
|
<div class='BroadcastReleases'> |
||||
|
<div class="body"> |
||||
|
<div class="left"> |
||||
|
<div class="title">路测广播列表</div> |
||||
|
<CheckboxGroup class="checkbox-group" :value="[]" :options="options" /> |
||||
|
</div> |
||||
|
<div class="right"> |
||||
|
<div class="top-content"> |
||||
|
<Video class="item-video" /> |
||||
|
|
||||
|
<label>发布内容: </label> |
||||
|
<ElInput type="textarea" :autosize="{ minRows: 3, maxRows: 3 }" :maxlength="150" showWordLimit /> |
||||
|
</div> |
||||
|
|
||||
|
<div class="footer"> |
||||
|
<Button style="background-color: rgba(0, 179, 204, .3);" |
||||
|
@click.native="modelVisible = false, submitting = false"> |
||||
|
取消 |
||||
|
</Button> |
||||
|
<Button @click.native="handleSubmit" :loading="submitting"> |
||||
|
确定 |
||||
|
</Button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- <Form class="form" ref="FormConfigRef" :formList="formList" column="1" style="flex: 1;" labelWidth="120px" /> --> |
||||
|
|
||||
|
</div> |
||||
|
</Dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Dialog from "@screen/components/Dialog/index.vue"; |
||||
|
import Button from "@screen/components/Buttons/Button.vue" |
||||
|
import Form from '@screen/components/FormConfig'; |
||||
|
import Video from "@screen/components/Video" |
||||
|
import CheckboxGroup from "@screen/components/FormConfig/components/ElCheckboxGroup.vue" |
||||
|
|
||||
|
import { delay } from "@screen/utils/common.js" |
||||
|
import request from "@/utils/request"; |
||||
|
|
||||
|
import { Message } from "element-ui"; |
||||
|
// import { axiosIns } from "@screen/utils/axios/auth.js"; |
||||
|
|
||||
|
export default { |
||||
|
name: 'BroadcastReleases', |
||||
|
components: { |
||||
|
Dialog, |
||||
|
Button, |
||||
|
Form, |
||||
|
Video, |
||||
|
CheckboxGroup |
||||
|
}, |
||||
|
model: { |
||||
|
prop: 'visible', |
||||
|
event: "update:value" |
||||
|
}, |
||||
|
props: { |
||||
|
visible: Boolean, |
||||
|
deviceId: String |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
submitting: false, |
||||
|
options: Array.from({ length: 24 }).map((_, index) => ({ |
||||
|
key: index, |
||||
|
label: "阿发" |
||||
|
})) |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
modelVisible: { |
||||
|
get() { |
||||
|
return this.visible |
||||
|
}, |
||||
|
set(val) { |
||||
|
this.$emit('update:value', val) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
modelVisible: { |
||||
|
immediate: true, |
||||
|
handler(bool) { |
||||
|
if (!bool) return; |
||||
|
|
||||
|
this.reDisplay(); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
reDisplay() { |
||||
|
}, |
||||
|
handleSubmit() { |
||||
|
const result = {}, formData = this.$refs.FormConfigRef?.formData; |
||||
|
|
||||
|
let functionId = 51; |
||||
|
|
||||
|
result.mode = formData.controlType === 'manual' ? "00" : "01"; |
||||
|
|
||||
|
delete result.controlType; |
||||
|
|
||||
|
if (result.mode === '01') { |
||||
|
if (!formData.displayTime?.length) return Message.error(`时间不能为空!`); |
||||
|
result.startDisplayTime = formData.displayTime[0]; |
||||
|
result.endDisplayTime = formData.displayTime[1]; |
||||
|
delete result.displayTime; |
||||
|
} else { |
||||
|
if (!formData.onWorkStatus || !formData.inWorkStatus) return Message.error(`工作状态不能为空!`); |
||||
|
|
||||
|
result.onWorkStatus = formData.onWorkStatus |
||||
|
result.inWorkStatus = formData.inWorkStatus |
||||
|
} |
||||
|
|
||||
|
this.submitting = true; |
||||
|
|
||||
|
// this.submitting = false; |
||||
|
// return; |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang='scss' scoped> |
||||
|
.BroadcastReleases { |
||||
|
// width: 450px; |
||||
|
height: 397px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 15px; |
||||
|
|
||||
|
.body { |
||||
|
display: flex; |
||||
|
gap: 9px; |
||||
|
height: 100%; |
||||
|
|
||||
|
.left { |
||||
|
width: 251px; |
||||
|
border-radius: 3px 3px 3px 3px; |
||||
|
border: 1px solid #3DE8FF; |
||||
|
padding: 3px 12px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 9px; |
||||
|
|
||||
|
.checkbox-group { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 6px; |
||||
|
overflow: auto; |
||||
|
height: 100%; |
||||
|
flex: 1; |
||||
|
flex-wrap: nowrap; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.right { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-between; |
||||
|
|
||||
|
.top-content { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 9px; |
||||
|
|
||||
|
.item-video { |
||||
|
width: 545px; |
||||
|
height: 216px; |
||||
|
} |
||||
|
|
||||
|
label { |
||||
|
font-size: 16px; |
||||
|
font-family: PingFang SC, PingFang SC; |
||||
|
font-weight: 400; |
||||
|
color: #3DE8FF; |
||||
|
line-height: 19px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.footer { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: flex-end; |
||||
|
gap: 9px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,157 @@ |
|||||
|
<template> |
||||
|
<Dialog v-model="obverseVisible" title="行车诱导"> |
||||
|
<Video class="item-video" /> |
||||
|
|
||||
|
<div class="Broadcast"> |
||||
|
<ElTabs v-model="activeName" @tab-click="handleClickTabs" class="tabs"> |
||||
|
<ElTabPane label="详细设计" name="first"> |
||||
|
<Descriptions :list="list" :data="data" style="gap: 18px" /> |
||||
|
</ElTabPane> |
||||
|
<ElTabPane label="设备参数" name="second">设备参数</ElTabPane> |
||||
|
</ElTabs> |
||||
|
|
||||
|
<div class="bottom"> |
||||
|
<Button @click.native="releaseVisible = true">广播发布</Button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<BroadcastReleases v-model="releaseVisible" :deviceId="dialogData.iotDeviceId || '8697-1'" /> |
||||
|
</Dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Dialog from "@screen/components/Dialog/index.vue"; |
||||
|
import Button from "@screen/components/Buttons/Button.vue" |
||||
|
import Descriptions from '@screen/components/Descriptions.vue'; |
||||
|
import CustomControlVideo from '@screen/components/CustomControlVideo/index.vue'; |
||||
|
import BroadcastReleases from "./components/BroadcastReleases.vue" |
||||
|
import Video from "@screen/components/Video" |
||||
|
|
||||
|
import { getRoadInfoByStakeMark, getOrganizationName, getProduct } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js" |
||||
|
import { dialogDelayVisible } from "./../mixin" |
||||
|
|
||||
|
// 广播发布 |
||||
|
export default { |
||||
|
name: 'Broadcast', |
||||
|
mixins: [dialogDelayVisible], |
||||
|
components: { |
||||
|
Dialog, |
||||
|
Button, |
||||
|
Descriptions, |
||||
|
CustomControlVideo, |
||||
|
BroadcastReleases, |
||||
|
Video |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
activeName: 'first', |
||||
|
releaseVisible: false, |
||||
|
data: { |
||||
|
deviceName: "LH24", |
||||
|
roadName: "G35济泽高速", |
||||
|
stakeMarkId: "k094+079", |
||||
|
direction: "1", |
||||
|
organizationName: "山东高速济南发展公司", |
||||
|
brand: "XXX厂家", |
||||
|
deviceState: "0", |
||||
|
}, |
||||
|
list: [ |
||||
|
{ |
||||
|
label: '设备名称', |
||||
|
key: "deviceName", |
||||
|
}, |
||||
|
{ |
||||
|
label: '道路名称', |
||||
|
key: "roadName", |
||||
|
}, |
||||
|
{ |
||||
|
label: '设备桩号', |
||||
|
key: "stakeMarkId", |
||||
|
}, |
||||
|
{ |
||||
|
label: '所属方向', |
||||
|
key: "direction", |
||||
|
enum: "CameraDirectionEnum" |
||||
|
}, |
||||
|
{ |
||||
|
label: '所属机构', |
||||
|
key: "organizationName", |
||||
|
}, |
||||
|
{ |
||||
|
label: '设备厂商', |
||||
|
key: "brand", |
||||
|
}, |
||||
|
{ |
||||
|
label: '设备状态', |
||||
|
key: "deviceState", |
||||
|
enum: "DeviceTypeEnum" |
||||
|
}, |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
async created() { |
||||
|
this.data = { ...this.dialogData, roadName: null } |
||||
|
|
||||
|
getProduct(this.dialogData.productId) |
||||
|
.then(data => { |
||||
|
this.dialogData.brand = data.brand; |
||||
|
}) |
||||
|
|
||||
|
getOrganizationName(this.dialogData.iotDeviceId) |
||||
|
.then(data => { |
||||
|
this.dialogData.organizationName = data.organizationName; |
||||
|
}) |
||||
|
|
||||
|
const roadInfo = await getRoadInfoByStakeMark(this.dialogData.stakeMarkId); |
||||
|
console.log("%c [ roadInfo ]-103-「index.vue」", "font-size:15px; background:#36347c; color:#7a78c0;", roadInfo.roadName); |
||||
|
|
||||
|
if (roadInfo) this.data.roadName = roadInfo.roadName; |
||||
|
}, |
||||
|
methods: { |
||||
|
handleClickTabs() { } |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang='scss' scoped> |
||||
|
.Broadcast { |
||||
|
width: 600px; |
||||
|
height: 240px; |
||||
|
color: #fff; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
|
||||
|
.camera-video { |
||||
|
flex: 1.5; |
||||
|
} |
||||
|
|
||||
|
.tabs { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
|
||||
|
::v-deep { |
||||
|
.el-tabs__content { |
||||
|
flex: 1; |
||||
|
|
||||
|
.el-tab-pane { |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.bottom { |
||||
|
margin-top: 12px; |
||||
|
display: flex; |
||||
|
gap: 9px; |
||||
|
align-items: center; |
||||
|
justify-content: end; |
||||
|
|
||||
|
>div { |
||||
|
font-size: 16px; |
||||
|
padding: 6px 12px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -1,122 +0,0 @@ |
|||||
<template> |
|
||||
<div class='Descriptions'> |
|
||||
<p class="desc-item"> |
|
||||
<span>设备类型:</span> |
|
||||
<span> |
|
||||
{{ cameraType || '-' }} |
|
||||
<img src="@screen/images/dialog/icon-control.png"> |
|
||||
</span> |
|
||||
</p> |
|
||||
<p class="desc-item"> |
|
||||
<span>道路名称:</span> |
|
||||
<span>{{ roadName || '-' }}</span> |
|
||||
</p> |
|
||||
<p class="desc-item"> |
|
||||
<span>所属机构:</span> |
|
||||
<span>{{ organizationName || '-' }}</span> |
|
||||
</p> |
|
||||
<p class="desc-item"> |
|
||||
<span>设备桩号:</span> |
|
||||
<span>{{ data.stakeMarkId || '-' }}</span> |
|
||||
</p> |
|
||||
<p class="desc-item"> |
|
||||
<span>上行相机:</span> |
|
||||
<span> |
|
||||
米 |
|
||||
<img src="@screen/images/dialog/icon-monitor.png"> |
|
||||
</span> |
|
||||
</p> |
|
||||
<p class="desc-item"> |
|
||||
<span>下行相机:</span> |
|
||||
<span> |
|
||||
米 |
|
||||
<img src="@screen/images/dialog/icon-monitor.png"> |
|
||||
</span> |
|
||||
</p> |
|
||||
<p class="desc-item singleline"> |
|
||||
<span>设备状态:</span> |
|
||||
<span :style="{ color: statusEnum.color || '#19E1B1' }">{{ statusEnum.text }}</span> |
|
||||
</p> |
|
||||
<p class="desc-item singleline"> |
|
||||
<span>状态更新时间:</span> |
|
||||
<span>{{ data.updateTime }}</span> |
|
||||
</p> |
|
||||
</div> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { CameraStatusEnum, CameraControlTypeEnum } from "@screen/utils/enum.js" |
|
||||
import { getRoadInfoByStakeMark } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js" |
|
||||
import request from "@/utils/request"; |
|
||||
|
|
||||
export default { |
|
||||
name: 'Descriptions', |
|
||||
props: { |
|
||||
data: { |
|
||||
type: Object, |
|
||||
default: () => ({}) |
|
||||
} |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
statusEnum: CameraStatusEnum[this.data.status] || {}, |
|
||||
cameraType: CameraControlTypeEnum[this.data.ptzCtrl]?.text, |
|
||||
organizationName: null, |
|
||||
roadName: "" |
|
||||
} |
|
||||
}, |
|
||||
async created() { |
|
||||
request({ |
|
||||
url: `/business/organization/${id}`, |
|
||||
method: "get", |
|
||||
}) |
|
||||
.then(({ code, data }) => { |
|
||||
if (code != 200) return; |
|
||||
|
|
||||
this.organizationName = data.organizationName; |
|
||||
}) |
|
||||
.catch((err) => { |
|
||||
|
|
||||
}); |
|
||||
|
|
||||
|
|
||||
const roadInfo = await getRoadInfoByStakeMark(this.dialogData.stakeMarkId); |
|
||||
|
|
||||
if (roadInfo) this.roadName = roadInfo.roadName; |
|
||||
}, |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang='scss' scoped> |
|
||||
.Descriptions { |
|
||||
height: 100%; |
|
||||
display: grid; |
|
||||
grid-template-columns: repeat(2, 1fr); |
|
||||
font-size: 16px; |
|
||||
// font-family: PingFang SC, PingFang SC; |
|
||||
font-weight: 400; |
|
||||
line-height: 19px; |
|
||||
grid-auto-rows: min-content; |
|
||||
gap: 15px; |
|
||||
// -webkit-background-clip: text; |
|
||||
// -webkit-text-fill-color: transparent; |
|
||||
|
|
||||
>p { |
|
||||
>span { |
|
||||
&:first-child { |
|
||||
color: #3DE8FF; |
|
||||
} |
|
||||
|
|
||||
&:last-child { |
|
||||
display: inline-flex; |
|
||||
align-items: center; |
|
||||
gap: 9px; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.singleline { |
|
||||
grid-column: span 2; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -0,0 +1,202 @@ |
|||||
|
<template> |
||||
|
<Dialog v-model="modelVisible" title="相机控制" noneMask> |
||||
|
<div class='CameraControlDialog'> |
||||
|
<div class="direction"> |
||||
|
<div class="control-container top" @click="controlClick(21)"> |
||||
|
<div class="icon-horizontal" /> |
||||
|
<img src="../images/top.svg"> |
||||
|
</div> |
||||
|
<div class="control-container right" @click="controlClick(24)"> |
||||
|
<div class="icon-vertical" /> |
||||
|
<img src="../images/right.svg"> |
||||
|
</div> |
||||
|
<div class="center"></div> |
||||
|
<div class="control-container bottom" @click="controlClick(22)"> |
||||
|
<div class="icon-horizontal" style="transform: rotate(180deg);" /> |
||||
|
<img src="../images/bottom.svg"> |
||||
|
</div> |
||||
|
<div class="control-container left" @click="controlClick(23)"> |
||||
|
<div class="icon-vertical" style="transform: rotate(180deg);" /> |
||||
|
<img src="../images/left.svg"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="options"> |
||||
|
<div v-for="item in options" :key="item.key"> |
||||
|
<img src="../images/sub.svg" @click="controlClick(item.sub)"> |
||||
|
<span>{{ item.label }}</span> |
||||
|
<img src="../images/add.svg" @click="controlClick(item.add)"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</Dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Dialog from "@screen/components/Dialog/index.vue"; |
||||
|
import { controlCamera } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js" |
||||
|
import { throttle } from "lodash" |
||||
|
|
||||
|
export default { |
||||
|
name: 'CameraControlDialog', |
||||
|
components: { |
||||
|
Dialog |
||||
|
}, |
||||
|
model: { |
||||
|
prop: 'visible', |
||||
|
event: "update:value" |
||||
|
}, |
||||
|
props: { |
||||
|
visible: Boolean, |
||||
|
deviceId: String |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
options: [ |
||||
|
{ |
||||
|
label: "变倍", |
||||
|
key: "zoom", |
||||
|
add: "12", |
||||
|
sub: "11" |
||||
|
}, |
||||
|
{ |
||||
|
label: "光圈", |
||||
|
key: "aperture", |
||||
|
add: "15", |
||||
|
sub: "16" |
||||
|
}, |
||||
|
{ |
||||
|
label: "聚焦", |
||||
|
key: "focus", |
||||
|
add: "13", |
||||
|
sub: "14" |
||||
|
}, |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
modelVisible: { |
||||
|
get() { |
||||
|
return this.visible |
||||
|
}, |
||||
|
set(val) { |
||||
|
this.$emit('update:value', val) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
controlClick: throttle(function (type) { |
||||
|
controlCamera(this.deviceId, type) |
||||
|
}, 150) |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang='scss' scoped> |
||||
|
.CameraControlDialog { |
||||
|
width: 360px; |
||||
|
height: 210px; |
||||
|
display: flex; |
||||
|
|
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-around; |
||||
|
gap: 36px; |
||||
|
|
||||
|
img { |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
||||
|
.control-container { |
||||
|
position: relative; |
||||
|
width: min-content; |
||||
|
|
||||
|
&:active { |
||||
|
[class^="icon"] { |
||||
|
background-color: #48B0CB; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.icon-horizontal, |
||||
|
.icon-vertical { |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
background-color: #006A96; |
||||
|
z-index: -1; |
||||
|
} |
||||
|
|
||||
|
.icon-horizontal { |
||||
|
clip-path: path('M53.807 19.0734C51.1049 21.3657 47.1722 21.2685 44.0948 19.512C35.7042 14.7227 25.2544 13.7636 15.6704 17.82C14.5092 18.3114 13.3921 18.8632 12.321 19.4703C9.23352 21.2201 5.29428 21.3087 2.59447 19.0054V19.0054C-0.433686 16.4219 -0.827317 11.8122 2.24787 9.28482C4.93936 7.07281 7.91063 5.2081 11.093 3.74265C16.4653 1.26882 22.3109 -0.00817108 28.2253 6.86646e-05C34.1398 0.0083065 39.9818 1.30157 45.3471 3.79036C48.527 5.26539 51.4944 7.13947 54.1807 9.36039C57.2464 11.8949 56.8402 16.5002 53.807 19.0734V19.0734Z'); |
||||
|
width: 57px; |
||||
|
height: 21px; |
||||
|
} |
||||
|
|
||||
|
.icon-vertical { |
||||
|
clip-path: path('M2.33992 53.8068C0.0475853 51.1047 0.14481 47.172 1.90137 44.0945C6.69064 35.7039 7.64974 25.2542 3.59338 15.6702C3.10192 14.509 2.55008 13.3918 1.94307 12.3208C0.193261 9.23327 0.1046 5.29403 2.40796 2.59423V2.59423C4.99146 -0.433928 9.60116 -0.827561 12.1285 2.24762C14.3405 4.93912 16.2052 7.91038 17.6707 11.0928C20.1445 16.465 21.4215 22.3106 21.4133 28.2251C21.405 34.1395 20.1117 39.9816 17.623 45.3469C16.1479 48.5267 14.2738 51.4941 12.0529 54.1805C9.51843 57.2461 4.91315 56.84 2.33992 53.8068V53.8068Z'); |
||||
|
width: 21px; |
||||
|
height: 57px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.direction { |
||||
|
display: grid; |
||||
|
grid-template-columns: 0.3fr 1fr 0.3fr; |
||||
|
grid-template-rows: 0.3fr 1fr 0.3fr; |
||||
|
align-items: center; |
||||
|
justify-items: center; |
||||
|
|
||||
|
gap: 3px; |
||||
|
|
||||
|
|
||||
|
.top { |
||||
|
grid-area: 1/2/1/2; |
||||
|
} |
||||
|
|
||||
|
.right { |
||||
|
grid-area: 2/3/2/3; |
||||
|
} |
||||
|
|
||||
|
.bottom { |
||||
|
grid-area: 3/2/3/2; |
||||
|
} |
||||
|
|
||||
|
.left { |
||||
|
grid-area: 2/1/2/1; |
||||
|
} |
||||
|
|
||||
|
.center { |
||||
|
grid-area: 2/2/2/2; |
||||
|
|
||||
|
width: 66px; |
||||
|
height: 66px; |
||||
|
background: #006A96; |
||||
|
border-radius: 50%; |
||||
|
opacity: 1; |
||||
|
border: 1px solid #3DE8FF |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.options { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
|
||||
|
gap: 18px; |
||||
|
|
||||
|
>div { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 9px; |
||||
|
|
||||
|
img { |
||||
|
background-color: #006A96; |
||||
|
border-radius: 50%; |
||||
|
|
||||
|
&:active { |
||||
|
background-color: #48B0CB; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 657 B After Width: | Height: | Size: 643 B |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.2 KiB |