ScrollMagic - TimelineMax with Anchor Link On Page Parallax Scrolling - gsap

I am using ScrollMagic plugin for parallax scrolling effect. Below is my code
HTML Code
<div style="position:fixed;right:50px;top:50px;width:200px;height:300px;background:#fff;z-index:1">
<div>ONE</div>
<div>TWO</div>
<div>THREE</div>
<div>FOUR</div>
</div>
<div id="pinContainer">
<div id="slideContainer">
<section class="panel blue">
<a id="one"></a>
<b>ONE</b>
</section>
<section class="panel turqoise">
<a id="two"></a>
<b>TWO</b>
</section>
<section class="panel green">
<a id="three"></a>
<b>THREE</b>
</section>
<section class="panel bordeaux">
<a id="four"></a>
<b>FOUR</b>
</section>
</div>
</div>
JAVASCRipt Code
$(function () { // wait for document ready
// init
var controller = new ScrollMagic.Controller();
// define movement of panels
var wipeAnimation = new TimelineMax()
// animate to second panel
.to("#slideContainer", 0.5, {z: -150}) // move back in 3D space
.to("#slideContainer", 1, {x: "-25%"}) // move in to first panel
.to("#slideContainer", 0.5, {z: 0}) // move back to origin in 3D space
// animate to third panel
.to("#slideContainer", 0.5, {z: -150, delay: 1})
.to("#slideContainer", 1, {x: "-50%"})
.to("#slideContainer", 0.5, {z: 0})
// animate to forth panel
.to("#slideContainer", 0.5, {z: -150, delay: 1})
.to("#slideContainer", 1, {x: "-75%"})
.to("#slideContainer", 0.5, {z: 0});
// create scene to pin and link animation
new ScrollMagic.Scene({
triggerElement: "#pinContainer",
triggerHook: "onLeave",
duration: "500%"
})
.setPin("#pinContainer")
.setTween(wipeAnimation)
.addIndicators() // add indicators (requires plugin)
.addTo(controller);
// change behaviour of controller to animate scroll instead of jump
controller.scrollTo(function (newpos) {
TweenMax.to(window, 0.5, {scrollTo: {y: newpos}});
});
// bind scroll to anchor links
$(document).on("click", "a[href^='#']", function (e) {
var id = $(this).attr("href");
if ($(id).length > 0) {
e.preventDefault();
// trigger scroll
controller.scrollTo(id);
// if supported by the browser we can even update the URL.
if (window.history && window.history.pushState) {
history.pushState("", document.title, id);
}
}
});
});
How to achieve the anchor scrolling functionality using scrollmagic plugin.
Using above code when I click on anchor link its not going to the particular section.

I had the same problem today.
Try to replace the "window" element with your "#pinContainer" element.
Change your code from:
controller.scrollTo(function (newpos) {
TweenMax.to(window, 0.5, {scrollTo: {y: newpos}});
});
to:
controller.scrollTo(function (newpos) {
TweenMax.to($('#pinContainer'), 0.5, {scrollTo: {y: newpos}});
});
Hope that helps.

Related

Create Konvajs Shapes and Connections creating dynamically based on button click events

