| |
|
|
- Seite 1 - |
|
HofK | Auf einen heißen Tipp von IF hin, habe ich mir mal three.js [...] angeschaut. Da [...] (ganz unten) die ersten Resultate. |
|
|
| |
|
|
| |
|
- Seite 12 - |
|
|
p.specht
| Was ist von der freeware Game-Engine "Unity" zu halten? Aufmerksam gemacht wurde ich von einem Youtube-Video des jungen US-"AI-Professors" Siraj Raval (Indisch-stämmig?): Link: [...]
Bevorzugte Schnittstellensprachen sind C# und JavaScript (!!) Download-Link: [...] |
|
|
| XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 14.01.2018 ▲ |
|
|
|
|
HofK | |
|
| |
|
|
|
p.specht
| |
|
| XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 15.01.2018 ▲ |
|
|
|
|
HofK | Zur Modifizierung der exportierten Geometrie (siehe Ende Dezember 2017) habe ich noch etwas mit der Benutzerinteraktion herumgespielt. Eine ähnliche Variante wie vor begrenzt die Bewegung der Ausschnitte auf den grün umrandeten Bereich.
#divMain { width: 1000px; height: 600px; border: 4px solid rgba(0,255,0,0.5); padding: 12px; } <div id="divMain" ondragover="drag_over(event)" ondrop="drop(event)">
<!DOCTYPE html>
<!--
derived from
https://stackoverflow.com/questions/6230834/html5-drag-and-drop-anywhere-on-the-screen
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<style>
body {
margin: 0;
}
#divMain {
width: 1000px;
height: 600px;
border: 4px solid rgba(0,255,0,0.5); padding: 12px;
}
#pane1 {
position: absolute;
left: 0;
top: 50px;
width: 200px;
background: rgba(255,255,255,0.95);
border: 2px solid rgba(0,0,0,0.5);
border-radius: 12px; padding: 8px;
}
#pane2 {
position: absolute;
left: 0;
top: 200px;
width: 200px;
background: rgba(255,255,0,0.95);
border: 2px solid rgba(0,0,0,0.5);
border-radius: 12px; padding: 8px;
}
</style>
<script>
function drag_start(event) {
var style = window.getComputedStyle(event.target, null);
var str = (parseInt(style.getPropertyValue("left")) - event.clientX) +',' + (parseInt(style.getPropertyValue("top")) - event.clientY)+ ',' + event.target.id;
event.dataTransfer.setData("Text",str);
}
function drop(event) {
var offset = event.dataTransfer.getData("Text").split(',');
var dm = document.getElementById(offset[2]);
dm.style.left = (event.clientX + parseInt(offset[0],10)) +'px';
dm.style.top = (event.clientY + parseInt(offset[1],10)) +'px';
event.preventDefault();
return false;
}
function drag_over(event) { event.preventDefault(); return false; }
</script>
</head>
<body >
<span id="pane1" draggable="true" ondragstart="drag_start(event)">
<span id="title1"> ziehen!<br /> </span>
Inhalt 1 <br />
<img src="natur.png" width="126" height="95">
</span>
<span id="pane2" draggable="true" ondragstart="drag_start(event)">
Inhalt 2
<img src="further_examples.png" width="79" height="48">
</span>
<div id="divMain" ondragover="drag_over(event)" ondrop="drop(event)">
Hauptinhalt ... <br /><hr/>
</div>
</body>
</html>
Dann habe ich noch eine sehr komfortable Sache gefunden. Sie ist aber für meine Zwecke nicht geeignet. Ich bekomme Probleme mit der Kamerasteuerung per Maus. (OrbitControls.js)
Die Sache stammt von zz85 [...] (Link leider nicht mehr verfügbar!) dessen Beispiele [...] ( @author zz85 ) mich auch mit zur Entwicklung von THREEf gebracht haben.
Der Code ist fast unverändert von [...] übernommen. Einfach mal kopieren und ausprobieren. Mein Bild <img src="further_examples.png" width="789" height="481"> durch ein eigenes ersetzen.
<!DOCTYPE html>
<html lang="de" >
<head>
<meta charset="UTF-8">
<title>Resize, Drag, Snap</title>
<style>
body {
overflow: hidden;
}
#pane {
overflow: hidden;
position: absolute;
width: 45%;
height: 45%;
top: 20%;
left: 20%;
margin: 0;
padding: 0;
z-index: 99;
border: 2px solid purple;
background: #fefefe;
}
#title {
font-family: monospace;
background: purple;
color: white;
font-size: 24px;
height: 30px;
text-align: center;
}
#ghostpane {
background: #ffff33;
opacity: 0.2;
width: 45%;
height: 45%;
top: 20%;
left: 20%;
position: absolute;
margin: 0;
padding: 0;
z-index: 98;
-webkit-transition: all 0.25s ease-in-out;
-moz-transition: all 0.25s ease-in-out;
-ms-transition: all 0.25s ease-in-out;
-o-transition: all 0.25s ease-in-out;
transition: all 0.25s ease-in-out;
}
</style>
</head>
<body>
site content
<div id="pane">
<div id="title">Resize, Drag or Snap Me!</div>
pane content
<img src="further_examples.png" width="789" height="481">
</div>
<div id="ghostpane"> </div>
</body>
<script>
/*
* @author https://github.com/zz85
* https://codepen.io/zz85/pen/gbOoVP
*/
"use strict";
// Minimum resizable area
var minWidth = 100;
var minHeight = 80;
// Thresholds
var FULLSCREEN_MARGINS = -10;
var MARGINS = 4;
// End of what's configurable.
var clicked = null;
var onRightEdge, onBottomEdge, onLeftEdge, onTopEdge;
var rightScreenEdge, bottomScreenEdge;
var preSnapped;
var b, event, x, y;
var redraw = false;
var pane = document.getElementById('pane');
var ghostpane = document.getElementById('ghostpane');
function setBounds(element, x, y, w, h) {
element.style.left = x +'px';
element.style.top = y +'px';
element.style.width = w +'px';
element.style.height = h +'px';
}
function hintHide() {
setBounds(ghostpane, b.left, b.top, b.width, b.height);
ghostpane.style.opacity = 0;
}
// Mouse events
pane.addEventListener('mousedown', onMouseDown);
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onUp);
// Touch events
pane.addEventListener('touchstart', onTouchDown);
document.addEventListener('touchmove', onTouchMove);
document.addEventListener('touchend', onTouchEnd);
animate();
// ................................................
function onTouchDown(event) {
onDown(event.touches[0]);
event.preventDefault();
}
function onTouchMove(event) {
onMove(event.touches[0]);
}
function onTouchEnd(event) {
if (event.touches.length ==0) onUp(event.changedTouches[0]);
}
function onMouseDown(event) {
onDown(event);
event.preventDefault();
}
function onDown(event) {
calc(event);
var isResizing = onRightEdge || onBottomEdge || onTopEdge || onLeftEdge;
clicked = {
x: x,
y: y,
cx: event.clientX,
cy: event.clientY,
w: b.width,
h: b.height,
isResizing: isResizing,
isMoving: !isResizing && canMove(),
onTopEdge: onTopEdge,
onLeftEdge: onLeftEdge,
onRightEdge: onRightEdge,
onBottomEdge: onBottomEdge
};
}
function canMove() {
return x > 0 && x < b.width && y > 0 && y < b.height
&& y < 30;
}
function calc(event) {
b = pane.getBoundingClientRect();
x = event.clientX - b.left;
y = event.clientY - b.top;
onTopEdge = y < MARGINS;
onLeftEdge = x < MARGINS;
onRightEdge = x >= b.width - MARGINS;
onBottomEdge = y >= b.height - MARGINS;
rightScreenEdge = window.innerWidth - MARGINS;
bottomScreenEdge = window.innerHeight - MARGINS;
}
function onMove(paneEvent) {
calc(paneEvent);
event = paneEvent;
redraw = true;
}
function onUp(event) {
calc(event);
if (clicked && clicked.isMoving) {
// Snap
var snapped = {
width: b.width,
height: b.height
};
if (b.top < FULLSCREEN_MARGINS || b.left < FULLSCREEN_MARGINS || b.right > window.innerWidth - FULLSCREEN_MARGINS || b.bottom > window.innerHeight - FULLSCREEN_MARGINS) {
// hintFull();
setBounds(pane, 0, 0, window.innerWidth, window.innerHeight);
preSnapped = snapped;
} else if (b.top < MARGINS) {
// hintTop();
setBounds(pane, 0, 0, window.innerWidth, window.innerHeight / 2);
preSnapped = snapped;
} else if (b.left < MARGINS) {
// hintLeft();
setBounds(pane, 0, 0, window.innerWidth / 2, window.innerHeight);
preSnapped = snapped;
} else if (b.right > rightScreenEdge) {
// hintRight();
setBounds(pane, window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight);
preSnapped = snapped;
} else if (b.bottom > bottomScreenEdge) {
// hintBottom();
setBounds(pane, 0, window.innerHeight / 2, window.innerWidth, window.innerWidth / 2);
preSnapped = snapped;
} else {
preSnapped = null;
}
hintHide();
}
clicked = null;
}
function animateGhostPane() {
if (!redraw) return;
redraw = false;
if (clicked && clicked.isResizing) {
if (clicked.onRightEdge) pane.style.width = Math.max(x, minWidth) +'px';
if (clicked.onBottomEdge) pane.style.height = Math.max(y, minHeight) +'px';
if (clicked.onLeftEdge) {
var currentWidth = Math.max(clicked.cx - event.clientX + clicked.w, minWidth);
if (currentWidth > minWidth) {
pane.style.width = currentWidth +'px';
pane.style.left = event.clientX +'px';
}
}
if (clicked.onTopEdge) {
var currentHeight = Math.max(clicked.cy - event.clientY + clicked.h, minHeight);
if (currentHeight > minHeight) {
pane.style.height = currentHeight +'px';
pane.style.top = event.clientY +'px';
}
}
hintHide();
return;
}
if (clicked && clicked.isMoving) {
if (b.top < FULLSCREEN_MARGINS || b.left < FULLSCREEN_MARGINS || b.right > window.innerWidth - FULLSCREEN_MARGINS || b.bottom > window.innerHeight - FULLSCREEN_MARGINS) {
// hintFull();
setBounds(ghostpane, 0, 0, window.innerWidth, window.innerHeight);
ghostpane.style.opacity = 0.2;
} else if (b.top < MARGINS) {
// hintTop();
setBounds(ghostpane, 0, 0, window.innerWidth, window.innerHeight / 2);
ghostpane.style.opacity = 0.2;
} else if (b.left < MARGINS) {
// hintLeft();
setBounds(ghostpane, 0, 0, window.innerWidth / 2, window.innerHeight);
ghostpane.style.opacity = 0.2;
} else if (b.right > rightScreenEdge) {
// hintRight();
setBounds(ghostpane, window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight);
ghostpane.style.opacity = 0.2;
} else if (b.bottom > bottomScreenEdge) {
// hintBottom();
setBounds(ghostpane, 0, window.innerHeight / 2, window.innerWidth, window.innerWidth / 2);
ghostpane.style.opacity = 0.2;
} else {
hintHide();
}
if (preSnapped) {
setBounds(pane,
event.clientX - preSnapped.width / 2,
event.clientY - Math.min(clicked.y, preSnapped.height),
preSnapped.width,
preSnapped.height
);
return;
}
// moving
pane.style.top = (event.clientY - clicked.y) +'px';
pane.style.left = (event.clientX - clicked.x) +'px';
return;
}
// This code executes when mouse moves without clicking
// style cursor
if (onRightEdge && onBottomEdge || onLeftEdge && onTopEdge) {
pane.style.cursor ='nwse-resize';
} else if (onRightEdge && onTopEdge || onBottomEdge && onLeftEdge) {
pane.style.cursor ='nesw-resize';
} else if (onRightEdge || onLeftEdge) {
pane.style.cursor ='ew-resize';
} else if (onBottomEdge || onTopEdge) {
pane.style.cursor ='ns-resize';
} else if (canMove()) {
pane.style.cursor ='move';
} else {
pane.style.cursor ='default';
}
}
function animate() {
requestAnimationFrame(animate);
animateGhostPane();
}
</script>
</html>
Letztendlich habe ich mich für eine spartanische Variante entschieden. Das noch nicht ganz fertige Layout:
|
|
|
| |
|
|
|
p.specht
| Gibt es irgendwo auch den berühmten Hasen und den Teekessel in three? |
|
|
| XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 16.01.2018 ▲ |
|
|
|
|
HofK | |
|
| |
|
|
|
p.specht
| |
|
| XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 16.01.2018 ▲ |
|
|
|
|
HofK | Bei der Modifizierung der Geometrie gab es ein echtes Problem.
Ich benutze Raycaster und habe irgendwann bemerkt, dass ich die Rückseiten der Flächen nicht greifen konnte. . Also habe ich das Beispiel [...] genommen und stark vereinfacht/abgewandelt und statt non-indexed eine indexed BufferGeometry und Multimaterial (array) mit THREE.DoubleSide, THREE.FrontSide, THREE.BackSide. Da [...] kann man es probieren. Es wird immer nur die Vorderseite erkannt. Selbst bei BackSide, wo das Material dann nicht angezeigt wird - aber die weiße Umrandung.
Also bei discourse.threejs.org eine Frage formuliert [...]
Ich hatte keine Chance! Multimaterial wird nicht unterstützt. Aber Mugen87 hat ein workaround [...] parat.
Man ersetzt in three.js function Mesh( geometry, material ) { … } Mesh.prototype = Object.assign( … )
und schon funktioniert es. [...]
Trotz der Hilfsgitter ist die Orientierung im Raum schwierig. Man bewegt sich ja mit dem Handhabungspunkt (Würfel) in der sich stets selbst ausrichtenden grauen orthogonalen Hilfsebene.
Die Punkte (1, 2 oder 3) des Dreiecks bewegen sich parallel. Da muss mir noch etwas einfallen. |
|
|
| |
|
|
|
HofK | Nach einigen Experimenten -------
habe ich mich entschieden, zusätzlich zur Kamera - orthogonalen Ausrichtung der Hilfsebene die Koordinatenebenen fixierbar zu gestalten. Dazu drückt man die Tasten x, y, oder z.
Die jeweilige Koordinate bleibt dann unverändert, die Hilfsebene ist orthogonal zur Achse.
Trotzdem ist die Handhabung etwas "hakelig" und man muss ein wenig üben. Problem ist, dass die Maus einerseits die Kamera steuern muss (OrbitControls.js) und andererseits auch die Geometriekoordinaten verschieben soll.
Dabei ist die praktische Umschaltung problematisch. Mag sein, dass meine Lösung nicht optimal ist. Vielleicht erhalte ich ja noch einen Expertentipp?
Wer lieber mit der Eingabe arbeitet, hat da keine Probleme. Die Genauigkeit lässt sich einstellen.
Für den Export habe ich mit Hilfe von prisoner849 (Paul West) [...] eine recht elegante Variante. Sie ist auch bei modifyCreateGeo.html [...] nachgetragen. (siehe weiter oben)
Da [...] bzw. [...] ausprobieren.
Bitte beachten, dass der Export ohne Nachfrage in der Zwischenablage landet. Steht auch da!
Export the changed code. The code is displayed here and is also copied to the clipboard. |
|
|
| |
|
|
|
HofK | THREEp ist fertiggestellt
Vor ziemlich genau einem Jahr begonnen! Da konnte ich nicht absehen, wohin das führt und wie lange es dauert.
Nun sind beide Addons fertig! Siehe meine Seite [...] und GitHub [...] Auch Beispiele und dazu eine Formenbibliothek zu THREEp. [...] Noch erweiterbar.
Von der Beseitigung der Nähte bei Geometry habe ich abgesehen. Der Aufwand ist unverhältnismäßig hoch. Besonders, da Geometry keine dauernde Zukunft hat.
Da noch das Tool für THREEf - siehe Bild im vorherigen Beitrag [...] Bei discourse [...]
Da kann es mit anderen Sachen weitergehen |
|
|
| |
|
|
|
p.specht
| Gratuliere! Ausprobieren leider eine Zeitfrage, aber geplant! Gruss
P.S.: GitHub-Link hat einen Punkt am Ende zuviel. |
|
|
| Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 28.01.2018 ▲ |
|
|
|
|
HofK | |
|
| |
|
|