Can I make this slider auto play? - javascript

I am trying to get this slider to auto play but I can't seem to get it to workDoes anyone know how I can achieve this?
This is the slideshow:
Slideshow

Replace demo6.js code with given -
{
// From https://davidwalsh.name/javascript-debounce-function.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
class Slideshow {
constructor(el, settings) {
this.DOM = {};
this.DOM.el = el;
this.settings = {
animation: {
slides: {
duration: 500,
easing: 'easeOutQuint'
},
shape: {
duration: 300,
easing: {in: 'easeOutQuint', out: 'easeOutQuad'}
}
},
frameFill: 'url(#gradient1)'
}
this.settings.autoSlide = settings.autoSlide || false;
this.settings.autoSlideTimeout = settings.autoSlideTimeout || 4000;
this.init();
}
init() {
this.DOM.slides = Array.from(this.DOM.el.querySelectorAll('.slides--images > .slide'));
this.slidesTotal = this.DOM.slides.length;
this.DOM.nav = this.DOM.el.querySelector('.slidenav');
this.DOM.titles = this.DOM.el.querySelector('.slides--titles');
this.DOM.titlesSlides = Array.from(this.DOM.titles.querySelectorAll('.slide'));
this.DOM.nextCtrl = this.DOM.nav.querySelector('.slidenav__item--next');
this.DOM.prevCtrl = this.DOM.nav.querySelector('.slidenav__item--prev');
this.current = 0;
this.createFrame();
this.initEvents();
}
createFrame() {
this.rect = this.DOM.el.getBoundingClientRect();
this.frameSize = this.rect.width/12;
this.paths = {
initial: this.calculatePath('initial'),
final: this.calculatePath('final')
};
this.DOM.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this.DOM.svg.setAttribute('class', 'shape');
this.DOM.svg.setAttribute('width','100%');
this.DOM.svg.setAttribute('height','100%');
this.DOM.svg.setAttribute('viewbox',`0 0 ${this.rect.width} ${this.rect.height}`);
this.DOM.svg.innerHTML = `
<defs>
<linearGradient id="gradient1" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#09012d"/>
<stop offset="100%" stop-color="#0f2b73"/>
</linearGradient>
</defs>
<path fill="${this.settings.frameFill}" d="${this.paths.initial}"/>`;
this.DOM.el.insertBefore(this.DOM.svg, this.DOM.titles);
this.DOM.shape = this.DOM.svg.querySelector('path');
}
updateFrame() {
this.paths.initial = this.calculatePath('initial');
this.paths.final = this.calculatePath('final');
this.DOM.svg.setAttribute('viewbox',`0 0 ${this.rect.width} ${this.rect.height}`);
this.DOM.shape.setAttribute('d', this.isAnimating ? this.paths.final : this.paths.initial);
}
calculatePath(path = 'initial') {
if ( path === 'initial' ) {
return `M 0,0 0,${this.rect.height} ${this.rect.width},${this.rect.height} ${this.rect.width},0 0,0 Z M 0,0 ${this.rect.width},0 ${this.rect.width},${this.rect.height} 0,${this.rect.height} Z`;
}
else {
const point1 = {x: this.rect.width/4-50, y: this.rect.height/4+50};
const point2 = {x: this.rect.width/4+50, y: this.rect.height/4-50};
const point3 = {x: this.rect.width-point2.x, y: this.rect.height-point2.y};
const point4 = {x: this.rect.width-point1.x, y: this.rect.height-point1.y};
return `M 0,0 0,${this.rect.height} ${this.rect.width},${this.rect.height} ${this.rect.width},0 0,0 Z M ${point1.x},${point1.y} ${point2.x},${point2.y} ${point4.x},${point4.y} ${point3.x},${point3.y} Z`;
}
}
initEvents() {
this.DOM.nextCtrl.addEventListener('click', () => this.navigate('next'));
this.DOM.prevCtrl.addEventListener('click', () => this.navigate('prev'));
window.addEventListener('resize', debounce(() => {
this.rect = this.DOM.el.getBoundingClientRect();
this.updateFrame();
}, 20));
document.addEventListener('keydown', (ev) => {
const keyCode = ev.keyCode || ev.which;
if ( keyCode === 37 ) {
this.navigate('prev');
}
else if ( keyCode === 39 ) {
this.navigate('next');
}
});
if(this.settings.autoSlide) {
setInterval(() => this.navigate('next'), this.settings.autoSlideTimeout);
}
}
navigate(dir = 'next') {
if ( this.isAnimating ) return false;
this.isAnimating = true;
const animateShapeIn = anime({
targets: this.DOM.shape,
duration: this.settings.animation.shape.duration,
easing: this.settings.animation.shape.easing.in,
d: this.paths.final
});
const animateSlides = () => {
return new Promise((resolve, reject) => {
const currentSlide = this.DOM.slides[this.current];
anime({
targets: currentSlide,
duration: this.settings.animation.slides.duration,
easing: this.settings.animation.slides.easing,
translateY: dir === 'next' ? this.rect.height : -1*this.rect.height,
complete: () => {
currentSlide.classList.remove('slide--current');
resolve();
}
});
const currentTitleSlide = this.DOM.titlesSlides[this.current];
anime({
targets: currentTitleSlide.children,
duration: this.settings.animation.slides.duration,
easing: this.settings.animation.slides.easing,
delay: (t,i,total) => dir === 'next' ? i*100 : (total-i-1)*100,
translateY: [0, dir === 'next' ? 100 : -100],
opacity: [1,0],
complete: () => {
currentTitleSlide.classList.remove('slide--current');
resolve();
}
});
this.current = dir === 'next' ?
this.current < this.slidesTotal-1 ? this.current + 1 : 0 :
this.current > 0 ? this.current - 1 : this.slidesTotal-1;
const newSlide = this.DOM.slides[this.current];
newSlide.classList.add('slide--current');
anime({
targets: newSlide,
duration: this.settings.animation.slides.duration,
easing: this.settings.animation.slides.easing,
translateY: [dir === 'next' ? -1*this.rect.height : this.rect.height,0]
});
const newSlideImg = newSlide.querySelector('.slide__img');
anime.remove(newSlideImg);
anime({
targets: newSlideImg,
duration: this.settings.animation.slides.duration*3,
easing: this.settings.animation.slides.easing,
translateY: [dir === 'next' ? -100 : 100, 0],
scale: [0.2,1]
});
const newTitleSlide = this.DOM.titlesSlides[this.current];
newTitleSlide.classList.add('slide--current');
anime({
targets: newTitleSlide.children,
duration: this.settings.animation.slides.duration*1.5,
easing: this.settings.animation.slides.easing,
delay: (t,i,total) => dir === 'next' ? i*100+100 : (total-i-1)*100+100,
translateY: [dir === 'next' ? -100 : 100 ,0],
opacity: [0,1]
});
});
};
const animateShapeOut = () => {
anime({
targets: this.DOM.shape,
duration: this.settings.animation.shape.duration,
easing: this.settings.animation.shape.easing.out,
d: this.paths.initial,
complete: () => this.isAnimating = false
});
}
animateShapeIn.finished.then(animateSlides).then(animateShapeOut);
}
};
new Slideshow(document.querySelector('.slideshow'), {
autoSlide: true,
autoSlideTimeout: 4000 // 4 second
});
imagesLoaded('.slide__img', { background: true }, () => document.body.classList.remove('loading'));
};
I have added settings -
new Slideshow(document.querySelector('.slideshow'), {
autoSlide: true,
autoSlideTimeout: 4000 // 4 second
});
You may code diff to see the changes I have made.

