ScrollMagic unpin element from another scene - scrollmagic

I have this layout where the red card pins to the top of the screen and the yellow one rolls over it. I need to unpin the red when the bottom edge of the yellow reaches the bottom edge of the red, so it looks like the yellow grabs the red and pulls it across the top.
My take is I need to call removePin() from a different scene, an scene using .yellow as triggerElement with an offset, but it didn't work. I also tried setting a duration but then yellow never rolls over red, instead it waits until duration to show up from the bottom.
HTML:
<div class="content">
<div class="green"></div>
<div class="red"></div>
<div class="yellow"></div>
<div class="purple"></div>
<div class="brown"></div>
</div>
Javascript:
var controller = new ScrollMagic.Controller();
var slides = ['.green', '.red', '.yellow', '.purple', '.brown'];
var scene1 = new ScrollMagic.Scene({
triggerHook: 'onLeave',
triggerElement: slides[1],
offset: -20,
logLevel: 3
})
.setPin(slides[1])
.addIndicators()
.addTo(controller);
JSfiddle: http://jsfiddle.net/rLj18ud2/

Related

Scrolling a view or an element using webdriver

I have a dynamic list, containing varying no. of items, being displayed based on some selection.
If the list has more than 7 items, on hovering, the list shows a scroll bar. (If there are fewer items, there will be no scroll bar.)
I have found the element of the scroll bar based on its class name but tring to scroll using webdriver fails.
Here is the code:
//hover
Actions action = new Actions(driver);
WebElement placesList = driver.findElement(By.id("divPlaces"));
action.moveToElement(placesList).perform();
//scroll the list
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true)", element);
HTML code:
<div class="blk">
<div class="smlhead">
Places
</div>
<div id="divPlacesCont" class="sbarPrnt" style="height: 179.219px;">
<div id="divPlaces" class="tilewrap sbarcont" style="height: 179px;">
<div class="blksmlr smlhead sngline">
hyd
</div>
(removed 7 more items for simplicity...)
<div class="sbar" style="display: block;">
<div class="sbarpos" style="height: 152.576px; top: 0px;"></div>
</div>
</div>
</div>
</div>
Update: I got a thought to share. The list element is always visible on the left of the page (and I need not move/scroll to this element to make it visible as actions.moveToElement() does). When I hover, scroll bar within this list appears and I can click the bar, drag it down to see (last) items.
With the above code, it is moving the "frame" up i.e. everything from 'Country' to the list below move a bit up but still the last hidden item in the dynamic is not visible.

Showing time of the video frame on hover over seek bar

I am trying to show the time on hover of seek bar of a html5 video. ( similar to how youtube does it).
I have tried to use the timeupdate event on the video as below but looks like there is more to it.
<script>
function myFunction(event) {
// The currentTime property
document.getElementById("demo").innerHTML = event.currentTime;
var video = event;
video.addEventListener('progress', function() {
var bufferedEnd = video.buffered.end(video.buffered.length - 1);
var duration = video.duration.toFixed(1);
alert(duration);
if (duration > 0) {
document.getElementById('buffered-amount').style.width = ((bufferedEnd / duration)*100) + "%";
}
});
// display the current and remaining times
video.addEventListener("timeupdate", function () {
// Current time
var vTime = video.currentTime;
var vLength = video.duration.toFixed(1);
document.getElementById("curTime").textContent = vTime.toFixed(1);
document.getElementById("vRemaining").textContent = (vLength - vTime).toFixed(1);
}, false);
}
</script>
html:
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<div class="buffered">
<span id="buffered-amount"></span>
</div>
<div class="progress">
<span id="progress-amount"></span>
</div>
<p>Playback position: <span id="demo"></span></p>
<p>Current Time: <span id="curTime"></span></p>
<p>Remaining Time: <span id="vRemaining"></span></p>
I did try to understand multiple posts but did not find a solution.
Do I need to use onmouseover event instead? How do I calculate the time of the video frame when the user positions the mouse on the slider?
I would make a custom controls something like this:
Using the width of the controls div and video.duration to calculate the new time.
Hope this helps!
window.onload = function(){
controls.innerText = ''
function getNewTime(e){
return e.clientX / controls.clientWidth * video.duration
}
controls.addEventListener('mousemove', function(e){
controls.innerText = (getNewTime(e).toFixed(2))
})
controls.addEventListener('click', function(e){
video.currentTime = getNewTime(e)
})
video.addEventListener('click', function(){
video.play()
}
)
}
body{
margin:0;
background:black;
}
#wrapper{
display:flex;
flex-direction:column;
}
#video{
flex:1;
height:calc(100vh - 32px);
}
#controls{
height:32px;
background:red;
display:flex;
justify-content:center;
align-items:center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Custom Video Control</title>
</head>
<body>
<div id='wrapper'>
<video id='video' src='http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4'></video>
<div id='controls'>loading</div>
</div>
</body>
</html>
edit: to clarify my answer
If you look at the code: e.clientX / controls.clientWidth * video.duration you will see that
e.clientX is the current x position of your mouse on the controls rectangle.
controls.clientWidth is the total width of the controls rectangle.
video.duration is the total time of the video.
so if I would put my mouse on the end of the of the rectanlge. I would get 100% of the video duration. and in the beginning I would get 0%. if I would put my mouse at exactly in the middle I would get exactly the time of the middle of the video.
with video.currentTime I can change the current time of the video so that the frame is exactly the right frame of the time.
Try using controls attribute. You will get similar control bar that is present on YouTube videos.
If this attribute is present, Gecko will offer controls to allow the user to control video playback, including volume, seeking, and pause/resume playback.
https://developer.mozilla.org/pl/docs/Web/HTML/Element/video
Example in code.pen:(wait for video to load)
http://codepen.io/mikemoney/pen/QdQvXY
Example on SO: (wait for video to load)
<video src="http://www.sample-videos.com/video/mp4/480/big_buck_bunny_480p_1mb.mp4" autoplay poster="https://i.ytimg.com/vi/1iGy1Rp93o4/maxresdefault.jpg" controls width="480">
</video>

