-
旋转正方形
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-
<meta charset="utf-8">
-
<title>旋转立方体</title>
-
<style type="text/css">
-
.stage{
-
position: relative;
-
perspective: 800px;
-
}
-
@keyframes rotate-frame{ /* 设置动画效果 */
-
0% {
-
transform: rotateX(0deg) rotateY(0deg);
-
}
-
-
50% {
-
transform: rotateX(360deg) rotateY(0deg);
-
}
-
100% {
-
transform: rotateX(360deg) rotateY(360deg);
-
}
-
}
-
.container{
-
width: 450px;
-
height: 450px;
-
margin: 0 auto;
-
transform-style:preserve-3d;
-
animation: rotate-frame 8s infinite linear;
-
animation-timing-function: all;
-
animation-direction: normal;
-
-
animation-fill-mode: backwards;
-
-
transform-origin: 50% 50% 75px;
-
-
/*background: yellow; 容器屏幕背景色*/
-
}
-
.container:hover{
-
/*覆盖时暂停动画*/
-
animation-play-state: paused;
-
}
-
.side{
-
width: 150px;
-
height: 150px;
-
position: absolute;
-
text-align: center;
-
line-height: 150px;
-
font-size: 50px;
-
}
-
.top{
-
left: 150px;
-
top: 0;
-
transform: rotateX(-90deg); /* 设置角度 */
-
transform-origin: bottom;
-
background-color: rgba(0,0,255,0.5);
-
}
-
.bottom{
-
left: 150px;
-
top: 300px;
-
transform: rotateX(90deg);
-
transform-origin: top;
-
background-color: rgba(0,255,0,0.5);
-
}
-
.left{
-
left: 0;
-
top: 150px;
-
transform: rotateY(90deg);
-
transform-origin: right;
-
background-color: rgba(255,0,0,0.5);
-
}
-
.right{
-
left: 300px;
-
top: 150px;
-
transform: rotateY(-90deg);
-
transform-origin: left;
-
background-color: rgba(0,0,100,0.5);
-
}
-
.front{
-
left: 150px;
-
top: 150px;
-
transform: translateZ(150px);
-
background-color: rgba(0,100,0,0.5);
-
}
-
.back{
-
left: 150px;
-
top: 150px;
-
background-color: rgba(100,0,0,0.5);
-
}
-
.rotateX180{
-
/*让倒置的数字倒置回正常状态*/
-
transform: rotateX(180deg);
-
}
-
-
</style>
-
-
</head>
-
<body>
-
<div class="stage">
-
<div class="container">
-
<div class="side top" >1</div>
-
<div class="side bottom">2</div>
-
<div class="side left">3</div>
-
<div class="side right">4</div>
-
<div class="side front">5</div>
-
<div class="side back">6</div>
-
</div>
-
</div>
-
</body>
-
</html>
-
纸片旋转
-
<!DOCTYPE html>
-
<html lang="en">
-
<head>
-
<meta charset="UTF-8">
-
<title>Document</title>
-
<style type="text/css">
-
.zpbox{
-
/*设置3D视角*/
-
perspective: 800px;
-
perspective-origin: bottom right;
-
}
-
.box{
-
height: 200px;
-
width: 100px;
-
margin: 50px auto;
-
-
/*preserve-3d 指定子元素定位在三维空间内 */
-
transform-style: preserve-3d;
-
/*指定变换为:linear-线性过渡*/
-
transition-timing-function:linear;
-
-
/*指定旋转动画*/
-
animation-name: action_b1;
-
animation-duration: 4s;
-
animation-timing-function: all;
-
animation-direction: normal;
-
animation-iteration-count: infinite;
-
animation-fill-mode: backwards;
-
-
position: relative;
-
}
-
.box:hover{
-
/*覆盖时暂停动画*/
-
animation-play-state: paused;
-
}
-
-
.b1{
-
/*声明第一个卡片为浮动,使得两个卡片能重叠*/
-
float: left;
-
height: 200px;
-
width: 100px;
-
background-color: #000;
-
text-align:center;
-
line-height: 100px;
-
color: #fff;
-
font-size:50px;
-
}
-
.b2{
-
height: 200px;
-
width: 100px;
-
background-color: #000;
-
text-align:center;
-
line-height: 100px;
-
color: #fff;
-
font-size:50px;
-
-
/*第二个卡片旋转90度*/
-
transform: rotateX(90deg);
-
-
/*第二个卡片位于中间位置*/
-
position: absolute;
-
margin-left: 0;
-
margin-top: 0;
-
}
-
.rotateX180{
-
/*让倒置的2、4数字倒置回正常状态*/
-
transform: rotateX(180deg);
-
}
-
-
@keyframes action_b1{
-
100%{
-
transform: rotateX(-360deg);
-
}
-
}
-
-
-
-
-
</style>
-
</head>
-
<body>
-
<div class="zpbox">
-
<div class="box">
-
<div class="b1">
-
<div>1</div>
-
<div class="rotateX180">3</div>
-
</div>
-
<div class="b2">
-
<div>2</div>
-
<div class="rotateX180">4</div>
-
</div>
-
</div>
-
</div>
-
-
-
</body>
-
</html>
-
轮播图3D
-
<!DOCTYPE html>
-
<html lang="en">
-
<head>
-
<meta charset="UTF-8">
-
<title>Document</title>
-
<style type="text/css">
-
html, body, ul, li, ol, dl, dd, dt, p, h1, h2, h3, h4, h5, h6, form, fieldset, legend, img { margin:0; padding:0; } /*去掉多余的像素*/
-
body{
-
perspective: 800px;
-
}
-
.box{
-
width: 800px;
-
height: 360px;
-
margin: 100px auto;
-
text-align:center;
-
position: relative;
-
left: 50%;
-
margin-left: -400px;
-
/*background-color: #eee;*/
-
transform-style: preserve-3d; /*设置为3D模式*/
-
/*transform: rotateY(-30deg) rotateX(57deg);*/
-
/*transition:5s ease;*/
-
animation-name: animate;
-
animation-duration: 10s;
-
animation-iteration-count: infinite;
-
}
-
-
.box>div{
-
width: 800px;
-
height: 360px;
-
position: absolute;
-
}
-
.box>.up{
-
background: url(flower.jpg); /*引入照片*/
-
transform: rotateX(90deg) translateZ(180px); /* 设置角度 */
-
}
-
.box>.down{
-
background: url(flower.jpg);
-
transform: rotateX(90deg) rotateZ(180deg)translateZ(-180px);
-
}
-
.box>.before{
-
background: url(flower.jpg);
-
transform: translateZ(180px);
-
}
-
.box>.after{
-
background: url(flower.jpg);
-
transform: translateZ(-180px) rotateX(180deg);
-
}
-
.box:hover{
-
animation-play-state: paused; /* 当鼠标悬停的时候停止 */
-
}
-
@keyframes animate{
-
0%{
-
-
}
-
25%{
-
transform: rotateX(90deg);
-
}
-
50%{
-
transform: rotateX(180deg);
-
}
-
75%{
-
transform: rotateX(270deg);
-
}
-
100%{
-
transform: rotateX(360deg);
-
}
-
</style>
-
</head>
-
<body>
-
<div class="box">
-
<div class="up"></div>
-
<div class="down"></div>
-
<div class="before"></div>
-
<div class="after"></div>
-
</div>
-
</body>
-
</html>
-
轮播
-
<!DOCTYPE html>
-
<html lang="en">
-
<head>
-
<meta charset="UTF-8">
-
<title>轮播</title>
-
<style>
-
.frame{
-
position:absolute;
-
margin: 50px 200px;
-
width:280px;
-
height:200px;
-
overflow:hidden;
-
border-radius:6px;
-
background-color: #000;
-
}
-
.imgdiv img{
-
float:left;
-
width:280px;
-
height:200px;
-
}
-
.imgdiv {
-
position: absolute;
-
width: 1500px;
-
}
-
.play{
-
animation: lbt 10s ;
-
animation-direction: normal;
-
animation-iteration-count: infinite;
-
}
-
.play:hover{
-
animation-play-state: paused;
-
}
-
-
@keyframes lbt {
-
0%,20% {
-
margin-left: 0px;
-
}
-
20%,40% {
-
margin-left: -300px;
-
}
-
40%,60% {
-
margin-left: -600px;
-
}
-
60%,80% {
-
margin-left: -900px;
-
}
-
80%,100% {
-
margin-left: -1200px;
-
}
-
}
-
-
</style>
-
</head>
-
<body>
-
<div class="frame" >
-
<div class="imgdiv play">
-
<img src="lunbo.jpg" > <!-- 引入照片 -->
-
<img src="lunbo.jpg" >
-
<img src="lunbo.jpg" >
-
<img src="lunbo.jpg" >
-
<img src="lunbo.jpg" >
-
</div>
-
</div>
-
</body>
-
</html>
-
1
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
部分借鉴自:csdn
原文链接:
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
聊一聊力导向图。力导向图在echarts等快捷的可视化工具中都有非常方便的实现方式。来看看d3.js是如何实现的。
先来一张d3.js官网实现的力导向图的照片:
接下来解释一下d3.js中实现此力导向图的过程。
<!DOCTYPE html> <meta charset="utf-8"> <style> .links line { stroke: #999; stroke-opacity: 0.6; } .nodes circle { stroke: #fff; stroke-width: 1.5px; } </style> <svg width="960" height="600"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> // 定义一个svg画布 var svg = d3.select("svg"), // 获取svg画布的宽度 width = +svg.attr("width"), // 获取svg画布的高度 height = +svg.attr("height"); // 定义一个颜色函数 // d3.scaleOrdinal()函数用来定义一个序列,其中的参数d3.schemeCategory20代表序 // 列函数的值域,这里d3.schemeCategory20指的是由RGB十六进制字符串表示的二十种分类 // 颜色的数组。因此,color()函数的值域就是离散的20中颜色值 var color = d3.scaleOrdinal(d3.schemeCategory20); // 创建一个力学模拟器 // d3.forceSimulation()函数用来创建一个空的模拟器 var simulation = d3.forceSimulation() // simulation.force(name,[force])函数的作用是:如果指定了力force,则为指 // 定的名称name分配力并返回该模拟。 如果未指定力,则返回具有指定名称的力,如果 // 没这样的力,则返回undefined。 (默认情况下,新的模拟没有力量。) // d3.forceLink()函数用来创建一个空的link力数组 // d3.forceLink().id()用来指定link力数组中每个节点的id的获取方式 .force("link", d3.forceLink().id(function(d) { return d.id; })) // 创建一个charge数组,forceManyBody()返回一个新的多体力数组 .force("charge", d3.forceManyBody()) // d3.forceCenter()用指定的x坐标和y坐标创建一个新的居中力。 // 如果未指定x和y,则默认为⟨0,0⟩。 .force("center", d3.forceCenter(width / 2, height / 2)); // 读取数据,该例子中的数据是雨果的《悲惨世界》中的人物关系信息。 // 通过力学模拟,人物关系相近的节点会比较接近;反之,节点会比较疏远 d3.json("miserables.json", function(error, graph) { if (error) throw error; // 定义人物节点之间连线的信息 var link = svg.append("g")
.attr("class", "links") // 用line元素来绘制 .selectAll("line") // 绑定json文件中的links数据 .data(graph.links)
.enter().append("line") // 人物节点之间连接线的粗细通过连接线的value字段来计算,value越大,连接线 // 越粗 .attr("stroke-width", function(d) { return Math.sqrt(d.value); }); // 定义人物节点信息 var node = svg.append("g")
.attr("class", "nodes") // 人物节点通过圆来绘制 .selectAll("circle") // 为人物节点绑定nodes数据 .data(graph.nodes)
.enter().append("circle") // 设置节点半径 .attr("r", 5) // 设置节点的填充色,通过节点的group属性来计算节点的填充颜色 .attr("fill", function(d) { return color(d.group); }) // 以定义的这些人物节点为参数,调用drag()函数 // 绑定拖拽函数的三个钩子,即拖拽开始、拖拽中、拖拽结束 .call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended)); //为人物节点绑定文字 node.append("title")
.text(function(d) { return d.id; }); // 为力模拟器绑定节点数据 // 会为每个节点自动添加可视化时所需的index,vx,xy,x,y五个字段信息 // 并且为simulation内部计时器tick监听绑定动作,来绘制图形 simulation
.nodes(graph.nodes)
.on("tick", ticked);// 此处在每次tick时绘制力导向图 // 为力模拟器绑定连接线数据 // 调用结束后,会为每个连接线添加可视化时所需要的index,vx,vy,x,y五个字段信息 simulation.force("link")
.links(graph.links); // 定义simulation内部计时器tick每次结束时的动作 function ticked() { // 每次tick计时到时,连接线的响应动作 // 设置连接线两端的节点的位置 link
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; }); // 每次tick计时到时,节点的响应动作 // 设置节点的圆心坐标 node
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
}); // 定义开始拖拽节点时的动作 function dragstarted(d) { // restart()方法重新启动模拟器的内部计时器并返回模拟器。 // 与simulation.alphaTarget或simulation.alpha一起使用时,此方法可用于在交互 // 过程中进行“重新加热”模拟,例如在拖动节点时,在simulation.stop暂停之后恢复模 // 拟。 if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
} // 定义拖拽中的动作 function dragged(d) { d.fx = d3.event.x;
d.fy = d3.event.y;
} // 定义拖拽结束的动作 function dragended(d) { if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
} </script>
至此,力导向图解析完毕,这篇中有很多关于力学的专业的功能函数,理解起来有点难度。今天周日,起床后第一件事就是把这篇完结了,欧耶~
这篇文
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
部分借鉴自:csdn
原文链接:
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
input失去焦点和获得焦点
鼠标在搜索框中点击的时候里面的文字就消失了。
我们在做网站的时候经常会用到搜索框的获得焦点和失去焦点的事件,因为懒,每次都去写非常的烦,于是就一劳永逸,遇到类似情况就来调用一下就OK 了
相关js代码:
<script src="jquery-1.9.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$('#username').focus(function ()//得到教室时触发的时间
{
$('#username').val('');
})
$('#username').blur(function () 失去焦点时触发的时间
{
if ($('#username').val() == 'marry') {
$('#q').text('用户名已存在!')
}
else { $('#q').text('ok!') }
})
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
部分借鉴自:脚本之家
原文链接:
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
ECharts中dataZoom组件及散点图的绘制
dataZoom 组件是对 数轴(axis) 进行『数据窗口缩放』『数据窗口平移』操作。
可以通过 dataZoom.xAxisIndex 或 dataZoom.yAxisIndex 来指定 dataZoom 控制哪个或哪些数轴。
dataZoom 组件可同时存在多个,起到共同控制的作用。控制同一个数轴的组件,会自动联动。下面例子中会详细说明。
dataZoom 的运行原理是通过『数据过滤』来达到『数据窗口缩放』的效果。
dataZoom 的数据窗口范围的设置,目前支持两种形式:
百分比形式:参见 dataZoom.start 和 dataZoom.end。
绝对数值形式:参见 dataZoom.startValue 和 dataZoom.endValue。
dataZoom 组件现在支持几种子组件:
内置型数据区域缩放组件(dataZoomInside):内置于坐标系中。
滑动条型数据区域缩放组件(dataZoomSlider):有单独的滑动条操作。
框选型数据区域缩放组件(dataZoomSelect):全屏的选框进行数据区域缩放。入口和配置项均在 toolbox中。
在代码中加入dataZoom组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>代码加入dataZoom组件</title>
<!--引入Echarts文件-->
<script src="js/echarts.min.js"></script>
</head>
<body>
<div id="main" style="width: 800px;height:400px;"></div>
<script type="text/javascript">
var dom=document.getElementById("main");
var myChart=echarts.init(dom);
var app={};
var option=null;
//先只在对单独一个横轴,加上 dataZoom 组件,代码示例如下:
option = {
tooltip:{},//提示框
xAxis: {
type: 'value'
},
yAxis: {
type: 'value'
},
dataZoom: [
{
type: 'slider', //这个dataZoom组件是slider型dataZoom组件
xAxisIndex:0, //dataZoom-slider组件控制第一个XAxis
start: 10, //左边在10%位置
end: 60 //右边在60%位置
},
{
type: 'inside', //这个dataZoom组件是inside型dataZoom组件
xAxisIndex:0, //dataZoom-inslide组件控制第一个XAxis
start: 10, //左边在10%的位置
end: 60 //右边在60%的位置
},{
type:'slider',
yAxisIndex:0, //dataZoom-slider组件控制第一个yAxis
start:30,
end:80
},{
type:'inside',
yAxisIndex:0, //dataZoom-inside组件控制第一个yAxis
start:30,
end:80
}
],
series: [
{
name: 'scatter',
type: 'scatter',
itemStyle: {
normal: {
opacity: 0.8
}
},
symbolSize: function (val) {//控制点的大小,(参数为data中第三列的数据)
return val[2] * 40; //用回调函数控制点的大小(请查看官方文档)
},
data: [//data中第三个参数控制点的大小
["14.616","7.241","0.896"],
["3.958","5.701","0.955"],
["2.768","8.971","0.669"],
["9.051","9.710","0.171"],
["14.046","4.182","0.536"],
["12.295","1.429","0.962"],
["4.417","8.167","0.113"],
["0.492","4.771","0.785"],
["7.632","2.605","0.645"],
["14.242","5.042","0.368"]
]
}
]
}
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
可以通过滑动滑轮实现图形的缩放
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
部分借鉴自:csdn
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
本问下面有矢量图层设置的区域,和热力图层设置的热力图的效果,区域绘制效怎么设置详细内容可以访问 openlayers6【十七】vue VectorLayer矢量图层画地图省市区,多省市区(粤港澳大湾区)效果详解,主要讲解的是热力图层效果实现。区域绘制只是为了效果更好看。好了,继续往下看
在 openlayers 中,图层是使用 layer 对象表示的,主要有 WebGLPoints Layer、热度图(HeatMap Layer)、图片图层(Image Layer)、切片图层(Tile Layer)和 矢量图层(Vector Layer)五种类型,它们都是继承 Layer 类的。
前面两篇文章 我们讲了矢量图层 VectorLayer的常用的场景,这篇我们写一篇 HeatMapLayer 的使用。可以看下图所示的热力图实现效果。 放大缩小地图热力图效果。
var heatmapLayer = new ol.layer.Heatmap({ source: source,//热力图资源 opacity:1,//透明度,默认1 visible:true,//是否显示,默认trur zIndex:1,//图层渲染的Z索引,默认按图层加载顺序叠加 gradient:['#00f','#0ff','#0f0','#ff0','#f00'],//热图的颜色渐变 blur: 15,//模糊大小(像素为单位) radius: 8,//半径大小默认为8(像素为单位) extent:[100,30,104,40],//渲染范围,可选值,默认渲染全部 });
2.2.1 addHeatMap()方法详解:
HeatmapLayer
map 中
AppendFeatures()
2.2.2 addHeatMap()方法代码:
/**
* 添加热力图
*/ addHeatMap() { let colors = [ "#2200FF", "#16D9CC", "#4DEE12", "#E8D225", "#EF1616" ]; let hatmapData = [ { name: "成都市" }, { name: "成都市" }, { name: "成都市" }, { name: "成都市" }, { name: "绵阳市" }, { name: "广安市" }, { name: "雅安市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "宜宾市" }, { name: "甘孜藏族自治州市" } ]; let codeList = { 成都市: { center: { lng: 104.061902, lat: 30.609503 } }, 广安市: { center: { lng: 106.619126, lat: 30.474142 } }, 绵阳市: { center: { lng: 104.673612, lat: 31.492565 } }, 雅安市: { center: { lng: 103.031653, lat: 30.018895 } }, 自贡市: { center: { lng: 104.797794, lat: 29.368322 } }, 宜宾市: { center: { lng: 104.610964, lat: 28.781347 } }, 甘孜藏族自治州市: { center: { lng: 101.592433, lat: 30.426712 } } }; this.layer = new HeatmapLayer({ source: new VectorSource(), blur: 30, radius: 15, gradient: colors }); this.map.addLayer(this.layer); this.AppendFeatures(hatmapData, colors, codeList, 50); },
2.2.3 AppendFeatures()方法详解:
new Feature点new Point信息
2.2.4 AppendFeatures()方法代码:
/**
* 增加要素到热力图
*/ AppendFeatures(hatmapData, colors, points, max) { for (var i in hatmapData) { if (points[hatmapData[i].name]) { var coords = points[hatmapData[i].name]; this.max = max; var f = new Feature({ geometry: new Point( fromLonLat([coords.center.lng, coords.center.lat]) ) }); this.layer.getSource().addFeature(f); } } }
<template> <div id="app"> <div id="Map" ref="map"></div> </div> </template> <script> import "ol/ol.css"; import VectorLayer from "ol/layer/Vector"; import VectorSource from "ol/source/Vector"; import { Tile as TileLayer, Heatmap as HeatmapLayer } from "ol/layer"; import Proj from "ol/proj/Projection"; import XYZ from "ol/source/XYZ"; import { Map, View, Feature, ol } from "ol"; import { Style, Stroke, Fill } from "ol/style"; import { Polygon, Point } from "ol/geom"; import { defaults as defaultControls } from "ol/control"; import { fromLonLat } from "ol/proj"; // 四川的边界数据文件 import areaGeo from "@/geoJson/sichuan.json"; export default { data() { return { map: null }; }, methods: { /**
* 初始化地图
*/ initMap() { this.map = new Map({ target: "Map", controls: defaultControls({ zoom: true }).extend([]), layers: [ new TileLayer({ source: new XYZ({ url: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}" }) }) ], view: new View({ center: fromLonLat([104.065735, 30.659462]), zoom: 6.5, maxZoom: 19, minZoom: 5 }) }); }, /**
* 设置区域
*/ addArea(geo = []) { if (geo.length == 0) { return false; } let features = []; geo.forEach(g => { let lineData = g.features[0]; let routeFeature = ""; if (lineData.geometry.type == "MultiPolygon") { routeFeature = new Feature({ geometry: new MultiPolygon( lineData.geometry.coordinates ).transform("EPSG:4326", "EPSG:3857") }); } else if (lineData.geometry.type == "Polygon") { routeFeature = new Feature({ geometry: new Polygon( lineData.geometry.coordinates ).transform("EPSG:4326", "EPSG:3857") }); } routeFeature.setStyle( new Style({ fill: new Fill({ color: "#4e98f444" }), stroke: new Stroke({ width: 3, color: [71, 137, 227, 1] }) }) ); features.push(routeFeature); }); // 设置图层 let routeLayer = new VectorLayer({ source: new VectorSource({ features: features }) }); // 添加图层 this.map.addLayer(routeLayer); }, /**
* 添加热力图
*/ addHeatMap() { let colors = [ "#2200FF", "#16D9CC", "#4DEE12", "#E8D225", "#EF1616" ]; let hatmapData = [ { name: "成都市" }, { name: "成都市" }, { name: "成都市" }, { name: "成都市" }, { name: "绵阳市" }, { name: "广安市" }, { name: "雅安市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "自贡市" }, { name: "宜宾市" }, { name: "甘孜藏族自治州市" } ]; let codeList = { 成都市: { center: { lng: 104.061902, lat: 30.609503 } }, 广安市: { center: { lng: 106.619126, lat: 30.474142 } }, 绵阳市: { center: { lng: 104.673612, lat: 31.492565 } }, 雅安市: { center: { lng: 103.031653, lat: 30.018895 } }, 自贡市: { center: { lng: 104.797794, lat: 29.368322 } }, 宜宾市: { center: { lng: 104.610964, lat: 28.781347 } }, 甘孜藏族自治州市: { center: { lng: 101.592433, lat: 30.426712 } } }; this.layer = new HeatmapLayer({ source: new VectorSource(), blur: 30, radius: 15, gradient: colors }); this.map.addLayer(this.layer); this.AppendFeatures(hatmapData, colors, codeList, 50); }, /**
* 增加要素至热力图
*/ AppendFeatures(hatmapData, colors, points, max) { for (var i in hatmapData) { if (points[hatmapData[i].name]) { var coords = points[hatmapData[i].name]; this.max = max; var f = new Feature({ geometry: new Point( fromLonLat([coords.center.lng, coords.center.lat]) ) }); this.layer.getSource().addFeature(f); } } } }, mounted() { this.initMap(); //初始化地图 this.addArea(areaGeo); //添加四川省的边界描边和填充 this.addHeatMap(); //添加热力图数据 } }; </script> <style lang="scss" scoped> // 此处非核心内容,已删除 </style>
//添加热力图层 this.map.addLayer(this.layer) //删除热力图层 this.map.removeLayer(this.layer)
//获取-设置,模糊大小 heatmapLayer.getBlur() heatmapLayer.setBlur(15) //获取-设置,渲染范围 heatmapLayer.getExtent() heatmapLayer.setExtent([100,30,104,40]) //获取-设置,热力图渐变色 heatmapLayer.getGradient() heatmapLayer.setGradient(['#00f','#0ff','#0f0','#ff0','#f00']) //获取-设置,最大级别 heatmapLayer.getMaxZoom() heatmapLayer.setMaxZoom(18) //获取-设置,最小级别 heatmapLayer.getMinZoom() heatmapLayer.setMinZoom(2) //获取-设置,透明度 heatmapLayer.getOpacity() heatmapLayer.setOpacity(0.5) //获取-设置,半径 heatmapLayer.getRadius() heatmapLayer.setRadius(5) //获取-设置,热力源 heatmapLayer.getSource() heatmapLayer.setSource(source) //获取-设置,是否可见 heatmapLayer.getVisible() heatmapLayer.setVisible(true) //获取-设置,图层的Z-index heatmapLayer.getZIndex() heatmapLayer.setZIndex(2) //绑定事件-取消事件 type事件类型,listener函数体 heatmapLayer.on(type,listener) heatmapLayer.un(type,listener)
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
部分借鉴自:csdn
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
Force-directed(力导向)图形绘制算法通过图形本身的结构(图中顶点与边的拓扑关系)计算出图形的层次,而不依赖于特定领域的知识。使用力导向算法绘制的平面图形通常比较美观,并且图中各条边之间的交叉尽可能的少。
本文对使用D3js绘制Foorce-Directed Graph(力导向图)的过程进行简要的介绍,以下面的逻辑图(包含6个节点和5条边)为例。
import json #nodes为图的节点集合 nodes = [{'name' : 'nodeA'},
{'name' : 'nodeB'},
{'name' : 'nodeC'},
{'name' : 'nodeD'},
{'name' : 'nodeE'},
{'name' : 'nodeF'}] #links为图的边集合,source为起点,target为终点 links = [{'source' : 0 , 'target' : 1},
{'source' : 0 , 'target' : 2},
{'source' : 0 , 'target' : 3},
{'source' : 0 , 'target' : 4},
{'source' : 0 , 'target' : 5}] #graph为逻辑图,由节点集合和边集合组成 graph = {'nodes' : nodes , 'links' : links} print json.dumps(graph)
上例的源码 force-directed-graph.html 及注释如下:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <style> .link { stroke : #CCC; stroke-width : 2; } .node text { pointer-events : none; font-size : 12px; } svg { overflow : hidden; } </style> <script src="http://libs.useso.com/js/jquery/1.11.1/jquery.min.js"></script> <script src="http://libs.useso.com/js/d3/3.4.8/d3.min.js"></script> <script> var graph = {"nodes": [{"name": "nodeA"},
{"name": "nodeB"},
{"name": "nodeC"},
{"name": "nodeD"},
{"name": "nodeE"},
{"name": "nodeF"}], "links": [{"source": 0, "target":1},
{"source": 0, "target": 2},
{"source": 0, "target": 3},
{"source": 0, "target": 4},
{"source": 0, "target": 5}]}; //返回随机颜色代码 function random_color() { var letters = '0123456789ABCDEF'.split(''); var color = '#'; for (var i = 0; i < 6; i++ ) {
color += letters[Math.round(Math.random() * 15)];
} return color;
} function draw() { var width = 400; var height = 300; //设置svg宽度和高度 var svg = d3.select("#canvas svg")
.attr("width", width)
.attr("height", height); //设置Force-Directed力参数 var force = d3.layout.force()
.gravity(.05)
.distance(120)
.charge(-100)
.size([width, height]);
force
.nodes(graph.nodes)
.links(graph.links)
.start(); //选择边集合 var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link"); //选择节点集合 var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag); //响应鼠标拖拽事件 //节点添加圆形图案 node.append("svg:circle").attr("r", 10)
.style("fill", function(){ return random_color();
})
.style("stroke", "#FFF").style("stroke-width", 3);
node.append("text")
.attr("dx", 12)
.attr("dy", ".36em")
.text(function(d) { return d.name }); //绑定tick事件 force.on("tick", function() { link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
}
$(function(){ draw();
}); </script> </head> <body> <div id="canvas"> <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="300"></svg> </div> </body> </html>
本文链接:http://bookshadow.com/weblog/2014/11/04/d3js-force-directed-graph/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
首先3d-force-graph在码云或者github直接搜索,它的文档确实有点少。这个插件用了3次,每一次都有不同的痛苦,也有粗心大意所导致的。
好的,我们现在讲解一下这个插件中的导向树DAG模式
我的案例都会基于Vue开发,创建项目等等我们进不说了,进入正题。
步骤:1.安装:npm i 3d-force-graph (我安装的是"3d-force-graph": “^1.67.5”,)
2.导入 import ForceGraph from ‘3d-force-graph’;
首先注意点:
1.不要全部cv我的代码,或者光放文档中的代码,我们要依据后台数据实际看问题,但是基本的代码步骤是差不多的,但是也不要全CV,不然你的浏览器会报错,而且你以为错误是你的逻辑问题,实际上是cv多了的问题(这一点使我耽误了半天的时间)
2. 数据处理设计到了递归等,数据接口我就不写了
在模板中定义:
<template>
<div class="wrap"></div>
</template>
import ForceGraph from '3d-force-graph'; // 导入 import { subjectList } from '../src/request/api'; // 掉数据的接口
data() { return { // 源数据 sourceData: null, // 力导向图数据 nodes: [], links: [], ForceGraphData: {} }; },
初始话完成
async created() { // 获取数据接口 try { const { data: res } = await subjectList(); this.sourceData = res.data; console.log(this.sourceData); } catch (err) { console.log(err); } this.digui(this.sourceData); // 递归处理数据 this.SetForce(); // 调用力导向图 },
进入数据
methods: { // 1.先定义数据 // 首先定义nodes数据;节点数据 设计递归定义方法 digui(data) { data.children.forEach(item => { if (item.children) { this.digui(item); } const nodeObjs = {}; nodeObjs.name = item.name; nodeObjs.id = item.id; nodeObjs.level = item.level; nodeObjs.parent_id = item.parent_id; nodeObjs.has_children = item.has_children; const linksObjs = {}; linksObjs.source = item.parent_id; linksObjs.target = item.id; this.nodes.push(nodeObjs); this.links.push(linksObjs); }); },
后端返回的数据是格式我们需要用递归地方法把他们处理
要知道插件的节点是nodes数据,连线是links数据,links数组中的每一项都有source和target,source的是连线的开始端,target是连线的结束端,source的是parent_id,target的是id,也就是依据数据进行连接,这一不懂的话可以看看这个插件的这个案例

好,继续,处理完的数据是nodes数据后端数据返回的每一项包括children下的每一项,links数据是每一项是的target:id和source:parent_id
处理数据完成,下一部在methods中设置力导向图的函数
// 设置力导向图 SetForce() { // 这里在最想面插入了一条数据是因为后端返还的数据和依据插件的机制需要我在最前面插入一条最起点的数据 //也就是这条数据就是起源,一般来说你们也会在最前面插入一条起源数据,因为后端数据差不多样式都是一样的 // 这条数据就不用在添加parent_id了,就是返回的有parent_id,而不需要添加。 this.nodes.unshift({ id: 10515, name: '化学', level: 1, }); this.ForceGraphData.links = this.links; this.ForceGraphData.nodes = this.nodes; const gukergForce = ForceGraph(); gukergForce(document.querySelector('.wrap')) // 力导向图放在容器中 记住这个容器在样式中要给大小 .graphData(this.ForceGraphData)// 这条就是数据源 .dagMode('td') // 模式有很多选择,我选择的td,自上而下的格式,文档中有选择,你们按自己需求选 } },
现在一个简单的力导向树就出来了,随项目的需求你可在节点加图片,你需要import * as THREE from ‘three’;这个包不用下载,直接导入就可以,
const gukergForce = ForceGraph(); // 力导向图放在容器中 gukergForce(document.querySelector('.wrap')) .graphData(this.ForceGraphData) .dagLevelDistance(70) // 两点直接的距离 .dagMode('td') .nodeResolution(50) // 较高的值产生较光滑的球体。 .nodeThreeObject(node => { .nodeThreeObject(node => { if (node.level === 1) { console.log('你好'); } let imgTexture = ''; if (node.level === 1) { imgTexture = new THREE.TextureLoader().load(require('./assets/1.png')); } else if (node.level === 2) { imgTexture = new THREE.TextureLoader().load(require('./assets/2.png')); } else if (node.level === 3) { imgTexture = new THREE.TextureLoader().load(require('./assets/3.png')); } else if (node.level === 4) { imgTexture = new THREE.TextureLoader().load(require('./assets/4.png')); } else if (node.level === 5) { imgTexture = new THREE.TextureLoader().load(require('./assets/5.png')); } const material = new THREE.SpriteMaterial({ map: imgTexture }); const sprite = new THREE.Sprite(material); if (node.level === 1) { sprite.scale.set(50, 45); return sprite; } else if (node.level === 2) { sprite.scale.set(20, 20); return sprite; } if (node.level === 3) { sprite.scale.set(30, 30); return sprite; } if (node.level === 4) { sprite.scale.set(20, 15); return sprite; } if (node.level === 5) { sprite.scale.set(20, 20); return sprite; } }); }
其实由谁解决了它节点之间不重复的问题,可以给我留言,谢谢
转自:csdn论坛
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
Node.js 是一个基于 Chrome V8 引擎 的 JavaScript 运行时(即node.js不是一门语言也不是库和框架,它是一个JavaScript运行时环境)。 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js使用事件驱动,非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。
安装node
直接到官网上下载自己电脑的版本,官网地址:https://nodejs.org/zh-cn/
安装完成之后可以通过在终端上运行node -v //查看是否安装成功,成功的话会展示当前安装版本 npm -v //安装node的时会连同一起将npm安装包一起打包安装了,npm是nodejs的包管理器 npm install -g cnpm --registry=https://registry.npm.taobao.org //安装淘宝镜像可提高下载包工具的速度Express框架
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
使用 Express 可以快速地搭建一个完整功能的网站。express 是nodejs的一个web框架,使用express,能够更便捷的使用nodejs.
安装
第一步:安装express
npm install express --save -g第二步:安装express-generator
npm install express-generator --save -g //express-generator是express应用生成器,相当于express 的骨架第三步:打开终端进入你将要建立项目的文件夹中创建你的项目
express expressDemo //你要建立的项目名称第四步:安装:npm install
第五步:启动项目:npm start
这样你的第一个express项目就创建成功了express-路由
Express框架建立在node.js内置的http模块上。http模块生成服务器的原始代码如下。
var http = require("http"); var app = http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.end("Hello world!"); }); app.listen(3000, "localhost");上面代码的关键是http模块的createServer方法,表示生成一个HTTP服务器实例。该方法接受一个回调函数,该回调函数的参数,分别为代表HTTP请求和HTTP回应的request对象和response对象。
Express框架的核心是对http模块的再包装。上面的代码用Express改写如下。
var express = require('express'); var app = express(); app.get('/', function (req, res) { res.send('Hello world!'); }); app.listen(3000);比较两段代码,可以看到它们非常接近。原来是用http.createServer方法新建一个app实例,现在则是用Express的构造方法,生成一个Epress实例。两者的回调函数都是相同的。Express框架等于在http模块之上,加了一个中间层。
中间件
简单说,中间件(middleware)就是处理HTTP请求的函数。它最大的特点就是,一个中间件处理完,再传递给下一个中间件。App实例在运行过程中,会调用一系列的中间件。
每个中间件可以从App实例,接收三个参数,依次为request对象(代表HTTP请求)、response对象(代表HTTP回应),next回调函数(代表下一个中间件)。每个中间件都可以对HTTP请求(request对象)进行加工,并且决定是否调用next方法,将request对象再传给下一个中间件。
Express 应用程序基本上是一系列中间件函数调用。
中间件函数可以执行以下任务:
- 执行任何代码。
- 对请求和响应对象进行更改。
- 结束请求/响应循环。
- 调用堆栈中的下一个中间件函数。
Express 应用程序可以使用以下类型的中间件:
- 应用层中间件
- 路由器层中间件
- 错误处理中间件
- 内置中间件
- 第三方中间件
应用层中间件
使用app.use()和app.METHOD()函数将应用层中间件绑定到应用程序对象的实例,其中METHOD是中间件函数处理的请求的小写 HTTP 方法(例如 GET、PUT 或 POST)。app.use('/user/:id', function (req, res, next) { //在 /user/:id 路径中为任何类型的 HTTP 请求执行此函数。 console.log('Request Type:', req.method); next(); }); app.get('/user/:id', function (req, res, next) { res.send('USER'); });路由器层中间件
路由器层中间件的工作方式与应用层中间件基本相同,差异之处在于它绑定到 express.Router() 的实例。var router = express.Router();错误处理中间件
错误处理中间件函数的定义方式与其他中间件函数基本相同,差别在于错误处理函数有四个自变量而不是三个,专门具有特征符 (err, req, res, next):app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!'); });有关错误处理中间件的详细信息,请参阅:错误处理。
内置中间件
自 V4.x 起,Express 不再依赖于 Connect。除express.static外,先前 Express 随附的所有中间件函数现在以单独模块的形式提供。请查看中间件函数的列表。第三方中间件
使用第三方中间件向 Express 应用程序添加功能。
安装具有所需功能的 Node.js 模块,然后在应用层或路由器层的应用程序中将其加装入。
列如cookie-parser中间件函数
首先安装cookie-parser。npm install cookie-parservar express = require('express'); var app = express(); var cookieParser = require('cookie-parser'); // load the cookie-parsing middleware app.use(cookieParser());MongoDB数据库
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。你可以在mongodb官网下载该安装包,地址为:https://www.mongodb.com/download-center#community。
以下以Mac版本为例讲解1,打开终端修改环境变量
echo $PATH你可以查看到你当前的环境变量下面的文件
image.png2,选择其中一个文件夹进去然后将你的mongodb的安装包路径映射到此文件上
ln -s 你的MongoDB的安装包路径/bin/mongo mongo3,你创建一个数据库存储目录 /data/db:
sudo mkdir -p /data/db4,启动 mongodb,默认数据库目录即为 /data/db:
sudo mongod5,再打开一个终端执行以下命令连接
mongo这样你就启动连接上了本地的数据库
你可以下载安装mongosBooster数据库管理你的数据,地址为https://nosqlbooster.com/downloadsmongoose
mongoose是nodeJS提供连接 mongodb的一个库. 此外还有mongoskin, mongodb(mongodb官方出品). 本人,还是比较青睐mongoose的, 因为他遵循的是一种, 模板式方法, 能够对你输入的数据进行自动处理. 有兴趣的同学可以去Mongoose官网看看.
安装mongoosenpm install mongoose --saveMongoose里面有几个基本概念.
- Schema: 相当于一个数据库的模板. Model可以通过mongoose.model 集成其基本属性内容. 当然也可以选择不继承.
- Model: 基本文档数据的父类,通过集成Schema定义的基本方法和属性得到相关的内容.
- instance: 这就是实实在在的数据了. 通过 new Model()初始化得到.
在保证你已经启动连接上了mongoDB时你就可以使用了,列如以下Democonst mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/test'); const con = mongoose.connection; con.on('error', console.error.bind(console, '连接数据库失败')); con.once('open',()=>{ //定义一个schema let Schema = mongoose.Schema({ category:String, name:String }); Schema.methods.eat = function(){ console.log("I've eatten one "+this.name); } //继承一个schema let Model = mongoose.model("fruit",Schema); //生成一个document let people = new Model({ category:'apple', name:'apple' }); //存放数据 people.save((err,apple)=>{ if(err) return console.log(err); apple.eat(); //查找数据 Model.find({name:'apple'},(err,data)=>{ console.log(data); }) }); //查询所有数据 people.find(function(err,ret){ if(err){ console.log('查询失败') }else{ console.log('查询成功') } }) //按条件查询符合条件的数据 people.find({},function(err,ret){ }) //按条件查询单个数据 people.findOne({},function(err,ret){ }) //删除数据 people.remove({uesername:'zhangsan'},function(err,ret){ }) //根据ID删除数据 peop.findByIdAndRemove({},function(err,ret){ }) //更新数据 people.findByIdAndUpdate('dfsfs',function(err,ret){ }) })到这里, 实际上, mongoose我们已经就学会了. 剩下就是看一看官方文档的API–CRUD相关操作
作者:orange_9706
来源:简书
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
进行傻瓜式安装:最后点击install即可;
首先在安装路径下新建两个文件夹【node_global】及【node_cache】,如下:
然后cmd执行命令
-
npm config set prefix "E:\Program Files\node_js\node_global"
-
npm config set cache "E:\Program Files\node_js\node_cache"
接着配置环境变量,系统变量里新建:
用户变量里的
改为E:\Program Files\node_js\node_global;
最后可以测试一下是否安装到了新的路径里:可以看到成功了
npm install express -g ,其中 -g 表示全局,不加会安装在当前路径C:/users/dell下
傻瓜式安装:
npm install express -g和express应用生成器 npm install express-generator -g;
然后打开终端,如图
结果报错:express : 无法加载文件 E:\Program Files\node_js\node_global\express.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/
go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。
+ express mytest
+ ~~~~~~~
+ CategoryInfo : SecurityError: (:) [],PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
那就解决错误先:解决方法如图
这样就创建成功了。
这里应该是先新建一个文件夹来存放项目,然后进入指定位置。默认的话就放到c盘了。
在终端执行如下代码
然后浏览器输入http://localhost:3000/
接下来安装项目依赖,如图;
进入项目,运行项目;
浏览器输入http://localhost:8080进行访问,如下图。
github地址附上:https://vuejs-templates.github.io/webpack
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
部分借鉴自:csdn 作者:狼丶宇先生
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
现在是互联网逐渐发展,已经出现了很多可以供自己写博客的网站,大家可以在上面 发表自己的文章,供自己记录或者是供他人阅读。但是,可不可以自己搭建一个只属于自己的个人博客网站呢?这篇文章就带你从0开始搭建一个自己的个人博客网站,并部署到属于自己服务器。这里有一点要说的是,没有服务器的同学使用自己机器的linux系统也是一样的操作。我们选用一个很好用的博客框架Hexo进行搭建我们的个人博客。
Hexo是一个快速,简介而且高效的博客框架,Hexo 使用Markdown(或其他渲染引擎)解析文章,在几秒内,即可生成一个静态网页展示我们发布的文章,同时也提供了大量精美的博客主题供我们使用。
我们使用Centos7系统作为演示,使用其他linux系统也是可以的,只需要更换为对应Linux版本的软件安装命令即可。
1.安装Git
直接使用yum安装即可,在命令行输入 yum -y install git
完成之后输入git version 查看是否安装成功,如果显示git版本信息即为成功,如下:
2.安装Node.js
Node.js是一种运行在服务端的JavaScript,是一个基于Chrome JavaScript运行时建立的一个平台。
Hexo基于Node.js,所以安装Node.js是必须的一个操作,安装步骤如下:
2.1:下载安装包:
wget https://nodejs.org/dist/v12.13.1/node-v12.13.1-linux-x64.tar.xz
2.2:解压缩软件包并配置环境变量:
#解压 tar -xvJf node-v6.10.1-linux-x64.tar.xz #移动到/usl/lcoal目录下 mv node-v6.10.1-linux-x64 /usr/local/node-v6 #创建软链接 ln -s /usr/local/node-v6/bin/node /bin/node ln -s /usr/local/node-v6/bin/npm /bin/npm #添加环境变量 echo 'export PATH=/usr/local/node-v6/bin:$PATH' >> /etc/profile source /etc/profile #让环境变量生效
2.3:测试是否安装成功:
在命令行输入node -v 和 npm -v,若是显示出了版本号,即为安装成功:
3.安装并使用Hexo
Hexo的安装较为简单,使用如下命令安装
npm install -g hexo-cli #这里有一点要注意的就是,npm的源是在国外的,访问可能会很慢,这里可以换成我们国内的源进行安装加快速度。操作如下: npm config set registry https://registry.npm.taobao.org
3.1:初始化Hexo
上面的安装完成之后执行下面的命令进行对Hexo进行一个初始化
#这个文件名字可以自己指定,之后会在当前目录下生成对应文件夹 hexo init <文件名字> cd 文件名字 npm install
可以看到安装好之后的一个目录结构:
目录文件说明:
_config.yml:网站的配置信息,您可以在此配置大部分的参数。
package.json:应用程序的信息。EJS, Stylus 和 Markdown renderer 已默认安装,您可以自由移除。
scaffolds:模版文件夹。当您新建文章时Hexo 会根据 scaffold 来建立文件Hexo的模板是指在新建的文章文件中默认填充的内容。例如,如果您修改scaffold/post.md中的Front-matter内容,那么每次新建一篇文章时都会包含这个修改。
source:资源文件夹是存放用户资源的地方。除 _posts 文件夹之外,开头命名为 _ (下划线)的文件 / 文件夹和隐藏的文件将会被忽略。Markdown 和 HTML 文件会被解析并放到 public 文件夹,而其他文件会被拷贝过去。
themes:主题 文件夹。Hexo 会根据主题来生成静态页面。
查看hexo的版本以及对应的数据:
3.2生成静态文件,并开启Hexo服务:
进入到了hexo的安装目录之后,使用hexo generate来生成静态文件,也可以使用hexo g,之后使用hexo server(可以写成hexo s)命令启动服务,操作如下:
可以看到4000端口的服务已经开启,之后在你的浏览器输入http://<你的linux机器的ip地址或者服务器公网地址>:4000,如下可以看到最开始的一个界面:
4.初步使用Hexo:
使用前,我们对我们的站点进行一个配置,也就是我们创建的hexo目录的_config.yml文件,可以修改的部分介绍如下:
# Site
title: QIMING.INFO #博客网站的标题
subtitle: #博客网站的副标题
description: #你的网站描述
keywords: #网站的关键词
author: #作者的名字
language: #博客网站使用的语言
timezone: #网站时区
我自己的修改如下供大家参考,这里的修改没有太大的限制:
4.1:开始使用Hexo发布自己的第一篇博客!
执行下面的目录创建一篇新文章:
hexo new post <文章标题>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Tz5aBlT-1622032930755)(pictures/image-20210526145922392.png)]
这里我创建了一篇标题为First_Blog的博客,创建之后hexo目录下面的source/_post文件夹下会产生一个First_Blog.md的文件
4.2:编辑文章
进入到上面说的那个目录下可以看到我们创建的博客文件:
直接使用vim或者vi就可以对我们的博客文章进行编辑了,打开此First_Blog.md后可以看到—分隔的区域,这部分主要对文章进行标注变量,如下:
title:标题
tage:标签
categories:分类
date:时间
这些标注大家在-----区域可以进行使用
4.3:发布文章
输入如下命令,生成静态网页,静态网页会存放在public文件下
hexo g
hexo s
之后就可以去浏览器访问了!可以看到我们发布的文章已经成功在浏览器显示,到这里个人博客网站就已经成功搭建了。
5.主题的选择:
主题网站:https://hexo.io/themes/ hexo提供了大量精美的主题供我们选择,选择喜欢的主题,在hexo目录下的themes文件夹下使用git clone下载主题,之后再配置文件_config.yml把theme后面修改成下载的主题的名字,之后运行hexo clean ,hexo g即可看到生效的主题。
如果是有服务器的小伙伴,也可以将Hexo部署到服务器供全网访问,服务器的购买这里就不多说,阿里云跟腾讯云上面对于学生也有较为优惠的价格。部署到服务器的话,就需要将上面的全部操作,在你的服务器系统上面执行,之后我们使用Nginx(反向代理服务器)进行部署。
Nginx安装:
Nginx是一款高性能的 HTTP 和反向代理服务器,这里我们采用编译安装的方式,按照下面的指引依次执行命令
#安装gcc编译环境: yum install -y gcc-c++ #安装zlib-devel库: yum install -y zlib-devel #安装OpenSSL密码库: yum install -y openssl openssl-devel #安装pcre正则表达式库:编译nginx,需要需要指定pcre的路径,这里我们选择安装稳定版本的。 下载地址:https://ftp.pcre.org/pub/pcre/ #选择对应的版本下载下来之后上传到我们的服务器,也可以使用wget直接下载 tar -xf pcre-8.43.tar.gz cd pcre-8.43 mkdir -p /usr/local/pcre
./configure --prefix=/usr/local/pcre make && make install
下载编译安装nginx:
nginx下载官网:http://nginx.org/en/download.html wget http://nginx.org/download/nginx-1.16.0.tar.gz mkdir -p /usr/local/nginx tar -xf nginx-1.16.0.tar.gz #编译指定安装路径需要进入nginx cd nginx-1.16.0
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-pcre #http_ssl_module 这是支持https的一个模块,就是可以使用https://这样去访问。 make && make install #编译安装
启动nginx服务:
#启动: /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf #用指定配置文件的方式启动 -c #测试: /usr/local/nginx/sbin/nginx -t #这个用于测试nginx的语法是否有问题 显示is successful即为成功。 #关闭: /usr/local/nginx/sbin/nginx -s stop #继续输入以下命令使Nginx开机自动启动: systemctl enable nginx #配置文件的位置:/usr/local/nginx/conf
之后我们需要配置服务器公网ip,编辑配置文件。
之后再重启nginx服务,开启hexo服务,这个时候使用公网的ip就可以访问到我们的hexo服务了!
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
部分借鉴自:csdn
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
蓝蓝设计的小编 http://www.lanlanwork.com