i am learning Canvas, but it does not paint colors:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas</title>
<link rel="stylesheet" href="css/all.css">
</head>
<body>
<Canvas id="c1" height="200px" width ="400px">ooo</Canvas>
<script src="JS/script.js"></script>
</body>
</html>
CSS
#c1{
width: 400px;
height: 200px;
border: 3px solid black;
margin: 5px;
background-image: url(../images/setka.png);
}
JS
function Figure(x,y, color) {
this.x = x;
this.y = y;
this.сolor = color;
};
function Line(x1, y1, x2, y2, color) {
Figure.call(this, x1, y1, color);
this.x2 = x2;
this.y2 = y2;
this.draw = function(ctx) {
// let ctx = document.getElementById('c1').getContext('2d');
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.x2,this.y2);
ctx.strokeStyle = this.color;
ctx.stroke();
}
};
function Rect(x,y,width, height, color) {
Figure.call(this, x, y, color);
this.w = width;
this.h = height;
this.draw = function(ctx) {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.fillRect(this.x,this.y, this.w, this.h);
}
};
function Circle(x,y, r, color) {
Figure.call(this, x, y, color);
this.rad = r;
this.draw = function(ctx) {
ctx.beginPath();
ctx.arc(this.x,this.y,this.rad, 0, 2 * Math.PI, true);
ctx.fillStyle = this.color;
ctx.fill();
}
};
var line = new Line(50, 50, 200, 200, 'red'); // x1, y1, x2, y2, color
var circle = new Circle(120, 120, 50, 'green'); // x, y, r, color
var rect = new Rect(260, 130, 60, 120, 'blue'); // x, y, w, h, color
function Canvas() {
let canvasField = document.getElementById('c1');
this.ctx = canvasField.getContext('2d');
this.add = function(...args) {
for (let i = 0; i< args.length; i++) {
let ctx = this.ctx;
args[i].draw(this.ctx);
}
}
}
let drawArea = new Canvas();
drawArea.add(line, circle, rect);
This is what I get.... I want it to be colored! What do I do wrong?
i am adding colors as arguments of functions, but it does not function
i tried all the ways to make the shapes colored, but i did not succeed in it, please tell me what I ought to do.
this is what I get
Related
How can I print the values of an array using three.js textGeometry. Trying the following code but no output.
`for(let i=0;i<=4;i++)
{
let arr = [1,2,3,4,5,6,7,8];
let char = arr[i];
let loader = new THREE.FontLoader();
let font = loader.parse(fontJSON);
let geometry = new THREE.TextBufferGeometry(char ,{font : font , size : 1 , height : 0.1 });
let material = new THREE.MeshBasicMaterial({ color : 0xffffff });
let text = new THREE.Mesh(geometry , material);
text.position.set(i,0,0);
scene.add(text);
}`
You have to make sure to provide a string to TextBufferGeometry, no number. You can easily ensure this by calling toString() on your char variable. I've refactored your code a bit to show you a complete example.
let camera, scene, renderer;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 8;
scene = new THREE.Scene();
const material = new THREE.MeshBasicMaterial({
color: 0xffffff
});
const arr = [1, 2, 3, 4, 5, 6, 7, 8];
const loader = new THREE.FontLoader();
loader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', (font) => {
for (let i = 0; i <= 4; i++) {
const char = arr[i];
const geometry = new THREE.TextBufferGeometry(char.toString(), {
font: font,
size: 1,
height: 0.1
});
const text = new THREE.Mesh(geometry, material);
text.position.set(i, 0, 0);
scene.add(text);
}
});
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
body {
margin: 0;
}
canvas {
display: block;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.117.1/build/three.js"></script>
I have a simple scene in WebGL where i store every transformation (for the camera and the models) in a single model/view matrix and i set them by rotating and moving said matrix.
What i want is, to being able to rotate the camera around and when i "move forward" to move towards where the camera is pointing.
So far, i have modified this code to this:
mat4.identity(mvMatrix);
mat4.rotateX(mvMatrix, degToRad(elev), mvMatrix);
mat4.rotateY(mvMatrix, degToRad(ang), mvMatrix);
mat4.rotateZ(mvMatrix, degToRad(-roll), mvMatrix);
mat4.translate(mvMatrix, [-px, -py, -pz], mvMatrix);
since it wasn't working as it was and it kind of works, until you do an extreme rotation (more than 90 degrees).
This is not a deal breaker for what i'm doing, but i want to know. Is this the best i can get without moving away from calculating the camera orientation like this?
WebGL cameras generally point down the -Z axis so to move in the direction the camera is facing you just add the camera's Z axis (elements 8, 9, 10) to the position of the camera multiplied by some velocity.
const m4 = twgl.m4;
const v3 = twgl.v3;
const gl = document.querySelector("canvas").getContext("webgl");
const vs = `
uniform mat4 u_worldViewProjection;
uniform mat4 u_worldInverseTranspose;
attribute vec4 position;
attribute vec3 normal;
varying vec3 v_normal;
void main() {
gl_Position = u_worldViewProjection * position;
v_normal = (u_worldInverseTranspose * vec4(normal, 0)).xyz;
}
`;
const fs = `
precision mediump float;
varying vec3 v_normal;
uniform vec3 u_lightDir;
uniform vec4 u_color;
void main() {
vec3 norm = normalize(v_normal);
float light = dot(u_lightDir, norm) * .5 + .5;
gl_FragColor = vec4(u_color.rgb * light, u_color.a);
}
`;
const progInfo = twgl.createProgramInfo(gl, [vs, fs]);
const bufferInfo = twgl.primitives.createCubeBufferInfo(gl, 1);
const projection = m4.identity();
const camera = m4.identity();
const view = m4.identity();
const viewProjection = m4.identity();
const world = m4.identity();
const worldViewProjection = m4.identity();
const worldInverse = m4.identity();
const worldInverseTranspose = m4.identity();
const fov = degToRad(90);
const zNear = 0.1;
const zFar = 100;
const lightDir = v3.normalize([1, 2, 3]);
const keys = {};
let px = 0;
let py = 0;
let pz = 0;
let elev = 0;
let ang = 0;
let roll = 0;
const speed = 1;
const turnSpeed = 90;
let then = 0;
function render(now) {
now *= 0.001; // seconds;
const deltaTime = now - then;
then = now;
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.useProgram(progInfo.program);
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
m4.perspective(fov, aspect, zNear, zFar, projection);
m4.identity(camera);
m4.translate(camera, [px, py, pz], camera);
m4.rotateX(camera, degToRad(elev), camera);
m4.rotateY(camera, degToRad(-ang), camera);
m4.rotateZ(camera, degToRad(roll), camera);
m4.inverse(camera, view);
m4.multiply(projection, view, viewProjection);
for (let z = -1; z <= 1; ++z) {
for (let y = -1; y <= 1; ++y) {
for (let x = -1; x <= 1; ++x) {
if (x === 0 && y === 0 && z === 0) {
continue;
}
m4.identity(world);
m4.translate(world, [x * 3, y * 3, z * 3], world);
m4.multiply(viewProjection, world, worldViewProjection);
m4.inverse(world, worldInverse);
m4.transpose(worldInverse, worldInverseTranspose);
twgl.setBuffersAndAttributes(gl, progInfo, bufferInfo);
twgl.setUniforms(progInfo, {
u_worldViewProjection: worldViewProjection,
u_worldInverseTranspose: worldInverseTranspose,
u_color: [(x + 2) / 3, (y + 2) / 3, (z + 2) / 3, 1],
u_lightDir: lightDir,
});
twgl.drawBufferInfo(gl, bufferInfo);
}
}
}
if (keys['87'] || keys['83']) {
const direction = keys['87'] ? 1 : -1;
px -= camera[ 8] * deltaTime * speed * direction;
py -= camera[ 9] * deltaTime * speed * direction;
pz -= camera[10] * deltaTime * speed * direction;
}
if (keys['65'] || keys['68']) {
const direction = keys['65'] ? 1 : -1;
ang += deltaTime * turnSpeed * direction;
}
if (keys['81'] || keys['69']) {
const direction = keys['81'] ? 1 : -1;
roll += deltaTime * turnSpeed * direction;
}
if (keys['38'] || keys['40']) {
const direction = keys['38'] ? 1 : -1;
elev += deltaTime * turnSpeed * direction;
}
requestAnimationFrame(render);
}
requestAnimationFrame(render);
window.addEventListener('keydown', (e) => {
keys[e.keyCode] = true;
e.preventDefault();
});
window.addEventListener('keyup', (e) => {
keys[e.keyCode] = false;
e.preventDefault();
});
function degToRad(d) {
return d * Math.PI / 180;
}
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
pre { position: absolute; left: 1em; top: 0; }
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas></canvas>
<pre>
A = left
D = right
W = forward
S = down
Q = roll left
E = roll right
UP = look up
DN = look down
</pre>
I am trying to move an object with mouse using pressmove event on the object. In PC and Tablet it is working well. But, in the mobile devices it is not working well as those have different width and height.
You can view the following URL:-
http://quirktools.com/screenfly/#u=http://saurabhysecit.byethost15.com/scratchGame_Canvas.html&w=320&h=568&a=37&s=1
Direct URL is - http://saurabhysecit.byethost15.com/scratchGame_Canvas.html
It has been generated from Animate CC.
These are the code below.
JS Code -
(function (lib, img, cjs, ss, an) {
var p; // shortcut to reference prototypes
lib.ssMetadata = [];
function mc_symbol_clone() {
var clone = this._cloneProps(new this.constructor(this.mode, this.startPosition, this.loop));
clone.gotoAndStop(this.currentFrame);
clone.paused = this.paused;
clone.framerate = this.framerate;
return clone;
}
function getMCSymbolPrototype(symbol, nominalBounds, frameBounds) {
var prototype = cjs.extend(symbol, cjs.MovieClip);
prototype.clone = mc_symbol_clone;
prototype.nominalBounds = nominalBounds;
prototype.frameBounds = frameBounds;
return prototype;
}
(lib.coin = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#AA8801").ss(1,2,1).p("AH5AAQAACrhhCBQgIAKgIAKQgQAUgTASQiKCLjAAKQgNAAgOAAQi5AAiKh2QgRgOgQgRQiUiTAAjTQAAjDCBiOIAAgBQAJgKAKgKQAUgUAVgSQB9hlCigIQAOgBAOAAQAaAAAZACQAHAAAHABQCoAUB8B9QATASAQAUQBtCEAECvQAAADAAACQAAAFAAADg");
this.shape.setTransform(-4.8,0.1);
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#D9AE01").s().p("AlbGiQgTgQgSgSQigieAAjiQAAjhCgifQAWgWAXgTQCRh2DCgBQAdABAbACQC+ARCLCMQAUATASAWQB6CTAADEQAADGh6CSQgSAVgUATQiUCWjQAKIgdAAQjHAAiUh+gAgqnnQijAIh8BmQgVARgUAUIgUAUIAAABQiBCOAADEQAADSCVCTQAQARARAOQCJB2C6AAIAbAAQDAgJCJiMQATgSAQgUIAQgUQBhiBAAiqIAAgJIAAgGQgEithtiFQgQgTgTgTQh7h9ipgTIAAgDQgYgCgaAAQgVAAgVACg");
this.shape_1.setTransform(-3.3,-1.7);
this.shape_2 = new cjs.Shape();
this.shape_2.graphics.f("#FFCC00").s().p("AlDGFQgQgOgQgQQiViUAAjSQAAjDCBiPIAAAAIAUgVQAUgUAUgRQB9hmCigIQAWgCAVAAQAZAAAZACIAAADIgNgCQgZgCgbAAIgcABIAcgBQAbAAAZACIANACQCoATB8B9QATATAQAUQBsCEAFCvIAAAFIAAAIQAACqhhCCIgQATQgQAUgTATQiKCLjAAJIgbABQi5AAiKh3g");
this.shape_2.setTransform(-4.8,0.1);
this.shape_3 = new cjs.Shape();
this.shape_3.graphics.f("#695400").s().p("Ah6I1IgBAAQjHgKiUiJQCUB+DIAAIAeAAQDOgKCUiWQAUgTASgWQB6iSAAjFQAAjEh6iTQgSgWgUgUQiKiLi+gRQgbgDgdAAQjCAAiSB3QCSiBDBgKIABAAIAfAAIAbAAIAAAAQDXAJCbCcIAaAbIACAEQCJCcAADUIAAACQgBDViICaIgCAEQgMANgOANQikCmjpAAIgfAAg");
this.shape_3.setTransform(9,-1.7);
this.timeline.addTween(cjs.Tween.get({}).to({state:[{t:this.shape_3},{t:this.shape_2},{t:this.shape_1},{t:this.shape}]}).wait(1));
}).prototype = getMCSymbolPrototype(lib.coin, new cjs.Rectangle(-57.8,-58.2,113.9,113.1), null);
// stage content:
(lib.scratchGame_Canvas = function(mode,startPosition,loop) {
if (loop == null) { loop = false; } this.initialize(mode,startPosition,loop,{});
// timeline functions:
this.frame_0 = function() {
var pressBool=false;
var mask_mc = new createjs.Shape();
var bg_mc = new createjs.Bitmap("images/YLogo1.jpg");
//var coin_mc = new lib.coin();
var coin_mc = new createjs.Shape(new createjs.Graphics().beginFill("#FFFFFF").drawCircle(0, 0, 50));
coin_mc.x = stage.canvas.width/2;
coin_mc.y = stage.canvas.width/2;
stage.addChild(bg_mc, coin_mc);
createjs.Touch.enable(stage, false, true);
if(sRatio<1){
coin_mc.scaleX = coin_mc.scaleY = sRatio;
}
coin_mc.addEventListener('pressmove', moveCoin.bind(this));
coin_mc.addEventListener('mouseup', releaseCoin.bind(this));
updateCacheImage(false);
function moveCoin(e){
e.currentTarget.x = e.stageX;
e.currentTarget.y = e.stageY;
stage.update();
createMask(e);
}
function createMask(e) {
if(!pressBool)return;
var xLoc = stage.mouseX-20;
var yLoc = stage.mouseY-30;
mask_mc.graphics.beginFill("FFFFFF").drawEllipse(xLoc, yLoc, 40, 60);
updateCacheImage(true);
}
function updateCacheImage(update){
var w = 361;
if (update) {
mask_mc.updateCache();
} else {
mask_mc.cache(0, 0, w, w);
}
maskFilter = new createjs.AlphaMaskFilter(mask_mc.cacheCanvas);
bg_mc.filters = [maskFilter];
if (update) {
bg_mc.updateCache(0, 0, w, w);
} else {
bg_mc.cache(0, 0, w, w);
}
}
function releaseCoin(e) {
//stage.canvas.style.cursor = "default";
pressBool = false;
updateCacheImage(true);
}
}
// actions tween:
this.timeline.addTween(cjs.Tween.get(this).call(this.frame_0).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(385.9,359.4,113.9,113);
// library properties:
lib.properties = {
width: 550,
height: 400,
fps: 24,
color: "#999999",
opacity: 1.00,
manifest: [],
preloads: []
};
})(lib = lib||{}, images = images||{}, createjs = createjs||{}, ss = ss||{}, AdobeAn = AdobeAn||{});
var lib, images, createjs, ss, AdobeAn;
HTML Code:-
<!DOCTYPE html>
<!--
NOTES:
1. All tokens are represented by '$' sign in the template.
2. You can write your code only wherever mentioned.
3. All occurrences of existing tokens will be replaced by their appropriate values.
4. Blank lines will be removed automatically.
5. Remove unnecessary comments before creating your template.
-->
<html>
<head>
<meta charset="UTF-8">
<meta name="authoring-tool" content="Adobe_Animate_CC">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui" />
<meta name="msapplication-tap-highlight" content="no"/>
<title>scratchGame_Canvas</title>
<!-- write your code here -->
<script src="jquery-3.2.1.slim.min.js"></script>
<script src="createjs-2015.11.26.min.js"></script>
<script src="scratchGame_Canvas.js?1497868121984"></script>
<script>
var canvas, stage, exportRoot, anim_container, dom_overlay_container, fnStartAnimation;
var pRatio = window.devicePixelRatio || 1, xRatio, yRatio, sRatio=1;
function init() {
canvas = document.getElementById("canvas");
anim_container = document.getElementById("animation_container");
dom_overlay_container = document.getElementById("dom_overlay_container");
handleComplete();
}
function handleComplete() {
//This function is always called, irrespective of the content. You can use the variable "stage" after it is created in token create_stage.
exportRoot = new lib.scratchGame_Canvas();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
//Registers the "tick" event listener.
fnStartAnimation = function() {
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
}
//Code to support hidpi screens and responsive scaling.
function makeResponsive(isResp, respDim, isScale, scaleType) {
var lastW, lastH, lastS=1;
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
function resizeCanvas() {
var w = lib.properties.width, h = lib.properties.height;
var iw = window.innerWidth, ih=window.innerHeight;
pRatio = window.devicePixelRatio || 1, xRatio=iw/w, yRatio=ih/h, sRatio=1;
if(isResp) {
if((respDim=='width'&&lastW==iw) || (respDim=='height'&&lastH==ih)) {
sRatio = lastS;
}
else if(!isScale) {
if(iw<w || ih<h)
sRatio = Math.min(xRatio, yRatio);
}
else if(scaleType==1) {
sRatio = Math.min(xRatio, yRatio);
}
else if(scaleType==2) {
sRatio = Math.max(xRatio, yRatio);
}
}
canvas.width = w*pRatio*sRatio;
canvas.height = h*pRatio*sRatio;
canvas.style.width = dom_overlay_container.style.width = anim_container.style.width = w*sRatio+'px';
canvas.style.height = anim_container.style.height = dom_overlay_container.style.height = h*sRatio+'px';
stage.scaleX = pRatio*sRatio;
stage.scaleY = pRatio*sRatio;
lastW = iw; lastH = ih; lastS = sRatio;
}
}
makeResponsive(true,'both',false,1);
fnStartAnimation();
}
</script>
<!-- write your code here -->
</head>
<body onload="init();" style="margin:0px;">
<div id="animation_container" style="background-color:rgba(153, 153, 153, 1.00); width:550px; height:400px">
<canvas id="canvas" width="550" height="400" style="position: absolute; display: block; background-color:rgba(153, 153, 153, 1.00);"></canvas>
<div id="dom_overlay_container" style="pointer-events:none; overflow:hidden; width:550px; height:400px; position: absolute; left: 0px; top: 0px; display: block;">
</div>
</div>
</body>
</html>
Hope to get response soon.
Thanks.
As I mentioned in the comments, you can transform the coordinates, so your x/y mouse position is not affected by the canvas scaling by responsiveness, and one alternative is to use, in the binded function with the pressmove event (in your case, the function moveCoin()), the globalToLocal() method.
scratchGame_Canvas.js
Function moveCoin()
function moveCoin(e){
var point;
point = stage.globalToLocal(e.stageX, e.stageY);
e.currentTarget.x = point.x;
e.currentTarget.y = point.y;
stage.update();
createMask(e);
}
See also: Drag and drop with easeljs in Animate CC 2017
& MovieClip class (EaselJS API)
Following the documentation it was easy to figure it out how to click on a mesh, but preventing the camera from going though a mesh not that easy. I need some guidelines.
How can I stop the camera from moving through messes using Raycaster?
jsbin
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - interactive cubes</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body style="margin:0;overflow:hidden;">
<div style="position:fixed;background:rgba(255,255,255,0.9);" onmouseout="new function(){controls=new function(){this.moveX=0;this.moveY=0;this.moveZ=0;this.rotateX=0;this.rotateY=0;};}">Move RightMove LeftMove DownMove UpMove BackMove FrontRotate RightRotate LeftRotate UpRotate Down</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js"></script>
<script>
var container;
var camera, scene, raycaster, renderer;
var mouse = new THREE.Vector2(),INTERSECTED=[],clickedIn/*bc starts like it was clicked*/=false,controls;
var clock = new THREE.Clock();
init();
animate();
function init() {
controls = new function () {
this.moveX = 0;
this.moveY = 0;
this.moveZ = 0;
this.rotateX = 0;
this.rotateY = 0;
}
container = document.createElement('div');
document.body.appendChild(container);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1).normalize();
scene.add(light);
var geometry = new THREE.BoxBufferGeometry(20, 20, 20);
for (var i = 0; i < 50; i++) {
var object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff }));
object.name = 'Index:' + i;
object.userData.foo = 'foo';
object.position.x = Math.floor(Math.random() * 201) - 100;
object.position.y = Math.floor(Math.random() * 201) - 100;
object.position.z = Math.floor(Math.random() * 201) - 100;
object.rotation.x = Math.random() * 2 * Math.PI;
object.rotation.y = Math.random() * 2 * Math.PI;
object.rotation.z = Math.random() * 2 * Math.PI;
object.scale.x = Math.random() + 0.5;
object.scale.y = Math.random() + 0.5;
object.scale.z = Math.random() + 0.5;
scene.add(object);
}
raycaster = new THREE.Raycaster();
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xf0f0f0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
container.addEventListener('click', function (event) {
event.preventDefault();
clickedIn = true;
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
}, false);
window.addEventListener('resize', function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}, false);
}
function animate() {
requestAnimationFrame(animate);
// raycaster
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(scene.children);
for (var i = 0; i < INTERSECTED.length; i++) {
INTERSECTED[i].material.emissive.setHex(INTERSECTED[i].currentHex);
INTERSECTED.splice(i, 1);
}
for (var i = 0; clickedIn && i < intersects.length; i++) {
var length = INTERSECTED.push(intersects[0].object) - 1;
INTERSECTED.currentHex = INTERSECTED[length].material.emissive.getHex();
INTERSECTED[length].material.emissive.setHex(0xff0000);
}
// move
var delta = clock.getDelta(), step = 100, stepAngle = (Math.PI / 2);
if (controls.moveX == 1) camera.translateX(step * delta);
else if (controls.moveX == -1) camera.translateX(-step * delta);
if (controls.moveY == 1) camera.translateY(step * delta);
else if (controls.moveY == -1) camera.translateY(-step * delta);
if (controls.moveZ == 1) camera.translateZ(step * delta);
else if (controls.moveZ == -1) camera.translateZ(-step * delta);
if (controls.rotateX == 1) camera.rotateOnAxis(new THREE.Vector3(1, 0, 0), stepAngle * delta);
if (controls.rotateX == -1) camera.rotateOnAxis(new THREE.Vector3(1, 0, 0), -stepAngle * delta);
if (controls.rotateY == 1) camera.rotateOnAxis(new THREE.Vector3(0, 1, 0), stepAngle * delta);
if (controls.rotateY == -1) camera.rotateOnAxis(new THREE.Vector3(0, 1, 0), -stepAngle * delta);
camera.updateMatrixWorld();
// render
renderer.render(scene, camera);
}
</script>
</body>
</html>
For a First-Person Camera, I think that the right way to do that would be to use the bounding sphere of the camera and test it over each mesh of the scene, but if you really want to use a raycaster then I can think of 2 approaches :
Approach 1
In your rendering loop :
Update the position of your camera ;
For each object in your scene :
Create a ray that goes from the camera to the mesh and starts slightly before the camera;
Cast the ray. If an intersection is found and lies before the camera (1), move the camera to the intersection point.
Approach 2
In your rendering loop again :
Update the position of your camera ;
Create one ray that points towards the direction of the camera and starts slightly before the camera ;
Create another ray that points in the opposite direction of the camera and starts slightly after the camera ;
Cast the first ray. If an intersection is found and the intersection point lies before the camera (1) than move the camera to the intersection point ;
If no intersection is found, cast the second ray. If an intersection is found and the intersection point lies after the camera (2) than move the camera to the intersection point.
The first algorithm is in O(n), n being the number of objects in your scene whereas the second one is in O(1) but can be tricky with big meshes.
Im trying to resize everything on window resize.
I have this function but only seems to resize one layer ( graphLayer.add(drawGraph);)
I thought the code below should resize everything??
function onResize(){
var widowWidth = (window.innerWidth) -yPadding; // width - the padding
var widowHeight = (window.innerHeight) -xPadding; // Height - the padding
stage.setWidth((window.innerWidth) -yPadding);
stage.setHeight((window.innerHeight) -xPadding);
stage.draw();
}
here is a the basics of my code
$(window).resize(onResize);
var graph;
var graphLayer = new Kinetic.Layer();
var BubbleLayer = new Kinetic.Layer();
var tooltipLayer = new Kinetic.Layer();
var widowWidth = (window.innerWidth) -yPadding; // width - the padding
var widowHeight = (window.innerHeight) -xPadding; // Height - the padding
var stage = new Kinetic.Stage({
container: 'graph',
width: widowWidth, // width - the padding
height: widowHeight, // Height - the padding
});
var tooltip = new Kinetic.Label({
opacity: 0.75,
visible: false,
listening: false
});
tooltip.add(new Kinetic.Tag({
.........
}));
tooltip.add(new Kinetic.Text({
.........
}));
var drawGraph = new Kinetic.Shape ({
sceneFunc: function(ctx){
.........
}
ctx.fillStrokeShape(this);
},
stroke: 'black',
strokeWidth: 1
});
var drawGraphquarter = new Kinetic.Shape ({
sceneFunc: function(ctx){
.........
}
},
stroke: 'red',
strokeWidth: 3
});
// build data
$.getJSON( "bubble_data.json", function( data ) {
$.each( data.projects, function(i) {
var bubbleData = [];
.........
bubbleData.push({
.........
});
.........
for(var n = 0; n < bubbleData.length; n++) {
addBubble(bubbleData[n], BubbleLayer);
stage.add(BubbleLayer);
}
});
graphLayer.add(drawGraph);
graphLayer.add(drawGraphquarter);
stage.add(BubbleLayer);
stage.add(graphLayer);
graphLayer.moveToBottom();
tooltipLayer.add(tooltip);
stage.add(tooltipLayer);
});
});
// add bubles to layer
function addBubble(obj, BubbleLayer) {
var bubble = new Kinetic.Shape({
sceneFunc: function(ctx) {
.........
});
BubbleLayer.add(bubble);
}
// calendar quarter
function getQuarter(d) {
.........
}
function onResize(){
var widowWidth = (window.innerWidth) -yPadding; // width - the padding
var widowHeight = (window.innerHeight) -xPadding; // Height - the padding
stage.setWidth((window.innerWidth) -yPadding);
stage.setHeight((window.innerHeight) -xPadding);
stage.draw();
}
Updated my code to this.
var graph;
var xPadding = 10;
var yPadding = 10;
var graphLayer = new Kinetic.Layer();
var graphLayerQuater = new Kinetic.Layer();
var BubbleLayer = new Kinetic.Layer();
var tooltipLayer = new Kinetic.Layer();
var widowWidth = (window.innerWidth) -yPadding; // width - the padding
var widowHeight = (window.innerHeight) -xPadding; // Height - the padding
var stage = new Kinetic.Stage({
container: 'graph',
width: widowWidth,
height: widowHeight,
});
var initialScale = stage.scale(); //returns {x: 1, y: 1}
var initialWidth = (window.innerWidth) -yPadding; // width - the padding
var initialHeight = (window.innerHeight) -xPadding; // Height - the padding
onresize function
window.onresize = function(event) {
var width = (window.innerWidth) -yPadding;
var height =(window.innerHeight) -xPadding;
var xScale = (width / initialWidth) * initialScale.x;
var yScale = (height / initialHeight) * initialScale.y;
var newScale = {x: xScale, y: yScale};
stage.setAttr('width', width);
stage.setAttr('height', height);
stage.setAttr('scale', newScale );
stage.draw();
}