Easeljs addEventListener do not work when bitmap added to stage - addeventlistener

I do not understand, why eventlistener (copied from demo) does not work, If I add an bitmap to stage. It seems that bitmap causes problem, because if I add another circle etc. the click works fine.
See example:
<!DOCTYPE html>
<html>
<head>
<title>EaselJS demo: Simple animation</title>
<link href="../_shared/demo.css" rel="stylesheet" type="text/css">
<script src="http://code.createjs.com/easeljs-0.7.0.min.js"></script>
<script>
var stage, circle;
var counter = 0;
var ticounter = 0
var images = []
var mytext = 'kk';
var lepakko;
var mx = 0;
function init() {
stage = new createjs.Stage("demoCanvas");
var circle = new createjs.Shape();
circle.graphics.beginFill("red").drawCircle(0, 0, 50);
circle.x = 500;
circle.y = 500;
stage.addChild(circle);
stage.update();
lepakko = new createjs.Bitmap("halloween-bat.png");
//Click works, if line below is commented out, why?
//stage.addChild(lepakko);
circle.addEventListener("click",circle_event);
stage.update();
}
function circle_event(event) {
alert("clicked");
};
</script>
</head>
<body onLoad="init();">
<canvas id="demoCanvas" width="700" height="700">
alternate content
</canvas>
</body>
</html>

The click should not work by default. EaselJS library needs explicit enabling of the mouseover event. You need to add:
stage.enableMouseOver(20);
after creating the stage. To change the cursor to a pointer when it's over the object there is a property in EaselJS called cursor:
// doesn't work, even if a function is decleared outside
// circle.addEventListener("mouseover", function() { document.body.style.cursor = "pointer"; });
// this works
circle.cursor = "pointer";
Method enableMouseOver is documented on EaselJS website. Do note that listening to mouseover and other events in EaselJS is a lot more demanding for a web browser.

Related

Apply Multiple Filters

Dispite the tutorial here https://konvajs.org/docs/filters/Multiple_Filters.html of using multiple filters, I have been unsuccessful in applying multiple to an image in a NodeJS space.
Here is an example of the "fun" I went through trying to get it to work:
(Konva, layer, imageNode) => {
console.log('Callback');
imageNode.cache();
// imageNode.filters([
// Konva.Filters.Brighten,
// Konva.Filters.HSL,
// ]);
imageNode.filters([Konva.Filters.Posterize]);
imageNode.levels(0.8); // between 0 and 1
// imageNode.brightness(0.8);
// imageNode.contrast(0.8);
// imageNode.saturation(0.8);
// imageNode.cache();
// imageNode.filters([
// // Konva.Filters.Brighten,
// Konva.Filters.HSL,
// ]);
// imageNode.hue(0.5);
// imageNode.saturation(0.8);
// imageNode.luminance(0.85);
imageNode.cache();
As you can see, I'm trying to use a mix of brightness, contrast, saturation, hue, lumiance; however some work, some don't, and it all doesn't seem very reliable and if any work, only one ever does.
So how do I for example, brighten, and saturate an image?
Example Image I would like to "bring into the light" by adjusting different factors of it.
My end goal is something like this:
Update #1
No Luck, I cannot even get brightness to work on a small 50x35 image:
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva#8.3.12/konva.min.js"></script>
<meta charset="utf-8" />
<title>Konva Image Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height,
});
var layer = new Konva.Layer();
// main API:
var imageObj = new Image();
imageObj.onload = function () {
var imageNode = new Konva.Image({
x: 0,
y: 0,
image: imageObj,
width: 50, // 2048 / 2,
height: 35, // 1440 / 2,
});
imageNode.cache({ pixelRatio: 1})
imageNode.filters([
Konva.Filters.Brighten,
// Konva.Filters.HSL,
// Konva.Filters.Invert
]);
// imageNode.filters([Konva.Filters.Posterize]);
// imageNode.levels(0.2); // between 0 and 1
imageNode.brightness(0.8);
// imageNode.contrast(0.8);
// imageNode.saturation(0.8);
// imageNode.cache({ pixelRatio: 1})
// imageNode.filters([
// // Konva.Filters.Brighten,
// Konva.Filters.HSL,
// ]);
// imageNode.hue(0.5);
// imageNode.saturation(0.8);
// imageNode.luminance(0.85);
// imageNode.cache({ pixelRatio: 1})
layer.add(imageNode);
stage.add(layer);
};
imageObj.src = 'C:/Users/<User>/Downloads/Small.png';
</script>
</body>
</html>
Update #2
Ok this seems to be firstly an issue with doing this off a local html file, as not even taking the code from https://konvajs.org/docs/filters/Brighten.html and swapping in an absolute path to a file on my machine, works.
Seems to be an issue with editing images on a local HTML file, something stops them actually taking the changes.

Disable Chrome's pull-to-refresh on iPhone