How to save drawn image with a background color using Signature Pad library for AngularJS/Ionic?

I'm working on an Ionic project and implemented this library to handle the drawing of a client signature.
I've managed to implement this with no problem, I can draw, save and show the image with no problem, except one detail: the image is saved with a transparent background.
By default, the image is saved as a PNG file, which is something desired on my end, but it needs to have a white background. The library states that the backgroundColor can be set to any non-transparent color, but only works for JPEG images, and indeed I tried this for a PGN image and it got saved with a transparent background.
I tried to apply a background color to my canvas on my CSS, but when the image is saved the background color isn't applied to the image. I know I could just display on a white background, but it's part of our requirements for it to have a white background.
This is how my template for drawing the signature:
<ion-modal-view class="signature-modal">
<div class="button button-clear signature-close-button" ng-click="closeSignatureModal()"><span class="icon ion-close"></span></div>
<div class="signature-container">
<div class="signature_canvas_container">
<canvas id="signature-pad" class="signature-canvas"></canvas>
</div>
<div class="signature-container-separator"></div>
<div class="row signature-buttons-container">
<div class="col col-11"></div>
<div class="col col-33">
<button class="button button-full button-light" data-action="clear" ng-click="clearSignature()">Limpiar</button>
</div>
<div class="col col-12"></div>
<div class="col col-33">
<button class="button button-full button-positive" data-action="save" ng-click="saveSignature()">Guardar</button>
</div>
<div class="col col-11"></div>
</div>
</div>
</ion-modal-view>
My style for the canvas is this:
.signature-canvas{
width : 100%;
height : 100%;
background-color: white;
}
The configuration properties for the signature pad are these:
canvasPad = document.getElementById("signature-pad");
$scope.resizeCanvas();
signaturePad = new SignaturePad(canvasPad);
signaturePad.minWidth = 1;
signaturePad.maxWidth = 1.5;
signaturePad.dotSize = 3;
signaturePad.backgroundColor = "rgb(255, 255, 255)";
signaturePad.penColor = "rgb(66, 133, 244)";
Saving it is done like this:
var rawImage = signaturePad.toDataURL();
Am I missing something? Can PNG images be saved with a background color?
EDIT
I changed the background color to rgb(0, 125, 255) and the canvas didn't change the color, thought it was my CSS and removed the background-color property from there and still the canvas was shown as white, the color from the CSS is used but that doesn't affect the background for the image. Why isn't rendering the canvas with the background set on the signature pad's properties? No matter where I put the background color, either the CSS or the pad's properties, no color is applied to the image signature I save.
I checked the Draw over image example from the author's page and the way he instantiated the SignaturePad gave away a solution for this issue:
var signaturePad = new SignaturePad(document.getElementById('signature-pad'), {
backgroundColor: 'rgba(255, 255, 255, 1)',
penColor: 'rgb(0, 0, 0)'
});
If you set the background color like this, instead of doing signaturePad.backgroundColor = 'rgba(255,255,255,1)', then the background color takes effect and when you save the image and you display it later it will be shown with a background color.
Although if you require to change the background color after the SignaturePad is instantiated, then I might suggest dismissing and recreating the canvas again, since setting the background color property after creating the instance of the SignaturePad doesn't affect the color.

