I want to make a plane with HTML element in webGL and can do an action like real HTML, example: make a button and when we click it, it give us an animation feedback and run the function. I already seek the answear and found html2canvas and rasterizeHTML.js but it just give like an image not natural HTML. Is there any library or any way for me to do like example above. Thanks in advance...
NOTE : For some reason i can't use CSS3DRenderer in Three.js
For example image you can see in the link below:
If I understand correctly, you're wanting to define an interactive user interface with HTML that is rendered with "3D perspective".
There are a few ways this can be done - one would be to not use WebGL at all, and instead use CSS3 transforms and perspective:
/* Add click handler to demonstrate that elements are still
interactive, even when orientated in 3D space */
const button = document.getElementById("clickme");
button.addEventListener("click", () => {
alert("hi!");
});
/* Optional - just for purpose of demonstration */
#keyframes movement {
from {
transform: rotateY(20deg);
}
to {
transform: rotateY(-20deg);
}
}
/* Define a "perspective wrapper" to give
the child elements the effect of 3D perspective */
.perspective {
width: 500px;
perspective: 500px;
perspective-origin: 50% 50%;
padding: 1rem;
}
.surface {
/* Style the UI surface using regular CSS */
background: red;
padding: 1rem;
text-align: center;
/* Orientates the surface in 3D space */
transform: rotateY(20deg);
animation: movement 5s infinite;
}
<div class="perspective">
<div class="surface">
<button id="clickme">Click me, I'm in 3D and I'm interactive!</button>
</div>
</div>
This approach retains the benefits of declarative HTML, the existing JavaScript DOM WebAPI, while also giving you smooth, hardware accelerated rendering of that HTML in 3D perspective.
Alternatively, if you are needing to render interactive user interfaces within a canvas element (ie, without CSS3 transforms), you could consider a library like Babylon.js which offers a pretty comprehensive GUI framework.
Here is an example show casing a fairly complex GUI rendered in 3D space, built using the Babylon.js framework - the caveat is that the GUI is defined with JavaScript (rather than HTML) however is more akin to the "Three.js way" of doing things.
Related
First of all, here's a link to a page I'm working on, so you can see what I mean for yourself:
http://37.60.224.20/~mdg17761/mirzarasic.com/about-me/
And, here's a link to the effect in the background:
https://github.com/jnicol/particleground
If you go to the page, you'll notice you can't scroll the section in the middle. The website link also isn't clickable and you can't select any of the text.
I'm using Wordpress with the Divi theme to build the website, as well.
I've added the code which creates the background in a Code Module and, it looks like this:
<script>
document.addEventListener("DOMContentLoaded", function() {
particleground(document.getElementById("particleground"), {
dotColor: '#ffffff',
lineColor: '#blue',
particleRadius: 0
});
var intro = document.getElementById('intro');
intro.style.marginTop = -intro.offsetHeight / 2 + 'px';
}, false);
</script>
<style>
#particleground {
position: relative;
}
#particleground canvas {
position: absolute;
z-index: 996;
opacity: 0.2;
}
</style>
Removing the Code Module makes the entire section work again. I've been looking through the source of the plugin, but, I simply don't have enough experience with JavaScript and can't figure out what might be doing this.
I assume you want the particle canvas in the background?
You'll need to change the z-index of your "particle ground", as it's rendering on top of your content area. I'd consider adjusting where you put the code for the particle ground (either higher in the DOM for a naturally lower z-index, or at the bottom closer to the </body> tag and setting the z-index to 0 giving it a structurally lower presence while still needing to lower the z-index.
#particleground {
position: relative;
z-index: 0;
}
(Note, with this you can remove the z-index from your #particleground canvas selector.
If you don't want the center section to be white (which the above code will do), you can set the background of it to transparent to let the canvas show through it:
.et_pb_section_1 {
background: transparent;
}
If you really want the particles "on top" for some reason, while I strongly recommend against it, you can add pointer-events: none; to #particleground - read more here
if I have element,and I want to translate it for 50px more than the current value.Why I can't do something like this?
element.style.transform="translateX(+=50px)"
Is there a way to do something like that?
If your transform is set in a stylesheet, element.style.transform will return an empty string. You must use getComputedStyle.
To get the x translation as an integer use:
var transform = parseInt(window.getComputedStyle(element, null).transform.split(',')[4]);
Then use this to increment by 50 pixels:
element.style.transform = "translateX(" + (transform + 50) + "px)"
Here is a fiddle: https://jsfiddle.net/uhuh9r64/
JS does not understand CSS and vice versa, but CSS can solve this on its own.
Unknown to most people, the ECMAScript (proper name for JS) specification and the CSS and DOM standards are maintained by different groups and have little ability for interoperation. Most interfacing between them happens with JS invoking the APIs, but JS does not typically consider or care what API it invokes.
That is, JS has no explicit support for CSS and sees this as a string.
That doesn't matter when you can transform elements using pure CSS, without JS needing to be involved (although you can apply transforms from JS). A simple position transform, even in 2D, can easily move an element down by 50px.
The translateX() is a css function used to move the element horizontally on the plane. This transformation is define by a length that define how much it moves in horizontally. The sample code example is for you in the bellow.....
exm.html
<div>
<p>welcome</p>
<p class="transformed">bar</p>
<p>thanks</p>
</div>
exm.css
p {
width: 50px;
height: 50px;
background-color: teal;
}
.transformed {
transform: translateX(10px);
background-color: blue;
}
I've written an Ionic app, where nine images are positioned inside a DIV. Here's the relevant snippet from my CSS file:
.mydiv {
position: relative;
overflow: hidden;
}
.mydiv > img {
position: absolute;
box-shadow: 6px 6px 8px #aaaaaa;
}
I'm using $ionicGesture.on('drag', function(e) {}) to move these images around, following the move of my finger. That's the relevant part from my controller.js:
jQuery('.mydiv > img').each(function(i, myImg) {
jQuery(myImg).css('left', initLeft + e.gesture.touches[0].pageX - initX);
jQuery(myImg).css('top', initTop + e.gesture.touches[0].pageY - initY);
}
So, basically, every time the drag event occurs, I move the images by changing their 'left' and 'top' attribute.
The problem is though, that this solutions works wonderfully in a browser, but is horribly lagging as an Ionic app on my iPhone 5. When I put the contents of the Ionic 'www' folder on a web server and access the web app with my iPhone's web browser, the movement is extremely smooth. So, obviously, it's not a performance issue, but Ionic is doing something that makes the app stuttering. Using the Chrome profiler on my Mac, I learned nearly all of the time is used by internal Ionic functions and not by my client code. This seems to be another hint, that this is some kind of Ionic problem.
Why is my app, that runs perfectly smooth in my mobile browser on the same device gets jerky as hell when packed as an Ionic app?
Additional information:
Those images I drag along are scaled with jQuery(myImg).width(). I now replaced them with pre-scaled image files and got rid of the box-shadow style. Now the lagging is reduced but still worse than in the mobile browser. Is it possible, that the mobile Safari on my iPhone uses the GPU for Javascript induced style changes, while for a Cordova app the GPU is not used?
Looks like you have animation issue. Here is an article from Ionic team that explains on how to deal with this.
What’s happening is that as you try to animate the left property of
the items, the web view will have to go back and try to recalculate
that item’s position. This happens for a lot of CSS properties.
Thankfully, we have other ways to animate these items.
Let’s change that left property to transform and set the value to use
translate3d. Translate3d is a special CSS value that will actually
move the animation to the device’s GPU. This is called hardware
accelerated animation.
#-webkit-keyframes slideIn {
0% {
left: -100%;
}
100% {
left: 0;
}
}
#-webkit-keyframes slideInSmooth {
0% {
-webkit-transform: translate3d(-100%,0,0);
}
100% {
-webkit-transform: translate3d(0,0,0);
}
}
.slide-in{
-webkit-animation: slideInSmooth ease-in 1;
animation: slideInSmooth ease-in 1;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation-duration: 750ms;
animation-duration: 750ms;
}
I haven't seen your animation or your code but my guess is that the device GPU isn't carrying the weight it should.
Obviously without seeing your app, I'm doing some guessing here -- but from what you've described this may be the issue:
There are a couple ways to get the GPU to kick in, but the most basic is not to animate using "top" and "left". Using standard CSS positioning like top/left to animate DOM elements works, but it's the slowest way to go and as you've discovered: performance tends to suck in many environments. (Particularly when you're using complex images or blurs/shadows).
A far better way to go is to use translateX / translateY which engages the GPU. That should give you silky smooth performance. Using translateX and translateY will also allow for subpixel rendering and give a far smoother appearance than using top/left which blips along pixel-by-pixel.
There's an excellent discussion of this by a Chrome team member here:
https://www.youtube.com/watch?v=NZelrwd_iRs
Lastly, if for some reason you must use top/left -- a quick and somewhat hacky method to get the GPU to kick in is to set the parent DIV to translate3d(0, 0, 0);
This forces the parent layer into the hands of the GPU (via 3D transforms) during the browser-paint, and the subsequent standard CSS top/left changes that you're using should now render using the GPU. Needless to say, this second method isn't the best way to go in terms of best-practices, so go with CSS transforms first if that's an option.
Using transform: translate3d() does the trick. Animations are now extremely smooth. Because I had some trouble to convert my code from the CSS left-top-style to using translate3d(), here is what I did as a reference for other users:
jQuery('.mydiv > img').each(function(i, myImg) {
var x = initLeft + e.gesture.touches[0].pageX - initX;
var y = initTop + e.gesture.touches[0].pageY - initY;
jQuery(myImg).css({
'-webkit-transform' : 'translate3d('+x+'px, '+y+'px, 0px)',
'transform' : 'translate3d('+x+'px, '+y+'px, 0px)'
});
}
I even can switch on box-shadow again and the animation stays silky smooth.
On my main page, I have 3 links (images). Like a portal.
This is what i want to make:
When you click on one of the links, you zoom really far onto that one. So far that it filled up the full screen. But I dont want you to see whats in that page yet.
Example:
http://prezi.com/0ehjgvtr9fzu/?utm_campaign=share&utm_medium=copy (click on the cloud which says:"Main idea")
Is this possible with HTML/CSS/JavaScript?
You can't "zoom" the viewport but you can use CSS/JS to mimic the behavior by scaling elements in animations. With CSS transforms/transitions you can pretty easily scale a "page" down and then expand it on click (like your demo Flash object).
Basic demo:
#container {
transform-style : preserve-3d;
perspective : 400px;
}
#container .page {
transition : transform 500ms ease-out;
transform : scale(0.2);
}
#container .page.make-page-big {
transform : scale(1);
}
Where #container is the "viewport" and .page is a page that will be animated into full-view.
Here is a demo: http://jsfiddle.net/j1k3mcLp/
That should get you started, you can do a lot with 3D transforms as well, which will allow you to really get the effect you want.
UPDATE
Here's a demo using 3D transforms: http://jsfiddle.net/j1k3mcLp/1/
I am working on a project that involves a lot of CSS. The customer wants to have a grid layout on the home page where he wants to be able to rearrange UI components with drag and drop. These UI components could be of different sizes: 1x1, 2x2 and 3x3. When I drop an UI item at the desired new location it should push the other components aside. Any possible holes should be filled with 1x1 components.
How it should work
Before I have draged a component
Draging the 2x2 component
Dropping the component in the middle, the two 1x1 components make room and adapt around the 2x2
Note that the size of the grid is not limited to 8 1x1, but the height as well as the width of it should be possible to expand and make smaller.
I’ll rather not use tables but other than that I am open to suggestions. Right now I've just used inline-block divs which I can drag and drop to switch the jQuery DOM objects. The effect isn't quite what the customer wants:
How it is now
I've made a lot dynamic layouts with the same idea. You need to think more in how your float behavior from block to block is stopping for the next following blocks, so they become correct repositioned like you want. So to define a float-stop element is necessary.
Your blocks will work with float:left maybe float:right. At some point you will figure out that this behavior has to stop somewhere best done with
CSS
.floatstop {
clear: both; //the important code here..
width: 100%;
height: 1px;
line-height: 1px;
margin-top:-1px;
}
and Html
<div class="floatstop"></div>
Made of all blocks who need border to the next block on the left side (maybe right side too) you have to define a base layout which has space for the very right placed block too with borderspace for it, otherwise it would float down under the block before.
But there is a more modern way!
You can use CSS3 codes to define your layout.
.columnblock {
width: 100%;
column-gap: 30px;
// for symmetric columned layouts use..
column-count: 3;
// or for not symmetric layouts use..
column-width: 280px;
}
<div class="columnblock">
<p>Lorem Ipsum</p>
<p>another Paragraph</p>
</div>
There other things to mention here but you can read about
http://www.w3schools.com/css3/css3_multiple_columns.asp