Related

Custom range slider does not work on mobile phone

I have a webpage with a custom price slider. For desktop it works just fine and when I check it in google developer tools for mobile, it works too, but when I open the webpage with my phone, slider stops working properly, it does not change the plan column. How can I debug something like that?
http://sagemailer-17.eugeneskom.com/
that's the code being used for the slider
window.onload = () => {
const init = function() {
const breakpoints = [{
value: 0,
step: 12.5,
stepsSoFar: 0
},
{
value: 200,
step: 50,
stepsSoFar: 16
},
{
value: 1000,
step: 50,
stepsSoFar: 32
},
{
value: 2000,
step: 500,
stepsSoFar: 52
},
{
value: 10000,
step: 1000,
stepsSoFar: 68
},
{
value: 30000,
step: 5000,
stepsSoFar: 88
},
{
value: 100000,
step: 10000,
stepsSoFar: 102
},
{
value: 300000,
step: 50000,
stepsSoFar: 122
},
{
value: 1000000,
stepsSoFar: 136,
step: 1
}
];
const pricing = [
[200, 4, 0.2],
[500, 10, 0.01],
[1000, 15, 0.01],
[2000, 20, 0.005],
[7000, 50, 0.005],
[10000, 65, 0.0025],
[16000, 80, 0.0022],
[25000, 100, 0.006],
[30000, 130, 0.002],
[65000, 200, 0.002],
[100000, 270, 0.0015],
[200000, 420, 0.0015],
[300000, 570, 0.0006],
[600000, 750, 0.0006],
[700000, 810, 0.0006],
[800000, 870, 0.0006],
[900000, 930, 0.0006],
[1000000, 990, 0.001]
];
const planBgs = document.querySelectorAll(".StepRangeSlider__trackHeadItem");
const media = window.matchMedia("(max-width: 1024px)");
const minValue = 200;
const maxStep = breakpoints[breakpoints.length - 1].stepsSoFar;
const slider = document.getElementById("stepRangeSliderWrap");
const handle = document.getElementById("rangeSliderHandle");
const tooltip = document.getElementById("rangeSliderTooltip");
const plans = document.querySelectorAll(".plan-content .right .content");
let plansBreakPoints;
let valueBlock;
let emailsBlock;
let isHorizontal;
let value = 200;
let step = 18;
let pressed = false;
const checkRangeSliderVersion = () => {
if (media.matches) {
valueBlock = document.querySelectorAll(".display-price-mob");
emailsBlock = document.querySelectorAll(".emails-count");
isHorizontal = false;
} else {
valueBlock = document.querySelectorAll(".display-price");
emailsBlock = document.querySelectorAll(".emails-count");
isHorizontal = true;
}
plansBreakPoints = [
planBgs[1].getBoundingClientRect()[isHorizontal ? "left" : "top"],
planBgs[2].getBoundingClientRect()[isHorizontal ? "left" : "top"]
];
};
checkRangeSliderVersion();
media.addListener(checkRangeSliderVersion);
const getPriceForEmailsCount = emails => {
for (let i = pricing.length - 1; i >= 0; i--) {
if (emails === pricing[i][0]) {
return pricing[i][1];
}
if (emails > pricing[i][0]) {
return (emails - pricing[i][0]) * pricing[i + 1][2] + pricing[i][1];
}
}
return null;
};
const getValueForStep = step => {
const nearest = breakpoints.reduce((prev, curr) =>
curr.stepsSoFar < step && curr.stepsSoFar > prev.stepsSoFar ?
curr :
prev
);
const additionalValue = (step - nearest.stepsSoFar) * nearest.step;
return nearest.value + additionalValue;
};
const handleChange = () => {
const offset = (step / maxStep) * 100;
handle.style[isHorizontal ? "left" : "top"] = offset + "%";
tooltip.textContent = Math.floor(value);
valueBlock.forEach(e => {
e.textContent = getPriceForEmailsCount(value) + "$";
});
emailsBlock.forEach(e => {
e.textContent = Math.floor(value);
});
};
const handleMove = e => {
const client = isHorizontal ? e.clientX : e.clientY;
const sliderRect = slider.getBoundingClientRect();
let startPosition = isHorizontal ? sliderRect.left : sliderRect.top;
let endPosition = isHorizontal ? sliderRect.right : sliderRect.bottom;
if (client <= plansBreakPoints[0]) {
plans.forEach(e => {
e.style.display = "none";
});
plans[0].style.display = "block";
} else if (
client >= plansBreakPoints[0] &&
client <= plansBreakPoints[1]
) {
plans.forEach(e => {
e.style.display = "none";
});
plans[1].style.display = "block";
} else if (client >= plansBreakPoints[1]) {
plans.forEach(e => {
e.style.display = "none";
});
plans[2].style.display = "block";
}
if (!client) return;
let position;
if (client < startPosition) {
position = 0;
} else if (client > endPosition) {
position = endPosition - startPosition;
} else {
position = client - startPosition;
}
const currentStep = Math.round(
(position / (isHorizontal ? sliderRect.width : sliderRect.height)) *
maxStep
);
const currentStepValue = getValueForStep(currentStep);
if (
currentStepValue >= minValue &&
(currentStepValue !== value || currentStep !== step)
) {
value = currentStepValue;
step = currentStep;
handleChange();
}
};
const handleTouchMove = e => {
if (pressed) {
handleMouseMove(e.touches[0]);
}
};
const handleMouseUp = e => {
if (pressed) {
pressed = false;
}
};
const handleMouseMove = e => {
if (pressed) {
handleMove(e);
}
};
window.addEventListener("touchmove", handleTouchMove);
window.addEventListener("touchend", handleMouseUp);
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("mouseup", handleMouseUp);
slider.addEventListener("mousedown", function(e) {
e.preventDefault();
pressed = true;
handleMove(e);
});
slider.addEventListener("touchmove", e => {
e.preventDefault();
pressed = true;
handleMove(e.touches[0]);
});
handle.addEventListener("mousedown", function(e) {
e.preventDefault();
pressed = true;
handleMove(e);
});
handle.addEventListener("ontouchstart", function(e) {
e.preventDefault();
pressed = true;
handleMove(e.touches[0]);
});
};
init();
};

