123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332 |
- // 发布订阅,事件模型
- var Event = (function () {
- var _default = 'default';
- var _shift = Array.prototype.shift;
- var _unshift = Array.prototype.unshift;
- function createEvent() {
- var namespaceCache = {}
- function _listen(cache, key, fn) {
- if (cache[key]) {
- cache[key].push(fn)
- } else {
- cache[key] = [fn]
- }
- }
- function _trigger() {
- var args = arguments
- return new Promise(function (resolve) {
- setTimeout(function () {
- var cache = _shift.call(args);
- var key = _shift.call(args);
- var stack = cache[key]
- if (!stack || stack.length === 0) return;
- stack.forEach(function (fn) {
- fn.apply(this, args)
- })
- resolve(stack);
- }, 100)
- })
- }
- function _remove(cache, key, fn) {
- var stack = cache[key]
- if (!stack || stack.length === 0) return
- if (fn) {
- for (var i = stack.length; i >= 0; i--) {
- if (stack[i] === fn) {
- stack.splice(i, 1)
- }
- }
- } else {
- stack.length = 0
- }
- }
- function _create(namespace) {
- namespace = namespace || _default
- if (namespaceCache[namespace]) {
- return namespaceCache[namespace]
- }
- var cache = {}
- var ret = {
- listen: function (key, fn) {
- _listen(cache, key, fn)
- },
- once: function (key, fn) {
- fn.__once = true
- _listen(cache, key, fn)
- },
- remove: function (key, fn) {
- _remove(cache, key, fn)
- },
- trigger: function () {
- _unshift.call(arguments, cache)
- _trigger.apply(this, arguments).then(function (stack) {
- if (stack) {
- for (var i = stack.length; i >= 0; i--) {
- if (stack[i] && stack[i].__once) {
- stack.splice(i, 1)
- }
- }
- }
- })
- }
- }
- namespaceCache[namespace] = ret;
- return ret
- }
- return {
- create: _create,
- once: function () {
- this.create().once.apply(this, arguments)
- },
- listen: function () {
- this.create().listen.apply(this, arguments)
- },
- remove: function () {
- this.create().remove.apply(this, arguments)
- },
- trigger: function () {
- this.create().trigger.apply(this, arguments)
- }
- }
- }
- return createEvent()
- })();
- var grendCAD = (function grentWall() {
- var util = {
- /**
- * 计算直线向量
- * @param {*} line
- */
- lineVector(line) {
- var cpoint = {
- x: line.points[1].x - line.points[0].x,
- y: line.points[1].y - line.points[0].y
- }
- var xd = Math.abs(Math.floor(cpoint.x / 1))
- var yd = Math.abs(Math.floor(cpoint.y / 1))
- var js = xd > yd ? xd : yd
- var verctor = {
- x: cpoint.x / js,
- y: cpoint.y / js,
- }
- return verctor
- },
- /**
- * 计算直线与X轴夹角
- * @param {*} line1
- */
- lineAngle(line1) {
- var height = line1[0].y - line1[1].y,
- width = line1[0].x - line1[1].x;
- if (width == 0) {
- // 如果和y轴平行,角度为90或270
- return line1[0].y >= line1[1].y ? 90 : 270;
- } else {
- var tan = Math.atan(height / width),
- angle = tan * 180 / Math.PI;
- return tan > 0 ? (line1[0].x > line1[1].x ? angle : angle + 180) : (line1[0].x > line1[1].x ? angle + 360 : angle + 180);
- }
- },
- /**
- * 计算直线的长度
- * @param {*} line
- */
- lineDistance(line) {
- return Math.sqrt(Math.pow(line[0].x - line[1].x, 2) + Math.pow(line[0].y - line[1].y, 2))
- },
- isInfinity(num) {
- return num === Infinity || num === -Infinity
- },
- /**
- * 获取一组坐标的XY坐标区间
- * @param {*} points
- */
- getSection(points) {
- var ret = {
- minx: points[0].x,
- maxx: points[0].x,
- miny: points[0].y,
- maxy: points[0].y
- }
- points.forEach(function (point) {
- if (ret.minx > point.x) {
- ret.minx = point.x
- }
- if (ret.maxx < point.x) {
- ret.maxx = point.x
- }
- if (ret.miny > point.y) {
- ret.miny = point.y
- }
- if (ret.maxy < point.y) {
- ret.maxy = point.y
- }
- })
- return ret
- },
- /**
- * 计算垂直向量
- * @param {向量} arr
- */
- verticalLine(line) {
- var arr = [
- line.points[1].x - line.points[0].x,
- line.points[1].y - line.points[0].y
- ]
- if (arr.length !== 0) {
- var x, y;
- y = Math.sqrt(1 / ((arr[1] * arr[1]) / (arr[0] * arr[0]) + 1));
- x = Math.sqrt(1 - y * y);
- return [x, y];
- }
- return [];
- },
- /**
- * 将所有坐标转化为指定范围之间的值,但是保持比例不变
- * @param {*} points 要转化的坐标
- * @param {*} section 指定范围
- * @returns Array 转化后的值
- */
- tranProp(points, section) {
- var args = util.getSection(points)
- var xlen = args.maxx - args.minx
- var ylen = args.maxy - args.miny
- var prop = xlen > ylen ? xlen : ylen
- var offsetX = -(args.minx + xlen / 2)
- var offsetY = -(args.miny + ylen / 2)
- var range = section[1] - section[0]
- return {
- offset: {
- x: offsetX,
- y: offsetY
- },
- prop,
- range: range
- }
- },
- /**
- * 将屏幕转化为真实坐标
- * @param {*} point
- * @param {*} section
- */
- tranPoint(point, section) {
- return {
- x: point.x + section.minx,
- y: point.y + section.miny
- }
- },
- /**
- * 判断点是否在线上
- * @param {*} point 要判断的点
- * @param {*} line 线段
- * @param {*} width 线宽
- */
- isContainPoint(point, line, width) {
- var dis = 0
- var s1 = line[1].x - line[0].x
- var s2 = point.x - line[0].x
- var s3 = point.x - line[1].x
- var k1 = line[1].y - line[0].y
- var k2 = point.y - line[0].y
- var k3 = point.y - line[1].y
- var max = width / 2
- var min = 0 - max
- var cross = s1 * s2 + k1 * k2;
- var d2 = s1 * s1 + k1 * k1;
- if (cross <= 0) {
- dis = Math.sqrt(s2 * s2 + k2 * k2);
- } else if (cross >= d2) {
- dis = Math.sqrt(s3 * s3 + k3 * k3);
- } else {
- var r = cross / d2;
- var px = line[0].x + s1 * r;
- var py = line[0].y + k1 * r;
- dis = Math.sqrt((point.x - px) * (point.x - px) + (py - point.y) * (py - point.y));
- }
- return dis >= min && dis <= max
- },
- /**
- * 判断两条线段是否相交
- * @param {*} line1
- * @param {*} line2
- */
- isLineIntersect(line1, line2) {
- var a1 = line1[1].y - line1[0].y;
- var b1 = line1[0].x - line1[1].x;
- var c1 = a1 * line1[0].x + b1 * line1[0].y;
- //转换成一般式: Ax+By = C
- var a2 = line2[1].y - line2[0].y;
- var b2 = line2[0].x - line2[1].x;
- var c2 = a2 * line2[0].x + b2 * line2[0].y;
- // 计算交点
- var d = a1 * b2 - a2 * b1;
- // 当d==0时,两线平行
- if (d == 0) {
- return false;
- } else {
- var x = (b2 * c1 - b1 * c2) / d;
- var y = (a1 * c2 - a2 * c1) / d;
- // 检测交点是否在两条线段上
- if ((isInBetween(line1[0].x, x, line1[1].x) || isInBetween(line1[0].y, y, line1[1].y)) &&
- (isInBetween(line2[0].x, x, line2[1].x) || isInBetween(line2[0].y, y, line2[1].y))) {
- return true;
- }
- }
- function isInBetween(a, b, c) {
- // 如果b几乎等于a或c,返回false.为了避免浮点运行时两值几乎相等,但存在相差0.00000...0001的这种情况出现使用下面方式进行避免
- if (Math.abs(a - b) < 0.000001 || Math.abs(b - c) < 0.000001) {
- return false;
- }
- return (a <= b && b <= c) || (c <= b && b <= a);
- }
- return false;
- },
- /**
- * 判断两个点是否相同
- * @param {*} point1
- * @param {*} poin2
- */
- equalPoint(point1, poin2) {
- return point1.x === poin2.x && point1.y === poin2.y
- },
- /**
- * 判断两个面是否相交,
- * @param {*} face1
- * @param {*} face2
- */
- isFaceIntersect(face1, face2) {
- for (var i = 0; i < face1.length; i++) {
- var next = i + 1 === face1.length ? 0 : i + 1
- var line1 = [face1[i], face1[next]]
- for (var j = 0; j < face2.length; j++) {
- var next = j + 1 === face2.length ? 0 : j + 1
- var line2 = [face2[j], face2[next]]
- var isIntersect1 = util.isLineIntersect(line2, line1)
- var isIntersect2 = util.isLineIntersect(line1, line2)
- if (isIntersect1 && isIntersect2) {
- return true
- }
- }
- }
- },
- /**
- * 判断一个点是否在面上
- * @param {*} face1
- * @param {*} face2
- */
- pointInside(point, face) {
- var inside = false;
- var x = point.x,
- y = point.y;
- for (var i = 0, j = face.length - 1; i < face.length; j = i++) {
- var xi = face[i].x,
- yi = face[i].y;
- var xj = face[j].x,
- yj = face[j].y;
- if (((yi > y) != (yj > y)) &&
- (x < (xj - xi) * (y - yi) / (yj - yi) + xi)) {
- inside = !inside;
- }
- }
- return inside;
- }
- }
- /**
- * 获取一个元素在指定父元素或文档中的位置
- */
- function getPosition(dom, parent) {
- var ret = {
- x: 0,
- y: 0
- }
- while (dom && dom !== parent && dom !== document.documentElement) {
- ret.x += dom.offsetLeft
- ret.y += dom.offsetTop
- dom = dom.offsetParent
- }
- return ret
- }
- /**
- * 添加拖拽事件
- */
- function addMouseEvent(dom, event) {
- dom.addEventListener('mousedown', function downHandle(ev) {
- var prevPoint = {
- x: ev.pageX,
- y: ev.pageY
- }
- var con = event.down(prevPoint)
- if (!con) return;
- document.documentElement.addEventListener('mousemove', moveHandle, {
- passive: false
- })
- document.documentElement.addEventListener('mouseup', endHandle, {
- passive: false
- })
- function moveHandle(ev) {
- event.move({
- x: ev.pageX,
- y: ev.pageY
- }, prevPoint)
- prevPoint = {
- x: ev.pageX,
- y: ev.pageY
- }
- }
- function endHandle(ev) {
- document.documentElement.removeEventListener('mousemove', moveHandle, {
- passive: false
- })
- document.documentElement.removeEventListener('mouseup', endHandle, {
- passive: false
- })
- event.up()
- }
- }, false)
- }
- /**
- * 包含对象
- */
- function inherit(origin, target) {
- for (var key in target) {
- origin.prototype[key] = target[key]
- }
- }
- /**
- * 墙面跟相机
- */
- var Wall = (function Wall() {
- /**
- * 获取面的所有点
- * @param {*} face
- */
- function getFacePoints(face) {
- var start = face[0]
- var ret = []
- var iteration = start
- do {
- ret.push(iteration.points[0])
- iteration = face.find(function (item) {
- return item.id === iteration.linkedLineID[1]
- })
- } while (start !== iteration)
- return ret
- }
- function Wall(data, cameras) {
- this.lineWidth = 8
- this.cameras = cameras
- this.stateStack = []
- var faces = {}
- data.forEach(function (line) {
- if (faces[line.roomIndex]) {
- faces[line.roomIndex].push(line)
- } else {
- faces[line.roomIndex] = [line]
- }
- })
- this.faces = faces
- // this.regEvent()
- // this.init()
- // this.draw()
- }
- Wall.prototype._down = function (point, renderer) {
- this.preservationState()
- for (var key in this.faces) {
- var face = this.faces[key]
- for (var i = 0, line; line = face[i]; i++) {
- if (util.isContainPoint(point, line.points, (this.lineWidth + 4) / renderer.status.prop)) {
- return {
- face: face,
- line: line,
- dire: util.verticalLine(line)
- }
- }
- }
- }
- }
- Wall.prototype.updateLine = function (line, x, y) {
- if (!x && !y) return;
- var face
- for (var key in this.faces) {
- var index = this.faces[key].findIndex(function (item) {
- return item === line
- })
- if (~index) {
- face = this.faces[key]
- break
- }
- }
- if (!face) return
- var prevLine = face.find(function (cLine) {
- return line.linkedLineID[0] === cLine.id
- })
- var lastLine = face.find(function (cLine) {
- return line.linkedLineID[1] === cLine.id
- })
- var prevK = (prevLine.points[1].y - prevLine.points[0].y) / (prevLine.points[1].x - prevLine.points[0].x)
- var lastK = (lastLine.points[1].y - lastLine.points[0].y) / (lastLine.points[1].x - lastLine.points[0].x)
- var prevX, prevY, lastX, lastY
- if (x) {
- prevX = prevLine.points[1].x + x
- prevY = (prevX - prevLine.points[0].x) * prevK + prevLine.points[0].y
- lastX = lastLine.points[0].x + x
- lastY = (lastX - lastLine.points[0].x) * lastK + lastLine.points[0].y
- } else {
- prevY = prevLine.points[1].y + y
- prevX = (prevY - prevLine.points[0].y) / prevK + prevLine.points[0].x
- lastY = lastLine.points[0].y + y
- lastX = (lastY - lastLine.points[0].y) / lastK + lastLine.points[0].x
- }
- if (util.isInfinity(prevX) ||
- util.isInfinity(prevY) ||
- util.isInfinity(lastX) ||
- util.isInfinity(lastY)) {
- prevX = prevLine.points[1].x + x
- prevY = prevLine.points[1].y + y
- lastX = lastLine.points[0].x + x
- lastY = lastLine.points[0].y + y
- }
- prevLine.points[1].x = prevX
- prevLine.points[1].y = prevY
- lastLine.points[0].x = lastX
- lastLine.points[0].y = lastY
- line.points[0].x = prevLine.points[1].x
- line.points[0].y = prevLine.points[1].y
- line.points[1].x = lastLine.points[0].x
- line.points[1].y = lastLine.points[0].y
- }
- Wall.prototype._move = function (point, prevPoint, movePosition, renderer) {
- var xdis = point.x - prevPoint.x
- var ydis = point.y - prevPoint.y
- var revoke = false
- var dire = movePosition.dire[0] - movePosition.dire[1] > 0 ? 'X' : 'Y'
- if (dire === 'X') {
- this.updateLine(movePosition.line, xdis, 0)
- } else {
- this.updateLine(movePosition.line, 0, ydis)
- }
- var activeFacePoint = getFacePoints(movePosition.face)
- for (let key in this.faces) {
- if (this.faces[key] !== movePosition.face &&
- util.isFaceIntersect(activeFacePoint, getFacePoints(this.faces[key]))) {
- revoke = true;
- break;
- }
- }
- var cameras;
- if (this.cameras && (cameras = this.cameras[movePosition.face[0].roomIndex])) {
- for (var i = 0, camera; camera = cameras[i]; i++) {
- if (!util.pointInside(camera, activeFacePoint)) {
- revoke = true
- break;
- }
- }
- }
- if (revoke) {
- if (dire === 'X') {
- this.updateLine(movePosition.line, -xdis, 0)
- } else {
- this.updateLine(movePosition.line, 0, -ydis)
- }
- } else {
- this.trigger('changePosition', movePosition.line)
- renderer.render()
- }
- }
- Wall.prototype.draw = function (renderer, context) {
- for (var key in this.faces) {
- var face = this.faces[key]
- for (var i = 0, line; line = face[i]; i++) {
- var _line = [
- renderer.transScreenPoint(line.points[0]),
- renderer.transScreenPoint(line.points[1])
- ]
-
- context.beginPath();
- context.strokeStyle = line.selected ? 'rgb(255,85,0)' : '#fff';
- context.lineWidth = this.lineWidth;
- context.lineCap = 'round'
- context.moveTo(_line[0].x, _line[0].y);
- context.lineTo(_line[1].x, _line[1].y);
- context.closePath();
- context.stroke();
- }
- }
- if (this.cameras) {
- for (var key in this.cameras) {
- for (var i = 0; i < this.cameras[key].length; i++) {
- var point = renderer.transScreenPoint(this.cameras[key][i])
- context.fillStyle = "#00cc00";
- context.fillRect(point.x - this.lineWidth / 2, point.y - this.lineWidth / 2, this.lineWidth, this.lineWidth);
- }
- }
- }
- }
- Wall.prototype.preservationState = function (renderer) {
- var state = {}
- for (var key in this.faces) {
- state[key] = {}
- for (var i = 0; i < this.faces[key].length; i++) {
- var line = this.faces[key][i]
- state[key][line.id] = [{
- x: line.points[0].x,
- y: line.points[0].y
- },
- {
- x: line.points[1].x,
- y: line.points[1].y
- }
- ]
- }
- }
- this.stateStack.push(state)
- }
- Wall.prototype.revokeState = function (renderer) {
- var state = this.stateStack.pop()
- for (var key in state) {
- for (var id in state[key]) {
- var cline = state[key][id]
- var line = this.faces[key].find(function (line) {
- return line.id === id
- })
- line.points[0].x = cline[0].x
- line.points[0].y = cline[0].y
- line.points[1].x = cline[1].x
- line.points[1].y = cline[1].y
- }
- }
- renderer.render();
- }
- Wall.prototype.getIndex = function() {
- return -1
- }
- inherit(Wall, Event.create('__wall__'))
- return Wall
- })();
- /**
- * 当前所在位置
- */
- var Position = (function Position() {
- function Position(point, angle) {
- this.point = point
- this.angle = angle
- this.withinW = 8
- this.abroadW = 4
- this.lightW = 14
- this.lightrRdian = 1 / 2.5 * Math.PI
- }
- Position.prototype.draw = function (renderer, context) {
- var point = renderer.transScreenPoint(this.point)
- var startRdian = this.angle - this.lightrRdian / 2
- var endRdian = this.angle + this.lightrRdian / 2
- var ligWidth = this.withinW + this.abroadW + this.lightW
- var abroadWidth = this.withinW + this.abroadW
- var grd = context.createRadialGradient(point.x, point.y, abroadWidth, point.x, point.y, ligWidth);
- grd.addColorStop(0, "rgba(0,200,175,0.9)");
- grd.addColorStop(1, "rgba(0,200,175,0.3)");
- context.beginPath();
- context.fillStyle = grd;
- context.moveTo(point.x, point.y);
- context.arc(point.x, point.y, ligWidth, startRdian, endRdian, false);
- context.fill()
- context.closePath();
- context.beginPath();
- context.fillStyle = "#ffffff";
- context.arc(point.x, point.y, abroadWidth, 0, 2 * Math.PI, false);
- context.fill()
- context.closePath();
- context.beginPath();
- context.fillStyle = "rgba(0,200,175,1)";
- context.arc(point.x, point.y, this.withinW, 0, 2 * Math.PI, false);
- context.fill()
- context.closePath();
- }
- inherit(Position, Event.create('__position__'))
- return Position
- })();
- /**
- * 门(第一个版本)
- */
- (function Door() {
- function Door(line, point) {
- this.line = line
- this.point = point
- this.lineWidth = 8
- this.color = 'rgba(0,200,175,1)'
- }
- Door.prototype.getPoints = function () {
- var cpoint = util.lineVector(this.line)
- var vpoint = util.verticalLine(this.line)
- var width = 3
- var point1 = {
- x: this.point.x + cpoint.x * width,
- y: this.point.y + cpoint.y * width
- }
- var point2 = {
- x: this.point.x + vpoint[0] * width,
- y: this.point.y + vpoint[1] * width
- }
- return [this.point, point1, point2]
- }
- Door.prototype.draw = function (renderer, context) {
- points = this.getPoints().map(function (point) {
- return renderer.transScreenPoint(point)
- })
- var startDeg = util.lineAngle([points[1], points[0]]) * Math.PI / 180
- var endDeg = util.lineAngle([points[2], points[0]]) * Math.PI / 180
- var deg = endDeg - startDeg
- var router = ((deg > Math.PI || (deg < 0 && deg > -Math.PI)) ? true : false)
- var r = util.lineDistance([points[1], points[0]])
- var grd = context.createLinearGradient(points[0].x, points[0].y, points[0].x, points[0].y - 100);
- grd.addColorStop(0, "rgba(25,31,31,1)");
- grd.addColorStop(0.3, "rgba(255,255,255,1)");
- grd.addColorStop(0.7, "rgba(255,255,255,1)");
- grd.addColorStop(0.71, "rgba(25,31,31,1)");
- context.strokeStyle = this.color;
- context.lineWidth = this.lineWidth;
- context.beginPath();
- context.moveTo(points[0].x, points[0].y);
- context.arc(points[0].x, points[0].y, r, startDeg, endDeg, router);
- context.lineTo(points[0].x, points[0].y);
- context.stroke()
- context.closePath();
- context.beginPath();
- context.strokeStyle = '#000';
- context.moveTo(points[0].x, points[0].y);
- context.lineTo(points[1].x, points[1].y);
- context.stroke()
- context.closePath();
- }
- return Door
- });
- /**
- * 门,正式版本
- */
- var Door = (function Door() {
- var count = 0
- function Door(line, points) {
- count++
- this.line = line
- this.points = points
- this.lineWidth = 8
- this.color = 'rgba(0,200,175,1)'
- }
- Door.prototype.getIndex = function() {
- return 1;
- }
- Door.prototype.detection = function () {
- var collision = true
- var detection = []
- this.line.doors && detection.push.apply(detection, this.line.doors)
- this.line.casements && detection.push.apply(detection, this.line.casements)
- for (var i = 0; i < detection.length; i++) {
- if (detection[i].points !== this.points && (
- util.isContainPoint(this.points[0], detection[i].points, 0.1) ||
- util.isContainPoint(this.points[1], detection[i].points, 0.1)
- )) {
- collision = false
- }
- }
- return collision && util.isContainPoint(this.points[0], this.line.points, 0.1) &&
- util.isContainPoint(this.points[1], this.line.points, 0.1)
- }
- Door.prototype._down = function (point) {
- var info = {
- vector: util.lineVector(this.line)
- };
- if (util.lineDistance([point, this.points[0]]) < 0.3) {
- info.scalePoint = 0
- } else if (util.lineDistance([point, this.points[1]]) < 0.3) {
- info.scalePoint = 1
- } else if (!util.isContainPoint(point, this.points, 0.5)) {
- info = null
- }
- return info
- }
- Door.prototype.getMoveChange = function (vector, curr, prev) {
- var move = {
- x: vector.x < 0 ? (prev.x - curr.x) : (curr.x - prev.x),
- y: vector.y < 0 ? (prev.y - curr.y) : (curr.y - prev.y)
- }
- if (Math.abs(vector.x) > Math.abs(vector.y)) {
- move = {
- x: move.x * vector.x,
- y: move.x * vector.y
- }
- } else {
- move = {
- x: move.y * vector.x,
- y: move.y * vector.y
- }
- }
- return move
- }
- Door.prototype._move = function (point, prevPoint, info, renderer) {
- if (info.scalePoint !== undefined) {
- this.scale(point, prevPoint, info, renderer)
- } else {
- this.move(point, prevPoint, info.vector, renderer)
- }
- }
- Door.prototype.move = function (point, prevPoint, vector, renderer) {
- var move = this.getMoveChange(vector, point, prevPoint)
- this.points.forEach(function (point) {
- point.x += move.x
- point.y += move.y
- })
- if (this.detection()) {
- renderer.render()
- this.trigger('changePoints')
- } else {
- this.points.forEach(function (point) {
- point.x -= move.x
- point.y -= move.y
- })
- }
- }
- Door.prototype.scale = function (point, prevPoint, info, renderer) {
- var move = this.getMoveChange(info.vector, point, prevPoint)
- this.points[info.scalePoint].x += move.x
- this.points[info.scalePoint].y += move.y
- if (this.detection()) {
- renderer.render()
- this.trigger('changePoints')
- } else {
- this.points[info.scalePoint].x -= move.x
- this.points[info.scalePoint].y -= move.y
- }
- }
- Door.prototype.draw = function (renderer, context) {
- var points = this.points.map(function (point) {
- return renderer.transScreenPoint(point)
- })
- context.strokeStyle = this.color;
- context.lineWidth = this.lineWidth;
- context.beginPath();
- context.moveTo(points[0].x, points[0].y);
- context.lineTo(points[1].x, points[1].y);
- context.stroke()
- context.closePath();
- }
-
- inherit(Door, Event.create('__door' + count + '__'))
- return Door
- })();
- /**
- * 窗
- */
- var Casement = (function Casement() {
- var count = 0
- function Casement(line, points) {
- count++
- this.line = line
- this.points = points
- this.lineWidth = 8
- this.color = '#202123'
- }
- Casement.prototype.getIndex = function () {
- return 1;
- }
- Casement.prototype.detection = function () {
- var collision = true
- var detection = []
- this.line.doors && detection.push.apply(detection, this.line.doors)
- this.line.casements && detection.push.apply(detection, this.line.casements)
- for (var i = 0; i < detection.length; i++) {
- if (detection[i].points !== this.points &&(
- util.isContainPoint(this.points[0], detection[i].points, 0.1) ||
- util.isContainPoint(this.points[1], detection[i].points, 0.1)
- )
- ) {
- collision = false
- }
- }
- return collision && util.isContainPoint(this.points[0], this.line.points, 0.1) &&
- util.isContainPoint(this.points[1], this.line.points, 0.1)
- }
- Casement.prototype._down = function (point) {
- var info = {
- vector: util.lineVector(this.line)
- };
- if (util.lineDistance([point, this.points[0]]) < 0.3) {
- info.scalePoint = 0
- } else if (util.lineDistance([point, this.points[1]]) < 0.3) {
- info.scalePoint = 1
- } else if (!util.isContainPoint(point, this.points, 0.5)) {
- info = null
- }
- return info
- }
- Casement.prototype.getMoveChange = function (vector, curr, prev) {
- var move = {
- x: vector.x < 0 ? (prev.x - curr.x) : (curr.x - prev.x),
- y: vector.y < 0 ? (prev.y - curr.y) : (curr.y - prev.y)
- }
- if (Math.abs(vector.x) > Math.abs(vector.y)) {
- move = {
- x: move.x * vector.x,
- y: move.x * vector.y
- }
- } else {
- move = {
- x: move.y * vector.x,
- y: move.y * vector.y
- }
- }
- return move
- }
- Casement.prototype._move = function (point, prevPoint, info, renderer) {
- if (info.scalePoint !== undefined) {
- this.scale(point, prevPoint, info, renderer)
- } else {
- this.move(point, prevPoint, info.vector, renderer)
- }
- }
- Casement.prototype.move = function (point, prevPoint, vector, renderer) {
- var move = this.getMoveChange(vector, point, prevPoint)
- this.points.forEach(function (point) {
- point.x += move.x
- point.y += move.y
- })
- if (this.detection()) {
- renderer.render()
- this.trigger('changePoints')
- } else {
- this.points.forEach(function (point) {
- point.x -= move.x
- point.y -= move.y
- })
- }
- }
- Casement.prototype.scale = function (point, prevPoint, info, renderer) {
- var move = this.getMoveChange(info.vector, point, prevPoint)
- this.points[info.scalePoint].x += move.x
- this.points[info.scalePoint].y += move.y
- if (this.detection()) {
- renderer.render()
- this.trigger('changePoints')
- } else {
- this.points[info.scalePoint].x -= move.x
- this.points[info.scalePoint].y -= move.y
- }
- }
- Casement.prototype.draw = function (renderer, context) {
- var points = this.points.map(function (point) {
- return renderer.transScreenPoint(point)
- })
- context.strokeStyle = this.color;
- context.lineWidth = this.lineWidth;
- context.beginPath();
- context.moveTo(points[0].x, points[0].y);
- context.lineTo(points[1].x, points[1].y);
- context.stroke()
- context.closePath();
- }
- inherit(Casement, Event.create('__casement' + count + '__'))
- return Casement
- })();
- /**
- * 总控制
- */
- var Renderer = (function Renderer() {
- var execFilter = 'FUNCTION_EXEC'
- /**
- * 渲染器
- * @param {*} canvas 画布
- * @param {*} wallData 墙面数据
- */
- function Renderer(canvas, wallData) {
- this.canvas = canvas
- this.context = canvas.getContext('2d')
- this.origin = wallData
- this.models = []
- this.init()
- this.regEvent()
- }
- /**
- * 计算所有需要的信息,渲染器需要的宽高,真实比例等
- */
- Renderer.prototype.init = function () {
- this.width = this.canvas.width
- this.height = this.canvas.height
- this.wMultiple = this.canvas.width / this.canvas.offsetWidth
- this.hMultiple = this.canvas.height / this.canvas.offsetHeight
- this.context.translate(this.width / 2, this.height / 2);
- this.screenOffset = getPosition(this.canvas)
- var points = []
- this.origin.forEach(function (line) {
- points = points.concat(...line.points)
- })
- var result = util.tranProp(points, [-0.99, 0.99])
- this.status = {
- offset: result.offset,
- prop: result.prop,
- range: result.range
- }
- }
- /**
- * 真实点位转化为画布点位
- */
- Renderer.prototype.transScreenPoint = function (point) {
- var spoint = {
- x: point.x,
- y: point.y
- }
- spoint.x += this.status.offset.x
- spoint.y += this.status.offset.y
- spoint.x = (spoint.x * this.status.range / this.status.prop) * (this.width / 2)
- spoint.y = (spoint.y * this.status.range / this.status.prop) * (this.height / 2)
- return spoint
- }
- /**
- * 画布点位转化为真实点位
- */
- Renderer.prototype.transRealPoint = function (point) {
- return {
- x: (point.x * this.status.prop) / (this.status.range * this.width / 2) - this.status.offset.x,
- y: (point.y * this.status.prop) / (this.status.range * this.height / 2) - this.status.offset.y
- }
- }
- Renderer.prototype.regEvent = function () {
- var sinfo, model;
- var section = {
- minx: -this.width / 2,
- maxx: this.width / 2,
- miny: -this.height / 2,
- maxy: this.height / 2
- }
- var startPoint = null
- var prevPoint = null
- var event = {
- down(offset) {
- offset.x = (offset.x - this.screenOffset.x) * this.wMultiple
- offset.y = (offset.y - this.screenOffset.y) * this.hMultiple
- startPoint = this.transRealPoint(util.tranPoint(offset, section))
- prevPoint = startPoint
- var models = Object.assign([], this.models).sort(function(a, b) {
- return ((b.getIndex && b.getIndex()) || 0) - ((a.getIndex && a.getIndex()) || 0)
- })
- for (var i = 0; i < models.length; i++) {
- sinfo = models[i]._down && models[i]._down(startPoint, this)
- if (sinfo) {
- model = models[i]
- break;
- }
- }
- return sinfo
- },
- move(move) {
- move.x = (move.x - this.screenOffset.x) * this.wMultiple
- move.y = (move.y - this.screenOffset.y) * this.hMultiple
- var point = this.transRealPoint(util.tranPoint(move, section))
- model._move(point, prevPoint, sinfo, this, this.context)
- prevPoint = point
- },
- up() {
- model._up && model._up(startPoint, prevPoint, this, this.context)
- startPoint = null
- prevPoint = null
- model = null
- sinfo = null
- }
- }
- event.down = event.down.bind(this)
- event.move = event.move.bind(this)
- event.up = event.up.bind(this)
- addMouseEvent(this.canvas, event)
- }
- /**
- * 统一执行命令
- */
- Renderer.prototype.unifiedExec = function () {
- var args = Array.from(arguments)
- var command = args.shift()
- var ret = []
- var filter = args[args.length - 1] === execFilter
- this.models.map(function (model) {
- if (model[command]) {
- if (filter) {
- ret.push(args[0].apply(model, [model, args.slice(1, args.length - 1)]))
- } else {
- ret.push(model[command].apply(model, args))
- }
- } else {
- ret.push(null)
- }
- })
- return ret
- }
- /**
- * 保存状态
- */
- Renderer.prototype.preservationState = function () {
- this.unifiedExec('preservationState', this)
- }
- Renderer.prototype.revokeState = function () {
- this.unifiedExec('revokeState', this)
- }
- /**
- * 渲染所有依赖了渲染器的模型
- */
- Renderer.prototype.render = function () {
- var that = this
- that.context.clearRect(-that.width / 2, -that.height / 2, that.width, that.height)
- that.unifiedExec('draw', function (model) {
- that.context.save()
- model.draw(that, that.context)
- that.context.restore()
- }, execFilter);
- }
- return Renderer
- })();
- function update3D(line) {
- if (line.updateLine3D) {
- line.updateLine3D()
- } else {
- console.error('当前线条没有注册3D线条方法')
- }
- }
- function update2d(wall, line) {
- var update = line.update
- line.update = function (dirs, len) {
- var args = [
- {x: 0, y: 0},
- {x: 0, y: 0},
- {
- line: this,
- face: wall.faces[this.roomIndex]
- }
- ]
- args[0][dirs[0]] = len;
- wall._move.apply(wall, args.concat([dirs[1]]))
- update && update.bind(this)()
- }
- }
- return function (dom, line2Ds, cameras) {
- var doors = []
- var casements = []
- var wall = new Wall(line2Ds, cameras)
- line2Ds.forEach(function(line) {
- if (line.doors) {
- doors.push.apply(doors,
- line.doors.map(function(door) {
- return new Door(line, door.points)
- })
- )
- }
- if (line.casements) {
- casements.push.apply(casements,
- line.casements.map(function (casements) {
- return new Casement(line, casements.points)
- })
- )
- }
- update2d(wall, line)
- })
- wall.listen('changePosition', function(line2D) {
- line2Ds.forEach(function (line) {
- if (line.id === line2D.linkedLineID[0] ||
- line.id === line2D.linkedLineID[1]) {
- update3D(line)
- }
- })
- update3D(line2D)
- })
- doors.concat(casements).forEach(function (obj) {
- obj.listen('changePoints', function() {
- update3D(obj.line)
- })
- })
- var renderer = new Renderer(dom, line2Ds)
- renderer.models.push(wall)
- renderer.models.push.apply(renderer.models, doors.concat(casements))
- renderer.render()
- var position;
- return {
- position: function (posPoint, angle) {
- if (!position) {
- position = new Position(posPoint, angle)
- renderer.models.push(position)
- } else {
- position.point = posPoint
- position.angle = angle
- }
- renderer.render()
- },
- renderer: renderer
- }
- }
- })();
|