HTML5 Canvas Animation - Rotate Grouped Arc Sectors - html5-canvas

I think I'm almost there, but I could be wrong. I'm trying to get the grouped arc sectors to animate as a whole circle in one direction. How do I reference the createWheel function inside the animateWheel function?
Here is the code:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Circle - Arc 3</title>
<style>
h1 {
font-family:Arial, Helvetica, sans-serif;
font-size: 1.5em;
color:#333;
}
#canvas1{ background-color:#699;}
</style>
</head>
<body>
<h1>Circle - Arc</h1>
<canvas id="canvas1" width="600" height="600"> Your Browser does not support HTML 5
</canvas>
<script>
// arc sectors vars
var centerX = 200;
var centerY = 200;
var radius = 100;
var fullCircleDegree = 360;
// Closure Function to ceate dynamic arc sectors
var arcSectors = function(num) { // The outer function defines a variable called "num"
var getNum = function() {
return 360 / num; // The inner function has access to the "num" variable of the outer function
}
return getNum; // Return the inner function, thereby exposing it to outer scopes
},
createArcSectors = arcSectors(7);
var rotateAngle = createArcSectors() * Math.PI/180;
var startAngle = 0 * Math.PI/180;
var endAngle = createArcSectors() * Math.PI/180;
var animateRot = 0;
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
window.onload = function () {
createWheel();
}
function createWheel() {
var theCanvas = document.getElementById('canvas1');
var context = theCanvas.getContext('2d');
context.clearRect(0, 0, canvas1.width, canvas1.height);
context.arc(centerX, centerY, radius, startAngle, endAngle, false);
// create arc sectors
for (i = 0; i < 7; i++) {
context.translate(centerX, centerY);
context.rotate(rotateAngle);
context.translate(-centerX, -centerY);
context.beginPath();
context.moveTo(centerX, centerY);
context.lineTo(centerX + radius, centerY);
context.arc(centerX, centerY, radius, startAngle, endAngle, false);
context.closePath();
context.stroke();
}
animateWheel();
}
function animateWheel() {
var theCanvas = document.getElementById('canvas1');
var context = theCanvas.getContext('2d');
//rotateAngle = animateRot * Math.PI / 180;
rotateAngle = .002;
console.log(rotateAngle);
animateRot += .002;
if (rotateAngle > 360) {
animateRot -= 1;
}
requestAnimFrame(function() {
animateWheel();
});
}
</script>
</body>
</html>

