#react-three/drei Html element is not bubbling up the scroll event - react-three-fiber

I have a <Html><svg /></Html> element in my react-three-fiber project. This element is grouped with the camera to keep element in front of the camera. When mouse pointer is on this element scroll i not working for ScrollControl and not scrolling. Is there a way to keep scrolling on the background ?

It is because your HTML elements didn't be in canvas.
You can do the following.
Add props 'fullpage' and 'zIndexRange={[-100, -2]}'
ex: <Html fullscreen zIndexRange={[-100, -2]}>
Then you can use your scrolling

I saw the answer at discourse threejs, but i could not find it right now, here is the solution for people here.
function App() {
const html = useCallback((element) => {
if (element) element.parentElement.style.pointerEvents = 'none';
}, []);
return (
<Html ref={html} as="div" >
Hello World
</Html>
)
}

Related

Adobe Animate gotoAndPlay on mouse scroll

It's been a REALLY long time since using Flash and now have to use Adobe Animate for an HTML 5 Canvas project. I created the animation, set all the actions on the timeline to stop the timeline where I need it to be but now I need to know how to play the animation again from outside of another JS file (custom.js) inside my Animate JS file (animate.js)
I've read a ton of articles and most reference the scope of this being the problem.
Here's how I would imagine this would work.
// On scroll of div
<div onscroll="myFunction()">
// inside my custom.js
myFunction() {
this.gotoAndPlay(2);
};
Some have said to set a var of
var that=this;
And then calling that.gotoAndPlay(2);
Many thanks
Animate declares a global (window) variable exportRoot on publish that points to the root timeline.
As a demonstration, if you put this code on the root timeline:
alert(exportRoot === this);
You should see "true".
Thanks to ClayUUID
<script type="text/javascript">
function playTimeLine () {
//alert ("working");
exportRoot.gotoAndPlay(30);
}
</script>
<button onclick="playTimeLine()">PRESS</button>

Threejs: Rendering scene in Div - Prevent scrolling of browser window, do zoom instead (OrbitControls.js)