How to restrict linking between ports of elements if one link already exist between them in JointJS?

I have 3 elements with ports. My goal is to not allow linking ports between source and destination elements if one of their ports are already linked to each other. Please see my visualization below:
As you can see, I need only 1 to 1 connection between cells. How do I acheive this with JointJS? Please see my JSFiddle.
HTML
<html>
<body>
<button id="btnAdd">Add Table</button>
<div id="dbLookupCanvas"></div>
</body>
</html>
JS
$(document).ready(function() {
$('#btnAdd').on('click', function() {
AddTable();
});
InitializeCanvas();
// Adding of two sample tables on first load
AddTable(50, 50);
AddTable(250, 50);
AddTable(150, 180);
});
var graph;
var paper
var selectedElement;
var namespace;
function InitializeCanvas() {
let canvasContainer = $('#dbLookupCanvas').parent();
namespace = joint.shapes;
graph = new joint.dia.Graph({}, {
cellNamespace: namespace
});
paper = new joint.dia.Paper({
el: document.getElementById('dbLookupCanvas'),
model: graph,
width: canvasContainer.width(),
height: 500,
gridSize: 10,
drawGrid: true,
cellViewNamespace: namespace,
validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
// Prevent link to self
if (cellViewS === cellViewT)
return false;
// Prevent linking from input ports
if ((magnetS !== magnetT))
return true;
},
snapLinks: {
radius: 20
},
defaultLink: () => new joint.shapes.standard.Link({
router: {
name: 'manhattan'
},
connector: {
name: 'normal'
},
attrs: {
line: {
stroke: 'black',
strokeWidth: 1,
sourceMarker: {
'type': 'path',
'stroke': 'black',
'fill': 'black',
'd': 'M 10 -5 0 0 10 5 Z'
},
targetMarker: {
'type': 'path',
'stroke': 'black',
'fill': 'black',
'd': 'M 10 -5 0 0 10 5 Z'
}
}
}
})
});
//Dragging navigation on canvas
var dragStartPosition;
paper.on('blank:pointerdown',
function(event, x, y) {
dragStartPosition = {
x: x,
y: y
};
}
);
paper.on('cell:pointerup blank:pointerup', function(cellView, x, y) {
dragStartPosition = null;
});
$("#dbLookupCanvas")
.mousemove(function(event) {
if (dragStartPosition)
paper.translate(
event.offsetX - dragStartPosition.x,
event.offsetY - dragStartPosition.y);
});
// Remove links not connected to anything
paper.model.on('batch:stop', function() {
var links = paper.model.getLinks();
_.each(links, function(link) {
var source = link.get('source');
var target = link.get('target');
if (source.id === undefined || target.id === undefined) {
link.remove();
}
});
});
paper.on('cell:pointerdown', function(elementView) {
resetAll(this);
let isElement = elementView.model.isElement();
if (isElement) {
var currentElement = elementView.model;
currentElement.attr('body/stroke', 'orange');
selectedElement = elementView.model;
} else
selectedElement = null;
});
paper.on('blank:pointerdown', function(elementView) {
resetAll(this);
});
$('#dbLookupCanvas')
.attr('tabindex', 0)
.on('mouseover', function() {
this.focus();
})
.on('keydown', function(e) {
if (e.keyCode == 46)
if (selectedElement) selectedElement.remove();
});
}
function AddTable(xCoord = undefined, yCoord = undefined, portID = undefined) {
// This is a sample database data here
let data = [{
columnName: "radomData1"
},
{
columnName: "radomData2"
}
];
if (xCoord == undefined && yCoord == undefined) {
xCoord = 50;
yCoord = 50;
}
const rect = new joint.shapes.standard.Rectangle({
position: {
x: xCoord,
y: yCoord
},
size: {
width: 150,
height: 200
},
ports: {
groups: {
'a': {},
'b': {}
}
}
});
$.each(data, (i, v) => {
const port = {
group: 'a',
args: {}, // Extra arguments for the port layout function, see `layout.Port` section
label: {
position: {
name: 'right',
args: {
y: 6
} // Extra arguments for the label layout function, see `layout.PortLabel` section
},
markup: [{
tagName: 'text',
selector: 'label'
}]
},
attrs: {
body: {
magnet: true,
width: 16,
height: 16,
x: -8,
y: -4,
stroke: 'red',
fill: 'gray'
},
label: {
text: v.columnName,
fill: 'black'
}
},
markup: [{
tagName: 'rect',
selector: 'body'
}]
};
rect.addPort(port);
});
rect.resize(150, data.length * 40);
graph.addCell(rect);
}
function resetAll(paper) {
paper.drawBackground({
color: 'white'
});
var elements = paper.model.getElements();
for (var i = 0, ii = elements.length; i < ii; i++) {
var currentElement = elements[i];
currentElement.attr('body/stroke', 'black');
}
var links = paper.model.getLinks();
for (var j = 0, jj = links.length; j < jj; j++) {
var currentLink = links[j];
currentLink.attr('line/stroke', 'black');
currentLink.label(0, {
attrs: {
body: {
stroke: 'black'
}
}
});
}
}
Any help would be appreciated. Thanks!
If you add another condition to validateConnection, it should do the trick.
If you compare the links of the source and target, then return false if they already contain a link with the same ID.
The following seems to work well in your JSFiddle.
validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
// Prevent link on body
if (magnetT == null)
return false;
// Prevent link to self
if (cellViewS === cellViewT)
return false;
const sourceCell = cellViewS.model;
const sourceLinks = graph.getConnectedLinks(sourceCell);
const targetCell = cellViewT.model;
const targetLinks = graph.getConnectedLinks(targetCell);
let isConnection;
// Compare link IDs of source and target elements
targetLinks.forEach((linkT) => {
sourceLinks.forEach((linkS) => {
if (linkS.id === linkT.id) isConnection = true;
});
});
// If source and target already contain a link with the same id , return false
if (isConnection) return false;
// Prevent linking from input ports
if ((magnetS !== magnetT))
return true;
},