Cannot find the element for a button

I have a test that searches for restaurants, i choose one, and then add it to a map. I can find the restaurant I want easily but cannot seem to get to the button I am trying to get at.
Here is the code I'm using to pick restaurant from list:
this.selectsAttraction = function() {
attraction = "El Jefe Burger Shack";
var addedAttraction = element(by.cssContainingText('div.name', attraction));
// get ancestor (that accepts mouseover to show icons)
var parent = addedAttraction.element(by.xpath('../..'));
if (parent) {
// scroll into view
browser.executeScript('arguments[0].scrollIntoView()', parent.getWebElement());
// mouse over the target row (in order to click on gear icon, it must be visible)
browser.actions().mouseMove(parent).perform();
browser.driver.sleep(3000);
// find edit icon - third child and then the first element under that
var editIcon = element(by.cssContainingText('span.button', 'Add')).click();
//also have tried:
/*var editIcon = parent.element(By.css("div:nth-child(2)")).element(By.css("span:nth-child(1)")); */
browser.driver.sleep(2000);
}
//The below works but only if I search the restaurant name which will only come back with one result, if I search restaurant there are multiple results to choose from
//element(by.css(".button.button-add")).click();
};
Here is the .html:
<div class="search-item">
<div class="description">
<div class="name" data-bind="text: name">El Jefe Burger Shack</div>
<div class="address" data-bind="text: $data.vicinity || ''">Rout 3, KM 34.5, Cll 14 De Julio, Luquillo</div>
</div>
<div class="btn-container">
<span class="button button-add" data-bind="click: $root.addAttraction">Add</span>
</div>
</div>
<div class="search-item">
Any help would be fantastic a bit lost here *this is a nonangular part of the site and Sync is off
You can actually get to the button directly from addedAttraction:
var addButton = addedAttraction.element(by.xpath("../following-sibling::div/span[. = 'Add']"));
We are going one level up, getting the following sibling containing span element with "Add" text.

Fotorama: height for slides with html content

this is my first question on Stackoverflow, I hope it makes sense :)
I need to create a swipeable image gallery with html content in each slide (text, images, external links, social network buttons etc) and full screen option.
Fotorama is the best solution I have found, I am a very big fan of it :)
However, I am finding it difficult to fit the html content in the gallery, as it gets cropped to the height of the first image.
I need the image to be in the html, not a background image. And I need all the content to be visible both in the normal mode and in the full screen mode. The text can vary in length and the images in size, so I cannot give the gallery a fixed height.
Does it make sense?
I couldn't find a similar question asked already, so if you have any idea please let me know!
Thanks :)
This is the simplified code of what I have done so far, any comment is more than welcome!
<div class="fotorama" data-allowfullscreen="true" data-nav="thumbs" data-click="false" data-width="100%">
<div data-thumb="image-01.jpg" id="slide1">
<h2>Title 01</h2>
<img src="image-01.jpg" width="100%">
<div class="content">
<p>Blah blah blah</p>
<div class="photoShare">
<h6>Share</h6>
<!-- Social Network Buttons -->
</div>
<div class="buyThisPhoto">
<!-- Buy this photo link -->
</div>
</div>
</div>
<!-- etc -->
Update:
I am working on possibe solution, using the API. Seems to work but any suggestion for improvement is welcome :)
$(function () {
var $fotoramaDiv = $('#fotorama').fotorama();
var fotorama = $fotoramaDiv.data('fotorama');
$('.fotorama').on('fotorama:ready ' + 'fotorama:show ' + 'fotorama:load ', function () {
var currentContainer = $(".fotorama__active").children('div');
var newHeight = /* calculate the height by adding up the heights of the elements contained in currentContainer */;
fotorama.resize({
height: newHeight
});
}).fotorama();
});

Resources