Я работаю над сценарием, который позволяет клиентам рисовать так, как они хотят сгибать железо, с подробными углами. все в порядке.
Теперь клиенту нужен трехмерный вид. но я понятия не имею, как это сделать (с тремя. js Я думаю)
Мне нужен простой 3D-вид.
Вот что я делал до сих пор для 2D-вида, основан на Фабри cJS:
$(function(){
var canvas = this.__canvas = new fabric.Canvas('c', { selection: false });
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
var Lines = Array();
var Points = Array();
var circleAngles = Array();
var anglesValues = Array();
function radianToDegrees(r){
r = r * 180/Math.PI;
if(r < 0) r = -r;
if(360 - r < r) r = 360 - r;
return 180 - parseFloat(r).toFixed(0);
}
function makeCircle(left, top, line1, line2) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 0,
radius: 8,
fill: '#000',
stroke: '#000'
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
c.line2 = line2;
return c;
}
function makeLine(coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 2,
selectable: false,
evented: false,
});
}
function makeCircleAngle(angle, startAngle, endAngle){
if (angle == 1) color = 'red'; else color = '#003366';
circleAngle = new fabric.Circle({
radius: 20,
left: Lines[i].get('x1'),
top: Lines[i].get('y1'),
angle: 0,
startAngle: startAngle,
endAngle: endAngle,
strokeDashArray: [3, 2],
stroke: color,
fill: '',
selectable: false,
evented: false,
});
return circleAngle;
}
function makeText(text, x, y){
t = new fabric.Text(text, {
left: x, top: y, fontSize: 13, fill: '#003366', fontFamily: 'Arial',
selectable: false,
evented: false,
});
return t;
}
function drawLinesCanvas(){
$.each(Lines, function(i, e){
canvas.add(e);
})
}
function drawDotsCanvas(){
Points = Array();
p = makeCircle(Lines[0].get('x1'), Lines[0].get('y1'), null, Lines[0]);
Points.push(p)
canvas.add(p);
for(i = 0; i< Lines.length-1; i++){
p = makeCircle(Lines[i].get('x2'), Lines[i].get('y2'), Lines[i], Lines[i+1]);
Points.push(p)
canvas.add( p );
}
if (Lines.length-1 >= 0){
p = makeCircle(Lines[Lines.length-1].get('x2'), Lines[Lines.length-1].get('y2'), Lines[Lines.length-1]);
Points.push(p)
canvas.add( p );
}
}
function calculateAndDrawAngles(){
$.each(circleAngles, function(i, ce){
canvas.remove(ce);
})
$.each(Lines, function(i, l){
canvas.remove(l);
})
$.each(Points, function(i, p){
canvas.remove(p);
})
$.each(anglesValues, function(i, a){
canvas.remove(a);
})
if(Lines.length >= 2){
for(i=1; i<Lines.length; i++){
y11 = Lines[i].get('y1');
y12 = Lines[i].get('y2');
y21 = Lines[i-1].get('y1');
y22 = Lines[i-1].get('y2');
x11 = Lines[i].get('x1');
x12 = Lines[i].get('x2');
x21 = Lines[i-1].get('x1');
x22 = Lines[i-1].get('x2');
angle1 = Math.atan2(y11 - y12, x11 - x12);
angle2 = Math.atan2(y21 - y22, x21 - x22);
angle = angle1 - angle2;
if (angle < 0){
sStartAngle = Math.PI + angle1;
sEndAngle = angle2;
} else {
sStartAngle = angle1 - Math.PI;
sEndAngle = angle2;
}
myAngle = radianToDegrees(angle1 - angle2);
if(sStartAngle > sEndAngle) {
c = makeCircleAngle(1, sStartAngle, sEndAngle);
c1 = makeCircleAngle(2, sEndAngle, sStartAngle);
myAngleText = makeText(myAngle.toString()+'°', Lines[i].get('x1') +20, Lines[i].get('y1') + 20)
} else {
c = makeCircleAngle(2, sStartAngle, sEndAngle);
c1 = makeCircleAngle(1, sEndAngle, sStartAngle);
myAngleText = makeText(myAngle.toString()+'°', Lines[i].get('x1') - 20, Lines[i].get('y1') - 20)
}
circleAngles.push(c, c1);
canvas.add(c, c1);
canvas.add(myAngleText)
anglesValues.push(myAngleText);
}
drawLinesCanvas();
drawDotsCanvas();
}
}
canvas.on('object:moving', function(e) {
var p = e.target;
p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top });
p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top });
if (Lines.length > 1){
calculateAndDrawAngles();
}
});
canvas.on('mouse:wheel', function(opt) {
var delta = opt.e.deltaY;
var zoom = canvas.getZoom();
zoom = zoom + delta/200;
if (zoom > 20) zoom = 5;
if (zoom < 0.01) zoom = 0.5;
canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom);
opt.e.preventDefault();
opt.e.stopPropagation();
var vpt = this.viewportTransform;
if (zoom < 400 / 1000) {
this.viewportTransform[4] = 200 - 1000 * zoom / 2;
this.viewportTransform[5] = 200 - 1000 * zoom / 2;
} else {
if (vpt[4] >= 0) {
this.viewportTransform[4] = 0;
} else if (vpt[4] < canvas.getWidth() - 1000 * zoom) {
this.viewportTransform[4] = canvas.getWidth() - 1000 * zoom;
}
if (vpt[5] >= 0) {
this.viewportTransform[5] = 0;
} else if (vpt[5] < canvas.getHeight() - 1000 * zoom) {
this.viewportTransform[5] = canvas.getHeight() - 1000 * zoom;
}
}
});
canvas.on('mouse:down', function(opt) {
var evt = opt.e;
if (evt.altKey === true) {
this.isDragging = true;
this.selection = false;
this.lastPosX = evt.clientX;
this.lastPosY = evt.clientY;
}
});
canvas.on('mouse:move', function(opt) {
if (this.isDragging) {
var e = opt.e;
this.viewportTransform[4] += e.clientX - this.lastPosX;
this.viewportTransform[5] += e.clientY - this.lastPosY;
this.requestRenderAll();
this.lastPosX = e.clientX;
this.lastPosY = e.clientY;
}
});
canvas.on('mouse:up', function(opt) {
this.isDragging = false;
this.selection = true;
});
$('#addRight').on('click', function(){
fromPoint = Lines[Lines.length - 1];
Lines.push(makeLine([ fromPoint.get('x2'), fromPoint.get('y2'), fromPoint.get('x2') - 50, fromPoint.get('y2') + 50 ]))
calculateAndDrawAngles()
});
$('#addLeft').on('click', function(){
fromPoint = Lines[0];
Lines.unshift(makeLine([ fromPoint.get('x1') + 50, fromPoint.get('y1') + 50, fromPoint.get('x1'), fromPoint.get('y1') ]))
calculateAndDrawAngles()
});
function drawGrid(){
options = {
distance: 10,
width: c.width,
height: c.height,
param: {
stroke: '#ebebeb',
strokeWidth: 1,
selectable: false
}
},
gridLen = options.width / options.distance;
for (var i = 0; i < gridLen; i++) {
distance = i * options.distance,
horizontal = new fabric.Line([ distance, 0, distance, options.width], options.param),
vertical = new fabric.Line([ 0, distance, options.width, distance], options.param);
canvas.add(horizontal);
canvas.add(vertical);
if(i%5 === 0){
horizontal.set({stroke: '#cccccc'});
vertical.set({stroke: '#cccccc'});
};
canvas.sendBackwards(horizontal);
canvas.sendBackwards(vertical);
};
}
Lines = [makeLine([ 100, 50, 400, 50 ])];
drawGrid();
drawLinesCanvas();
drawDotsCanvas();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.3/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="c" width="500" height="400" style="border:1px solid #ccc;"></canvas>
<div class="text-center">
<button class="btn btn-info" id="addLeft">Ajouter un point à gauche</button>
<button class="btn btn-info" id="addRight">Ajouter un point à droite</button>
</div>