PDFjs view pdf to canvas

I am developing a pdf viewer, with the ability to apply additional elements by the user.
Pdf has drag and drop capability, zoom in and out.
I ran into the following problems that baffle me:
Correctly position the new elements so that the image is set at coordinates x: 0, y: 0. (image 1) When displacing pdf, I can not track what distance to displace the coordinates of the new element. (image 2)
To keep the image quality when zooming in, I set the camera Zoom (init scale) to 3. I can't find a solution how to display it in a smaller size when opening the page, so as not to lose quality when zooming in. (image 3)
import React, { useEffect, useState, useRef } from 'react';
import * as PDFJS from 'pdfjs-dist'
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
import {makeStyles} from "#material-ui/core/styles";
export const PdfCanvas = ({pageNum, editCanvas, colorCircle}) => {
const canvasRef = useRef();
const [image, setImage] = useState();
const fileUri = "https://s3-us-east-2.amazonaws.com/c9e8e9c8-7ec0-412f-81cc-60fc07201419/Bar%20Yohai_Coordination%20plane%2000.pdf";
const mainCanvas = canvasRef.current
const mainCtx = mainCanvas?.getContext('2d');
let cameraOffset = { x: window.innerWidth/2, y: window.innerHeight/2 }
let cameraZoom = 3
let MAX_ZOOM = 108
let MIN_ZOOM = 0.01
let SCROLL_SENSITIVITY = 0.0005
const [positionArr, setPositionArr] = useState([
{id: '1', x: 400, y: 40, radius: 10, color: 'rgb(255,0,0)'},
{id: '2', x: 800, y: 40, radius: 10, color: 'rgb(134,211,17)'},
{id: '3', x: 100, y: 40, radius: 10, color: 'rgb(32,52,157)'},
{id: '4', x: 720, y: 40, radius: 10, color: 'rgb(10,9,9)'},
{id: '5', x: 640, y: 40, radius: 10, color: 'rgb(227,170,24)'},
]);
function isIntersect(point: { x: any; y: any; }, circle: { id?: string; x: any; y: any; radius: any; color?: string; }) {
return Math.sqrt((point.x-circle.x) ** 2 + (point.y - circle.y) ** 2) < circle.radius;
}
const renderPage = (pageNum) => {
const canvas = document.createElement('canvas'), ctx = canvas.getContext('2d');
const container = document.getElementById("container")
if (fileUri) {
const loadingTask = PDFJS.getDocument(fileUri);
loadingTask.promise.then(loadedPdf => {
loadedPdf && loadedPdf.getPage(pageNum).then(function(page) {
const viewport = page.getViewport({scale: cameraZoom});
canvas.width = viewport.width;
canvas.height = viewport.height ;
canvas.style.width = "100%";
canvas.style.height = "100%";
container.style.width = Math.floor(viewport.width/cameraZoom) + 'pt';
container.style.height = Math.floor(viewport.height/cameraZoom) + 'pt';
const renderContext = {
canvasContext: ctx,
viewport: viewport
};
page.render(renderContext).promise.then(() => {
var pdfImage = new Image();
pdfImage.src = canvas.toDataURL("image/png", 1)
setImage(pdfImage)
})
});
}, function (reason) {
console.error(reason);
});
}
};
function draw()
{
if (mainCanvas) {
mainCanvas.width = visualViewport.width
mainCanvas.height = visualViewport.height
}
// Translate to the canvas centre before zooming - so you'll always zoom on what you're looking directly at
if (mainCtx) {
mainCtx.scale(cameraZoom, cameraZoom)
mainCtx.translate( -window.innerWidth / .8 + cameraOffset.x, -window.innerHeight / .8 + cameraOffset.y )
mainCtx.clearRect(0,0, window.innerWidth, window.innerHeight)
mainCtx.fillStyle = "#991111"
if (image) {
mainCtx.drawImage(image, 1, 1);
(positionArr || []).map(circle => {
mainCtx?.beginPath();
mainCtx?.arc(circle.x, circle.y, circle.radius / cameraZoom, 0, 2 * Math.PI, false);
if (mainCtx) {
mainCtx.fillStyle = circle.color
}
mainCtx?.fill();
});
}
}
requestAnimationFrame( draw )
}
// Gets the relevant location from a mouse or single touch event
function getEventLocation(e)
{
if (e.touches && e.touches.length === 1)
{
return { x:e.touches[0].clientX, y: e.touches[0].clientY }
}
else if (e.clientX && e.clientY)
{
return { x: e.clientX, y: e.clientY }
}
}
let isDragging = false
let dragStart = { x: 0, y: 0 }
function onPointerDown(e)
{
isDragging = true
dragStart.x = getEventLocation(e).x/cameraZoom - cameraOffset.x
dragStart.y = getEventLocation(e).y/cameraZoom - cameraOffset.y
}
function onPointerUp(e)
{
isDragging = false
initialPinchDistance = null
lastZoom = cameraZoom
}
function onPointerMove(e)
{
if (isDragging)
{
cameraOffset.x = getEventLocation(e).x/cameraZoom - dragStart.x
cameraOffset.y = getEventLocation(e).y/cameraZoom - dragStart.y
}
}
function handleTouch(e, singleTouchHandler)
{
if ( e.touches.length === 1 )
{
singleTouchHandler(e)
}
else if (e.type === "touchmove" && e.touches.length === 2)
{
isDragging = false
handlePinch(e)
}
}
let initialPinchDistance = null
let lastZoom = cameraZoom
function handlePinch(e)
{
e.preventDefault()
let touch1 = { x: e.touches[0].clientX, y: e.touches[0].clientY }
let touch2 = { x: e.touches[1].clientX, y: e.touches[1].clientY }
// This is distance squared, but no need for an expensive sqrt as it's only used in ratio
let currentDistance = (touch1.x - touch2.x)**2 + (touch1.y - touch2.y)**2
if (initialPinchDistance == null)
{
initialPinchDistance = currentDistance
}
else
{
adjustZoom( null, currentDistance/initialPinchDistance )
}
}
function adjustZoom(zoomAmount, zoomFactor, e)
{
if (!isDragging)
{
if (zoomAmount)
{
cameraZoom += zoomAmount*zoomFactor
}
else if (zoomFactor)
{
cameraZoom = zoomFactor*lastZoom
}
cameraZoom = Math.min( cameraZoom, MAX_ZOOM )
cameraZoom = Math.max( cameraZoom, MIN_ZOOM )
}
}
const handleAddIcon = (event: React.MouseEvent<HTMLCanvasElement, MouseEvent>) => {
if (editCanvas){
const x = event.nativeEvent.offsetX / cameraZoom
const y = event.nativeEvent.offsetY / cameraZoom
console.log(x, y)
const circle = {
id: Math.random().toFixed(2), x, y, radius: 10, color: colorCircle
}
mainCtx?.beginPath();
mainCtx?.arc(circle.x, circle.y, circle.radius, 0, 2 * Math.PI, false);
if (mainCtx) {
mainCtx.fillStyle = circle.color
}
mainCtx?.fill();
const newArr = positionArr;
newArr.push(circle)
setPositionArr(newArr)
} else {
const point = {
x : event.nativeEvent.offsetX / cameraZoom,
y : event.nativeEvent.offsetY / cameraZoom
};
console.log(cameraOffset, "cameraOffset")
console.log(point, "point")
positionArr.forEach(circle => {
if (isIntersect(point, circle)) {
alert('click on circle: ' + circle.id);
}
});
}
};
// Ready, set, go
useEffect(() => {
renderPage(pageNum)
}, [])
draw()
return (
<div id="container">
<canvas
onWheel={(e) => adjustZoom(cameraZoom, e.deltaY*SCROLL_SENSITIVITY, e)}
onMouseMove={onPointerMove}
onMouseUp={onPointerUp}
onTouchStart={(e) => handleTouch(e, onPointerDown)}
onTouchMove={(e) => handleTouch(e, onPointerMove)}
onTouchEnd={(e) => handleTouch(e, onPointerUp)}
onMouseDown={(e) => {onPointerDown(e)}}
onClick={(e) => handleAddIcon(e)}
ref={canvasRef} />
</div>
)
}
image 1
image 2
image 3
I would be very glad if someone can tell me the ways to solve these problems.