The requestAnimationFrame design pattern looks like this:
function animate() {
// request a new animation frame as soon as possible
requestAnimFrame(animate);
// reset any values that need to change with every frame
rotation+=PI2/120;
// do the drawing
drawWheel(cx,cy,rotation);
}
Here's a demo of your code (slightly refactored): http://jsfiddle.net/m1erickson/LydNg/
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var PI2=Math.PI*2;
var cx=100;
var cy=100;
var radius=30;
var rotation=-Math.PI/2;
animate();
function drawWheel(cx,cy,rotation){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.translate(cx,cy);
ctx.rotate(rotation);
ctx.beginPath();
ctx.arc(0,0,radius,0,PI2,false);
ctx.closePath();
for(var i=0;i<7;i++){
var r=PI2/7*i;
ctx.moveTo(0,0);
ctx.lineTo(radius*Math.cos(r),radius*Math.sin(r));
}
ctx.stroke();
ctx.restore();
}
var fps = 60;
function animate() {
setTimeout(function() {
requestAnimFrame(animate);
// Drawing code goes here
rotation+=PI2/120;
drawWheel(cx,cy,rotation);
}, 1000 / fps);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=350 height=350></canvas>
</body>
</html>

Related

HTML5 Canvas How To Fill A Mouse Drawn Triangle

I am trying to fill a triangle shape on a HTML5 canvas drawn by dragging the mouse.
I have similar effect for circles, rectangles working.
The code showing both the working drawCircle and not working drawTriangle functions is below. The outline of the triangle gets drawn but it is not filled. I have tried loving the context.stroke line to various places in the sequence of there is no effect.
<style>
#divContainer {
width: 100%;
height: 80%;
background: #ddd;
}
#divContentArea {
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
}
.canvas {
cursor: crosshair;
position:relative;
left:0px;
top:0px;
}
</style>
<div>
Click the button to select the shape type then click and drag mouse on the canvas below.
<BR>
<button type="button" onClick='shapetype="circle";'>Draw Circle</button>
<button type="button" onClick='shapetype="triangle";'>Draw Triangle</button>
<BR>
</div>
<div id="divContainer">
<div id="divContentArea">
<canvas id="canvas" class='canvas'>
Sorry, your browser does not support a canvas object.
</canvas>
</div>
</div>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var canrect = canvas.getBoundingClientRect();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var lastPoint;
var startPoint;
var isDrawing = false;
var shapetype = 'triangle';
canvas.onmousedown = function(e) {
isDrawing = true;
if ( shapetype == 'circle' ) {
canvas.removeEventListener("mousemove", drawTriangle, false);
canvas.addEventListener("mousemove", drawCircle, false);
} else {
canvas.removeEventListener("mousemove", drawCircle, false);
canvas.addEventListener("mousemove", drawTriangle, false);
}
lastPoint = { x: e.offsetX, y: e.offsetY };
startPoint = lastPoint;
};
function drawTriangle(e) {
// This doesn't work - triangle is not filled
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var twidth = Math.abs(mx - startPoint.x) ;
var theight = Math.abs(my - startPoint.y) ;
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
if ( mx >= startPoint.x ) {
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.moveTo(mx-(2*twidth), my );
context.lineTo(mx, my);
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx-(2*twidth), my );
} else {
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.moveTo(mx+(2*twidth), my );
context.lineTo(mx, my);
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx+(2*twidth), my );
}
context.closePath();
context.strokeStyle = 'red';
context.stroke();
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
}
function drawCircle(e) {
// This works
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var cradius = Math.abs(mx - startPoint.x) ;
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
context.strokeStyle = 'red';
context.arc(startPoint.x, startPoint.y, cradius, 0, 2 * Math.PI, false);
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
context.stroke();
}
canvas.onmouseup = function() {
isDrawing = false;
};
canvas.onmouseleave = function() {
isDrawing = false;
};
</script>
function drawTriangle(e) {
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// draw a new rect from the start position
// to the current mouse position
context.strokeStyle = 'red';
context.fillStyle = 'rgba(25,50,75,0.5)';
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
context.beginPath();
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(e.offsetX, e.offsetY);
context.lineTo(startPoint.x * 2 - e.offsetX, e.offsetY);
context.closePath();
context.stroke();
context.fill();
}
The CanvasRenderingContext2D's fill() method fills a path with a given color. To be able to fill such a path, it must contain at least three points - which is fulfilled in your case.
The problem is the way you're creating the path:
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.moveTo(mx-(2*twidth), my );
context.lineTo(mx, my);
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx-(2*twidth), my );
By calling moveTo() again, you're essentially starting a new path - thus you have just three single lines hence nothing to fill.
Try making the path in one go:
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.lineTo(mx-(2*twidth), my );
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var canrect = canvas.getBoundingClientRect();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var lastPoint;
var startPoint;
var isDrawing = false;
var shapetype = 'triangle';
canvas.onmousedown = function(e) {
isDrawing = true;
if (shapetype == 'circle') {
canvas.removeEventListener("mousemove", drawTriangle, false);
canvas.addEventListener("mousemove", drawCircle, false);
} else {
canvas.removeEventListener("mousemove", drawCircle, false);
canvas.addEventListener("mousemove", drawTriangle, false);
}
lastPoint = {
x: e.offsetX,
y: e.offsetY
};
startPoint = lastPoint;
};
function drawTriangle(e) {
// This doesn't work - triangle is not filled
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var twidth = Math.abs(mx - startPoint.x);
var theight = Math.abs(my - startPoint.y);
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
if (mx >= startPoint.x) {
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(mx, my);
context.lineTo(mx - (2 * twidth), my);
} else {
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(mx, my);
context.lineTo(mx + (2 * twidth), my);
}
context.closePath();
context.strokeStyle = 'red';
context.stroke();
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
}
function drawCircle(e) {
// This works
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var cradius = Math.abs(mx - startPoint.x);
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
context.strokeStyle = 'red';
context.arc(startPoint.x, startPoint.y, cradius, 0, 2 * Math.PI, false);
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
context.stroke();
}
canvas.onmouseup = function() {
isDrawing = false;
};
canvas.onmouseleave = function() {
isDrawing = false;
};
#divContainer {
width: 100%;
height: 80%;
background: #ddd;
}
#divContentArea {
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
}
.canvas {
cursor: crosshair;
position: relative;
left: 0px;
top: 0px;
}
<div>
Click the button to select the shape type then click and drag mouse on the canvas below.
<BR>
<button type="button" onClick='shapetype="circle";'>Draw Circle</button>
<button type="button" onClick='shapetype="triangle";'>Draw Triangle</button>
<BR>
</div>
<div id="divContainer">
<div id="divContentArea">
<canvas id="canvas" class='canvas'>
Sorry, your browser does not support a canvas object.
</canvas>
</div>
</div>

