身为一个三线小城市的开发者,开发管理类的前端项目,必须有一个首页大屏页面,因为领导们都喜欢看这个,于是参考别人的项目也做了一个。
中间的地图模块有点意思,载入的是一张网络上的图片,使用svg技术画了建筑的边框,然后就可以像操作dom一样触发交互了。
中间地图可以换成任何图片,比如大楼的设计图,厂区的平面图等等,实现定制化地图的开发。
绘制svg用的软件是cdr,画布使用像素做单位,将图片载入cdr中,然后绘制轮廓图,导出svg格式的文件就可以在项目中使用了,说起来挺简单,但是学习cdr还是要花点时间的。
一想到用代码去画图就很蛋疼,偶然发现cdr可以导出svg格式的文件,本人业余时间喜欢搞点设计绘画什么的,正好派上用场,研究了一下午svg技术,上手做了个这个小东西,给有需求的同学们做个参考。
地图模块没有做窗口自适应。
此项目的框架使用vue。
这是index.vue
<template >
<div class="chartMain">
<svg class="commu" width="300px" height="35px" style="transform: scale(0.666667, 0.571429);"><rect fill="#7acaec" x="8.038461538461538" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="19.576923076923077" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.3509551554555508s" begin="0.9979486091755545" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="31.115384615384613" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.7637955340176938s" begin="1.6805424644533238" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="42.65384615384615" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="54.19230769230769" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.3747094662786s" begin="0.19808113937130178" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="65.73076923076923" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.3582927763248147s" begin="0.3826910406214452" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="77.26923076923077" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.2356613685960556s" begin="0.906340497984393" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="88.8076923076923" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.190398572665799s" begin="0.31425562628166226" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="100.34615384615384" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="111.88461538461539" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.7610740681880848s" begin="0.9188888980921393" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="123.42307692307692" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.8660856952000844s" begin="1.1529554149565775" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="134.96153846153845" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="146.5" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.5298307185524032s" begin="0.47617417673840334" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="158.03846153846155" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.095277295656217s" begin="0.5458242166039429" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="169.57692307692307" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="181.1153846153846" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.0882628254060283s" begin="0.12544313244181682" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="192.65384615384616" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="204.19230769230768" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="215.73076923076923" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="227.26923076923077" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.314860655388488s" begin="0.2314555034915884" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="238.8076923076923" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.2923221508749196s" begin="0.1395582878569468" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="250.34615384615384" y="8.166666666666666" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.3398513682820994s" begin="0.5501367445873719" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="261.88461538461536" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="273.4230769230769" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="284.96153846153845" y="8.166666666666666" width="7" height="7">rect><rect fill="#7acaec" x="8.038461538461538" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="19.576923076923077" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="31.115384615384613" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="42.65384615384615" y="19.833333333333332" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.8434621648340461s" begin="1.4854327963498637" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="54.19230769230769" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="65.73076923076923" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="77.26923076923077" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="88.8076923076923" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="100.34615384615384" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="111.88461538461539" y="19.833333333333332" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.6792044936409287s" begin="1.852986216666268" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="123.42307692307692" y="19.833333333333332" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.540012954273926s" begin="1.7752272962493065" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="134.96153846153845" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="146.5" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="158.03846153846155" y="19.833333333333332" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.9457622153010579s" begin="0.8602651128463727" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="169.57692307692307" y="19.833333333333332" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.8909055204160286s" begin="1.5640207633154337" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="181.1153846153846" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="192.65384615384616" y="19.833333333333332" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.6251410471874284s" begin="1.155740498287225" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="204.19230769230768" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="215.73076923076923" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="227.26923076923077" y="19.833333333333332" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.5884886285146997s" begin="0.31865144631108633" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="238.8076923076923" y="19.833333333333332" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.7821157194319543s" begin="0.3587508606161629" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="250.34615384615384" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="261.88461538461536" y="19.833333333333332" width="7" height="7">rect><rect fill="#7acaec" x="273.4230769230769" y="19.833333333333332" width="7" height="7"><animate attributeName="fill" values="#7acaec;transparent" dur="1.05086576292224s" begin="1.6073987662135174" repeatCount="indefinite">animate>rect><rect fill="#7acaec" x="284.96153846153845" y="19.833333333333332" width="7" height="7">rect>svg>
<header>
<h1>智慧养殖图像项目展示平台h1>
header>
<showTime>showTime>
<floatInfo v-show="floatShow" :mapClick11="mapClick" @closeFloatInfo="closeFloatInfo">floatInfo>
<section class="mainbox">
<div class="column" style="width: 29%;">
<div class="panel">
<h2>平均运动量h2>
<lineChart style="height: 90%">lineChart>
<div class="panel-footer">div>
div>
<div class="panel">
<h2>栏位信息h2>
<scrollList>scrollList>
<div class="panel-footer">div>
div>
div>
<div class="column" style="width: 42%;">
<mainHeader class="mainHeader">mainHeader>
<div class="videoCenter">
<mapSvg @mapChange="onMapChange">mapSvg>
div>
div>
<div class="column" style="width: 29%;">
<div class="panel line1">
<h2>身体指标h2>
<progressBar>progressBar>
<div class="panel-footer">div>
div>
<div class="panel bar1">
<h2>整体估重h2>
<barChart style="height: 90%">barChart>
<div class="panel-footer">div>
div>
div>
section>
div>
template>
<script>
import lineChart from './cmp/lineChart'
import barChart from './cmp/barChart'
import progressBar from './cmp/progressBar'
import scrollList from './cmp/scrollList'
import mainHeader from './cmp/mainHeader'
import showTime from './cmp/showTime'
import mapSvg from './cmp/mapSvg'
import floatInfo from './cmp/floatInfo'
export default {
name: "Screen",
data() {
return {
mapClick: 0,
floatShow: false
}
},
components: {
lineChart,
barChart,
progressBar,
scrollList,
mainHeader,
showTime,
mapSvg,
floatInfo
},
mounted() {
},
methods: {
onMapChange(n) {
// console.log(n)
this.mapClick = n
this.floatShow = true
},
closeFloatInfo() {
this.floatShow = false
}
}
};
script>
<style scoped>
.chartMain {
background-color: #09163b;
/* 上面的导航栏是固定的84 */
/* 必须这么写,height 100%没用 */
height: calc(100vh - 84px);
overflow-y: scroll;
}
.chartMain .commu {
position: absolute;
top: 15px;
}
header {
position: relative;
background: url(/img/head_bg.png) no-repeat top center;
background-size: 100% 100%;
}
header h1 {
color: rgb(255, 255, 255);
margin: 0;
padding: 20px 0;
text-align: center;
}
.mainbox {
/* height: 90vh; */
padding: 0 1.5rem;
display: flex;
margin: 0 auto;
}
/* 每个小块图表 */
.panel {
position: relative;
/* 如果设置为百分比,图表在渲染时获取的高度值是不准确的,不能用!!! */
/* height: 43%; */
height: 350px;
border: 1px solid rgba(25, 186, 139, 0.17);
background: rgba(255, 255, 255, 0.04) url(/img/line.png);
padding: 7px;
margin-bottom: 15px;
}
/*四个角的边框 */
.panel::before {
position: absolute;
top: 0;
left: 0;
content: "";
width: 10px;
height: 10px;
border-top: 2px solid #02a6b5;
border-left: 2px solid #02a6b5;
border-radius: 20%;
}
.panel::after {
position: absolute;
top: 0;
right: 0;
content: "";
width: 10px;
height: 10px;
border-top: 2px solid #02a6b5;
border-right: 2px solid #02a6b5;
border-radius: 20%;
}
.panel .panel-footer {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
}
.panel .panel-footer::before {
position: absolute;
bottom: 0;
left: 0;
content: "";
width: 10px;
height: 10px;
border-bottom: 2px solid #02a6b5;
border-left: 2px solid #02a6b5;
border-radius: 20%;
}
.panel .panel-footer::after {
position: absolute;
bottom: 0;
right: 0;
content: "";
width: 10px;
height: 10px;
border-bottom: 2px solid #02a6b5;
border-right: 2px solid #02a6b5;
border-radius: 20%;
}
.panel h2 {
text-align: center;
color: #fff;
font-size: 15px;
/* 400就是标准值 */
/* font-weight: 400; */
}
.mainHeader {
margin: 0 15px;
}
.videoCenter {
/* background-color: rgb(201, 201, 201); */
position: relative;
height: 485px;
margin: 15px;
/* color: #fff;
font-size: 20px;
text-align: center;
line-height: 485px; */
}
/* .videoCenter video {
width: 100%;
} */
/* 媒体查询 */
/* @media screen and (max-width: 1024px) {
html {
font-size: 42px !important;
}
}
@media screen and (min-width: 1920px) {
html {
font-size: 80px !important;
}
} */
style>
这是svg地图的模块
<template>
<div>
<svg class="svgAll" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="590px" height="485px" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 590 485"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="id0">
<rect x="2" y="3" width="586" height="479"/>
clipPath>
defs>
<g style="clip-path:url(#id0)">
<image x="2" y="3" width="586" height="479" xlink:href="map.png"/>
g>
<g id="building">
<path @click="onSvg(1)" class="fil0" d="M89 33c-1,3 -1,10 -2,14 -1,5 -3,7 -5,9 -2,2 -5,2 -7,4 -2,2 -4,5 -5,8 -2,3 -3,6 -3,9 -1,3 -1,7 -1,15 0,8 -1,19 -1,25 0,6 0,6 -1,6 -1,0 -2,0 -3,4 -1,4 -1,11 -1,16 0,5 0,7 1,8 1,1 3,2 9,2 5,0 14,1 24,1 10,0 22,-1 28,-1 6,0 6,0 6,-5 0,-5 0,-15 0,-20 0,-5 -1,-6 -1,-14 0,-8 0,-23 0,-31 0,-8 -1,-9 -3,-10 -2,-1 -6,-2 -9,-1 -3,1 -6,3 -8,4 -2,1 -2,1 -2,-1 0,-2 -1,-6 -2,-10 -1,-4 -3,-7 -5,-11 -2,-4 -4,-8 -5,-13 -1,-4 -2,-9 -2,-11 0,-3 0,-3 -1,-3 -1,0 -2,1 -2,4z"/>
<path @click="onSvg(2)" class="fil0" d="M355 230c-2,-2 -3,-5 -5,-10 -2,-5 -4,-11 -6,-17 -2,-5 -5,-10 -6,-17 -1,-7 0,-16 1,-21 1,-5 3,-4 6,-3 2,1 5,4 7,5 2,1 4,1 5,0 1,-2 0,-5 1,-7 1,-2 5,-2 7,-2 2,-1 4,-3 5,-3 2,0 4,2 5,4 1,2 1,6 1,9 0,3 1,6 2,6 1,0 2,-1 3,-3 1,-2 0,-5 1,-9 1,-5 3,-11 7,-15 3,-4 7,-6 11,-6 4,0 8,1 12,5 4,4 8,11 12,20 4,9 7,20 8,26 2,6 2,7 2,8 1,1 3,3 4,5 1,2 1,4 -1,6 -2,2 -5,3 -8,3 -3,0 -5,0 -8,0 -3,0 -7,2 -14,4 -8,2 -19,5 -26,6 -7,1 -10,1 -11,1 -2,0 -2,-1 -3,0 -1,1 -2,4 -5,5 -2,2 -5,2 -7,0z"/>
g>
svg>
div>
template>
<script>
export default {
name: "MapSvg",
data() {
return {};
},
mounted() {
},
methods: {
onSvg(n) {
// console.log(n)
this.$emit('mapChange', n)
},
},
};
script>
<style scoped>
.svgAll {
position: absolute;
top: 0;
left: 0;
}
#building path:hover {
cursor: pointer;
stroke:#d70000;
stroke-width: 4px;
}
.fil0 {fill:#FEFEFE;fill-opacity:0.200000}
style>
其他模块的代码就不贴了,canvas和svg的对比网上有很多文章,基本上的结论就是图形量比较少的话svg性能更好,需要大量重绘的项目适合用canvas。
但是svg可以使用其他工具软件画,并且可以当作dom使用,css也可以控制其样式,这些优势canvas是无法比拟的。
代码没啥难点,关键是你得会cdr等矢量图绘制软件。
有此需求的同学可以学习一下绘图软件。