What is the initialize function of this code below?

I have this code from an old website. I want to initialize this function in my custom js file. But I can't understand how to call this function in my custom.js file. Actually, This code performs as like as a scrollable slider which behaves that when I scroll to down than previous & next scroll step will be opacity 0 and current step opacity will be 1.
(window.webpackJsonpOdmans = window.webpackJsonpOdmans || []).push([
[64], {
433: function(t, e, i) {},
435: function(t, e, i) {
var n = {
"./oddmans-cross-grey.svg": 436,
"./global-scroll.svg": 437
};
function s(t) {
var e = o(t);
return i(e)
}
function o(t) {
var e = n[t];
if (!(e + 1)) {
var i = new Error("Cannot find module '" + t + "'");
throw i.code = "MODULE_NOT_FOUND", i
}
return e
}
s.keys = function() {
return Object.keys(n)
}, s.resolve = o, t.exports = s, s.id = 435
},
436: function(t, e, i) {
"use strict";
i.r(e), e.default = {
id: "icon-oddmans-cross-grey-usage",
viewBox: "33 -33 88 88",
url: i.p + "scroll-steps.svg#icon-oddmans-cross-grey",
toString: function() {
return this.url
}
}
},
437: function(t, e, i) {
"use strict";
i.r(e), e.default = {
id: "icon-global-scroll-usage",
viewBox: "0 0 14 22",
url: i.p + "scroll-steps.svg#icon-global-scroll",
toString: function() {
return this.url
}
}
},
482: function(t, e, i) {
"use strict";
i.r(e), i(16), i(11), i(12), i(433);
var n = i(1),
s = (i(28), i(34), i(35), i(36), i(5), i(6), i(29), i(3), i(8), i(9), i(10), i(0)),
o = i(4),
r = i.n(o),
a = i(2);
function l(t) {
return (l = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
})(t)
}
function h(t) {
return (h = Object.setPrototypeOf ? Object.getPrototypeOf : function(t) {
return t.__proto__ || Object.getPrototypeOf(t)
})(t)
}
function u(t, e) {
return (u = Object.setPrototypeOf || function(t, e) {
return t.__proto__ = e, t
})(t, e)
}
function c(t) {
if (void 0 === t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
return t
}
var d = function(t) {
function e() {
var t, i, n;
! function(t, i) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}(this);
for (var s = arguments.length, o = new Array(s), r = 0; r < s; r++) o[r] = arguments[r];
return (i = !(n = (t = h(e)).call.apply(t, [this].concat(o))) || "object" !== l(n) && "function" != typeof n ? c(this) : n).setBinds = i.setBinds.bind(c(c(i))), a.f.isTouch && !a.f.deviceTypeByViewport !== a.c ? i.onTouchDetect() : (i.setBinds(), i.initContent()), i
}
var i;
return function(t, e) {
if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
t.prototype = Object.create(e && e.prototype, {
constructor: {
value: t,
writable: !0,
configurable: !0
}
}), e && u(t, e)
}(e, s.a), (i = [{
key: "setBinds",
value: function() {
this.showNextStep = this.showNextStep.bind(this), this.initContent = this.initContent.bind(this), this.onScroll = this.onScroll.bind(this), this.setIndex = this.setIndex.bind(this), this.change = this.change.bind(this), this.setHiddens = this.setHiddens.bind(this), this.addListeners = this.addListeners.bind(this), this.goScroll = this.goScroll.bind(this)
}
}, {
key: "onTouchDetect",
value: function() {
this.element.classList.add("scroll-steps--second-style")
}
}, {
key: "initContent",
value: function() {
this.steps = this.refs.steps, this.btn = this.refs.btn, this.cross = this.refs.cross, this.scrollIcon = this.refs.scrollIcon, this.toDown = !0, this.blockEvent = !1, this.duration = 600, this.index = 0, this.height = this.element.getBoundingClientRect().height;
for (var t = 0; t < this.steps.length; t++) this.steps[t].style.visibility = "hidden", this.steps[t].style.opacity = 0, this.steps[t].hiddenElements = function(t) {
if (Array.isArray(t)) {
for (var e = 0, i = new Array(t.length); e < t.length; e++) i[e] = t[e];
return i
}
}(e = this.steps[t].querySelectorAll(".hidden")) || function(t) {
if (Symbol.iterator in Object(t) || "[object Arguments]" === Object.prototype.toString.call(t)) return Array.from(t)
}(e) || function() {
throw new TypeError("Invalid attempt to spread non-iterable instance")
}(), this.steps[t].header = this.steps[t].querySelector(".scroll-steps__title");
var e;
this.setIndex(), this.currentStep.style.visibility = "", this.currentStep.style.opacity = 1, this.setHiddens(this.currentStep, "remove"), this.addListeners()
}
}, {
key: "addListeners",
value: function() {
var t = this;
this.btn.addEventListener("click", function() {
t.toDown = !0, t.goScroll(t.height)
}), document.body.addEventListener("wheel", this.onScroll)
}
}, {
key: "goScroll",
value: function(t) {
r()({
targets: "body, html",
duration: 500,
scrollTop: t,
easing: "easeInOutQuart"
})
}
}, {
key: "setHiddens",
value: function(t, e) {
for (var i = 0; i < t.hiddenElements.length; i++) t.hiddenElements[i].classList[e]("hidden")
}
}, {
key: "onScroll",
value: function(t) {
this.blockEvent && t.preventDefault();
var e = window.pageYOffset < .6 * this.height;
if (!this.blockEvent && e) {
var i = t.deltaY;
i > 0 && this.nextStep ? (t.preventDefault(), this.toDown = !0, this.change()) : i < 0 && this.previousStep && (t.preventDefault(), this.toDown = !1, window.pageYOffset > 0 && e && this.goScroll(0), this.change())
}
}
}, {
key: "change",
value: function() {
this.index >= 0 && this.index < this.steps.length && (this.blockEvent = !0, 0 === this.index && (this.scrollIcon.classList.add("hidden"), console.log("hided")), this.setHiddens(this.currentStep, "add"), r()({
targets: this.currentStep.header,
opacity: 0,
translateY: this.toDown ? "-50px" : "50px",
duration: .7 * this.duration,
easing: "easeInSine"
}), r()({
targets: this.currentStep,
opacity: 0,
translateY: [{
value: "-50%",
duration: 0
}, {
value: this.toDown ? "-90%" : "-10%",
duration: this.duration
}],
duration: this.duration,
easing: "easeInSine",
complete: this.showNextStep
}))
}
}, {
key: "showNextStep",
value: function() {
var t = this;
this.currentStep.style.visibility = "hidden";
var e = this.toDown ? this.nextStep : this.previousStep;
e.style.visibility = "", this.toDown ? this.index++ : this.index--, this.setIndex(), 0 === this.index && this.scrollIcon.classList.remove("hidden"), r()({
targets: this.cross,
rotate: [{
value: 0,
duration: 0
}, {
value: this.toDown ? 90 : -90,
duration: .7 * this.duration
}],
easing: "easeInOutSine"
}), r()({
targets: e.header,
opacity: [{
value: 0,
duration: 0
}, {
value: 1,
duration: .7 * this.duration
}],
translateY: [{
value: this.toDown ? "-50px" : "50px",
duration: 0
}, {
value: 0,
duration: .7 * this.duration
}],
easing: "easeOutSine"
}), r()({
targets: e,
opacity: [{
value: 0,
duration: 0
}, {
value: 1,
duration: this.duration
}],
translateY: [{
value: this.toDown ? "-10%" : "-90%",
duration: 0
}, {
value: "-50%",
duration: this.duration
}],
easing: "easeOutSine",
complete: function() {
t.blockEvent = !1, t.setHiddens(e, "remove")
}
})
}
}, {
key: "setIndex",
value: function() {
this.previousStep = this.steps[this.index - 1] || null, this.currentStep = this.steps[this.index], this.nextStep = this.steps[this.index + 1] || null
}
}]) && function(t, e) {
for (var i = 0; i < e.length; i++) {
var n = e[i];
n.enumerable = n.enumerable || !1, n.configurable = !0, "value" in n && (n.writable = !0), Object.defineProperty(t, n.key, n)
}
}(e.prototype, i), e
}(),
p = i(435);
p.keys().forEach(p), n.a.getInstance().define("scroll-steps", d)
}
},
[
[482, 0]
]
]);

