百度有许多优秀的开源软件,百度脑图就是其中的一款。这是一款开源产品,我们能够将其随意搭建在任何地方。今天咱们来在本地计算机上搭建这个项目。javascript
node
,npm
,git
,浏览器
npm
包准备,必备模块:grunt
, bower
web
服务器(Apache,tomcat,node server,nginx等)我这里是在Windows
下,使用git bash
进入D盘,建立文件夹baidunaotu
:css
# 进入D盘 $ cd /d # 建立baidunaotu文件夹,并进入该文件夹 $ mkdir baidunaotu && cd baidunaotu # 克隆项目 $ git clone https://github.com/fex-team/kityminder.git # 等待项目克隆完成...... # 进入项目目录 $ cd kityminder # 初始化子模块 $ git submodule init $ git submodule update # 安装项目的依赖 $ npm install $ bower install # 等待项目的依赖安装完成...... # 执行编译 $ grunt # 等待编译结果...... # 这时能够发如今该目录中多了一个文件夹dist # dist文件夹中就是能够运行的百度脑图 # 进入上一级目录,并建立文件夹naotu $ cd ../ && mkdir naotu # 将kityminder中的dist文件夹拷贝到naotu文件夹下 $ cp -r kityminder/dist naotu/ # 进入naotu目录 $ cd naotu # 初始化可运行的脑图项目 $ npm init -y # 安装express $ npm install --save express # 建立node服务器文件 $ touch server.js # 编辑server.js文件 $ vim server.js # ......编辑中...... # server.js文件内容看下面 # 编辑完成 # 执行server.js脚本,开启web服务器 $ node server.js # 在浏览器中打开项目:localhost:3000
server.js
文件内容html
var express = require('express'); var app = express(); // 定义本地服务器的端口 var port = 3000; // 设置dist目录为静态文件目录 app.use(express.static('./dist')); app.listen(port, function(){ console.log('本地服务器运行在:localhost:' + port); });
按道理说,该项目编译完成了,本地服务器也启动了,打开浏览器就可以使用了,就像在百度脑图网站上同样,各类功能齐全的。实际上在运行过程当中还会有一些问题。前端
getTransformToElement
的问题localhost:3000
:因为该项目是须要申请百度的Access Token
,本地部署会出现验证问题java
破解node
将dist
目录下的index.html
文件中的第56行开始的点击事件修改成以下:nginx
$('p.login a').click(function() { window.location.href = './edit.html'; // var urlparts = window.location.href.split('/'); // urlparts.pop(); // urlparts = urlparts.join('/'); // fio.user.login({ // redirectUrl: urlparts + '/edit.html', // remember: 7 * 24 * 60 * 60 // }); // loadingAnimate(true); });
这时,页面会跳转到edit.html
页面,可是控制台会报错git
此错误造成的缘由就是由于chrome
浏览器移除了一个SVG
的非标准API——getTransformToElement
github
解决问题web
在dist
目录下的edit.html
文件中, 在<script src="kityminder.edit.min.js?_=1539324364692" charset="utf-8"></script>
的下一行,加上如下几行代码:
这几行代码是为在SVGElement
的原型上添加被chrome
移除的API——getTransformToElement
,添加后,控制台就不会报错了
<script type="text/javascript"> SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(toElement) { return toElement.getScreenCTM().inverse().multiply(this.getScreenCTM()); }; </script>
破解
在<script src="kityminder.edit.min.js?_=1539324364692" charset="utf-8"></script>
的下一行,接着加上如下几行代码:
<script type="text/javascript"> fio.user.login = Function.prototype; </script>
刷新页面,就不会出现问题。
先后一共修改了两个文件:index.html
和edit.html
最终index.html
文件内容以下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="title" content="百度脑图(KityMinder) - 控制创意,如此简单"> <meta name="keyword" content="kityminder,脑图,思惟导图,kity,svg,minder,百度,fex,前端,在线"> <meta name="description" content="百度脑图,便捷的脑图编辑工具 - 控制创意,如此简单。让您在线上直接建立、保存并分享你的思路。免安装 云存储 易分享 体验温馨 功能丰富"> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <title>百度脑图 - 便捷的思惟编辑工具</title> <script src="kityminder.index.min.js?_=1539324364692"></script> <script> $(function() { var pattern = /(?:shareId|share_id)=(\w+)([&#]|$)/; var match = pattern.exec(window.location) || pattern.exec(document.referrer); if (match) { window.location.href = 'viewshare.html?shareId=' + match[1]; return; } /* 初始化网盘使用的 APP 身份 */ fio.user.init({ apiKey: 'wiE55BGOG8BkGnpPs6UNtPbb' }); var $a = $('p.login a').hide(); function loadingAnimate(on) { if (on) { $('hr').addClass('loading'); loadingAnimate.timer = setTimeout(function() { $('hr').addClass('animated'); }, 660); } else { clearTimeout(loadingAnimate.timer); $('hr').removeClass('loading animated'); } } loadingAnimate(true); fio.user.check().then(function(user) { if (user) { window.location.href = 'edit.html'; } else { $a.fadeIn(800); loadingAnimate(false); } }); $('p.login a').click(function() { window.location.href = './edit.html'; // var urlparts = window.location.href.split('/'); // urlparts.pop(); // urlparts = urlparts.join('/'); // fio.user.login({ // redirectUrl: urlparts + '/edit.html', // remember: 7 * 24 * 60 * 60 // }); // loadingAnimate(true); }); function preload(url) { return new Promise(function(resolve, reject) { var img = new Image(); img.onload = resolve; img.onerror = reject; img.src = url; }); } preload('ui/theme/default/images/indexbackground.jpg').then(function() { $('div.background').addClass('loaded'); }); }); </script> <link href="favicon.ico" type="image/x-icon" rel="shortcut icon"> <link href="favicon.ico" type="image/x-icon" rel="apple-touch-icon-precomposed"> <style> body, html { margin: 0; padding: 0; overflow: hidden; height: 100%; font-size: 0; line-height: 0; z-index: -2; } body { background: #99806B; overflow: auto; } ::-webkit-selection { background: #FFEFEF; color: #4A4F5D; } ::-moz-selection { background: #FFEFEF; color: #4A4F5D; } ::-ms-selection { background: #FFEFEF; color: #4A4F5D; } ::selection { background: #FFEFEF; color: #4A4F5D; } div.background { opacity: 0; display: block; background: url(ui/theme/default/images/indexbackground.jpg) no-repeat; background-size: cover; position: absolute; z-index: -1; left: -10px; top: -10px; right: -10px; bottom: -10px; -webkit-filter: blur(5px); -moz-filter: blur(5px); -mz-filter: blur(5px); -o-filter: blur(5px); filter: url(ui/theme/default/images/blur.svg#blur); filter: blur(5px); -webkit-transition: opacity 1.5s ease; transition: opacity 1.5s ease; } div.background.loaded { opacity: 1; } h1:before { content: ' '; display: block; position: absolute; top: 0; bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, .5); z-index: -1; } h1, p { font-weight: 100; font-family: Arial, "Microsoft Yahei", "Heiti SC", sans-serif; text-align: center; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } h1 { margin: 0; margin-top: 100px; color: white; font-size: 50px; line-height: 1.4em; } h1 span { font-size: 0.6em; } p span { font-size: 12px; display: block; margin-top: 30px; color: rgba(255, 255, 255, .7); text-shadow: 0 0 1px rgba(0, 0, 0, .5); } hr { height: 0; border: none; border-bottom: 1px solid #F98183; width: 110px; margin: 40px auto; -webkit-transition: -webkit-transform 0.66s ease; transition: transform 0.66s ease; -webkit-backface-visibility: hidden; } hr.loading { -webkit-transform: translate3d(100px, 0, 0); transform: translate3d(100px, 0, 0); } hr.animated { -webkit-animation: slide 1.33s ease-in-out infinite alternate; animation: slide 1.33s ease-in-out infinite alternate; } @-webkit-keyframes slide { 0% { -webkit-transform: translate3d(100px, 0, 0); transform: translate3d(100px, 0, 0); } 100% { -webkit-transform: translate3d(-100px, 0, 0); transform: translate3d(-100px, 0, 0); } } @keyframes slide { 0% { -webkit-transform: translate3d(100px, 0, 0); transform: translate3d(100px, 0, 0); } 100% { -webkit-transform: translate3d(-100px, 0, 0); transform: translate3d(-100px, 0, 0); } } p.description { color: #CCC; font-size: 20px; line-height: 1.8em; } p.login a { display: inline-block; width: 200px; height: 60px; background: #F98183; font-size: 24px; line-height: 60px; text-align: center; border-radius: 30px; color: white; text-shadow: 0 1px 0 #F8474F; cursor: pointer; position: relative; overflow: hidden; margin-top: 50px; -webkit-user-select: none; -moz-user-select: none; -mz-user-select: none; user-select: none; } p.login a:active { background: #FF6161; -webkit-transform: scale(0.95); transform: scale(0.95); } p.login a:before { content: ' '; display: block; background: rgba(255, 255, 255, .2); position: absolute; left: 0; top: 0; right: 0; bottom: 0; border-radius: 30px; transform: scale(0, 1); -webkit-transform: scale(0, 1); transition: transform 0.3s ease; -webkit-transition: -webkit-transform 0.3s ease; } p.login a:hover:before { transform: scale(1, 1); -webkit-transform: scale(1, 1); } </style> </head> <body> <div class="background"></div> <h1>百度脑图 <br/> <span>控制创意,如此简单</span></h1> <hr /> <p class="description"> 免安装 云存储 易分享<br/> 温馨的体验 丰富的功能<br/> </p> <p class="login"> <a>立刻开启</a> <span>使用百度帐号登陆</span> </p> </body> <!--Baidu Tongji Code--> <script type="text/javascript"> if (document.domain == 'naotu.baidu.com') { var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://"); document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F0703917f224067c887f3664479a03887' type='text/javascript'%3E%3C/script%3E")); } </script> </html>
最终edit.html
文件内容以下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="title" content="百度脑图(KityMinder)"> <meta name="keyword" content="kityminder,脑图,思惟导图,kity,svg,minder,百度,fex,前端,在线"> <meta name="description" content="百度脑图,便捷的脑图编辑工具。让您在线上直接建立、保存并分享你的思路。"> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <title>百度脑图 - 便捷的思惟编辑工具</title> <script src="kityminder.edit.min.js?_=1539324364692" charset="utf-8"></script> <script type="text/javascript"> SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(toElement) { return toElement.getScreenCTM().inverse().multiply(this.getScreenCTM()); }; fio.user.login = Function.prototype; </script> <script src="kityminder.config.js?_=1539324364692" charset="utf-8"></script> <script src="lang/zh-cn/zh-cn.js?_=1539324364692" charset="utf-8"></script> <link href="ui/theme/default/css/default.all.css?_=1539324364692" type="text/css" rel="stylesheet" /> <link href="favicon.ico" type="image/x-icon" rel="shortcut icon"> <link href="favicon.ico" type="image/x-icon" rel="apple-touch-icon-precomposed"> </head> <body> <div id="content-wrapper"> <div id="panel"></div> <div id="kityminder" onselectstart="return false"> </div> </div> </body> <!--脑图启动代码--> <script> /* global km:true, ZeroClipboard:true, zip:true */ /* jshint browser:true */ $(function() { /* 依赖库初始化 */ zip.inflateJSPath = 'lib/inflate.js'; }); // create km instance km = KM.getMinder('kityminder', window.KITYMINDER_CONFIG); // init ui for instance km.initUI(); // New Version Notify $(function() { var lastVersion = localStorage.lastKMVersion; $('#km-version').text( 'v' + KM.version ); if (lastVersion != KM.version) { $( '#km-version' ).addClass( 'new-version' ); localStorage.lastKMVersion = KM.version; } }); </script> <!--社会分享代码--> <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdMini":"2","bdMiniList":[],"bdPic":"","bdStyle":"1","bdSize":"32"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)]; </script> <!--Baidu Tongji Code--> <script type="text/javascript"> if (document.domain == 'naotu.baidu.com') { var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://"); document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F0703917f224067c887f3664479a03887' type='text/javascript'%3E%3C/script%3E")); } </script> </html>
Firefox
并无移除SVG的非标准API,若是不想解决兼容问题,直接使用Firefox
浏览器打开就行了node.getTransformToElement(SVGElement)
,该方法返回一个SVGMatrix
对象,表明当前元素坐标到指定元素坐标之间的转换。微信公众号:撩码