Changing <a-mixin> material texture with a javascript ID on a button press - javascript

So I have the following code:
function pictureChange()
{
document.getElementById("theImage").src="img02.png";
}
<a-mixin id="voxel"
geometry="primitive: box; height: 0.6; width: 0.6; depth: 0.6"
material="id: theImage; src: Box.jpg; color: #696969; roughness: 1; metalness: 0"
snap="offset: 0.4 0.4 0.4; snap: 0.6 0.6 0.6"
></a-mixin>
And I wanted to use the ID "theImage" to change the image url to somthing else, but CSS3 in Aframe doesn't work the same so I can't get it to run properly. If anybody has any ideas that might help me, it would be very appreciated. Thanks.
PS: to clarify, I want some way to change the url by the press of a button.

The id refers to an entity or asset, not a material. Try setting the image on the mixin:
var mixinEl = document.getElementById('voxel');
mixinEl.setAttribute('material','src: #super');
Example: https://glitch.com/edit/#!/swamp-sparrow?path=index.html:1:0

Related

AFRAME I cant display informations on pictures on click

I am starting aframe and I cant display some informations (a small text) on pictures.
If you could help me it would be very nice.
I put the script of my pictures in the head of my html page.
<script id="panInfor" type="text/html">
<a-entity class="panInfor"
geometry="primitive: plane; height: 1; width: 1"
material="shader: flat; src: ${thumb}"
sound="on: click; src: #click-sound"
event-set__mouseenter="scale: 1.2 1.2 1"
event-set__mouseleave="scale: 1 1 1"
event-set__click="_target: #text-informations;_delay: 300; material.src: ${src}"
proxy-event="event: click; to: #text-informations; as: switch">
</a-entity>
</script>
In the asset I put this code concerning the text of my picture
<a-text position="1 2 -4" rotation="0 -90 0" id="text-messi" value="Greatest Of All Times" align="center">
</a-text>
And out of the asset, in the ascene, i put this code :
<a-text id="text-informations" src="#text-messi" visible="false"
animation__click="property: visible; dur: 0; to: true; startEvents: switch" color="yellow">
</a-text>
The aim of my code is just to display informations when I click on the pictures.
I wanted to display informations on pictures, retrieving the code of the tutorial of aframe "360 image gallery" but it doesnt work...
Thank you
Afaik you can't place one a-text node in the assets and refer to it from another a-text node - the assets are rather used to load resources like images, models, videos, sound etc.
If you add the text via the value attribute to the animated a-text entity, it's working:
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-proxy-event-component/dist/aframe-proxy-event-component.min.js"></script>
<script src="https://unpkg.com/aframe-event-set-component#5.0.0/dist/aframe-event-set-component.min.js"></script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: a-entity">
<a-entity position="0 1.6 -2"
geometry="primitive: plane; height: 1; width: 1"
material="shader: flat; color: green"
event-set__mouseenter="scale: 1.2 1.2 1"
event-set__mouseleave="scale: 1 1 1"
proxy-event="event: click; to: #text-informations; as: switch">
<a-text id="text-informations" value="Greatest Of All Times" align="center" visible="false"
animation__click="property: visible; dur: 0; to: true; startEvents: switch" color="yellow">
</a-text>
</a-entity>
</a-scene>
I'd strongly recommend trying to create a custom component, which would handle the hide-show logic:
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-event-set-component#5.0.0/dist/aframe-event-set-component.min.js"></script>
<script>
// the component has to be defined before the <a-scene>
AFRAME.registerComponent("show-text", {
// a schema, so we can provide different <a-text>s
schema: {
txt: {type: "selector"}
},
// called upon initialisation
init: function() {
// on each click - toggle the visibility
this.el.addEventListener("click", evt => {
// if the text is invalid - lets get outta here
if (!this.data.txt) return;
// get the current visibility
const visible = this.data.txt.getAttribute("visible")
// set the visibility to its opposite
this.data.txt.setAttribute("visible", !visible)
})
}
})
</script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: a-entity">
<a-entity position="-1 1.6 -2"
geometry="primitive: plane; height: 1; width: 1"
material="shader: flat; color: green"
event-set__mouseenter="scale: 1.2 1.2 1"
event-set__mouseleave="scale: 1 1 1"
show-text="txt: #text-informations">
<a-text id="text-informations" value="Greatest Of All Times" align="center" visible="false"
animation__click="property: visible; dur: 0; to: true; startEvents: switch" color="yellow">
</a-text>
</a-entity>
<a-entity position="1 1.6 -2"
geometry="primitive: plane; height: 1; width: 1"
material="shader: flat; color: green"
event-set__mouseenter="scale: 1.2 1.2 1"
event-set__mouseleave="scale: 1 1 1"
show-text="txt: #text-informations2">
<a-text id="text-informations2" value="Something Else" align="center" visible="false"
animation__click="property: visible; dur: 0; to: true; startEvents: switch" color="yellow">
</a-text>
</a-entity>
</a-scene>