I am implementing a drawing app on my site and trying to prevent overscroll while the user draws on the canvas. Despite trying several reported solutions, I cannot disable Chrome's pull-to-refresh.
According to https://developers.google.com/web/updates/2017/11/overscroll-behavior, the following one line of css should do the trick..yet pull-to-refresh and an annoying user experience persists. Any ideas?
<!DOCTYPE html>
<html>
<style type="text/css">
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
</style>
<body>
<h1>Simple Site</h1>
</body>
<script type="text/javascript">
</script>
</html>
I had the same problem. I found that CSS property only works on chrome-android.
Finally, I successfully prevent pull-to-refresh on chrome-ios through the following:
<script>
function preventPullToRefresh(element) {
var prevent = false;
document.querySelector(element).addEventListener('touchstart', function(e){
if (e.touches.length !== 1) { return; }
var scrollY = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
prevent = (scrollY === 0);
});
document.querySelector(element).addEventListener('touchmove', function(e){
if (prevent) {
prevent = false;
e.preventDefault();
}
});
}
preventPullToRefresh('#id') // pass #id or html tag into the method
</script>
For newer version of Chrome v75.0.3770.103 on IOS
preventDefault()
does no longer disable pull-to-refresh.
Instead, you can add in
{passive:false}
as additional option into the event listener.
E.g.
window.addEventListener("touchstart", eventListener, {passive:false});
In newer version of chrome in IOS preventDefault(); is no longer disables pull to refresh.
For latest, you can just add inobounce js cdn to your header of the page you want to disable pull to refresh. This will do the magic.
<script src="https://cdnjs.cloudflare.com/ajax/libs/inobounce/0.2.0/inobounce.js"></script>
The only thing that worked for me was iNoBounce.
Example React snippet:
import 'inobounce'
...
<div style={{
height: windowHeight,
WebkitOverflowScrolling: 'touch',
overflowY: 'auto' }}
>Content goes here</div>

Creating responsive Google DFP ads

I am following the last example on this link:https://support.google.com/dfp_premium/answer/4578089?vid=1-635774352437004756-19071376
its resizing however my ad is not showing for some reason, pls see below:
<html>
<head>
<title>GPT Training - Responsive Test Page</title>
<script>
// Load GPT asynchronously
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
(function() {
var gads = document.createElement('script');
gads.async = true;
var useSSL = 'https:' == document.location.protocol;
gads.src = (useSSL ? 'https:' : 'http:') +
'//www.googletagservices.com/tag/js/gpt.js';
var node = document.getElementsByTagName('script')[0];
node.parentNode.insertBefore(gads, node);
})();
</script>
<script>
// GPT slots
var gptAdSlots = [];
googletag.cmd.push(function() {
// Define a size mapping object. The first parameter to addSize is
// a viewport size, while the second is a list of allowed ad sizes.
var mapping = googletag.sizeMapping().
// Small ad
addSize([100, 100], [88, 31]).
// Accepts both common mobile banner formats
addSize([320, 400], [[320, 50], [300, 50]]).
// Same width as mapping above, more available height
addSize([320, 700], [300, 250]).
// Landscape tablet
addSize([750, 200], [728, 90]).
// Desktop
addSize([1050, 200], [1024, 120]).build();
// Define the GPT slot
gptAdSlots[0] = googletag.defineSlot('/1034652/Z103Home_TopLeaderboard', [728, 90], 'div-gpt-ad-1441833752374-0').
defineSizeMapping(mapping).
addService(googletag.pubads());
googletag.pubads().setTargeting("test","responsive");
// Start ad fetching
googletag.enableServices();
});
</script>
</head>
<body>
<h1>GPT Training - Responsive Test Page</h1>
<div id="div-gpt-ad-1441833752374-0">
<script>
googletag.cmd.push(function() {
googletag.display('div-gpt-ad-1441833752374-0');
});
</script>
</div>
<p><span>GPT responsive ads do not resize on change in the size of the browser.
You can add your own custom code to refresh the ad slots on resize.
To demonstrate responsive capabilities, re-size your window and refresh the page.</span></p>
</body>
</html>
This example code you have should initially display an ad when you open it on your browser. How can you say its resizing but there is no ad? This confuses me.
What I actually don't see is a code that refreshes your ad slot on window resize.

Using drag and drop in phonegap installed