WebRTC and WebAudio Integration

I am trying to integrate WebRTC remote stream with WebAudio. I am using wavesurfer (https://github.com/katspaugh/wavesurfer.js) to accomplish this. When I attach the local stream, it plays well. When I attach the remote stream, buffer contents are filled with zeros and I see no activity. How to fix this?
My Code:
if (this.remoteStream_ != null) {
if (this.wavesurfer_ == null) {
var parent = this;
this.wavesurfer_ = Object.create(WaveSurfer);
this.wavesurfer_.init({
container: '#waveform',
waveColor: '#fff'
});
this.wavesurferStream_ = Object.create(WaveSurfer.Streamer);
this.wavesurferStream_.init({
wavesurfer: this.wavesurfer_
});
// start the microphone
this.wavesurferStream_.start(this.remoteStream_);
this.audioWaveIconSet_.on();
} else {
if (this.wavesurferStream_ != null) {
this.wavesurferStream_.destroy();
this.wavesurferStream_ = null;
}
this.wavesurfer_.destroy();
this.wavesurfer_ = null;
this.audioWaveIconSet_.off();
}
}
Wavesurfer Plugin for Streams:
/*! wavesurfer.js 1.0.57 (Thu, 25 Feb 2016 17:09:20 GMT)
* https://github.com/katspaugh/wavesurfer.js
* #license CC-BY-3.0 */
! function(a, b) {
"function" == typeof define && define.amd ? define(["wavesurfer"], function(a) {
return b(a)
}) : "object" == typeof exports ? module.exports = b(require("wavesurfer.js")) : b(WaveSurfer)
}(this, function(a) {
"use strict";
a.Streamer = {
init: function(a) {
this.params = a;
this.wavesurfer = a.wavesurfer;
if (!this.wavesurfer) throw new Error("No WaveSurfer instance provided");
this.active = !1, this.paused = !1, this.reloadBufferFunction = this.reloadBuffer.bind(this);
this.bufferSize = this.params.bufferSize || 4096, this.numberOfInputChannels = this.params.numberOfInputChannels || 1, this.numberOfOutputChannels = this.params.numberOfOutputChannels || 1, this.micContext = this.wavesurfer.backend.getAudioContext();
},
start: function(stream) {
this.gotStream(stream);
},
togglePlay: function() {
this.active ? (this.paused = !this.paused, this.paused ? this.pause() : this.play()) : this.start()
},
play: function() {
this.paused = !1, this.connect()
},
pause: function() {
this.paused = !0, this.disconnect()
},
stop: function() {
this.active && (this.stopDevice(), this.wavesurfer.empty())
},
stopDevice: function() {},
connect: function() {
void 0 !== this.stream && (this.mediaStreamSource = this.micContext.createMediaStreamSource(this.stream), this.levelChecker = this.micContext.createScriptProcessor(this.bufferSize, this.numberOfInputChannels, this.numberOfOutputChannels), this.mediaStreamSource.connect(this.levelChecker), this.levelChecker.connect(this.micContext.destination), this.levelChecker.onaudioprocess = this.reloadBufferFunction)
},
disconnect: function() {
void 0 !== this.mediaStreamSource && this.mediaStreamSource.disconnect(), void 0 !== this.levelChecker && (this.levelChecker.disconnect(), this.levelChecker.onaudioprocess = void 0)
},
reloadBuffer: function(a) {
this.paused || (this.wavesurfer.empty(), this.wavesurfer.loadDecodedBuffer(a.inputBuffer))
},
gotStream: function(a) {
this.stream = a, this.active = !0, this.play()
},
destroy: function(a) {
this.paused = !0, this.stop()
},
deviceError: function(a) {},
extractVersion: function(a, b, c) {
var d = a.match(b);
return d && d.length >= c && parseInt(d[c], 10)
},
detectBrowser: function() {
var a = {};
return a.browser = null, a.version = null, a.minVersion = null, "undefined" != typeof window && window.navigator ? navigator.mozGetUserMedia ? (a.browser = "firefox", a.version = this.extractVersion(navigator.userAgent, /Firefox\/([0-9]+)\./, 1), a.minVersion = 31, a) : navigator.webkitGetUserMedia && window.webkitRTCPeerConnection ? (a.browser = "chrome", a.version = this.extractVersion(navigator.userAgent, /Chrom(e|ium)\/([0-9]+)\./, 2), a.minVersion = 38, a) : navigator.mediaDevices && navigator.userAgent.match(/Edge\/(\d+).(\d+)$/) ? (a.browser = "edge", a.version = this.extractVersion(navigator.userAgent, /Edge\/(\d+).(\d+)$/, 2), a.minVersion = 10547, a) : (a.browser = "Not a supported browser.", a) : (a.browser = "Not a supported browser.", a)
}
}, a.util.extend(a.Streamer, a.Observer)
}), ! function(a, b) {
"function" == typeof define && define.amd ? define(["wavesurfer"], function(a) {
return b(a)
}) : "object" == typeof exports ? module.exports = b(require("wavesurfer.js")) : b(WaveSurfer)
}(this, function(a) {
"use strict";
a.Streamer = {
init: function(a) {
if (this.params = a, this.wavesurfer = a.wavesurfer, !this.wavesurfer) throw new Error("No WaveSurfer instance provided");
this.active = !1, this.paused = !1, this.reloadBufferFunction = this.reloadBuffer.bind(this);
this.bufferSize = this.params.bufferSize || 4096, this.numberOfInputChannels = this.params.numberOfInputChannels || 1, this.numberOfOutputChannels = this.params.numberOfOutputChannels || 1, this.micContext = this.wavesurfer.backend.getAudioContext();
},
start: function(stream) {
this.gotStream(stream);
},
togglePlay: function() {
this.active ? (this.paused = !this.paused, this.paused ? this.pause() : this.play()) : this.start()
},
play: function() {
this.paused = !1, this.connect()
},
pause: function() {
this.paused = !0, this.disconnect()
},
stop: function() {
this.active && (this.stopDevice(), this.wavesurfer.empty())
},
stopDevice: function() {},
connect: function() {
void 0 !== this.stream && (this.mediaStreamSource = this.micContext.createMediaStreamSource(this.stream), this.levelChecker = this.micContext.createScriptProcessor(this.bufferSize, this.numberOfInputChannels, this.numberOfOutputChannels), this.mediaStreamSource.connect(this.levelChecker), this.levelChecker.connect(this.micContext.destination), this.levelChecker.onaudioprocess = this.reloadBufferFunction)
},
disconnect: function() {
void 0 !== this.mediaStreamSource && this.mediaStreamSource.disconnect(), void 0 !== this.levelChecker && (this.levelChecker.disconnect(), this.levelChecker.onaudioprocess = void 0)
},
reloadBuffer: function(a) {
this.paused || (this.wavesurfer.empty(), this.wavesurfer.loadDecodedBuffer(a.inputBuffer))
},
gotStream: function(a) {
this.stream = a, this.active = !0, this.play()
},
destroy: function(a) {
this.paused = !0, this.stop()
},
deviceError: function(a) {},
extractVersion: function(a, b, c) {
var d = a.match(b);
return d && d.length >= c && parseInt(d[c], 10)
},
detectBrowser: function() {
var a = {};
return a.browser = null, a.version = null, a.minVersion = null, "undefined" != typeof window && window.navigator ? navigator.mozGetUserMedia ? (a.browser = "firefox", a.version = this.extractVersion(navigator.userAgent, /Firefox\/([0-9]+)\./, 1), a.minVersion = 31, a) : navigator.webkitGetUserMedia && window.webkitRTCPeerConnection ? (a.browser = "chrome", a.version = this.extractVersion(navigator.userAgent, /Chrom(e|ium)\/([0-9]+)\./, 2), a.minVersion = 38, a) : navigator.mediaDevices && navigator.userAgent.match(/Edge\/(\d+).(\d+)$/) ? (a.browser = "edge", a.version = this.extractVersion(navigator.userAgent, /Edge\/(\d+).(\d+)$/, 2), a.minVersion = 10547, a) : (a.browser = "Not a supported browser.", a) : (a.browser = "Not a supported browser.", a)
}
}, a.util.extend(a.Streamer, a.Observer)
});
This is a known chrome issue: Hook up Web Audio API with WebRTC for audio processing
After long wait, I guess it has finally been fixed in version 49. Try updating your chrome.
You can check if it works in this Demo app

Categories