PyQt/浏览器/QWebView/梦幻树/tree.html
2018-10-28 00:24:47 +08:00

257 lines
No EOL
11 KiB
HTML

<!DOCTYPE html><html slick-uniqueid="1">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>
梦幻树-PlasmaTree
</title>
<meta name="author" content="mhepekka">
<meta name="robots" content="index,follow">
<meta name="copyright" content="Copyright 2010 mhepekka">
<style type="text/css">
.footer{pointer-events: none;position:absolute;bottom:0;width:100%;height:50px;background-color: rgba(255,255,255,0.5);}
</style>
<script src="qrc:/jquery.js"></script>
<script type="text/javascript">
(function($) {
var Vector = function(x, y) {
this.x = x || 0;
this.y = y || 0;
};
Vector.prototype = {
add: function(v) {
this.x += v.x;
this.y += v.y;
return this;
},
length: function() {
return Math.sqrt(this.x * this.x + this.y * this.y);
},
rotate: function(theta) {
var x = this.x;
var y = this.y;
this.x = Math.cos(theta) * this.x - Math.sin(theta) * this.y;
this.y = Math.sin(theta) * this.x + Math.cos(theta) * this.y;
//this.x = Math.cos(theta) * x - Math.sin(theta) * y;
//this.y = Math.sin(theta) * x + Math.cos(theta) * y;
return this;
},
mult: function(f) {
this.x *= f;
this.y *= f;
return this;
}
};
var Leaf = function(p, r, c, ctx) {
this.p = p || null;
this.r = r || 0;
this.c = c || 'rgba(255,255,255,1.0)';
this.ctx = ctx;
}
Leaf.prototype = {
render: function() {
var that = this;
var ctx = this.ctx;
var f = Branch.random(1, 2)
for (var i = 0; i < 5; i++) {
(function(r) {
setTimeout(function() {
ctx.beginPath();
ctx.fillStyle = that.color;
ctx.moveTo(that.p.x, that.p.y);
ctx.arc(that.p.x, that.p.y, r, 0, Branch.circle, true);
ctx.fill();
},
r * 60);
})(i);
}
}
}
var Branch = function(p, v, r, c, t) {
this.p = p || null;
this.v = v || null;
this.r = r || 0;
this.length = 0;
this.generation = 1;
this.tree = t || null;
this.color = c || 'rgba(255,255,255,1.0)';
this.register();
};
Branch.prototype = {
register: function() {
this.tree.addBranch(this);
},
draw: function() {
var ctx = this.tree.ctx;
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.moveTo(this.p.x, this.p.y);
ctx.arc(this.p.x, this.p.y, this.r, 0, Branch.circle, true);
ctx.fill();
},
modify: function() {
var angle = 0.18 - (0.10 / this.generation);
this.p.add(this.v);
this.length += this.v.length();
this.r *= 0.99;
this.v.rotate(Branch.random( - angle, angle)); //.mult(0.996);
if (this.r < 0.8 || this.generation > 10) {
this.tree.removeBranch(this);
var l = new Leaf(this.p, 10, this.color, this.tree.ctx);
l.render();
}
},
grow: function() {
this.draw();
this.modify();
this.fork();
},
fork: function() {
var p = this.length - Branch.random(100, 200); // + (this.generation * 10);
if (p > 0) {
var n = Math.round(Branch.random(1, 3));
this.tree.stat.fork += n - 1;
for (var i = 0; i < n; i++) {
Branch.clone(this);
}
this.tree.removeBranch(this);
}
}
};
Branch.circle = 2 * Math.PI;
Branch.random = function(min, max) {
return Math.random() * (max - min) + min;
};
Branch.clone = function(b) {
var r = new Branch(new Vector(b.p.x, b.p.y), new Vector(b.v.x, b.v.y), b.r, b.color, b.tree);
r.generation = b.generation + 1;
return r;
};
Branch.rgba = function(r, g, b, a) {
return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
};
Branch.randomrgba = function(min, max, a) {
return Branch.rgba(Math.round(Branch.random(min, max)), Math.round(Branch.random(min, max)), Math.round(Branch.random(min, max)), a);
};
var Tree = function() {
var branches = [];
var timer;
this.stat = {
fork: 0,
length: 0
};
this.addBranch = function(b) {
branches.push(b);
};
this.removeBranch = function(b) {
for (var i = 0; i < branches.length; i++) {
if (branches[i] === b) {
branches.splice(i, 1);
return;
}
}
};
this.render = function(fn) {
var that = this;
timer = setInterval(function() {
fn.apply(that, arguments);
if (branches.length > 0) {
for (var i = 0; i < branches.length; i++) {
branches[i].grow();
}
}
else {
//clearInterval(timer);
}
},
1000 / 30);
};
this.init = function(ctx) {
this.ctx = ctx;
};
this.abort = function() {
branches = [];
this.stat = {
fork: 0,
length: 0
}
};
};
function init() {
// init
var $window = $(window);
var $body = $("body");
var canvas_width = $window.width();
var canvas_height = $window.height() - 0;
var center_x = canvas_width / 2;
var stretch_factor = 600 / canvas_height;
var y_speed = 3 / stretch_factor;
var $statMsg = $("#statMsg");
// tx
var canvas = $('#canvas')[0];
canvas.width = canvas_width;
canvas.height = canvas_height;
var ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = "lighter";
// tree
var t = new Tree();
t.init(ctx);
for (var i = 0; i < 3; i++) {
new Branch(new Vector(center_x, canvas_height), new Vector(Math.random( - 1, 1), -y_speed), 15 / stretch_factor, Branch.randomrgba(0, 255, 0.3), t);
}
t.render(function() {
$statMsg.html(this.stat.fork);
});
// events
$("#drawArea").click(function(e) {
//e.preventDefault();
var x, y;
x = e.pageX - this.offsetLeft;
y = e.pageY - this.offsetTop;
new Branch(new Vector(x, canvas_height), new Vector(0, -y_speed), 15 / stretch_factor, Branch.randomrgba(0, 255, 0.3), t);
});
$("#btnClear").click(function(e) {
e.stopPropagation();
t.abort();
ctx.clearRect(0, 0, canvas_width, canvas_height);
$statMsg.html("0");
});
$("#btnReload").click(function(e) {
e.stopPropagation();
window.location.reload();
});
$("#btnNewExperiment").click(function(e) {
window.location = "http://alyl.vip";
});
}
$(function() {
init();
});
})(jQuery);
</script>
</head>
<body huaban_screen_capture_injected="true" style="">
<div id="drawArea">
<div id="buttonArea">
</div>
<canvas id="canvas" width="1642" height="593">
</canvas>
</div>
<div class="footer"><center>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</center></div>
<script charset="utf-8">
(function(w, d, g, J) {
var e = J.stringify || J.encode;
d[g] = d[g] || {};
d[g]['showValidImages'] = d[g]['showValidImages'] ||
function() {
w.postMessage(e({
'msg': {
'g': g,
'm': 's'
}
}), location.href);
}
})(window, document, '__huaban', JSON);
</script>
</body>
</html>