Test: Difference between revisions

From Open Source Ecology
Jump to navigation Jump to search
(Replaced content with "{{subst:Learning Log}}")
Tag: Replaced
No edit summary
 
Line 1: Line 1:
<html>
<div id="ose-3d-mindmap" style="width:100%; height:700px; border:1px solid #ccc; overflow:hidden; position:relative;"></div>


<script src="https://unpkg.com/three@0.160.0/build/three.min.js"></script>
<script src="https://unpkg.com/three@0.160.0/examples/js/controls/OrbitControls.js"></script>


= Weekly Learning Log =
<script>
(function () {
  const container = document.getElementById('ose-3d-mindmap');
  if (!container) return;


'''Date:'''    
   const words = [
'''Name:''' 
    "collaborative",
'''Institution:''' 
    "design",
'''Week:'''    
    "for",
    "a",
    "transparent",
    "and",
    "inclusive",
    "economy",
    "of",
    "abundance"
   ];


== Learning ==
  const scene = new THREE.Scene();
  scene.background = new THREE.Color(0xffffff);


  const camera = new THREE.PerspectiveCamera(
    50,
    container.clientWidth / container.clientHeight,
    0.1,
    2000
  );
  camera.position.set(0, 0, 260);


== Output ==
  const renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio || 1);
  renderer.setSize(container.clientWidth, container.clientHeight);
  container.appendChild(renderer.domElement);


  const controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;
  controls.dampingFactor = 0.08;
  controls.rotateSpeed = 0.8;
  controls.zoomSpeed = 0.9;
  controls.panSpeed = 0.7;


== Evidence ==
  const ambient = new THREE.AmbientLight(0xffffff, 1.2);
  scene.add(ambient);


  const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
  dirLight.position.set(120, 150, 200);
  scene.add(dirLight);


== Tools ==
  function makeTextSprite(message) {
'''Technical:''' 
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');


'''Information:''' 
    const fontSize = 48;
    const paddingX = 28;
    const paddingY = 18;
    ctx.font = 'bold ' + fontSize + 'px Arial';


'''Coordination:''' 
    const textWidth = Math.ceil(ctx.measureText(message).width);
    canvas.width = textWidth + paddingX * 2;
    canvas.height = fontSize + paddingY * 2;


== Personal Mastery ==
    ctx.font = 'bold ' + fontSize + 'px Arial';
    ctx.textBaseline = 'middle';
    ctx.textAlign = 'center';


    ctx.fillStyle = 'rgba(255,255,255,0.92)';
    ctx.strokeStyle = 'rgba(40,40,40,0.9)';
    ctx.lineWidth = 3;
    roundRect(ctx, 2, 2, canvas.width - 4, canvas.height - 4, 14, true, true);


== Impact ==
    ctx.fillStyle = '#111111';
    ctx.fillText(message, canvas.width / 2, canvas.height / 2);


    const texture = new THREE.CanvasTexture(canvas);
    texture.needsUpdate = true;


== Failure + Next Step ==
    const material = new THREE.SpriteMaterial({
'''Failure:''' 
      map: texture,
      transparent: true
    });


'''Next Step:''' 
    const sprite = new THREE.Sprite(material);


== Scoring ==
    const scale = 0.34;
    sprite.scale.set(canvas.width * scale, canvas.height * scale, 1);


{| class="wikitable"
    return sprite;
! Component !! Score !! Max
  }
|-
 
| Output || 0 || 30
  function roundRect(ctx, x, y, w, h, r, fill, stroke) {
|-
    if (w < 2 * r) r = w / 2;
| Learning || 0 || 20
    if (h < 2 * r) r = h / 2;
|-
    ctx.beginPath();
| Evidence || 0 || 20
    ctx.moveTo(x + r, y);
|-
    ctx.arcTo(x + w, y, x + w, y + h, r);
| Impact || 0 || 15
    ctx.arcTo(x + w, y + h, x, y + h, r);
|-
    ctx.arcTo(x, y + h, x, y, r);
| Personal Mastery || 0 || 15
    ctx.arcTo(x, y, x + w, y, r);
|-
    ctx.closePath();
! Total
    if (fill) ctx.fill();
! {{#expr: 0 + 0 + 0 + 0 + 0 }}
    if (stroke) ctx.stroke();
! 100
  }
|}
 
  const nodeGroup = new THREE.Group();
  scene.add(nodeGroup);
 
  const positions = [];
  const radius = 95;
 
  // Distribute words across a sphere
  for (let i = 0; i < words.length; i++) {
    const phi = Math.acos(-1 + (2 * i + 1) / words.length);
    const theta = Math.sqrt(words.length * Math.PI) * phi;
 
    const x = radius * Math.cos(theta) * Math.sin(phi);
    const y = radius * Math.sin(theta) * Math.sin(phi);
    const z = radius * Math.cos(phi);
 
    positions.push(new THREE.Vector3(x, y, z));
 
    const sprite = makeTextSprite(words[i]);
    sprite.position.set(x, y, z);
    sprite.userData.word = words[i];
    nodeGroup.add(sprite);
  }
 
  // Connect every word to every other word
  const lineMaterial = new THREE.LineBasicMaterial({
    color: 0x777777,
    transparent: true,
    opacity: 0.45
  });
 
  for (let i = 0; i < positions.length; i++) {
    for (let j = i + 1; j < positions.length; j++) {
      const geometry = new THREE.BufferGeometry().setFromPoints([
        positions[i],
        positions[j]
      ]);
      const line = new THREE.Line(geometry, lineMaterial);
      scene.add(line);
    }
  }
 
  // Small center marker
  const centerGeom = new THREE.SphereGeometry(3, 16, 16);
  const centerMat = new THREE.MeshBasicMaterial({ color: 0x222222 });
  const centerDot = new THREE.Mesh(centerGeom, centerMat);
  scene.add(centerDot);
 
  const raycaster = new THREE.Raycaster();
  const pointer = new THREE.Vector2();
 
  const info = document.createElement('div');
  info.style.position = 'absolute';
  info.style.left = '12px';
  info.style.top = '12px';
  info.style.padding = '8px 10px';
  info.style.background = 'rgba(255,255,255,0.9)';
  info.style.border = '1px solid #ccc';
  info.style.fontFamily = 'Arial, sans-serif';
  info.style.fontSize = '14px';
  info.style.color = '#111';
  info.style.zIndex = '10';
  info.innerHTML = 'Drag to rotate. Scroll to zoom. Click a word.';
  container.appendChild(info);
 
  function onPointerMove(event) {
    const rect = renderer.domElement.getBoundingClientRect();
    pointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
    pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
  }
 
  function onClick() {
    raycaster.setFromCamera(pointer, camera);
    const intersects = raycaster.intersectObjects(nodeGroup.children, true);
 
    if (intersects.length > 0) {
      const obj = intersects[0].object;
      if (obj.userData && obj.userData.word) {
        info.innerHTML = 'Selected: <b>' + obj.userData.word + '</b>';
      }
    }
  }
 
  renderer.domElement.addEventListener('mousemove', onPointerMove);
  renderer.domElement.addEventListener('click', onClick);
 
  function resize() {
    const w = container.clientWidth;
    const h = container.clientHeight;
    camera.aspect = w / h;
    camera.updateProjectionMatrix();
    renderer.setSize(w, h);
  }
 
  window.addEventListener('resize', resize);
 
  function animate() {
    requestAnimationFrame(animate);
    controls.update();
    renderer.render(scene, camera);
  }
 
  animate();
})();
</script>
</html>

Latest revision as of 15:35, 4 April 2026