373 lines
10 KiB
HTML
373 lines
10 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||
|
||
<!-- Bootstrap 的 CSS 文件 -->
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" crossorigin="anonymous">
|
||
|
||
<title>十字导航</title>
|
||
|
||
<style type="text/css">
|
||
*{
|
||
moz-user-select: -moz-none;
|
||
-moz-user-select: none;
|
||
-o-user-select:none;
|
||
-khtml-user-select:none;
|
||
-webkit-user-select:none;
|
||
-ms-user-select:none;
|
||
user-select:none;
|
||
}
|
||
|
||
@font-face {
|
||
font-family: 'iconfont'; /* Project id 3145309 */
|
||
src: url('//at.alicdn.com/t/font_3145309_gmztz69c7.woff2?t=1642386884581') format('woff2'),
|
||
url('//at.alicdn.com/t/font_3145309_gmztz69c7.woff?t=1642386884581') format('woff'),
|
||
url('//at.alicdn.com/t/font_3145309_gmztz69c7.ttf?t=1642386884581') format('truetype');
|
||
}
|
||
|
||
.iconfont {
|
||
font-family: "iconfont" !important;
|
||
font-size: 16px;
|
||
font-style: normal;
|
||
-webkit-font-smoothing: antialiased;
|
||
-moz-osx-font-smoothing: grayscale;
|
||
}
|
||
|
||
#canvas canvas {
|
||
border: 1px dotted black
|
||
}
|
||
|
||
.tooltip-inner{
|
||
max-width: 400px !important;
|
||
text-align: justify;
|
||
}
|
||
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
|
||
<div class="container" style="text-align: center">
|
||
|
||
<div class="head" style="position: absolute; top: 2rem; right: 2rem">
|
||
<div class="btn-group" role="group">
|
||
<button onclick="addObj()" type="button" class="btn btn-primary"><span class="iconfont"></span>添加</button>
|
||
<button onclick="clearObjs()" type="button" class="btn btn-danger"><span class="iconfont"></span>清空</button>
|
||
</div>
|
||
|
||
<button type="button" class="btn btn-info" data-toggle="tooltip" data-placement="bottom" data-html="true"
|
||
title="</br><ol><li>点击【添加】画板中会添加一个默认事件</li><li>右键事件可以修改</li><li>将事件修改为空会完全删除事件</li><li>刷新页面会丢失所有数据</li></ol>">帮助</button>
|
||
|
||
<div class="btn-group" role="group">
|
||
<button onclick="imports()" type="button" class="btn btn-primary"><span class="iconfont"></span>导入
|
||
<input style="display: none" type="file" accept=".crossnav.png" class="custom-file-input" id="custom-file-input">
|
||
</button>
|
||
<button onclick="outports()" type="button" class="btn btn-primary"><span class="iconfont"></span>导出</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="canvas" style="margin-top: 5rem;">
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- 图片 exif 操作 -->
|
||
<script src="./exif.js"></script>
|
||
|
||
<!-- 选项 1:jQuery 和 Bootstrap 集成包(集成了 Popper) -->
|
||
<script src="./jquery.slim.min.js" crossorigin="anonymous"></script>
|
||
<script src="./bootstrap.bundle.min.js" crossorigin="anonymous"></script>
|
||
|
||
<!-- 动画库 -->
|
||
<script src="../../js/pixi.min.js"></script>
|
||
<script src="../../js/PIXI.TextInput.min.js"></script>
|
||
|
||
<script src="../../js/png.bundle.js"></script>
|
||
|
||
<script type="application/javascript">
|
||
document.oncontextmenu = function(e){
|
||
return false;
|
||
}
|
||
|
||
function newDelta(){
|
||
return 50 * (Math.random() - 0.5)
|
||
}
|
||
|
||
$(function () {
|
||
$('[data-toggle="tooltip"]').tooltip()
|
||
})
|
||
|
||
</script>
|
||
<script type="application/javascript">
|
||
var border = 20;
|
||
var size = 512 + 2 * border; // 10 的边框
|
||
//Create a Pixi Application
|
||
var app = new PIXI.Application({width: size, height: size});
|
||
//Add the canvas that Pixi automatically created for you to the HTML document
|
||
document.getElementById("canvas").appendChild(app.view);
|
||
|
||
var bg = new PIXI.Container();
|
||
bg.x = 0;
|
||
bg.y = 0;
|
||
app.stage.addChild(bg);
|
||
|
||
var rectangle = new PIXI.Graphics();
|
||
rectangle.beginFill(0xFFFFFF);
|
||
rectangle.drawRect(0, 0, app.renderer.view.width, app.renderer.view.height);
|
||
rectangle.endFill();
|
||
bg.addChild( rectangle )
|
||
|
||
var xyStyle = new PIXI.TextStyle({
|
||
fontFamily: "Arial",
|
||
fontSize: 18,
|
||
fill: "blank"
|
||
});
|
||
|
||
{
|
||
// x 轴
|
||
var lineX = new PIXI.Graphics();
|
||
lineX.lineStyle(2, 0x000000, 1);
|
||
lineX.moveTo( border, size /2);
|
||
lineX.lineTo( size - border, size /2);
|
||
bg.addChild(lineX);
|
||
|
||
// x 轴方向
|
||
var triangle = new PIXI.Graphics();
|
||
var baseX = size - border;
|
||
var baseY = size /2;
|
||
triangle.beginFill(0x000000);
|
||
//Use `drawPolygon` to define the triangle as
|
||
//a path array of x/y positions
|
||
triangle.drawPolygon([
|
||
baseX , baseY + 5, //First point
|
||
baseX , baseY - 5, //Second point
|
||
baseX + 8, baseY + 0 //Third point
|
||
]);
|
||
//Fill shape's color
|
||
triangle.endFill();
|
||
bg.addChild(triangle);
|
||
|
||
|
||
var message = new PIXI.Text("紧急", xyStyle);
|
||
message.position.set(baseX - 30 , baseY + 10 );
|
||
bg.addChild(message);
|
||
}
|
||
|
||
{
|
||
// y 轴
|
||
var lineX = new PIXI.Graphics();
|
||
lineX.lineStyle(2, 0x000000, 1);
|
||
lineX.moveTo( size /2, border );
|
||
lineX.lineTo( size /2 , size - border);
|
||
bg.addChild(lineX);
|
||
|
||
// x 轴方向
|
||
var triangle = new PIXI.Graphics();
|
||
var baseX = size / 2;
|
||
var baseY = border;
|
||
triangle.beginFill(0x000000);
|
||
//Use `drawPolygon` to define the triangle as
|
||
//a path array of x/y positions
|
||
triangle.drawPolygon([
|
||
baseX + 5, baseY , //First point
|
||
baseX - 5, baseY , //Second point
|
||
baseX, baseY - 8 //Third point
|
||
]);
|
||
//Fill shape's color
|
||
triangle.endFill();
|
||
bg.addChild(triangle);
|
||
|
||
var message = new PIXI.Text("重要", xyStyle);
|
||
message.position.set(baseX - 40 , baseY );
|
||
bg.addChild(message);
|
||
}
|
||
|
||
var objStyle = new PIXI.TextStyle({
|
||
fontFamily: "Arial",
|
||
fontSize: 18,
|
||
fill: 0x9966FF,
|
||
|
||
});
|
||
|
||
var objs = new PIXI.Container();
|
||
app.stage.addChild(objs);
|
||
|
||
function newObj(x, y, name){
|
||
|
||
var obj = new PIXI.Container();
|
||
obj.backgroundColor = 0x1099bb;
|
||
obj.x = x;
|
||
obj.y = y;
|
||
objs.addChild(obj);
|
||
|
||
// point
|
||
var circle = new PIXI.Graphics();
|
||
circle.beginFill(0x9966FF);
|
||
circle.drawCircle(0, 0, 5);
|
||
circle.endFill();
|
||
circle.position.set(0 , 0 );
|
||
obj.addChild(circle);
|
||
|
||
var message = new PIXI.Text(name, objStyle);
|
||
message.position.set( 8 , - 10);
|
||
message.name = 'message'
|
||
obj.addChild(message);
|
||
|
||
var input = new PIXI.TextInput({
|
||
input: objStyle,
|
||
box: {
|
||
default: {fill: 0xE8E9F3, rounded: 12, stroke: {color: 0xCBCEE0, width: 3}},
|
||
focused: {fill: 0xE1E3EE, rounded: 12, stroke: {color: 0xABAFC6, width: 3}},
|
||
disabled: {fill: 0xDBDBDB, rounded: 12}
|
||
}
|
||
})
|
||
input.position.set(0 + 8 , 0 - 10);
|
||
input.placeholder = 'Enter your Text...'
|
||
input.visible = false
|
||
input.maxLength = 20
|
||
input.on('keydown', function (keycode) {
|
||
console.log('key pressed:', keycode)
|
||
if ( 13 === keycode ) {
|
||
endEdit()
|
||
}
|
||
})
|
||
input.on('blur', function () {
|
||
console.log( "blur" )
|
||
endEdit()
|
||
})
|
||
function endEdit(){
|
||
input.visible = false
|
||
message.visible = true
|
||
if ( input.text ) {
|
||
message.text = input.text
|
||
} else {
|
||
app.stage.removeChild(obj);
|
||
}
|
||
}
|
||
|
||
obj.addChild(input);
|
||
|
||
// 实现头像拖动
|
||
obj.interactive = true; //设置为可交互的
|
||
|
||
obj
|
||
.on('touchstart', onDragStart)
|
||
.on('touchend', onDragEnd)
|
||
.on('touchmove', onDragMove)
|
||
.on('mousedown', onDragStart )
|
||
.on('mouseup', onDragEnd)
|
||
.on('mouseupoutside', onDragEnd)
|
||
.on('mousemove', onDragMove)
|
||
.on("rightclick", function (event) {
|
||
input.visible = true
|
||
message.visible = false
|
||
input.placeholder = "输入事件名称,回车确认,为空则删除整个事件。"
|
||
input.text = message.text
|
||
input.focus();
|
||
})
|
||
|
||
|
||
|
||
function onDragStart(event) {
|
||
this.data = event.data;
|
||
this.alpha = 0.5;
|
||
this.dragging = true;
|
||
}
|
||
|
||
function onDragEnd() {
|
||
this.alpha = 1;
|
||
this.dragging = false;
|
||
this.data = null;
|
||
}
|
||
|
||
function onDragMove(event) {
|
||
if (this.dragging) {
|
||
this.position = this.data.getLocalPosition(this.parent);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
</script>
|
||
|
||
|
||
<script type="application/javascript">
|
||
|
||
function addObj(){
|
||
var x = size /4 + newDelta()
|
||
var y = size /4 + newDelta()
|
||
newObj(x, y, "新建事件")
|
||
}
|
||
|
||
function clearObjs(){
|
||
objs.removeChildren()
|
||
}
|
||
|
||
function imports(){
|
||
var oFlieImg = document.getElementById("custom-file-input");
|
||
oFlieImg.onchange = function(e){
|
||
var _self = e.currentTarget;
|
||
var oSelfFile = _self.files[0]; //获取文件
|
||
|
||
// console.log(oSelfFile.name.lastIndexOf('.'));
|
||
// 如果要限制文件类型的话这里可以判定oSelfFile.name‘.’最后一次出现的位置之后的单词是否为想要的类型
|
||
// 或者判断oSelfFile.type
|
||
// 判断文件大小为size单位为字节
|
||
var oReader = new FileReader();
|
||
oReader.readAsDataURL(oSelfFile); // 读取文件
|
||
// 加载文件
|
||
oReader.onload = function(ev){
|
||
// 获取到FileReader读取文件的base64
|
||
var oImgBase64 = ev.currentTarget.result;
|
||
// console.log(oImgBase64)
|
||
|
||
var meta = png.de( oImgBase64 );
|
||
try {
|
||
var json = meta.crossnav
|
||
json = JSON.parse( json )
|
||
json.map(function (a){
|
||
newObj(a.x, a.y, a.text)
|
||
})
|
||
|
||
}catch ( e ) {
|
||
alert("导入错误 " + e)
|
||
}
|
||
}
|
||
}
|
||
|
||
oFlieImg.click();
|
||
}
|
||
|
||
function outports(){
|
||
var img = app.renderer.plugins.extract.base64(app.stage);
|
||
let a = document.createElement("a"); // 生成一个a元素
|
||
let event = new MouseEvent("click"); // 创建一个单击事件
|
||
a.download = (new Date()).toLocaleString() + ".crossnav.png"
|
||
|
||
|
||
let info = []
|
||
for (let c of objs.children) {
|
||
info.push({
|
||
x : c.x,
|
||
y : c.y,
|
||
text : c.getChildByName('message').text
|
||
})
|
||
}
|
||
|
||
img = png.en( img, {
|
||
"crossnav" : JSON.stringify( info )
|
||
})
|
||
|
||
a.href = img; // 将生成的URL设置为a.href属性
|
||
a.dispatchEvent(event); // 触发a的单击事件
|
||
}
|
||
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|