I'm using simple HTML code to work on a drag and drop function as part of my IOS app. This piece of code works perfectly in the browser however when I copy it into my xcode file the image won't drag.
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#div1 {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;}
</style>
<script>
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<p>Drag the image into the rectangle:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="images/face.png" draggable="true" ondragstart="drag(event)" width="336" height="69">
</body>
</html>
Reading over Apple's webview capabilities document states that you have to set a CSS property for this to work.
From the docs:
Making an Element Draggable
WebKit provides automatic support to let users drag common items, such as images, links
and selected text. You can extend this support to include specific elements on an HTML
page. For example, you could mark a particular div or span tag as draggable.
To mark an arbitrary element as draggable, add the -webkit-user-drag attribute
(previously -khtml-user-drag) to the style definition of the element. Because it is a
cascading style sheet (CSS) attribute, you can include it as part of a style definition
or as an inline style attribute on the element tag. The values for this attribute are
listed in Table 1.
So standard draggables will work out of the box, but other elements like div or span require the -webkit-user-drag attribute to be appended.
Example:
#drag1 { -webkit-user-drag: element; }
Source: https://developer.apple.com/library/mac/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/DragAndDrop.html
This code is what worked in the end.
<script>
var nodeList = document.getElementsByClassName('contents');
for(var i=0;i<nodeList.length;i++) {
var obj = nodeList[i];
obj.addEventListener('touchmove', function(event) {
var touch = event.targetTouches[0];
// Place element where the finger is
event.target.style.left = touch.pageX + 'px';
event.target.style.top = touch.pageY + 'px';
event.preventDefault();
});
}
</script>

iframe prevents iScroll scrolling on mobile Safari

I am using iScroll on my mobile enable website (using iPhone here) to scroll inside a div.
In this this div, I have an iframe with a fixed height like this:
<body>
<div id="iscroller">
<iframe id="theIframe"></iframe>
Other stuff
</div>
</body>
Now, while scrolling within the div, everything works as expected but I cannot scroll when the scrolling gesture begins on the iframe.
The problem is described here pretty well: https://github.com/cubiq/iscroll/issues/41
So, I used the css workaround from that post by applying pointer-events:none to the iframe.
Now scrolling works perfectly but I cannot click any links which are defined within the iframe because all click/touch events on the iframe seems to be blocked due to pointer-events: none.
So, I thought:
"Ok, while the user scrolls, I need pointer-events:none. If he is
not scrolling (and instead clicking), I must set pointer-events:auto
in order to let the click/touch events pass."
So I did this:
CSS
#theIframe{pointer-events:none}
JavaScript
$("#theIframe").bind("touchstart", function(){
// Enable click before click is triggered
$(this).css("pointer-events", "auto");
});
$("#theIframe").bind("touchmove", function(){
// Disable click/touch events while scrolling
$(this).css("pointer-events", "none");
});
Even adding this doesn't work:
$("#theIframe").bind("touchend", function(){
// Re-enable click/touch events after releasing
$(this).css("pointer-events", "auto");
});
No matter what I do: Either scrolling doesn't work or clicking the link inside the iframe doesn't work.
Doesn't work. Any ideas?
I found the perfect solution. Works great on iOS and Android.
The basic idea is to put a div layer on top of that iframe. This way scrolling works smoothly.
If the user wants to tap/click on an element on that iframe I simply catch that click on the layer, save the x and y coordinates and trigger a click event on the iframe's content at these coordinates:
HTML:
<div id="wrapper">
<div id="layer"></div>
<iframe id="theIframe"></iframe>
</div>
Other stuff
CSS:
#layer{
position:absolute;
opacity:0;
width:100%;
height:100%;
top:0;
left:0;
right:0;
bottom:0;
z-index:2
}
JavaScript:
$('#layer').click(function(event){
var iframe = $('#theIframe').get(0);
var iframeDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
// Find click position (coordinates)
var x = event.offsetX;
var y = event.offsetY;
// Trigger click inside iframe
var link = iframeDoc.elementFromPoint(x, y);
var newEvent = iframeDoc.createEvent('HTMLEvents');
newEvent.initEvent('click', true, true);
link.dispatchEvent(newEvent);
});
I found a solution for this, it happens to be close to what other guys already mentioned on github but this may be useful for whoever wants to find a fast working resolution for this problem.
I'm assuming a few things, like there's only one iscroll container, here represented as ID. This is not properly tested and needs refactor. It's working in my project, but I changed it here slightly for the example but I guess you'll easily understand what you need to do:
var $iscroll = $('#iscroll');
document.addEventListener('touchstart', function(e) {
if ($iscroll.find('iframe').length > 0){
$.each($iscroll.find('iframe'), function(k,v){
var $parent = $(v).parent().first();
if ($parent.find('.preventTouch').length == 0){
$('<div class="preventTouch" style="position:absolute; z-index:2; width:100%; height:100%;"></div>')
.prependTo($parent);
};
$parent
.css('position', 'relative').css('z-index', 1);
});
$iscroll.find('.preventTouch').on('click', function(e){
e.preventDefault();
e.stopPropagation();
return false;
});
};
};
document.addEventListener('touchend', function(e) {
if ($iscroll.find('iframe').length > 0){
setTimeout(function(){
var $iscroll = $('#iscroll');
$iscroll.find('.preventTouch').remove();
$iscroll.find('iframe').css('z-index', '');
$iscroll.find('.preventTouch').off('click');
}, 400);
};
};
Thanks for looking!

Resources