fullstack.web/swa/cross-nav/index.html

406 lines
12 KiB
HTML
Raw Normal View History

2022-12-22 06:57:51 +00:00
<!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">&#xe622;</span>添加</button>
<button onclick="clearObjs()" type="button" class="btn btn-danger"><span class="iconfont">&#xe66c;</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>
2023-08-09 05:57:49 +00:00
<div class="dropdown" style="display: inline-block">
<button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">
选色 <div id="color" style="display: inline-block; width: 0.8rem; height: 0.8rem; background: red">
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#" onclick="setColor(0xFF0000)"><div style="display: inline-block; width: 20px; height: 0.8rem; background: red"></div></a>
<a class="dropdown-item" href="#" onclick="setColor(0xFFBB00)"><div style="display: inline-block; width: 20px; height: 0.8rem; background: orange"></div></a>
<a class="dropdown-item" href="#" onclick="setColor(0x009FCC)"><div style="display: inline-block; width: 20px; height: 0.8rem; background: blue"></div></a>
<a class="dropdown-item" href="#" onclick="setColor(0x00FF00)">绿 <div style="display: inline-block; width: 20px; height: 0.8rem; background: green"></div></a>
</div>
</div>
2022-12-22 06:57:51 +00:00
<div class="btn-group" role="group">
<button onclick="imports()" type="button" class="btn btn-primary"><span class="iconfont">&#xe608;</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">&#xe8c6;</span>导出</button>
</div>
</div>
<div id="canvas" style="margin-top: 5rem;">
</div>
</div>
<!-- 图片 exif 操作 -->
<script src="./exif.js"></script>
<!-- 选项 1jQuery 和 Bootstrap 集成包(集成了 Popper -->
<script src="./jquery.slim.min.js" crossorigin="anonymous"></script>
<script src="./bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<!-- 动画库 -->
2023-08-09 05:57:49 +00:00
<script src="./pixi.min.js"></script>
<script src="./PIXI.TextInput.min.js"></script>
2022-12-22 06:57:51 +00:00
2023-08-09 05:57:49 +00:00
<script src="./png.bundle.js"></script>
2022-12-22 06:57:51 +00:00
<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">
2023-08-09 05:57:49 +00:00
function setColor( c ){
color = c;
var hex = c.toString(16);
if( hex.length < 6 ) {
hex = "000000" + hex
hex = hex.substr( hex.length -6 );
}
$("#color").css({ background : "#" + hex })
}
var color = 0xFF0000 ;
2022-12-22 06:57:51 +00:00
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 objs = new PIXI.Container();
app.stage.addChild(objs);
2023-08-09 05:57:49 +00:00
function newObj(x, y, name, c){
var objStyle = new PIXI.TextStyle({
fontFamily: "Arial",
fontSize: 18,
fill: c || color,
});
2022-12-22 06:57:51 +00:00
var obj = new PIXI.Container();
obj.backgroundColor = 0x1099bb;
obj.x = x;
obj.y = y;
objs.addChild(obj);
// point
var circle = new PIXI.Graphics();
2023-08-09 05:57:49 +00:00
circle.beginFill( c || color );
circle.drawCircle( 0, 0, 5 );
2022-12-22 06:57:51 +00:00
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);
2023-08-09 05:57:49 +00:00
input.placeholder = '输入...'
2022-12-22 06:57:51 +00:00
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()
})
2023-08-09 05:57:49 +00:00
2022-12-22 06:57:51 +00:00
function endEdit(){
input.visible = false
message.visible = true
2023-08-09 05:57:49 +00:00
2022-12-22 06:57:51 +00:00
if ( input.text ) {
message.text = input.text
} else {
2023-08-09 05:57:49 +00:00
objs.removeChild(obj);
2022-12-22 06:57:51 +00:00
}
}
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){
2023-08-09 05:57:49 +00:00
newObj(a.x, a.y, a.text, a.color)
2022-12-22 06:57:51 +00:00
})
}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) {
2023-08-09 05:57:49 +00:00
var t = c.getChildByName('message')
2022-12-22 06:57:51 +00:00
info.push({
x : c.x,
y : c.y,
2023-08-09 05:57:49 +00:00
text : t.text,
color : t.style.fill
2022-12-22 06:57:51 +00:00
})
}
img = png.en( img, {
"crossnav" : JSON.stringify( info )
})
a.href = img; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
}
</script>
</body>
</html>