When I click and drag my mouse across a scene, it takes two full screen widths to make a 360 degree turn.
Is it possible to adjust the sensitivity of an A-Frame scene?
In case anyone was curious, this is the html I am using:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script src="https://aframe.io/releases/0.5.0/aframe.min.js"></script>
</head>
<body>
<a-scene vr-mode-ui="enabled: false">
<a-assets>
<img id="image" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/sechelt.jpg">
</a-assets>
<a-sky id="image-360" radius="10" src="#image"></a-sky>
</a-scene>
</body>
</html>
<script type="text/javascript">
AFRAME.registerComponent('drag-rotate-component',{
schema : { speed : {default:1}},
init : function(){
this.ifMouseDown = false;
this.x_cord = 0;
this.y_cord = 0;
document.addEventListener('mousedown',this.OnDocumentMouseDown.bind(this));
document.addEventListener('mouseup',this.OnDocumentMouseUp.bind(this));
document.addEventListener('mousemove',this.OnDocumentMouseMove.bind(this));
},
OnDocumentMouseDown : function(event){
this.ifMouseDown = true;
this.x_cord = event.clientX;
this.y_cord = event.clientY;
},
OnDocumentMouseUp : function(){
this.ifMouseDown = false;
},
OnDocumentMouseMove : function(event)
{
if(this.ifMouseDown)
{
var temp_x = event.clientX-this.x_cord;
var temp_y = event.clientY-this.y_cord;
if(Math.abs(temp_y)<Math.abs(temp_x))
{
this.el.object3D.rotateY(temp_x*this.data.speed/100);
}
else
{
this.el.object3D.rotateX(temp_y*this.data.speed/100);
}
this.x_cord = event.clientX;
this.y_cord = event.clientY;
}
}
});
</script>
Source you can adjust the speed, and add the camera component right above the sky
<a-entity camera drag-rotate-component></a-entity>
Demo
You will only need the Y defined
Related
I have created a simple html using the draggable marker example from here maps. I have adapted it to support IE 11 by adding reference to legacy js, meta tag and using P2D engine in map options. Also added two url parameters for coordinates. It works perfectly in IE11 and it loads and shows pan and zoom buttons in ms-access webbrowser but it keeps static, it's not draggable, but pan and zoom works.
The curious thing is that if I navigate to wego.here.com in the same webbrowser control then the map is draggable. So they're doing something else in the here maps main page that I'm not doing in my script.
I have also tried using Microsoft Web Browser from the activex controls list in access.
I need it to be draggable so I can pick the coordinates after the user changes the marker position.
This is my script:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Draggable Marker</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-core.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-core-legacy.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-service.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-service-legacy.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-ui.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js" type="text/javascript" charset="utf-8"></script>
<style>
html, body { margin:0px; padding:0px; width: 100%; height: 100%; }
.main { height: 100%; }
</style>
</head>
<body id="markers-on-the-map">
<div class="main" style="width:100%" id="map"></div>
<input type="hidden" id="long" name="long">
<input type="hidden" id="lat" name="lat">
<script>
function addDraggableMarker(map, behavior){
var marker = new H.map.Marker({lat:latitud, lng:longitud}, {volatility: true});
// Ensure that the marker can receive drag events
marker.draggable = true;
map.addObject(marker);
// disable the default draggability of the underlying map
// and calculate the offset between mouse and target's position
// when starting to drag a marker object:
map.addEventListener('dragstart', function(ev) {
var target = ev.target,
pointer = ev.currentPointer;
if (target instanceof H.map.Marker) {
var targetPosition = map.geoToScreen(target.getGeometry());
target['offset'] = new H.math.Point(pointer.viewportX - targetPosition.x, pointer.viewportY - targetPosition.y);
behavior.disable();
}
}, false);
// re-enable the default draggability of the underlying map
// when dragging has completed
map.addEventListener('dragend', function(ev) {
var target = ev.target;
if (target instanceof H.map.Marker) {
$('#long').val(ev.target.b.lng);
$('#lat').val(ev.target.b.lat);
behavior.enable();
}
}, false);
// Listen to the drag event and move the position of the marker
// as necessary
map.addEventListener('drag', function(ev) {
var target = ev.target,
pointer = ev.currentPointer;
if (target instanceof H.map.Marker) {
target.setGeometry(map.screenToGeo(pointer.viewportX - target['offset'].x, pointer.viewportY - target['offset'].y));
}
}, false);
}
/**
* Boilerplate map initialization code starts below:
*/
//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: '?????????????????????????????????'
});
var defaultLayers = platform.createDefaultLayers();
//url parameters
var query_string = {};
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (typeof query_string[pair[0]] === "undefined") {
query_string[pair[0]] = decodeURIComponent(pair[1]);
} else if (typeof query_string[pair[0]] === "string") {
var arr = [ query_string[pair[0]],decodeURIComponent(pair[1]) ];
query_string[pair[0]] = arr;
} else {
query_string[pair[0]].push(decodeURIComponent(pair[1]));
}
}
var latitud=query_string.lat;
var longitud=query_string.long;
//Step 2: initialize a map - this map is centered over Boston
var map = new H.Map(document.getElementById('map'),
defaultLayers.raster.normal.map, {
center: {lat:latitud, lng:longitud},
engineType: H.map.render.RenderEngine.EngineType.P2D,
zoom: 12,
pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
//window.addEventListener('resize', () => map.getViewPort().resize());
window.addEventListener('resize', function () {map.getViewPort().resize(); });
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
//var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Step 4: Create the default UI:
var ui = H.ui.UI.createDefault(map, defaultLayers, 'en-US');
// Add the click event listener.
addDraggableMarker(map, behavior);
</script>
</body>
</html>```
Check please on this static page
: your code works for my IE11
Here is my calling html code
<!DOCTYPE html>
<html>
<head>
<title>Display Card Type</title>
</head>
<script src='Card.js'; ></script>
<body>
<script>
var card = new myCardType();
var value = new myCardType();
card.setCard('I am a club');
value.setFace('I am an Ace');
card.showSuit();
value.showFace();
</script>
</body>
</html>
And here is the separate function (saved in same folder).
function myCardType(){
this.suit = suit;
this.showSuit = function(){
alert(this.suit);
}
this.face = value;
this.showFace = function() {
alert(this.face);
}
this.setCard = function (newSuit) {
this.suit = newSuit;
}
this.setFace = function (newValue) {
this.face = newValue;
}
}
Spent ages reviewing this but just cannot see what is going on, grateful for any clues.
I am trying to resize a canvas element to the width of the window using VueJS. I've seen many examples of this working with vanilla JS, but for whatever reason, with VueJS I can't get the canvas content to re-render.
An example is attached. The example is modified from the vanilla JS version from here: http://ameijer.nl/2011/08/resizable-html5-canvas/
https://codepen.io/bastula/pen/yZXowo
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Canvas Test</title>
</head>
<body>
<div id="app">
<canvas id="image-canvas" ref="imagecanvas" v-bind:width="width" v-bind:height="height" style="
background-color: #000;">
</canvas>
</div>
</body>
</html>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: function () {
return {
height: 512,
width: 512,
margin: 20,
};
},
mounted() {
window.addEventListener('resize', this.handleResize);
this.handleResize();
},
computed: {
canvas: function () {
return this.$refs.imagecanvas;
},
ctx: function () {
return this.canvas.getContext('2d');
}
},
methods: {
handleResize: function () {
// Calculate new canvas size based on window
this.height = window.innerHeight - this.margin;
this.width = window.innerWidth - this.margin;
this.drawText();
},
drawText: function () {
// Redraw & reposition content
var resizeText = 'Canvas width: ' + this.canvas.width + 'px';
this.ctx.textAlign = 'center';
this.ctx.fillStyle = '#fff';
this.ctx.fillText(resizeText, 200, 200);
}
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
}
})
</script>
Solved here: https://forum.vuejs.org/t/resize-canvas-element-based-on-window-change-using-vuejs/55497/2?u=bastula
The solution is to use: nextTick.
So instead of this.drawText() in the handleResize method it should be:
this.$nextTick(() => {
this.drawText();
})
Updated working CodePen can be found here.
I am using Fabric.js to draw rectangles on a canvas. After drawing a rectangle, I want to disable all events on that object. I have tried to do it using canvas.__eventListeners["mouse:down"] = []; but then after the object selection is cleared, the canvas can't apply any events.
<html lang="en" >
<head>
<meta charset="utf-8" />
<title>HTML5 canvas - Image color picker | Script Tutorials</title>
<link href="index.css" rel="stylesheet" type="text/css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.1.0/fabric.all.min.js" ></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<div class="column1">
<canvas id="panel" width="700" height="350"></canvas>
</div>
<div style="clear:both;"></div>
<div id="log"></div>
</div>
</body>
<script>
(function() {
var canvas = new fabric.Canvas('panel');
var clicks=0;
var x1=0;var y1=0;
var rect;
canvas.on('mouse:down', function(e){
//check if you clicked on an object that exists canvas
if(e.target == undefined){
if (clicks == 0) {
var pointer=canvas.getPointer(event.e);
console.log(pointer);
x1 = pointer.x;
y1 =pointer.y;
console.log("Start Pointer " +x1 ,y1);
clicks++;
}
else
{
var endpointer=canvas.getPointer();
console.log(endpointer);
var endx=endpointer.x;
var endy=endpointer.y;
console.log("Endpointer " +endx ,endy);
console.log("x and y"+x1,y1);
var newwidth=endpointer.x- x1;
var newheight=endpointer.y - y1;
rect=new fabric.Rect({
left:x1,
top: y1,
originX :'left',
originY :'top',
width:newwidth,
height:newheight,
selectable: true,
evented:false,
fill:'red',
opacity :0.3
});
canvas.add(rect);
//console.log(rect.setWidth(pointer2.x- x1 ));
//console.log(rect.setHeight( pointer2.y - y1));
canvas.renderAll();
clicks=0;
}
}
else
{
//canvas.getActiveObject().remove();
canvas.__eventListeners["mouse:down"] = [];
}
});
canvas.on('object:moving',function(){
var bound=rect.getBoundingRect();
console.log(bound.left,bound.top,bound.width,bound.height);
});
canvas.on('object:scaling',function(){
var bound=rect.getBoundingRect();
console.log(bound.left,bound.top,bound.width,bound.height);
});
canvas.on('object:selected',function(e){
document.onkeydown = function(e) {
if (e.keyCode === 27||e.button==3) {
e.preventDefault();
canvas.getActiveObject().remove();
}
}
});
fabric.Image.fromURL('fedex.jpg', function (img) {
canvas.add(img.set({
width: 700,
height:350,
left: 350,
top: 175,
selectable: false,
}));
});
})();
</script>
With the method canvas.off('mouse:down', eventHandler) event handlers registered using canvas.on('mouse:down', eventHandler) can be removed. Be sure to pass the same function into both calls (e.g. by assigning the handler to a variable).
This method is available on all Observables in fabric (see API doc: http://fabricjs.com/docs/fabric.Observable.html#off)
What is the final answer? We're basing our decision to mousedown on or mousedown off, based on the event - if it has a target. I came up with this solution (a 2nd mousedown handler), but it didn't work.
canvas.on('mouse:down', function (e) {
// canvas click, not object click; so create the obj
if (e.target === undefined) {
canvas.on('mouse:down', eventHandler);
}
else {
// an object was clicked, so don't create the obj again
canvas.off('mouse:down', eventHandler);
}
});
Where eventHandler is the function that handles object creation.
I have created a streaming webcam with html5. At the moment I can take a picture through my web cam, but I would like to know if it is possible to choose media stream device from the list, e.g. I have two web cams I want to choose the webcam to activate. How can I do that with html5 getUserMedia() call?
Thanks!
You can get the list of web camera
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Video Camera List</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js" ></script>
<style type="text/css" media="screen">
video {
border:1px solid gray;
}
</style>
</head>
<body>
<script>
if (!MediaStreamTrack) document.body.innerHTML = '<h1>Incompatible Browser Detected. Try <strong style="color:red;">Chrome Canary</strong> instead.</h1>';
var videoSources = [];
MediaStreamTrack.getSources(function(media_sources) {
console.log(media_sources);
// alert('media_sources : '+media_sources);
media_sources.forEach(function(media_source){
if (media_source.kind === 'video') {
videoSources.push(media_source);
}
});
getMediaSource(videoSources);
});
var get_and_show_media = function(id) {
var constraints = {};
constraints.video = {
optional: [{ sourceId: id}]
};
navigator.webkitGetUserMedia(constraints, function(stream) {
console.log('webkitGetUserMedia');
console.log(constraints);
console.log(stream);
var mediaElement = document.createElement('video');
mediaElement.src = window.URL.createObjectURL(stream);
document.body.appendChild(mediaElement);
mediaElement.controls = true;
mediaElement.play();
}, function (e)
{
// alert('Hii');
document.body.appendChild(document.createElement('hr'));
var strong = document.createElement('strong');
strong.innerHTML = JSON.stringify(e);
alert('strong.innerHTML : '+strong.innerHTML);
document.body.appendChild(strong);
});
};
var getMediaSource = function(media) {
console.log(media);
media.forEach(function(media_source) {
if (!media_source) return;
if (media_source.kind === 'video')
{
// add buttons for each media item
var button = $('<input/>', {id: media_source.id, value:media_source.id, type:'submit'});
$("body").append(button);
// show video on click
$(document).on("click", "#"+media_source.id, function(e){
console.log(e);
console.log(media_source.id);
get_and_show_media(media_source.id);
});
}
});
}
</script>
</body>
</html>
In the latest Chrome Canary (30.0.1587.2) it looks like you can enable device enumeration in chrome://flags (looks like it might already be enabled) and use the MediaStreamTrack.getSources API to select the camera.
See this WebRTC bug and mailing list post for more details.