How do I trigger an animation in A-frame 1.0.4?

After reading through the a-frame animation documentation, I was working around with some code in JSFiddle to get an idea of how it actually works. Seemed pretty simple... Until I tried to apply it to my own project. What was working in JSFiddle, doesn't work in my project. The console returns the error: "document.querySelector(...).emit is not a function". In the fiddle I was working on, a-frame was set to its 0.3.0 version. I need to use the most recent version - 1.0.4. Is there an alternative to "emit"?
Here's the JSFiddle, and a code snippet. Both are working with the 0.3.0 version of A-Frame.If you change the script src from "https://aframe.io/releases/0.3.0/aframe.min.js" to "https://aframe.io/releases/1.0.4/aframe.min.js" though, you will observe that it no longer works.
https://jsfiddle.net/6y5qbr4z/
function lookAway() {
document.getElementById("myCam").innerHTML = '<a-animation id="away" begin="move-away" attribute="rotation" dur="2000" to="20 20 0"></a-animation>';
setTimeout(function(){document.querySelector('#away').emit('move-away');}, 1)
}
.sceneWrapper {
position: relative;
padding-top: 20px;
height: 100vh;
}
<script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script>
<button id="btn01" type="button" name="button" onclick="lookAway();">Look Away</button>
<div class="sceneWrapper">
<a-scene embedded>
<a-camera id="myCam" wasd-controls-enabled="false" look-controls="reverseMouseDrag:true">
</a-camera>
<a-sky src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Equirectangular_projection_SW.jpg/1920px-Equirectangular_projection_SW.jpg"></a-sky>
<a-sphere id="ball" material="color: red" position="0 1.5 -5"></a-sphere>
</a-scene>
</div>
I tried running your examples both the JS fiddle and the code snipet provided. on my local machine i.e through create a html page, add script, css and test,both are working without any errors.
I got this error when I block the aframe.io libraty from loading in the network tab.Can you please confirm that this is not the case.
Are you triggering the lookAway() function before aframe.io library has loaded ?
Is your library loading properly ?
If the above reasons are not one of the reasons for your error.please can you provide more info.
I also checked the checked the documentation for an alernative of .emit function
emit : emits a custom DOM event on the entity. For example, we can emit an event to trigger an animation
So we can trigger custom DOM evennts using javascript as well. please refer snippet for example.
function moveAway() {
document.getElementById("myCam").innerHTML = '<a-animation id="away" begin="move-away" attribute="rotation" dur="2000" to="20 20 0"></a-animation>';
// setTimeout(function(){
// document.querySelector('#away').emit('move-away');},
// 1)
setTimeout(() => document.querySelector('#away').dispatchEvent(new CustomEvent("move-away", {
bubbles: true
})));
}
.sceneWrapper {
position: relative;
padding-top: 20px;
height: 100vh;
}
<script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script>
<button id="btn01" type="button" name="button" onclick="moveAway();">Move Away</button>
<div class="sceneWrapper">
<a-scene embedded>
<a-camera id="myCam" wasd-controls-enabled="false" look-controls="reverseMouseDrag:true">
</a-camera>
<a-sky src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Equirectangular_projection_SW.jpg/1920px-Equirectangular_projection_SW.jpg"></a-sky>
<a-sphere id="ball" material="color: red" position="0 1.5 -5"></a-sphere>
</a-scene>
</div>
I get your point now, sorry I didnt notice the version above
The <a-animation> element was deprecated in a-frame 0.9.0 in favor of the animation component.
It should look a little bit like this:
<a-camera id="myCam" wasd-controls-enabled="false" rotation="0 0 0" look-controls="reverseMouseDrag:true" animation="property: rotation; to: 0 360 0; loop: false; dur: 10000; startEvents: move-away">
please refer example implementation example
function moveAway() {
// document.getElementById("myCam").setAttribute("animation", "property: rotation; to: 0 360 0; loop: false; dur: 10000; startEvents: move-away")
// document.getElementById("myCam").innerHTML = '<a-animation id="away" begin="move-away" attribute="rotation" dur="2000" to="20 20 0"></a-animation>';
setTimeout(function(){
document.querySelector('#myCam').emit('move-away');},
1)
}
.sceneWrapper {
position: relative;
padding-top: 20px;
height: 100vh;
}
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<button id="btn01" type="button" name="button" onclick="moveAway();">Move Away</button>
<div class="sceneWrapper">
<a-scene embedded>
<a-camera id="myCam" wasd-controls-enabled="false" rotation="0 0 0" look-controls="reverseMouseDrag:true" animation="property: rotation; to: 0 360 0; loop: false; dur: 10000; startEvents: move-away">
</a-camera>
<a-sky src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Equirectangular_projection_SW.jpg/1920px-Equirectangular_projection_SW.jpg"></a-sky>
<a-sphere id="ball" material="color: red" position="0 1.5 -5"></a-sphere>
</a-scene>
</div>
Please do let me know if anything else is needed.
Thank you