Three JS - Uncaught TypeError: Cannot read property 'length' of undefined at THREE.JSONLoader.parse

I'm trying to just render a blender exported json(exported to use in three js). I'm doing that as follows.
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Three.js JSON Loader Demo</title>
<script type="text/javascript" src="three.min.js"></script>
<script type="text/javascript">
var renderer; // A three.js WebGL or Canvas renderer.
var scene; // The 3D scene that will be rendered, containing the model.
var camera; // The camera that takes the picture of the scene.
var light; // A light shining from the direction of the camera.
var model; // The three.js object that represents the model.
var rotateX = 0; // rotation of model about the x-axis
var rotateY = 0; // rotation of model about the y-axis
function modelLoadedCallback(geometry, materials) {
var object = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
/* Determine the ranges of x, y, and z in the vertices of the geometry. */
var xmin = Infinity;
var xmax = -Infinity;
var ymin = Infinity;
var ymax = -Infinity;
var zmin = Infinity;
var zmax = -Infinity;
for (var i = 0; i < geometry.vertices.length; i++) {
var v = geometry.vertices[i];
if (v.x < xmin)
xmin = v.x;
else if (v.x > xmax)
xmax = v.x;
if (v.y < ymin)
ymin = v.y;
else if (v.y > ymax)
ymax = v.y;
if (v.z < zmin)
zmin = v.z;
else if (v.z > zmax)
zmax = v.z;
}
/* translate the center of the object to the origin */
var centerX = (xmin+xmax)/2;
var centerY = (ymin+ymax)/2;
var centerZ = (zmin+zmax)/2;
var max = Math.max(centerX - xmin, xmax - centerX);
max = Math.max(max, Math.max(centerY - ymin, ymax - centerY) );
max = Math.max(max, Math.max(centerZ - zmin, zmax - centerZ) );
var scale = 10/max;
object.position.set( -centerX, -centerY, -centerZ );
console.log("Loading finished, scaling object by " + scale);
console.log("Center at ( " + centerX + ", " + centerY + ", " + centerZ + " )");
/* Create the wrapper, model, to scale and rotate the object. */
model = new THREE.Object3D();
model.add(object);
model.scale.set(scale,scale,scale);
rotateX = rotateY = 0;
scene.add(model);
render();
}
function render() {
renderer.render(scene, camera);
}
function init() {
try {
var theCanvas = document.getElementById("cnvs");
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, theCanvas.width/theCanvas.height, 0.1, 100);
camera.position.z = 30;
light = new THREE.DirectionalLight();
light.position.set(0,0,1);
renderer = new THREE.WebGLRenderer( {
canvas: theCanvas,
antialias: true
} );
scene.add(light);
render();
var loader = new THREE.JSONLoader();
loader.load("DummyBox.js", modelLoadedCallback);
}
catch (e) {
document.getElementById("message").innerHTML = "Sorry, an error occurred: " + e;
}
}
</script>
</head>
<body onload="init()" bgcolor="#CCC">
<noscript>
<p style="color: #A00; font-weight: bold">Sorry, but this page requires JavaScript!</p>
</noscript>
<div style="float:left">
<canvas width=350 height=400 id="cnvs" style="background-color:black"></canvas>
</div>
</body>
</html>
The Contents of DummyBox.js is
{
"metadata":{
"generator":"io_three",
"type":"BufferGeometry",
"normal":36,
"version":3,
"position":36
},
"data":{
"index":{
"type":"Uint16Array",
"itemSize":1,
"array":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35]
},
"attributes":{
"position":{
"type":"Float32Array",
"itemSize":3,
"array":[1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,0.999999,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,0.999999,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,0.999999,1,1,1,1,-1,0.999999,1,1,1,-1,1,0.999999,1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1]
},
"normal":{
"type":"Float32Array",
"itemSize":3,
"array":[-7.10543e-15,-1,2.98023e-08,-7.10543e-15,-1,2.98023e-08,-7.10543e-15,-1,2.98023e-08,7.10543e-15,1,-2.98023e-08,7.10543e-15,1,-2.98023e-08,7.10543e-15,1,-2.98023e-08,1,-2.38419e-07,7.10543e-15,1,-2.38419e-07,7.10543e-15,1,-2.38419e-07,7.10543e-15,-5.96046e-08,-2.98023e-07,1,-5.96046e-08,-2.98023e-07,1,-5.96046e-08,-2.98023e-07,1,-1,-1.49012e-07,-2.38419e-07,-1,-1.49012e-07,-2.38419e-07,-1,-1.49012e-07,-2.38419e-07,2.38419e-07,1.78814e-07,-1,2.38419e-07,1.78814e-07,-1,2.38419e-07,1.78814e-07,-1,-1.77636e-15,-1,2.98023e-08,-1.77636e-15,-1,2.98023e-08,-1.77636e-15,-1,2.98023e-08,1.5099e-14,1,-2.98023e-08,1.5099e-14,1,-2.98023e-08,1.5099e-14,1,-2.98023e-08,1,3.27825e-07,5.66244e-07,1,3.27825e-07,5.66244e-07,1,3.27825e-07,5.66244e-07,-5.0664e-07,1.49012e-07,1,-5.0664e-07,1.49012e-07,1,-5.0664e-07,1.49012e-07,1,-1,-1.19209e-07,-2.08616e-07,-1,-1.19209e-07,-2.08616e-07,-1,-1.19209e-07,-2.08616e-07,2.38419e-07,1.78814e-07,-1,2.38419e-07,1.78814e-07,-1,2.38419e-07,1.78814e-07,-1]
}
}
}
}
I'm new to Three js and not able to figure out what is the problem. Is there any website i can go through.. Is there any problem in Exported JSON file.
The json script looks ok.
If you replace the loader class ( as already mentioned by #TheJim01 )
var loader = new THREE.BufferGeometryLoader(); //new THREE.JSONLoader();
and handle the geometry like this in the modelLoadedCallback function (more here):
var geometry = new THREE.Geometry().fromBufferGeometry(geometry);
you will go through without errors.
PS. The materials parameter in modelLoadedCallback function is undefined.
You can define it like this:
var materials = new THREE.MeshLambertMaterial({color:0xff0000});

How to render geojson with three.js and d3.js

I use three.js r49, d3.v2.js and d3-threeD.js i want to render my city(Mashhad) with three.js
but i got a problem i can render europian countries with these codes but i cant render with existing json file.
d3.js Ref
d3-threeD.js Ref
these are my codes:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>GEO Bar</title>
<link rel="stylesheet" href="">
<script type="text/javascript" src="./scripts/jquery-1.7.2.js"></script>
<script type="text/javascript" src="./scripts/d3.v2.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/three.js/r49/Three.min.js"></script>
<script type="text/javascript" src="./scripts/d3-threeD.js"></script>
<script type="text/javascript" src="./scripts/constants.js"></script>
<script type="text/javascript" src="./scripts/util-geo.js"></script>
<script type="text/javascript" src="./scripts/script.js"></script>
<style type="text/css">
.btns{
position: fixed;
right: 100px;
top: 100px;
}
.btn{
width: 40px;
height: 60px;
background-color: #999;
margin-top: 5px;
text-align: center;
color: #111;
}
.btn > div{
margin-bottom: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="chart"></div>
<div class="btns">
<div class="btn x">
<div class="plus">+</div>X
<div class="minus">-</div>
</div>
<div class="btn y">
<div class="plus">+</div>Y
<div class="minus">-</div>
</div>
<div class="btn z">
<div class="plus">+</div>Z
<div class="minus">-</div>
</div>
</div>
</body>
</html>
constants.js codes:
var appConstants = {
TRANSLATE_0 : -360,
TRANSLATE_1 : 10040,
SCALE : 60000
}
util-geo.js codes:
var geons = {};
geons.geoConfig = function() {
this.TRANSLATE_0 = appConstants.TRANSLATE_0;
this.TRANSLATE_1 = appConstants.TRANSLATE_1;
this.SCALE = appConstants.SCALE;
this.mercator = d3.geo.mercator();
this.path = d3.geo.path().projection(this.mercator);
this.setupGeo = function() {
var translate = this.mercator.translate();
translate[0] = this.TRANSLATE_0;
translate[1] = this.TRANSLATE_1;
this.mercator.translate(translate);
this.mercator.scale(this.SCALE);
}
console.log(2,this.path);
}
// geoConfig contains the configuration for the geo functions
geo = new geons.geoConfig();
script.js codes:
(function($) {
$(function(){
// get the correct geo for d3s
geo.setupGeo();
var
dataURL = "area.json",
scene,
renderer,
camera;
btnXPlus = $(".btns .x .plus"),
btnXMinus = $(".btns .x .minus"),
btnYPlus = $(".btns .y .plus"),
btnYMinus = $(".btns .y .minus"),
btnZPlus = $(".btns .z .plus"),
btnZMinus = $(".btns .z .minus"),
translate = geo.mercator.translate();
// get the data
$.getJSON( dataURL, function(data, textStatus, jqXHR) {
initScene();
addGeoObject();
renderer.render( scene, camera );
// Set up the three.js scene. This is the most basic setup without
// any special stuff
function initScene() {
// set the scene size
var
WIDTH = 600,
HEIGHT = 600;
// set some camera attributes
var
VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 1, FAR = 10000;
// create a WebGL renderer, camera, and a scene
renderer = new THREE.WebGLRenderer({antialias:true});
camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
scene = new THREE.Scene();
// add and position the camera at a fixed position
scene.add(camera);
camera.position.z = 550;
camera.position.x = 0;
camera.position.y = 550;
console.log("scene.position: ",scene.position);
camera.lookAt( scene.position );
// start the renderer, and black background
renderer.setSize(WIDTH, HEIGHT);
renderer.setClearColor(0x321);
// add the render target to the page
$("#chart").append(renderer.domElement);
// add a light at a specific position
var pointLight = new THREE.PointLight(0xFFFFFF);
scene.add(pointLight);
pointLight.position.x = 800;
pointLight.position.y = 800;
pointLight.position.z = 800;
// add a base plane on which we'll render our map
var planeGeo = new THREE.PlaneGeometry(10000, 10000, 10, 10);
var planeMat = new THREE.MeshLambertMaterial({color: 0x666699});
var plane = new THREE.Mesh(planeGeo, planeMat);
// rotate it to correct position
plane.rotation.x = -Math.PI/2;
scene.add(plane);
console.log(1);
}
// add the loaded gis object (in geojson format) to the map
function addGeoObject() {
// keep track of rendered objects
var meshes = [];
var colors = [];
var averageValues = [];
var totalValues = [];
// keep track of min and max, used to color the objects
var maxValueAverage = 0;
var minValueAverage = -1;
// keep track of max and min of total value
var maxValueTotal = 0;
var minValueTotal = -1;
// convert to mesh and calculate values
for (var i = 0 ; i < data.features.length ; i++) {
console.log(data.features[i]);
var geoFeature = data.features[i];
var feature = geo.path(geoFeature);
console.log("feature:",feature);
// we only need to convert it to a three.js path
var mesh = transformSVGPathExposed(feature);
console.log(mesh);
// add to array
meshes.push(mesh);
// we get a property from the json object and use it
// to determine the color later on
var value = parseInt(geoFeature.properties.bev_dichth);
if (value > maxValueAverage) maxValueAverage = value;
if (value < minValueAverage || minValueAverage == -1) minValueAverage = value;
averageValues.push(value);
// var style = JSON.parse(geoFeature.properties.style);
// colors.push(hexToRgb(style.strokeColor));
// colors.push(style.strokeColor);
// and we get the max values to determine height later on.
value = parseInt(geoFeature.properties.aant_inw);
if (value > maxValueTotal) maxValueTotal = value;
if (value < minValueTotal || minValueTotal == -1) minValueTotal = value;
totalValues.push(value);
}
console.log(averageValues,totalValues,colors);
// we've got our paths now extrude them to a height and add a color
for (var i = 0 ; i < averageValues.length ; i++) {
// create material color based on average
var scale = ((averageValues[i] - minValueAverage) / (maxValueAverage - minValueAverage)) * 255;
var mathColor = gradient(Math.round(scale),255);
console.log(scale,mathColor);
var material = new THREE.MeshLambertMaterial({
color: mathColor
});
// var material = new THREE.MeshLambertMaterial({
// // color: hexToRgb(colors[i])
// });
// material.color.setHex(colors[i]);
console.log("material:", material);
// create extrude based on total
var extrude = ((totalValues[i] - minValueTotal) / (maxValueTotal - minValueTotal)) * 100;
var shape3d = meshes[i].extrude({amount: Math.round(extrude), bevelEnabled: false});
console.log("extrude: ",extrude, "shape3d:", shape3d);
// create a mesh based on material and extruded shape
var toAdd = new THREE.Mesh(shape3d, material);
// rotate and position the elements nicely in the center
toAdd.rotation.x = Math.PI/2;
toAdd.translateX(-490);
toAdd.translateZ(50);
toAdd.translateY(extrude/2);
console.log("toAdd: ",toAdd);
// add to scene
scene.add(toAdd);
}
}
// simple gradient function
// function gradient(length, maxLength) {
// var i = (length * 255 / maxLength);
// var r = i;
// var g = 255-(i);
// var b = 0;
// var rgb = b | (g << 8) | (r << 16);
// console.log(rgb);
// return rgb;
// }
function gradient(color, maxLength) {
var i = (length * 255 / maxLength);
var r = i;
var g = 255-(i);
var b = 0;
var rgb = b | (g << 8) | (r << 16);
console.log("rgb: ",rgb);
return rgb;
}
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
// return result ? {
// r: parseInt(result[1], 16),
// g: parseInt(result[2], 16),
// b: parseInt(result[3], 16)
// } : null;
return result ? parseInt(result[1], 16) | (parseInt(result[2], 16) << 8) | (parseInt(result[3], 16) << 16) : null;
}
});
btnXPlus.click(function(){
camera.position.x +=10;
console.log(camera.position.x);
renderer.render( scene, camera );
});
btnXMinus.click(function(){
camera.position.x -=10;
console.log(camera.position.x);
renderer.render( scene, camera );
});
btnYPlus.click(function(){
camera.position.y +=10;
console.log(camera.position.y);
renderer.render( scene, camera );
});
btnYMinus.click(function(){
camera.position.x -=10;
console.log(camera.position.y);
renderer.render( scene, camera );
});
btnZPlus.click(function(){
camera.position.z +=10;
console.log(camera.position.z);
renderer.render( scene, camera );
});
btnZMinus.click(function(){
camera.position.z -=10;
console.log(camera.position.z);
renderer.render( scene, camera );
});
});
})(jQuery);
my geo json file: omidgharib.ir/area.json

canvas, 2 lineTo-paths at the same time

I want to draw a line and while doing so, at the same time the line shall be drawn horizontal reflected. So the User is doing like 2 Strokes. The problem is that a canvas has only one context-object, that cannot be used by two separate lineTo-commands. How can I approach this issue, or would this need an animation frame?
here the code for one lineTo:
[link] http://jsfiddle.net/FgNQk/1/
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var width = window.innerWidth;
var height = window.innerHeight;
canvas.height = height;
canvas.width = width;
canvas.addEventListener('mousedown', function(e) {
this.down = true;
this.X = e.pageX ;
this.Y = e.pageY ;
this.color = rgb();
}, 0);
canvas.addEventListener('mouseup', function() {
this.down = false;
}, 0);
canvas.addEventListener('mousemove', function(e) {
if(this.down) {
with(ctx) {
beginPath();
moveTo(this.X, this.Y);
lineTo(e.pageX , e.pageY );
strokeStyle = "rgb(0,0,0)";
ctx.lineWidth=1;
stroke();
}
this.X = e.pageX ;
this.Y = e.pageY ;
}
}, 0);
To do 2 line paths at once
Store your line segment points in an array.
Then redraw each line segment in both original and horizontally-reflected form.
The red line below is a horizontal-axis reflection of the user's black line
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/XhUdS/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var width = window.innerWidth;
var height = window.innerHeight;
var points=[];
var startingX;
var startingY;
canvas.height = height;
canvas.width = width;
canvas.addEventListener('mousedown', function (e) {
this.down = true;
this.X = e.pageX;
this.Y = e.pageY;
startingX=e.pageX;
startingY=e.pageY;
//this.color = rgb();
}, 0);
canvas.addEventListener('mouseup', function () {
this.down = false;
points=[];
}, 0);
canvas.addEventListener('mousemove', function (e) {
if (this.down) {
with(ctx) {
points.push({x:e.pageX,y:e.pageY});
drawWithHorizontalAxisReflection()
}
}
}, 0);
function drawWithHorizontalAxisReflection(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.lineWidth=3;
for(i=1;i<points.length;i++){
// the users line (black)
ctx.beginPath();
ctx.moveTo(points[i-1].x,points[i-1].y);
ctx.lineTo(points[i].x,points[i].y);
ctx.strokeStyle="black";
ctx.stroke();
// line reflected along horizontal axis (red)
ctx.beginPath();
ctx.moveTo(points[i-1].x,2*startingY-points[i-1].y);
ctx.lineTo(points[i].x,2*startingY-points[i].y);
ctx.strokeStyle="red";
ctx.stroke();
}
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Capturing the mouse coordinates on every step of a jQuery animation

I'm trying to get the mouse coordinates during a jQuery animation, I'm doing this because I'm working on an interactive plug-in which moves the background image inside a div from covercss property to 100% of it's scale when the user go over the element.
I'm near to completing the plug-in but the animation is buggy because it work on the last position of the mouse fired by mousemove event of jQuery.
Does exists some way to avoid the problem?
This is my situation:
$(settings.selector).hover(function (e) {
$(this).bind('mousemove', setFollowMouse);
}, function () {
$(this).unbind('mousemove', setFollowMouse);
zoomOut();
});
var setFollowMouse = function (e) {
var o = {offsetLeft:this.offsetLeft, offsetTop:this.offsetTop};
if (!settings.bg.zooming_in && settings.bg.current_scale != 100) {
settings.bg.zooming_in = true;
zoomIn(e, o);
} else {
followMouse(e, o);
}
}
var zoomIn = function (e, o) {
$({scale:settings.bg.min_perc}).animate ({
scale:100
},{
easing:settings.zoom_in.easing,
duration:settings.zoom_in.duration,
step:function () {
settings.bg.current_scale = this.scale;
followMouse(e, o);
},
complete:function () {
settings.bg.current_scale = 100;
settings.bg.zooming_in = false;
followMouse(e, o);
}
});
}
var followMouse = function (e, o) {
var m_x = e.pageX - o.offsetLeft;
var m_y = e.pageY - o.offsetTop;
settings.bg.perc_pos_x = ((m_x * 100) / (a_w - bg_w)) + '%';
settings.bg.perc_pos_y = ((m_y * 100) / (a_h - bg_h)) + '%';
var bg_w = getScalePercent(settings.bg.width, settings.bg.current_scale);
var a_w = settings.container.width;
var bg_h = getScalePercent(settings.bg.height, settings.bg.current_scale);
var a_h = settings.container.height;
var bpx = - (bg_w - a_w) * m_x / a_w;
var bpy = - (bg_h - a_h) * m_y / a_h;
$(settings.selector).css({
backgroundPosition:bpx + 'px ' + bpy + 'px'
,backgroundSize:bg_w + 'px ' + bg_h + 'px'
});
}
As you see, I use animation to calculate the progressive scaling of the background-image, and trying to calculating it with the follow mouse method, but if I sto moving the mouse, the animation works with the last mousemove event.pageX and Y mouse position.
I've done this because I have problems with make animation method fluid if I trying to rewrite it continuously by with the mouse.
Should I follow some different way to avoid the bug?
forgive my dodgy math; but this should help!
<html>
<head>
<script type="text/javascript" charset="utf-8">
window.onload = function () {
var img = new Image();
img.src = 'http://wallpapers.free-review.net/wallpapers/23/Autumn_Theme_-_Windows_7_Backgrounds.jpg';
var canvas = document.getElementById("canvas1");
canvas.width = img.width;
canvas.height = img.height;
canvas.addEventListener('mousemove', onMouseMove, false);
var ctx = canvas.getContext("2d");
var scale = 0.9;
var scaledwidth = canvas.width * scale;
var scaledheight = canvas.height * scale;
var scaledcenterX = scaledwidth /2;
var scaledcenterY = scaledheight /2;
var animloop = setInterval(function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, scaledwidth, scaledheight, canvas.width - scaledcenterX, canvas.height - scaledcenterY, 0, 0, canvas.width, canvas.height);
}, .01);
function onMouseMove(e) {
mouseX = e.clientX - canvas.offsetLeft;
mouseY = e.clientY - canvas.offsetTop;
scale = mouseX/1000;
scaledwidth = canvas.width * scale;
scaledheight = canvas.height * scale;
}
};
</script>
<style>
body {
background: #001;
background-size: cover;
overflow: hidden;
}
#canvas1 {
position: absolute;
top: 0;
left: 0;
padding: 0;
margin: 0;
height: 100% auto;
}
</style>
</head>
<body>
<canvas id="canvas1"></canvas>
</body>
</html>
I've just solved the problem with this simple edit to my code:
var setFollowMouse = function (e) {
settings.mouse.x = e.pageX - this.offsetLeft;
settings.mouse.y = e.pageY - this.offsetTop;
if (!settings.bg.zooming_in && settings.bg.current_scale != 100) {
settings.bg.zooming_in = true;
zoomIn();
} else {
followMouse();
}
}
the old one:
var setFollowMouse = function (e) {
var o = {offsetLeft:this.offsetLeft, offsetTop:this.offsetTop};
if (!settings.bg.zooming_in && settings.bg.current_scale != 100) {
settings.bg.zooming_in = true;
zoomIn(e, o);
} else {
followMouse(e, o);
}
}
this has removed the buggy behavior.

Resources