I would like to create Rectangle Shapes and Connections using the Vue-Konva/Konvajs within my application. I do not want to create load the Static values rather I would like to create the Shapes when the user clicks on the Add Node button and create Connectors when the user clicks on the Add Connector button and build the connections between Shapes.
I looked into a few things and was able to do it using the mouse events but was unable to convert it to button clicks.
Following is the current code I have: CodeSandbox
Can someone please guide me on how to create shapes and connectors on click of the button events? Any suggestion or guidance is much appreciated.
I am looking something like this:
After trying a few things I was able to get it working. Posting here as it can be useful to someone in the future:
<template>
<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
<button class="btn btn-primary btn-sm" #click="addEvent()">
Add Event
</button>
<button class="btn btn-success btn-sm" #click="submitNodes()">
Submit
</button>
</div>
</div>
<div class="row root">
<div class="col-sm-12 body">
<v-stage
ref="stage"
class="stage"
:config="stageSize"
#mouseup="handleMouseUp"
#mousemove="handleMouseMove"
#mousedown="handleMouseDown"
>
<v-layer ref="layer">
<v-rect
v-for="(rec, index) in nodeArray"
:key="index"
:config="{
x: Math.min(rec.startPointX, rec.startPointX + rec.width),
y: Math.min(rec.startPointY, rec.startPointY + rec.height),
width: Math.abs(rec.width),
height: Math.abs(rec.height),
fill: 'rgb(0,0,0,0)',
stroke: 'black',
strokeWidth: 3,
}"
/>
</v-layer>
</v-stage>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
stageSize: {
width: null,
height: 900
},
lines: [],
isDrawing: false,
eventFlag: false,
nodeCounter: 0,
nodeArray: []
}
},
mounted () {
if (process.browser && window !== undefined) {
this.stageSize.width = window.innerWidth
// this.stageSize.height = window.innerHeight
}
},
methods: {
handleMouseDown (event) {
if (this.eventFlag) {
this.isDrawing = true
const pos = this.$refs.stage.getNode().getPointerPosition()
const nodeInfo = this.nodeArray[this.nodeArray.length - 1]
nodeInfo.startPointX = pos.x
nodeInfo.startPointY = pos.y
console.log(JSON.stringify(nodeInfo, null, 4))
}
},
handleMouseUp () {
this.isDrawing = false
this.eventFlag = false
},
setNodes (element) {
this.nodeArray = element
},
handleMouseMove (event) {
if (!this.isDrawing) {
return
}
// console.log(event);
const point = this.$refs.stage.getNode().getPointerPosition()
// Handle rectangle part
const curRec = this.nodeArray[this.nodeArray.length - 1]
curRec.width = point.x - curRec.startPointX
curRec.height = point.y - curRec.startPointY
},
// Function to read the Nodes after add all the nodes
submitNodes () {
console.log('ALL NODE INFO')
console.log(JSON.stringify(this.nodeArray, null, 4))
this.handleDragstart()
},
addEvent () {
this.eventFlag = true
this.setNodes([
...this.nodeArray,
{
width: 0,
height: 0,
draggable: true,
name: 'Event ' + this.nodeCounter
}
])
this.nodeCounter++
}
}
}
</script>
<style scoped>
.root {
--bg-color: #fff;
--line-color-1: #D5D8DC;
--line-color-2: #a9a9a9;
}
.body {
height: 100vh;
margin: 0;
}
.stage {
height: 100%;
background-color: var(--bg-color);
background-image: conic-gradient(at calc(100% - 2px) calc(100% - 2px),var(--line-color-1) 270deg, #0000 0),
conic-gradient(at calc(100% - 1px) calc(100% - 1px),var(--line-color-2) 270deg, #0000 0);
background-size: 100px 100px, 20px 20px;
}
</style>

How to setup initial position of target element in anime.js?

Target
On click "Open menu" button:
Dim overlay appearing with fade-in animation
Once dim overlay animation done, from the top, dim overlay is appearing with the sliding animation from the top to bottom:
Solution attempt and problem
<template>
<transition #enter="animateOpening" #leave="animateClosing">
<div
class="SearchProductsPane-DimUnderlay"
v-if="isOpen"
:ref="elementsReferencesIDs.overlay"
>
<div
class="SearchProductsPane-Body"
:ref="elementsReferencesIDs.body"
>
<!-- ... -->
</div>
</div>
</transition>
</template>
import { Vue, Component } from "vue-property-decorator";
import Animation from "animejs";
#Component
export default class SearchProductsPane extends Vue {
private elementsReferencesIDs: Record<"overlay" | "body", string> = {
overlay: "Overlay", body: "Body"
};
private animateOpening(_element: Element, done: () => {}): void {
Animation
.timeline({
easing: "linear",
duration: 500,
complete: done
})
.add({
targets: this.$refs[this.elementsReferencesIDs.overlay],
opacity: [0, 1]
})
.add({
targets: this.$refs[this.elementsReferencesIDs.body],
translateY: "100%"
})
}
private animateClosing(): void {
}
}
With current solution, the .SearchProductsPane-Body will move from the normal position to the downward outside of the screen. Instead of it, I need it move from the upward outside of the screen to it normal position.
I tried reach it by adding of below class:
.SearchProductsPane-Body__InitialPosition {
transform: translateY(-100%);
}
However, the animejs animation starts from the 0%, not -100%. How to change it?
You can use From Value in animeJs, which allows you to define you'r animation origin:
anime.stagger(100, {from: 'center'})
you'r options are:
first: animation starts from the first element(Default from value)
last: animation starts from the last element
center: animation starts from the center
index: you choose which element the animation starts from
here is the docs.
Or you can use From to which forces the animation to start at a specified value.
In you'r code:
anime({
targets: '.SearchProductsPane-DimUnderlay'
});
docs here

Multiple sliders problems

I have some problem in my program two slides are working automatically but I want two slides have two move same and also i don't want any delay beteween two slides
Please help me
Thanks for help
var mySwiper = new Swiper('#first-slider',{
loop:true,
grabCursor: true,
autoplay: 2500,
simulateTouch: false,
transitionSpeed: 1000,
var mySwiper1 = new Swiper('#second-slider',{
loop:true,
grabCursor: true,
autoplay: 2500,
simulateTouch: false,
transitionSpeed: 1000,
});
in this two sliders;
when it is moving i have some delay between thease two sliders
delay means first of all first slider is moving after that second slider is moving I don't want that
I want two slides have two move same path without any delay
So as a workaround, don't set both sliders on a timed interval.
Only set the first slider to autoplay.
Then in the onSlideChangeStart, trigger the second one to slide, like thins:
var mySwiper = new Swiper('#first-slider',{ loop:true, grabCursor:true,
autoplay: 2500, simulateTouch: false, transitionSpeed: 1000,
onSlideChangeStart: function(swiper, direction) {
mySwiper1.slideNext();
} });
var mySwiper1 = new Swiper('#second-slider',{ loop:true, grabCursor:
true, simulateTouch: false, transitionSpeed: 1000});
This way your swiper will just do its thing, but the second one depending on the first, so they will ALWAYS move together...
Use this snippet to try, and accept answer if it is what you wanted :)
var mySwiper = new Swiper('#first-slider',{ loop:true, grabCursor:true,
autoplay: 2500, simulateTouch: false, transitionSpeed: 1000,
// Navigation arrows
onSlideChangeStart: function(swiper, direction) {
if (typeof mySwiper1 != "undefined"){
mySwiper1.slideNext();
}else{
alert("PageLoad");
}
}
});
var mySwiper1 = new Swiper('#second-slider',{ loop:true, grabCursor:
true, simulateTouch: false, transitionSpeed: 1000});
.swiper-container {
width: 100px;
height: 100px;
}
<link href="http://cdnjs.cloudflare.com/ajax/libs/Swiper/3.0.6/css/swiper.min.css" rel="stylesheet"/>
<script src="http://cdnjs.cloudflare.com/ajax/libs/Swiper/3.0.6/js/swiper.jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/Swiper/3.0.6/js/swiper.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Slider main container -->
<div class="swiper-container" id='first-slider'>
<!-- Additional required wrapper -->
<div class="swiper-wrapper" >
<!-- Slides -->
<div class="swiper-slide" style="background-color:red">Slide 1</div>
<div class="swiper-slide" style="background-color:green">Slide 2</div>
<div class="swiper-slide" style="background-color:yellow">Slide 3</div>
</div>
</div>
<!-- Slider main container -->
<div class="swiper-container" id='second-slider'>
<div class="swiper-wrapper" >
<!-- Slides -->
<div class="swiper-slide" style="background-color:green">Slide 1</div>
<div class="swiper-slide" style="background-color:yellow">Slide 2</div>
<div class="swiper-slide" style="background-color:blue">Slide 3</div>
</div>
</div>
Also, for you to play around with:
http://jsfiddle.net/yuayL7zq/2/
Here is a fiddle i made, to try my ideas.
The problem is that I had two sliders with sliding time interval 2500. In this case, two sliders are working fine without any delay during fist time. After that if I open two or more new tabs in my browsers, and then go to my webpage. Now there is a delay between two sliders.
Below is the code I had used for slide function,
var mySwiper = new Swiper('#first-slider',{
loop:true,
grabCursor: true,
autoplay: 2500,
simulateTouch: false,
transitionSpeed: 1000,
onSlideChangeStart: function(swiper, direction) {// my task will go here...}
});
var mySwiper1 = new Swiper('#second-slider',{
loop:true,
grabCursor: true,
autoplay: 2500,
simulateTouch: false,
transitionSpeed: 1000,
});
I can sure that whenever I reload the page two sliders are working fine with same time interval. I had this problem whenever I moved to new tab and come back to my webpage.Is there any mistake in the two sliders that cause delay between sliders? -Thanks for help

Want to animate the first slides of multiple cycles with one pager

I'm using two Cycle slideshows with a single pager and different effects on each slideshow (with the metadata plugin).
I would also like to animate the first slide of each slideshow as documented here, but I'm having trouble with the syntax.
This is my current js
$(document).ready(function() {
$('.slideshow').each(function(index) {
$(this).cycle({
pager: '#pager',
pagerAnchorBuilder: function(i) {
if (index == 0)
// for first slideshow, return a new anchro
return ''+(i+1)+'';
// for 2nd slideshow, select the anchor created previously
return '#pager a:eq('+i+')';
}
});
});
});
The effects are coded on the .slideshow divs (with the metadata plugin)
<div class="slideshow { fx: 'scrollRight', timeout: 0, cleartypeNoBg: true, speed: 750, easing: 'easeInOutBack' }">
<div class="slideshow { fx: 'scrollLeft', timeout: 0, cleartypeNoBg: true, speed: 750, easing: 'easeInOutBack' }">

Fancybox does not resize properly with PDF

I've been looking through the Fancybox API and the forums here with no luck so far.
Basically when the window is resized the embedded PDF in the fancybox resizes, but the fancybox container does not and bleeds off the right side of the browser.
Heres when it first opens: http://lizbmorrison.net/fancybox1.png
And when the window is resized: http://lizbmorrison.net/fancybox2.png
HTML:
<li class="pdf"><a class="fancypdf" href="#mydoc">View PDF</a></li>
<div id="mydoc" style="display:none;">
<embed class="embed" src="<?php echo wp_get_attachment_url( $PDF->ID ); ?>"></embed>
</div>
JS:
$(document).ready(function() {
var width = $(window).width() * 0.9;
var height = $(window).height() * 0.9;
$('.embed').css('width', width).css('height', height);
$('a.fancypdf').fancybox({
'type': 'inline',
'margin': 0,
'centerOnScroll': false,
'hideOnContentClick': false,
'autoDimensions': true,
'autoScale': true,
'transitionIn': 'fade',
'transitionOut': 'fade',
});
});
$(window).resize(function () {
var width = $(window).width() * 0.9;
var height = $(window).height() * 0.9;
$('.embed').css('width', width).css('height', height);
});
Any ideas?
This is what I've settled on, still not perfect though.
HTML:
<li class="pdf"><a class="fancypdf" style="padding-top: 20px;" href="<?php echo wp_get_attachment_url( $PDF->ID ); ?>">View PDF</a></li>
JS:
$('.fancypdf').fancybox({
'type': 'iframe',
'centerOnScroll': true,
'width': 800,
'height': 600,
'margin': 20,
'autoScale': false,
'autoDimensions': false
});