I have written a new tool in three.js which deals with a cylinder in 3d and renders the cylinder values in the scene that is located within a DIV.
JS:
container = document.getElementById('zylinder_3d');
var sceneWidth = document.getElementById('zylinder_3d').offsetWidth;
var sceneHeight = document.getElementById('zylinder_3d').offsetHeight;
renderer.setSize(sceneWidth, sceneHeight);
container.appendChild(renderer.domElement);
HTML:
<div id="zylinder_3d"></div>
For the navigation I am using OrbitControls.js:
var controls = new THREE.OrbitControls(camera, renderer.domElement);
// rotate at startup
controls.rotateLeft(-0.1);
controls.rotateUp(-0.25);
controls.dollyOut(2.5); // zoom out
The problem is, that if I use the mouse to scroll (having the mouse on top of the canvas), the entire browser window scrolls down - instead of the expected zooming.
Is there any way I can force the scroll to happen only within the scene / the canvas. In best case when the mouse is on top of the canvas.
I have tried some stop scroll advices for Javascript here on stackoverflow, but these were on "normal" DIVs not for DIVs with canvas.
I have found the solution thanks to WestLangleys's comment above who pointed out the TrackBallControls:
Open OrbitControls.js and find lines:
function onMouseWheel( event ) {
if ( scope.enabled === false || scope.noZoom === true ) return;
Add right below:
event.preventDefault();
event.stopPropagation();
This is it!
It works now as expected: Zylinder 3D Demo
PS: Maybe this should be added to the original file?

syncronized scroll does not work in div based ckeditor

Basically i have 2 instances of ckeditor on a single page. One on the left and another in the right side of the page.
The left editor uses a div rather than traditional iframe. I've done this by removing the iframe plugin and including the div editing area plugin.
The right editor loads in an iframe and but is also div based(i can use the iframe editor as well on the right if required, not an issue).
Now if the cursor/focus is on the right editor's content area then the left editor should scroll along with it. I've tried to use the code as provied by Reinmar in below url but it seems to work only with editors based on iframe on both sides. Also please note that i'm using jquery adapter for initializing the editors.
CKEDITOR how to Identify scroll event
I initialized the editor on left as below:
var editor_left = $( '#editor_left' ).ckeditor();
And below is my code for the right editor:-
var editor_right = $( '#editor_right' ).ckeditor();
editor_right.editor.on( 'contentDom', function() {
var editable = editor_right.editor.editable();
editable.attachListener( editable.getDocument(), 'scroll', function() {
alert('scroll detected');
parent.$('#left_editor_content_area').scrollTop($(this).scrollTop())
});
});
If i use the iframe based editor on the right then i'm able to get the "scroll detected" alert. But the scrollTop() function still does not work as expected
Any help will be appreciated.
The code that you mentioned is right. You got to update scrollTop property of the div-based editable with the scroll position of the window inside the iframe-based editor (JSFiddle).
var editor_div = CKEDITOR.replace( 'editor_div', {
extraPlugins: 'divarea'
} );
CKEDITOR.replace( 'editor_iframe', {
on: {
contentDom: function() {
var editable = this.editable(),
win = this.document.getWindow(),
doc = editable.getDocument();
editable.attachListener( doc, 'scroll', function( evt ) {
// Get scroll position of iframe-based editor.
var scroll = win.getScrollPosition();
// Update scroll position in the div-based editor.
editor_div.editable().$.scrollTop = scroll.y;
} );
}
}
} );

Virtual area around vml element

this is my first post, so my deepest excuses if something went wrong :)
I have a little html-control to write and biggest problem is ie6-8 support. There are no alternatives to skip ie6-8 support at all :( So after searching a while, I did found Raphael and it allows me to create custom shapes defined in SVG file. I need to attach 'mouseover' event and select element on hover. Event working great but I did find BIG problems in VML hover behavior.
Code was simplified to RAW html with VML shape.
<html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<style>v\: * { behavior:url(#default#VML); antialias: false; }</style>
</head>
<body>
<div id="message">hovered: nope</div>
<v:oval id="oval" style="width:100px; height:75px" fillcolor="#bbb"></v:oval>
<script>
var messageElm = document.getElementById('message');
var ovalElm = document.getElementById('oval');
ovalElm.attachEvent('onmouseover', function () { messageElm.innerText = 'hovered: yep'; });
ovalElm.attachEvent('onmouseout', function () { messageElm.innerText = 'hovered: nope'; });
</script>
</body>
</html>
If you try to move mouse over oval element you can noticed that rendered shape is not same as hover shape. I mean, hover triggers 2-3px from rendered shape (not from each side).
So question is: how to disable that virtual area (if it is possible at all)?
i had the same issue and i tried usemap;
first i create a map on a transparent png8 which covered the vml
this.dom.insertAdjacentHTML("AfterBegin",'<map name="'+_id+'"></map><img id="'+_id+'" src="'+transparent.png+
'" style="position:absolute;width:'+dom.clientWidth+';height:'+dom.clientHeight+'" />');
var map = this.dom.getElementsByTagName('map')[0];
this.dom.appendChild(map);
this.map = map;
then get the shape attach to an area; map it;
i made poly demo only;
function _getMap(shape){
this._map = this._map || {};
if(this._map[shape.id]){
}else if(shape.nodeName == 'shape'){
var arrDots = shape.childNodes[0].v.match(/(\d+),(\d+)/g)
this._map[shape.id] = _polyMap(arrDots);
}
return this.map[shape.id]
}
function _polyMap(arrDots){
var map = this.map;
var area = document.createElement('area');
area.setAttribute('shape',"poly");
area.setAttribute('coords',arrDots.join(','));
area.setAttribute('href','##');
area.setAttribute('alt','##');
map.appendChild(area);
}
then you can bind event on it;
function _onIE(shape, evtname, fn){
this._getMap(shape).attachEvent('on'+evtname, fn);
}

jQuery scrollstart, scrollstop and very quick scrolling issue

I'm having an issue with James Padolsey's custom events: scrollstart and scrolltop
When I use the mouse wheel to scroll one "notch" or I click the scroll bar somewhere far below or above its current position, causing sudden scroll by a large amount, I get the same scrollTop() values for scrollstart and scrolltop - I can't tell where the scroll started or in which direction the scroll has taken place. jsFiddle available here (note: if you have an extremely high resolution, you will have to add more text to the HTML so that a scroll bar appears in the Result window).
HTML:
<html>
<body>
<div id="scrollable">
<!-- insert lots of text here -->
</div>
</body>
</html>
CSS:
#scrollable {width: 120px;}
JavaScript:
var before = 0;
$(window).bind('scrollstart', function() {
before = $(window).scrollTop();
});
$(window).bind('scrollstop', function() {
alert('before: ' + before + "\nafter: " + $(window).scrollTop())
});
jsFiddle available here
Any ideas on how to retrieve the true scrollTop() value for the scrollstart event? Modifying the plugin is an option I guess, so all ideas welcome.
Instead of recording the before value when the scroll starts, I would suggest doing so in another event, for example mousemove()
jsFiddle of this idea working
Maybe I misunderstood your question (I haven't used that plugin), but I think you don't need to use every part of that plugin. If you only want to know the previous and current value of ScrollTop and its direction, take a look at this:
http://jsfiddle.net/C3ye7/
var currentScrollTop, temporalScroll = 0;
$(window).scroll(function(){
currentScrollTop = $(this).scrollTop();
console.log('Previous value: ' + temporalScroll)
if (currentScrollTop > temporalScroll) {
console.log('scroll down')
console.log('Current value: ' + currentScrollTop)
}
else {
console.log('scroll up');
console.log('Current value: ' + currentScrollTop)
}
temporalScroll = currentScrollTop;
});
In order to add the timing functionality, you can use only that part of that plugin (or simply, start a setTimeout to record a bigger change when scrolling).

Resources