Prevent SVG CSS bleeding

So basically I have a webpage with two SVGs. On click the chosen SVG will be visible.
Problem: If a SVG with viewport 0 0 20 20 is loaded first and has a stroke-width of 2 and then you load the other SVG with viewport 0 0 2000 2000, the stroke-width of the first one is inherited to the second one. The 2nd one has now a stroke-width of 2 instead of 200.
This is how the containers are:
<div class="clearView-container">
// svg 2
</div>
<div class="techView-container" style="display: none;">
// svg 1
</div>
svg1:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="273.263mm" height="210.784mm" viewBox="-49.35 -56.0421 136.632 105.392">
<defs>
<style type="text/css">
.pen_style1 {stroke: #000000;stroke-width: 0.25;}
.pen_style3 {stroke: #c6c6c6;stroke-width: 0.125;stroke-dasharray: 1, 0.5}
.pen_style4 {stroke: #ff0000;stroke-width: 0.125;stroke-dasharray: 0.2, 0.5, 1, 0.5}
.cos {stroke: #0037a0;}
.hiddenLine { display: none; }
</style>
</defs>
svg2:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="127.46mm" height="104.6mm" viewBox="-3214 -2698 6373 5230">
<defs>
<style type="text/css">
.pen_style1 {stroke: #000000;stroke-width: 25;}
.pen_style3 {stroke: #c6c6c6;stroke-width: 12.5;stroke-dasharray: 100, 50}
.pen_style4 {stroke: #ff0000;stroke-width: 12.5;stroke-dasharray: 20, 50, 100, 50}
.cos {stroke: #0037a0;}
.hiddenLine { display: none; }
</style>
</defs>
And now the SVG in the clearView-container gets the properties of the one from the techView-container if this one (svg1) is loaded first.
Is there a way to prevent the <defs> of the two SVGs to "bleed through"?
In case an answer is needed by someone. This is how I ended up doing it.
I get the svg from a server as string. Than I used #DBSs solution with the IDs (can't do it server-side so here it is:)
function _injectCustomCSS (svg: string): string {
const newID = 'id' + MathLib.hashCode(svg);
const replaceStr = /.pen/g;
const svgDoc = new DOMParser().parseFromString(svg, 'image/svg+xml');
svgDoc.getElementsByTagName('svg')[0].setAttribute('id', newID);
svgDoc.getElementsByTagName('style')[0].textContent = svgDoc.getElementsByTagName('style')[0].textContent.replace(replaceStr, '#' + newID + '>.pen');
/* ... */
return new XMLSerializer().serializeToString(svgDoc);
};

Can't seem to get a mask working in Snap.svg

I'm trying to create an SVG animation using Snap.svg.
Everytime I try to apply a mask, I just see nothing.
The code is relatively straightforward (and works perfectly in the examples):
var open = s.select('.open');
var circle = s.select('.circle').attr({mask:open});
Here's the whole example. I've commented out the code that should apply the mask so you can get an idea of what I'm going for.
Any help would be very appreciated!
The problem you are having is caused by the fact that the mask is affected by both the transform on your iris circle (.circle), and its own transform. In other words, the transform is being applied twice.
There are a number of solutions. One would be to remove the transform attribute from your mask path (.open).
You also need to give your mask element a fill. If it doesn't have a fill, nothing will show up. The reason is that in masks, black (or none/transparent) corresponds to transparency in the mask, and white corresponds to opaque. Colours in between result in translucent areas.
var s = Snap('#eye');
var open = s.select('.open');
var circle = s.select('.circle')
.attr({mask:open});
function closeEye() {
open.animate({ d: "M317.44,135.56s-3,7.41-14,7.41c-10.23,0-13.39-7.44-13.39-7.44s3.16,7.44,13.39,7.44C314.44,143,317.44,135.56,317.44,135.56Z" }, 200, mina.easeinout,openEye);
}
function openEye() {
console.log('callback fired');
open.animate({ d: "M317.44,135.56s-3-7.59-14-7.59c-10.23,0-13.39,7.56-13.39,7.56s3.16,7.44,13.39,7.44C314.44,143,317.44,135.56,317.44,135.56Z" }, 200, mina.easeinout);
}
$(document).ready(function() {
closeEye();
$('#eye').mouseenter( function() {
closeEye();
console.log('hovered');
});
});
.circle, .open {
stroke-width: 1px;
stroke-linecap: rounded;
stroke:black;
fill: none;
}
.open {
fill: white;
}
.svg-wrapper {
width:100px;
height:auto;
position:relative;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="svg-wrapper">
<svg id="eye" viewBox="0 0 28.5 16">
<defs></defs>
<path class="circle" d="M309.56,135.47a5.82,5.82,0,1,1-5.82-5.82A5.82,5.82,0,0,1,309.56,135.47Z" transform="translate(-289.48 -127.47)"/>
<path class="open" d="M317.44,135.56s-3-7.59-14-7.59c-10.23,0-13.39,7.56-13.39,7.56s3.16,7.44,13.39,7.44C314.44,143,317.44,135.56,317.44,135.56Z"/>
</svg>
</div>

How to change background color of inner area of Google Donut hole?

I'm using Google Pie Chart API and trying to create this UI
This is what I have : Fiddle
I'm not sure how to change the color of the inner area of the circle.
According to the Google Chart API, I found that chartArea.backgroundColor is one of the Configuration Options, so I tried it in here
JS
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 11]
]);
var options = {
width: 160,
height: 160,
chartArea: {
left: 10,
top: 20,
width: '100%',
height: '100%'
},
colors: ['#F46E4E', '#F9C262', '#ADB55E', ],
legend: 'none',
enableInteractivity: false,
pieSliceText: 'none',
pieHole: 0.85,
//chartArea.backgroundColor:'pink' // Try it here
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
Result, I still couldn't get to change the color.
After doing some research, the piehole is not able to be colored using Google's config.
The chartArea.backgroundColor that you speak of correlates to the entire area that the chart area takes up, not the PieHole, you have a few options however.
This is where it will cover without any solution and correct syntax
Example with no solutions.
Your second option is this, give the background a transparent background and use positioning to lay a div it behind your chart.
Example with div laid behind chart
As of right now, those seem to be the only option, i've read through the docs multiple times and there just isn't a way to specifically style the pieHole. Sorry it's not the solution you're looking for, but it will work, atleast.
<div class="piehole"></div>
.piehole{
display:block;
background:green;
height:140px;
width:140px;
position:absolute;
z-index:-1;
border-radius:100%;
top:27px;
left:23px;
}
JS Config
var options = {
width: 160,
height: 160,
chartArea: {
left: 10,
top: 20,
width: '100%',
height: '100%'
},
colors: ['#F46E4E', '#F9C262', '#ADB55E', ],
legend: 'none',
enableInteractivity: false,
pieSliceText: 'none',
pieHole: 0.85,
backgroundColor:'transparent'
};
I don't think this can be achieved with ease with google charts. I would recommend a different approach, maybe a SVG using an ellipse and some text-elements.
Thinking something like this.
if you don't want to use jQuery, you have another option is css3
Here is the example:
circle {
fill: yellowgreen;
stroke: #655;
stroke-width: 30;
}
<svg width="100" height="100">
<circle r="30" cx="50" cy="50" />
</svg>
Here is the full documentation
http://www.smashingmagazine.com/2015/07/designing-simple-pie-charts-with-css/
Demo Link :

Categories

Resources