Configure Javascript Range Slider - javascript

I have a very simple range slider here: https://jsfiddle.net/dv45kseb/
I'd like to be able to dynamically display 50% of the slider value in the <h3> but I'm not sure to start.
//slider javascript
/*! rangeslider.js - v2.0.2 | (c) 2015 #andreruffert | MIT license | https://github.com/andreruffert/rangeslider.js */
! function(a) {
"use strict";
"function" == typeof define && define.amd ? define(["jquery"], a) : a("object" == typeof exports ? require("jquery") : jQuery)
}(function(a) {
"use strict";
function b() {
var a = document.createElement("input");
return a.setAttribute("type", "range"), "text" !== a.type
}
function c(a, b) {
var c = Array.prototype.slice.call(arguments, 2);
return setTimeout(function() {
return a.apply(null, c)
}, b)
}
function d(a, b) {
return b = b || 100,
function() {
if (!a.debouncing) {
var c = Array.prototype.slice.apply(arguments);
a.lastReturnVal = a.apply(window, c), a.debouncing = !0
}
return clearTimeout(a.debounceTimeout), a.debounceTimeout = setTimeout(function() {
a.debouncing = !1
}, b), a.lastReturnVal
}
}
function e(a) {
return a && (0 === a.offsetWidth || 0 === a.offsetHeight || a.open === !1)
}
function f(a) {
for (var b = [], c = a.parentNode; e(c);) b.push(c), c = c.parentNode;
return b
}
function g(a, b) {
function c(a) {
"undefined" != typeof a.open && (a.open = a.open ? !1 : !0)
}
var d = f(a),
e = d.length,
g = [],
h = a[b];
if (e) {
for (var i = 0; e > i; i++) g[i] = d[i].style.cssText, d[i].style.display = "block", d[i].style.height = "0", d[i].style.overflow = "hidden", d[i].style.visibility = "hidden", c(d[i]);
h = a[b];
for (var j = 0; e > j; j++) d[j].style.cssText = g[j], c(d[j])
}
return h
}
function h(a, b) {
var c = parseFloat(a);
return Number.isNaN(c) ? b : c
}
function i(a) {
return a.charAt(0).toUpperCase() + a.substr(1)
}
function j(b, e) {
if (this.$window = a(window), this.$document = a(document), this.$element = a(b), this.options = a.extend({}, n, e), this.polyfill = this.options.polyfill, this.orientation = this.$element[0].getAttribute("data-orientation") || this.options.orientation, this.onInit = this.options.onInit, this.onSlide = this.options.onSlide, this.onSlideEnd = this.options.onSlideEnd, this.DIMENSION = o.orientation[this.orientation].dimension, this.DIRECTION = o.orientation[this.orientation].direction, this.DIRECTION_STYLE = o.orientation[this.orientation].directionStyle, this.COORDINATE = o.orientation[this.orientation].coordinate, this.polyfill && m) return !1;
this.identifier = "js-" + k + "-" + l++, this.startEvent = this.options.startEvent.join("." + this.identifier + " ") + "." + this.identifier, this.moveEvent = this.options.moveEvent.join("." + this.identifier + " ") + "." + this.identifier, this.endEvent = this.options.endEvent.join("." + this.identifier + " ") + "." + this.identifier, this.toFixed = (this.step + "").replace(".", "").length - 1, this.$fill = a('<div class="' + this.options.fillClass + '" />'), this.$handle = a('<div class="' + this.options.handleClass + '" />'), this.$range = a('<div class="' + this.options.rangeClass + " " + this.options[this.orientation + "Class"] + '" id="' + this.identifier + '" />').insertAfter(this.$element).prepend(this.$fill, this.$handle), this.$element.css({
position: "absolute",
width: "1px",
height: "1px",
overflow: "hidden",
opacity: "0"
}), this.handleDown = a.proxy(this.handleDown, this), this.handleMove = a.proxy(this.handleMove, this), this.handleEnd = a.proxy(this.handleEnd, this), this.init();
var f = this;
this.$window.on("resize." + this.identifier, d(function() {
c(function() {
f.update()
}, 300)
}, 20)), this.$document.on(this.startEvent, "#" + this.identifier + ":not(." + this.options.disabledClass + ")", this.handleDown), this.$element.on("change." + this.identifier, function(a, b) {
if (!b || b.origin !== f.identifier) {
var c = a.target.value,
d = f.getPositionFromValue(c);
f.setPosition(d)
}
})
}
Number.isNaN = Number.isNaN || function(a) {
return "number" == typeof a && a !== a
};
var k = "rangeslider",
l = 0,
m = b(),
n = {
polyfill: !0,
orientation: "horizontal",
rangeClass: "rangeslider",
disabledClass: "rangeslider--disabled",
horizontalClass: "rangeslider--horizontal",
verticalClass: "rangeslider--vertical",
fillClass: "rangeslider__fill",
handleClass: "rangeslider__handle",
startEvent: ["mousedown", "touchstart", "pointerdown"],
moveEvent: ["mousemove", "touchmove", "pointermove"],
endEvent: ["mouseup", "touchend", "pointerup"]
},
o = {
orientation: {
horizontal: {
dimension: "width",
direction: "left",
directionStyle: "left",
coordinate: "x"
},
vertical: {
dimension: "height",
direction: "top",
directionStyle: "bottom",
coordinate: "y"
}
}
};
j.prototype.init = function() {
this.update(!0, !1), this.$element[0].value = this.value, this.onInit && "function" == typeof this.onInit && this.onInit()
}, j.prototype.update = function(a, b) {
a = a || !1, a && (this.min = h(this.$element[0].getAttribute("min"), 0), this.max = h(this.$element[0].getAttribute("max"), 100), this.value = h(this.$element[0].value, this.min + (this.max - this.min) / 2), this.step = h(this.$element[0].getAttribute("step"), 1)), this.handleDimension = g(this.$handle[0], "offset" + i(this.DIMENSION)), this.rangeDimension = g(this.$range[0], "offset" + i(this.DIMENSION)), this.maxHandlePos = this.rangeDimension - this.handleDimension, this.grabPos = this.handleDimension / 2, this.position = this.getPositionFromValue(this.value), this.$element[0].disabled ? this.$range.addClass(this.options.disabledClass) : this.$range.removeClass(this.options.disabledClass), this.setPosition(this.position, b)
}, j.prototype.handleDown = function(a) {
if (a.preventDefault(), this.$document.on(this.moveEvent, this.handleMove), this.$document.on(this.endEvent, this.handleEnd), !((" " + a.target.className + " ").replace(/[\n\t]/g, " ").indexOf(this.options.handleClass) > -1)) {
var b = this.getRelativePosition(a),
c = this.$range[0].getBoundingClientRect()[this.DIRECTION],
d = this.getPositionFromNode(this.$handle[0]) - c,
e = "vertical" === this.orientation ? this.maxHandlePos - (b - this.grabPos) : b - this.grabPos;
this.setPosition(e), b >= d && b < d + this.handleDimension && (this.grabPos = b - d)
}
}, j.prototype.handleMove = function(a) {
a.preventDefault();
var b = this.getRelativePosition(a),
c = "vertical" === this.orientation ? this.maxHandlePos - (b - this.grabPos) : b - this.grabPos;
this.setPosition(c)
}, j.prototype.handleEnd = function(a) {
a.preventDefault(), this.$document.off(this.moveEvent, this.handleMove), this.$document.off(this.endEvent, this.handleEnd), this.$element.trigger("change", {
origin: this.identifier
}), this.onSlideEnd && "function" == typeof this.onSlideEnd && this.onSlideEnd(this.position, this.value)
}, j.prototype.cap = function(a, b, c) {
return b > a ? b : a > c ? c : a
}, j.prototype.setPosition = function(a, b) {
var c, d;
void 0 === b && (b = !0), c = this.getValueFromPosition(this.cap(a, 0, this.maxHandlePos)), d = this.getPositionFromValue(c), this.$fill[0].style[this.DIMENSION] = d + this.grabPos + "px", this.$handle[0].style[this.DIRECTION_STYLE] = d + "px", this.setValue(c), this.position = d, this.value = c, b && this.onSlide && "function" == typeof this.onSlide && this.onSlide(d, c)
}, j.prototype.getPositionFromNode = function(a) {
for (var b = 0; null !== a;) b += a.offsetLeft, a = a.offsetParent;
return b
}, j.prototype.getRelativePosition = function(a) {
var b = i(this.COORDINATE),
c = this.$range[0].getBoundingClientRect()[this.DIRECTION],
d = 0;
return "undefined" != typeof a["page" + b] ? d = a["client" + b] : "undefined" != typeof a.originalEvent["client" + b] ? d = a.originalEvent["client" + b] : a.originalEvent.touches && a.originalEvent.touches[0] && "undefined" != typeof a.originalEvent.touches[0]["client" + b] ? d = a.originalEvent.touches[0]["client" + b] : a.currentPoint && "undefined" != typeof a.currentPoint[this.COORDINATE] && (d = a.currentPoint[this.COORDINATE]), d - c
}, j.prototype.getPositionFromValue = function(a) {
var b, c;
return b = (a - this.min) / (this.max - this.min), c = Number.isNaN(b) ? 0 : b * this.maxHandlePos
}, j.prototype.getValueFromPosition = function(a) {
var b, c;
return b = a / (this.maxHandlePos || 1), c = this.step * Math.round(b * (this.max - this.min) / this.step) + this.min, Number(c.toFixed(this.toFixed))
}, j.prototype.setValue = function(a) {
a !== this.value && this.$element.val(a).trigger("input", {
origin: this.identifier
})
}, j.prototype.destroy = function() {
this.$document.off("." + this.identifier), this.$window.off("." + this.identifier), this.$element.off("." + this.identifier).removeAttr("style").removeData("plugin_" + k), this.$range && this.$range.length && this.$range[0].parentNode.removeChild(this.$range[0])
}, a.fn[k] = function(b) {
var c = Array.prototype.slice.call(arguments, 1);
return this.each(function() {
var d = a(this),
e = d.data("plugin_" + k);
e || d.data("plugin_" + k, e = new j(this, b)), "string" == typeof b && e[b].apply(e, c)
})
}
});
//custom slider javascript
$(function() {
var output = document.querySelectorAll('output')[0];
$(document).on('input', 'input[type="range"]', function(e) {
output.innerHTML = e.currentTarget.value;
});
$('input[type=range]').rangeslider({
polyfill: false
});
});
//when slider changes, hide start message
$("input").on("change", function() {
$("small").fadeOut("slow");
})
body {
color: #404040;
padding: 50px;
max-width: 500px;
margin: 0 auto;
text-align: center;
font-family: sans-serif;
}
h1 {
font-weight: 300;
}
#helper {
float: left;
margin-top: 20px;
color: #46b7d5;
font-style: italic;
}
output {
display: block;
font-size: 3em;
}
/* original css */
.rangeslider,
.rangeslider__fill {
display: block;
-moz-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3);
box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3);
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
.rangeslider {
background: #e6e6e6;
position: relative;
}
.rangeslider--horizontal {
height: 20px;
width: 100%;
}
.rangeslider--vertical {
width: 20px;
min-height: 150px;
max-height: 100%;
}
.rangeslider--disabled {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
opacity: 0.4;
}
.rangeslider__fill {
background: -webkit-linear-gradient(left, #abe0ed, #46b7d5);
/* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(right, #abe0ed, #46b7d5);
/* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(right, #abe0ed, #46b7d5);
/* For Firefox 3.6 to 15 */
background: linear-gradient(to right, #abe0ed, #46b7d5);
/* Standard syntax (must be last) */
position: absolute;
}
.rangeslider--horizontal .rangeslider__fill {
top: 0;
height: 100%;
}
.rangeslider--vertical .rangeslider__fill {
bottom: 0;
width: 100%;
}
.rangeslider__handle {
background: white;
border: 1px solid #ccc;
cursor: pointer;
display: inline-block;
width: 40px;
height: 40px;
position: absolute;
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4xIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g");
background-size: 100%;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(0, 0, 0, 0.1)));
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1));
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1));
background-image: linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1));
-moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
.rangeslider__handle:after {
content: "";
display: block;
width: 18px;
height: 18px;
margin: auto;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEzIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==");
background-size: 100%;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0, 0, 0, 0.13)), color-stop(100%, rgba(255, 255, 255, 0)));
background-image: -moz-linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0));
background-image: -webkit-linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0));
background-image: linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0));
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
.rangeslider__handle:active {
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwLjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4xMiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==");
background-size: 100%;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0, 0, 0, 0.1)), color-stop(100%, rgba(0, 0, 0, 0.12)));
background-image: -moz-linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12));
background-image: -webkit-linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12));
background-image: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12));
}
.rangeslider--horizontal .rangeslider__handle {
top: -10px;
touch-action: pan-y;
-ms-touch-action: pan-y;
}
.rangeslider--vertical .rangeslider__handle {
left: -10px;
touch-action: pan-x;
-ms-touch-action: pan-x;
}
input[type="range"]:focus + .rangeslider .rangeslider__handle {
-moz-box-shadow: 0 0 8px rgba(255, 0, 255, 0.9);
-webkit-box-shadow: 0 0 8px rgba(255, 0, 255, 0.9);
box-shadow: 0 0 8px rgba(255, 0, 255, 0.9);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<h1>
This form lets you drag the slider.
</h1>
<!--https://andreruffert.github.io/rangeslider.js/-->
<input type="range" value="3825" step="500" min="1000" max="40000">
<small id="helper" class="slideRight">Slide to get started →</small>
<br>
<br>
<h2 style="display: inline-block; margin-bottom: 50px;"></h2><output style="display: inline-block">3,825</output>
<h3>
<< Display 50% of total value here >>
</h3>

This part of the code is where the value in the header is modified:
$(document).on('input', 'input[type="range"]', function(e) {
output.innerHTML = e.currentTarget.value;
});
You just need to divide your the value like this:
output.innerHTML = e.currentTarget.value / 2;

To complete the answer - any time you need a value filled dynamically in a page by a javascript you can enclose it with a SPAN tag and an ID attribute (because IDs are unique). So:
<h3>
<span id="halfvalue"></span>
</h3>
and then you add additional code to your event handler code:
var output = document.querySelectorAll('output')[0];
var halfvalue = document.querySelector('#halfvalue');
$(document).on('input', 'input[type="range"]', function(e) {
output.innerHTML = e.currentTarget.value;
halfvalue.innerHTML = e.currentTarget.value / 2
});

Related

add js particule in header

I tried to add the particle effect in javascript, on a project but I don't really know javascript
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Леда</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<nav class="navbar">
ADVENTURE
<div class="nav-links">
<ul>
<li>About</li>
<li>Services</li>
<li>Support</li>
<li>Infos</li>
<li>Contact</li>
</ul>
</div>
<img src="menu-btn.png" alt="menu navbar" class="menu-navbar">
</nav>
<div id="particle-canvas"></div>
</header>
<script src="script.js"></script>
</body>
</html>
css
* {
margin: 0;
padding: 0;
text-decoration: none;
list-style: none;
}
header {
background-image: url('landscape.jpg');
}
header {
height: 100vh;
width: 100vw;
background-size: cover;
}
.navbar {
position: absolute;
padding: 30px;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
box-sizing: border-box;
}
.navbar a {
color: white;
}
.navbar .nav-links ul {
display: flex;
}
.navbar .nav-links ul li {
margin: 0 25px;
}
.navbar .nav-links ul li.active a {
margin: 0 25px;
font-weight: 600;
}
.navbar .menu-navbar{
display: none;
position: absolute;
width: 35px;
}
#media screen and (max-width: 900px) {
.navbar {
padding: 0;
}
.navbar .logo {
position: absolute;
top: 37px;
left: 50px;
}
.navbar .menu-navbar {
display: block;
top: 30px;
right: 50px;
}
.nav-links {
top: 0;
left: 0;
position: absolute;
background-color: rgba(255, 255, 255, 0.233);
width: 100%;
height: 100vh;
backdrop-filter: blur(7px);
display: flex;
justify-content: center;
align-items: center;
margin-left: -100%;
transition: all 0.5s ease;
}
.nav-links.mobile-menu {
margin-left: 0;
}
.nav-links ul {
display: flex;
flex-direction: column;
align-items: center;
}
.navbar .nav-links ul li {
margin: 25px 0;
font-size: 2em;
}
}
#particle-canvas {
width: 100%;
height: 100%;
}
js
const menuHamburger = document.querySelector(".menu-navbar")
const navLinks = document.querySelector(".nav-links")
menuHamburger.addEventListener('click', () => {
navLinks.classList.toggle('mobile-menu')
});
!function (a) { var b = "object" == typeof self && self.self === self && self || "object" == typeof global && global.global === global && global; "function" == typeof define && define.amd ? define(["exports"], function (c) { b.ParticleNetwork = a(b, c) }) : "object" == typeof module && module.exports ? module.exports = a(b, {}) : b.ParticleNetwork = a(b, {}) }(function (a, b) { var c = function (a) { this.canvas = a.canvas, this.g = a.g, this.particleColor = a.options.particleColor, this.x = Math.random() * this.canvas.width, this.y = Math.random() * this.canvas.height, this.velocity = { x: (Math.random() - .5) * a.options.velocity, y: (Math.random() - .5) * a.options.velocity } }; return c.prototype.update = function () { (this.x > this.canvas.width + 20 || this.x < -20) && (this.velocity.x = -this.velocity.x), (this.y > this.canvas.height + 20 || this.y < -20) && (this.velocity.y = -this.velocity.y), this.x += this.velocity.x, this.y += this.velocity.y }, c.prototype.h = function () { this.g.beginPath(), this.g.fillStyle = this.particleColor, this.g.globalAlpha = .7, this.g.arc(this.x, this.y, 1.5, 0, 2 * Math.PI), this.g.fill() }, b = function (a, b) { this.i = a, this.i.size = { width: this.i.offsetWidth, height: this.i.offsetHeight }, b = void 0 !== b ? b : {}, this.options = { particleColor: void 0 !== b.particleColor ? b.particleColor : "#fff", background: void 0 !== b.background ? b.background : "#1a252f", interactive: void 0 !== b.interactive ? b.interactive : !0, velocity: this.setVelocity(b.speed), density: this.j(b.density) }, this.init() }, b.prototype.init = function () { if (this.k = document.createElement("div"), this.i.appendChild(this.k), this.l(this.k, { position: "absolute", top: 0, left: 0, bottom: 0, right: 0, "z-index": 1 }), /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.background)) this.l(this.k, { background: this.options.background }); else { if (!/\.(gif|jpg|jpeg|tiff|png)$/i.test(this.options.background)) return console.error("Please specify a valid background image or hexadecimal color"), !1; this.l(this.k, { background: 'url("' + this.options.background + '") no-repeat center', "background-size": "cover" }) } if (!/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.particleColor)) return console.error("Please specify a valid particleColor hexadecimal color"), !1; this.canvas = document.createElement("canvas"), this.i.appendChild(this.canvas), this.g = this.canvas.getContext("2d"), this.canvas.width = this.i.size.width, this.canvas.height = this.i.size.height, this.l(this.i, { position: "relative" }), this.l(this.canvas, { "z-index": "20", position: "relative" }), window.addEventListener("resize", function () { return this.i.offsetWidth === this.i.size.width && this.i.offsetHeight === this.i.size.height ? !1 : (this.canvas.width = this.i.size.width = this.i.offsetWidth, this.canvas.height = this.i.size.height = this.i.offsetHeight, clearTimeout(this.m), void (this.m = setTimeout(function () { this.o = []; for (var a = 0; a < this.canvas.width * this.canvas.height / this.options.density; a++)this.o.push(new c(this)); this.options.interactive && this.o.push(this.p), requestAnimationFrame(this.update.bind(this)) }.bind(this), 500))) }.bind(this)), this.o = []; for (var a = 0; a < this.canvas.width * this.canvas.height / this.options.density; a++)this.o.push(new c(this)); this.options.interactive && (this.p = new c(this), this.p.velocity = { x: 0, y: 0 }, this.o.push(this.p), this.canvas.addEventListener("mousemove", function (a) { this.p.x = a.clientX - this.canvas.offsetLeft, this.p.y = a.clientY - this.canvas.offsetTop }.bind(this)), this.canvas.addEventListener("mouseup", function (a) { this.p.velocity = { x: (Math.random() - .5) * this.options.velocity, y: (Math.random() - .5) * this.options.velocity }, this.p = new c(this), this.p.velocity = { x: 0, y: 0 }, this.o.push(this.p) }.bind(this))), requestAnimationFrame(this.update.bind(this)) }, b.prototype.update = function () { this.g.clearRect(0, 0, this.canvas.width, this.canvas.height), this.g.globalAlpha = 1; for (var a = 0; a < this.o.length; a++) { this.o[a].update(), this.o[a].h(); for (var b = this.o.length - 1; b > a; b--) { var c = Math.sqrt(Math.pow(this.o[a].x - this.o[b].x, 2) + Math.pow(this.o[a].y - this.o[b].y, 2)); c > 120 || (this.g.beginPath(), this.g.strokeStyle = this.options.particleColor, this.g.globalAlpha = (120 - c) / 120, this.g.lineWidth = .7, this.g.moveTo(this.o[a].x, this.o[a].y), this.g.lineTo(this.o[b].x, this.o[b].y), this.g.stroke()) } } 0 !== this.options.velocity && requestAnimationFrame(this.update.bind(this)) }, b.prototype.setVelocity = function (a) { return "fast" === a ? 1 : "slow" === a ? .33 : "none" === a ? 0 : .66 }, b.prototype.j = function (a) { return "high" === a ? 5e3 : "low" === a ? 2e4 : isNaN(parseInt(a, 10)) ? 1e4 : a }, b.prototype.l = function (a, b) { for (var c in b) a.style[c] = b[c] }, b });
// Initialisation
var canvasDiv = document.getElementById('particle-canvas');
var options = {
particleColor: '#888',
interactive: true,
speed: 'medium',
density: 'high'
};
var particleCanvas = new ParticleNetwork(canvasDiv, options);
I copied and pasted the entire code but it gave me a problem. It covered my image and the navbar in blue and I can't see anything except a blue page with the particles. What needs to change in the code so that we see the image and the navbar and that the click on the navbar works.
Everything seems to be working OK except your canvas with the particles on it is 'on top' of the other stuff.
If you make the canvas go back (in the z axis sense - that is the axis that is orthogonal to the screen) then the header is seen.
Make canvas have z-index: -1;
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Леда</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<nav class="navbar">
ADVENTURE
<div class="nav-links">
<ul>
<li>About</li>
<li>Services</li>
<li>Support</li>
<li>Infos</li>
<li>Contact</li>
</ul>
</div>
<img src="menu-btn.png" alt="menu navbar" class="menu-navbar">
</nav>
<div id="particle-canvas"></div>
</header>
<style>
* {
margin: 0;
padding: 0;
text-decoration: none;
list-style: none;
}
header {
background-image: url('landscape.jpg');
}
header {
height: 100vh;
width: 100vw;
background-size: cover;
}
.navbar {
position: absolute;
padding: 30px;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
box-sizing: border-box;
}
.navbar a {
color: white;
}
.navbar .nav-links ul {
display: flex;
}
.navbar .nav-links ul li {
margin: 0 25px;
}
.navbar .nav-links ul li.active a {
margin: 0 25px;
font-weight: 600;
}
.navbar .menu-navbar {
display: none;
position: absolute;
width: 35px;
}
#media screen and (max-width: 900px) {
.navbar {
padding: 0;
}
.navbar .logo {
position: absolute;
top: 37px;
left: 50px;
}
.navbar .menu-navbar {
display: block;
top: 30px;
right: 50px;
}
.nav-links {
top: 0;
left: 0;
position: absolute;
background-color: rgba(255, 255, 255, 0.233);
width: 100%;
height: 100vh;
backdrop-filter: blur(7px);
display: flex;
justify-content: center;
align-items: center;
margin-left: -100%;
transition: all 0.5s ease;
}
.nav-links.mobile-menu {
margin-left: 0;
}
.nav-links ul {
display: flex;
flex-direction: column;
align-items: center;
}
.navbar .nav-links ul li {
margin: 25px 0;
font-size: 2em;
}
}
#particle-canvas {
width: 100%;
height: 100%;
z-index: -1;
}
</style>
<script>
const menuHamburger = document.querySelector(".menu-navbar")
const navLinks = document.querySelector(".nav-links")
menuHamburger.addEventListener('click', () => {
navLinks.classList.toggle('mobile-menu')
});
! function(a) {
var b = "object" == typeof self && self.self === self && self || "object" == typeof global && global.global === global && global;
"function" == typeof define && define.amd ? define(["exports"], function(c) {
b.ParticleNetwork = a(b, c)
}) : "object" == typeof module && module.exports ? module.exports = a(b, {}) : b.ParticleNetwork = a(b, {})
}(function(a, b) {
var c = function(a) {
this.canvas = a.canvas, this.g = a.g, this.particleColor = a.options.particleColor, this.x = Math.random() * this.canvas.width, this.y = Math.random() * this.canvas.height, this.velocity = {
x: (Math.random() - .5) * a.options.velocity,
y: (Math.random() - .5) * a.options.velocity
}
};
return c.prototype.update = function() {
(this.x > this.canvas.width + 20 || this.x < -20) && (this.velocity.x = -this.velocity.x), (this.y > this.canvas.height + 20 || this.y < -20) && (this.velocity.y = -this.velocity.y), this.x += this.velocity.x, this.y += this.velocity.y
}, c.prototype.h = function() {
this.g.beginPath(), this.g.fillStyle = this.particleColor, this.g.globalAlpha = .7, this.g.arc(this.x, this.y, 1.5, 0, 2 * Math.PI), this.g.fill()
}, b = function(a, b) {
this.i = a, this.i.size = {
width: this.i.offsetWidth,
height: this.i.offsetHeight
}, b = void 0 !== b ? b : {}, this.options = {
particleColor: void 0 !== b.particleColor ? b.particleColor : "#fff",
background: void 0 !== b.background ? b.background : "#1a252f",
interactive: void 0 !== b.interactive ? b.interactive : !0,
velocity: this.setVelocity(b.speed),
density: this.j(b.density)
}, this.init()
}, b.prototype.init = function() {
if (this.k = document.createElement("div"), this.i.appendChild(this.k), this.l(this.k, {
position: "absolute",
top: 0,
left: 0,
bottom: 0,
right: 0,
"z-index": 1
}), /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.background)) this.l(this.k, {
background: this.options.background
});
else {
if (!/\.(gif|jpg|jpeg|tiff|png)$/i.test(this.options.background)) return console.error("Please specify a valid background image or hexadecimal color"), !1;
this.l(this.k, {
background: 'url("' + this.options.background + '") no-repeat center',
"background-size": "cover"
})
}
if (!/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.particleColor)) return console.error("Please specify a valid particleColor hexadecimal color"), !1;
this.canvas = document.createElement("canvas"), this.i.appendChild(this.canvas), this.g = this.canvas.getContext("2d"), this.canvas.width = this.i.size.width, this.canvas.height = this.i.size.height, this.l(this.i, {
position: "relative"
}), this.l(this.canvas, {
"z-index": "20",
position: "relative"
}), window.addEventListener("resize", function() {
return this.i.offsetWidth === this.i.size.width && this.i.offsetHeight === this.i.size.height ? !1 : (this.canvas.width = this.i.size.width = this.i.offsetWidth, this.canvas.height = this.i.size.height = this.i.offsetHeight, clearTimeout(this.m), void(this.m = setTimeout(function() {
this.o = [];
for (var a = 0; a < this.canvas.width * this.canvas.height / this.options.density; a++) this.o.push(new c(this));
this.options.interactive && this.o.push(this.p), requestAnimationFrame(this.update.bind(this))
}.bind(this), 500)))
}.bind(this)), this.o = [];
for (var a = 0; a < this.canvas.width * this.canvas.height / this.options.density; a++) this.o.push(new c(this));
this.options.interactive && (this.p = new c(this), this.p.velocity = {
x: 0,
y: 0
}, this.o.push(this.p), this.canvas.addEventListener("mousemove", function(a) {
this.p.x = a.clientX - this.canvas.offsetLeft, this.p.y = a.clientY - this.canvas.offsetTop
}.bind(this)), this.canvas.addEventListener("mouseup", function(a) {
this.p.velocity = {
x: (Math.random() - .5) * this.options.velocity,
y: (Math.random() - .5) * this.options.velocity
}, this.p = new c(this), this.p.velocity = {
x: 0,
y: 0
}, this.o.push(this.p)
}.bind(this))), requestAnimationFrame(this.update.bind(this))
}, b.prototype.update = function() {
this.g.clearRect(0, 0, this.canvas.width, this.canvas.height), this.g.globalAlpha = 1;
for (var a = 0; a < this.o.length; a++) {
this.o[a].update(), this.o[a].h();
for (var b = this.o.length - 1; b > a; b--) {
var c = Math.sqrt(Math.pow(this.o[a].x - this.o[b].x, 2) + Math.pow(this.o[a].y - this.o[b].y, 2));
c > 120 || (this.g.beginPath(), this.g.strokeStyle = this.options.particleColor, this.g.globalAlpha = (120 - c) / 120, this.g.lineWidth = .7, this.g.moveTo(this.o[a].x, this.o[a].y), this.g.lineTo(this.o[b].x, this.o[b].y), this.g.stroke())
}
}
0 !== this.options.velocity && requestAnimationFrame(this.update.bind(this))
}, b.prototype.setVelocity = function(a) {
return "fast" === a ? 1 : "slow" === a ? .33 : "none" === a ? 0 : .66
}, b.prototype.j = function(a) {
return "high" === a ? 5e3 : "low" === a ? 2e4 : isNaN(parseInt(a, 10)) ? 1e4 : a
}, b.prototype.l = function(a, b) {
for (var c in b) a.style[c] = b[c]
}, b
});
// Initialisation
var canvasDiv = document.getElementById('particle-canvas');
var options = {
particleColor: '#888',
interactive: true,
speed: 'medium',
density: 'high'
};
var particleCanvas = new ParticleNetwork(canvasDiv, options);
</script>
<script src="script.js"></script>
</body>
</html>

Online Scratch Card Splice from array and call function when empty

here I have a script of a scratch card game that works. For now I want to ask a splice function where the image in the array will be removed for each attempt online and a function will execute when the array is empty. So far I can't seem to get it work. Maybe need to add somewhere at the library. Below are the scripts:
var promoCode = '';
var bg1 = 'http://farm5.static.flickr.com/4005/4706825697_c0367e6dee_b.jpg';
var bg2 = 'http://farm5.static.flickr.com/4017/4717107886_dcc1270a65_b.jpg';
var bg3 = 'http://images6.fanpop.com/image/photos/41500000/adorable-puppies-cute-puppies-41538743-590-393.jpg';
var bgArray = [bg1, bg2, bg3];
selectBG = bgArray.splice(Math.floor(Math.random() * bgArray.length), 1)[0];
console.log(selectBG);
if (selectBG === bg1) {
promoCode = 'SCRATCH400';
} else if (selectBG === bg2) {
promoCode = 'SCRATCH500';
} else if (selectBG === bg3) {
promoCode = 'SCRATCH600';
} else if (bgArray.length === 0) {
alert("No more voucher");
}
$('#promo').wScratchPad({
// the size of the eraser
size: 70,
// the randomized scratch image
bg: selectBG,
// give real-time updates
realtime: true,
// The overlay image
fg: 'https://cdn.glitch.com/2c225b7b-6134-4f2b-9842-1d5d060d9cd4%2Foverlay.png',
// The cursor (coin) image
'cursor': 'url("https://cdn.glitch.com/2c225b7b-6134-4f2b-9842-1d5d060d9cd4%2Fcoin1.png") 5 5, default',
scratchMove: function(e, percent) {
console.log(percent);
console.log(promoCode);
// Show the plain-text promo code and call-to-action when the scratch area is 50% scratched
if ((percent > 50) && (promoCode != '')) {
$('.promo-container').show();
$('body').removeClass('not-selectable');
$('.promo-code').html('Your code is: ' + promoCode);
}
}
});
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.scratchpad {
width: 450px;
height: 445px;
border: solid 10px #FFFFFF;
margin: 0 auto;
}
body {
background: #efefef;
}
.scratch-container {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
width: 100%;
}
#media only screen and (max-width: 480px) {
.scratchpad {
width: 400px;
height: 396px;
}
.scratch-container {
width: 400px !important;
}
}
/* Custom, iPhone Retina */
#media only screen and (max-width: 320px) {
.scratchpad {
width: 290px;
height: 287px;
}
.scratch-container {
width: 290px !important;
}
}
.promo-container {
background: #FFF;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
width: 450px;
padding: 20px;
margin: 0 auto;
text-align: center;
font-family: 'Open Sans', Arial, Sans-serif;
color: #333;
font-size: 16px;
margin-top: 20px;
}
.btn {
background: #56CFD2;
color: #FFF;
padding: 10px 25px;
display: inline-block;
margin-top: 15px;
text-decoration: none;
font-weight: 600;
text-transform: uppercase;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radiuss: 3px;
}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700italic,700" rel="stylesheet" type="text/css">
<title>Scratch Card</title>
</head>
<body>
<div class="scratch-container">
<div id="promo" class="scratchpad"></div>
</div>
<div class="promo-container" style="display:none;">
<div class="promo-code"></div>
Return
</div>
<script type="text/javascript">
(function(a) {
'use strict';
function b(c, d) {
this.$el = a(c), this.options = d, this.init = !1, this.enabled = !0, this._generate()
}
b.prototype = {
_generate: function() {
return a.support.canvas ? void(this.canvas = document.createElement('canvas'), this.ctx = this.canvas.getContext('2d'), 'static' === this.$el.css('position') && this.$el.css('position', 'relative'), this.$img = a('<img src=""/>').attr('crossOrigin', '').css({
position: 'absolute',
width: '100%',
height: '100%'
}), this.$scratchpad = a(this.canvas).css({
position: 'absolute',
width: '100%',
height: '100%'
}), this.$scratchpad.bindMobileEvents(), this.$scratchpad.mousedown(a.proxy(function(c) {
return !this.enabled || void(this.canvasOffset = a(this.canvas).offset(), this.scratch = !0, this._scratchFunc(c, 'Down'))
}, this)).mousemove(a.proxy(function(c) {
this.scratch && this._scratchFunc(c, 'Move')
}, this)).mouseup(a.proxy(function(c) {
this.scratch && (this.scratch = !1, this._scratchFunc(c, 'Up'))
}, this)), this._setOptions(), this.$el.append(this.$img).append(this.$scratchpad), this.init = !0, this.reset()) : (this.$el.append('Canvas is not supported in this browser.'), !0)
},
reset: function() {
var c = this,
d = Math.ceil(this.$el.innerWidth()),
f = Math.ceil(this.$el.innerHeight()),
g = window.devicePixelRatio || 1;
this.pixels = d * f, this.$scratchpad.attr('width', d).attr('height', f), this.canvas.setAttribute('width', d * g), this.canvas.setAttribute('height', f * g), this.ctx.scale(g, g), this.pixels = d * g * f * g, this.$img.hide(), this.options.bg && ('#' === this.options.bg.charAt(0) ? this.$el.css('backgroundColor', this.options.bg) : (this.$el.css('backgroundColor', ''), this.$img.attr('src', this.options.bg))), this.options.fg && ('#' === this.options.fg.charAt(0) ? (this.ctx.fillStyle = this.options.fg, this.ctx.beginPath(), this.ctx.rect(0, 0, d, f), this.ctx.fill(), this.$img.show()) : a(new Image).attr('crossOrigin', '').attr('src', this.options.fg).load(function() {
c.ctx.drawImage(this, 0, 0, d, f), c.$img.show()
}))
},
clear: function() {
this.ctx.clearRect(0, 0, Math.ceil(this.$el.innerWidth()), Math.ceil(this.$el.innerHeight()))
},
enable: function(c) {
this.enabled = !(!0 !== c)
},
destroy: function() {
this.$el.children().remove(), a.removeData(this.$el, 'wScratchPad')
},
_setOptions: function() {
var c, d;
for (c in this.options) this.options[c] = this.$el.attr('data-' + c) || this.options[c], d = 'set' + c.charAt(0).toUpperCase() + c.substring(1), this[d] && this[d](this.options[c])
},
setBg: function() {
this.init && this.reset()
},
setFg: function() {
this.setBg()
},
setCursor: function(c) {
this.$el.css('cursor', c)
},
_scratchFunc: function(c, d) {
c.pageX = Math.floor(c.pageX - this.canvasOffset.left), c.pageY = Math.floor(c.pageY - this.canvasOffset.top), this['_scratch' + d](c), (this.options.realtime || 'Up' === d) && this.options['scratch' + d] && this.options['scratch' + d].apply(this, [c, this._scratchPercent()])
},
_scratchPercent: function() {
for (var c = 0, d = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height), f = 0, g = d.data.length; f < g; f += 4) 0 === d.data[f] && 0 === d.data[f + 1] && 0 === d.data[f + 2] && 0 === d.data[f + 3] && c++;
return 100 * (c / this.pixels)
},
_scratchDown: function(c) {
this.ctx.globalCompositeOperation = 'destination-out', this.ctx.lineJoin = 'round', this.ctx.lineCap = 'round', this.ctx.strokeStyle = this.options.color, this.ctx.lineWidth = this.options.size, this.ctx.beginPath(), this.ctx.arc(c.pageX, c.pageY, this.options.size / 2, 0, 2 * Math.PI, !0), this.ctx.closePath(), this.ctx.fill(), this.ctx.beginPath(), this.ctx.moveTo(c.pageX, c.pageY)
},
_scratchMove: function(c) {
this.ctx.lineTo(c.pageX, c.pageY), this.ctx.stroke()
},
_scratchUp: function() {
this.ctx.closePath()
}
}, a.support.canvas = document.createElement('canvas').getContext, a.fn.wScratchPad = function(c, d) {
if ('string' == typeof c) {
var g, h = [],
j = (void 0 === d ? 'get' : 'set') + c.charAt(0).toUpperCase() + c.substring(1),
k = function() {
g.options[c] && (g.options[c] = d), g[j] && g[j].apply(g, [d])
},
l = function() {
return g[j] ? g[j].apply(g, [d]) : g.options[c] ? g.options[c] : void 0
},
m = function() {
g = a.data(this, 'wScratchPad'), g && (g[c] ? g[c].apply(g, [d]) : void 0 === d ? h.push(l()) : k())
};
return this.each(m), h.length ? 1 === h.length ? h[0] : h : this
}
return c = a.extend({}, a.fn.wScratchPad.defaults, c), this.each(function() {
var n = a.data(this, 'wScratchPad');
return n || (n = new b(this, a.extend(!0, {}, c)), a.data(this, 'wScratchPad', n)), n
})
}, a.fn.wScratchPad.defaults = {
size: 5,
bg: '#cacaca',
fg: '#6699ff',
realtime: !0,
scratchDown: null,
scratchUp: null,
scratchMove: null,
cursor: 'crosshair'
}, a.fn.bindMobileEvents = function() {
a(this).on('touchstart touchmove touchend touchcancel', function(c) {
var d = c.changedTouches || c.originalEvent.targetTouches,
f = d[0],
g = '';
switch (c.type) {
case 'touchstart':
g = 'mousedown';
break;
case 'touchmove':
g = 'mousemove', c.preventDefault();
break;
case 'touchend':
g = 'mouseup';
break;
default:
return;
}
var h = document.createEvent('MouseEvent');
h.initMouseEvent(g, !0, !0, window, 1, f.screenX, f.screenY, f.clientX, f.clientY, !1, !1, !1, !1, 0, null), f.target.dispatchEvent(h)
})
}
})(jQuery);
</script>
</body>
</html>

Drag image within container, not moving with mouse, slightly quicker

I have got a Vue component where i can zoom in on an image and then move it around the container. When zoomed there is also a small viewport to show what part of the image is visible. However when moving the image around it is moving faster than the mouse, i'm guessing this is due to using the scale transform.
I also feel like when i'm clicking and dragging on the viewport I shouldn't be reversing the values twice however this seems to be the only way to get it moving the square with the mouse.
Vue.component('test', {
template: '#template',
data: function() {
return {
loading: true,
loop: true,
speed: 8,
speedController: 0,
zoomEnabled: true,
zoomLevels: [1, 1.5, 2, 2.5, 3],
zoomLevel: 1,
frame: 1,
images: [],
imagesPreloaded: 0,
reverse: false,
viewportScale: 0.3,
viewportEnabled: true,
viewportOpacity: 0.8,
lastX: 0,
lastY: 0,
startX: 0,
startY: 0,
translateX: 0,
translateY: 0,
isMoving: false,
isDragging: false,
};
},
mounted() {
window.addEventListener('mouseup', this.handleEnd);
window.addEventListener('touchend', this.handleEnd);
},
beforeDestroy() {
window.removeEventListener('mouseup', this.handleEnd);
window.removeEventListener('touchend', this.handleEnd);
},
methods: {
handleSlider(event) {
this.frame = Number(event.target.value);
},
zoom(direction) {
const closest = this.zoomLevels.reduce((a, b) => {
return Math.abs(b - this.zoomLevel) < Math.abs(a - this.zoomLevel) ? b : a;
});
if (this.zoomLevels[this.zoomLevels.indexOf(closest) + direction] === undefined) {
return;
}
let current = this.zoomLevels.indexOf(closest);
let index = current += direction;
if (direction === 0) {
index = 0;
}
this.zoomLevel = this.zoomLevels[index];
window.requestAnimationFrame(() => {
this.translate(null, this.$refs.image, true);
});
},
zoomWheel($event) {
$event.preventDefault();
this.zoomLevel += $event.deltaY * -0.01;
if (this.zoomLevel < 1) {
this.zoomLevel = 1;
}
let maxZoom = this.zoomLevels[this.zoomLevels.length - 1];
this.zoomLevel = Math.min(Math.max(.125, this.zoomLevel), maxZoom);
window.requestAnimationFrame(() => {
this.translate(null, this.$refs.image, true);
});
},
handleStart($event) {
$event.preventDefault();
if ($event.button && $event.button !== 0) {
return;
}
this.isMoving = true;
this.isDragging = true;
this.startX = $event.pageX || $event.touches[0].pageX;
this.startY = $event.pageY || $event.touches[0].pageY;
},
handleMove($event, viewport) {
if ($event.button && $event.button !== 0) {
return;
}
if (this.isMoving && this.isDragging) {
const positions = {
x: $event.pageX || $event.touches[0].pageX,
y: $event.pageY || $event.touches[0].pageY
}
if (this.zoomLevel !== 1) {
this.translate(positions, $event.target, null, viewport);
}
if (this.zoomLevel === 1) {
this.changeFrame(positions);
}
}
},
handleEnd($event) {
if ($event.button && $event.button !== 0) {
return;
}
this.isMoving = false;
},
translate(positions, element, zooming, viewport) {
if (positions === null) {
positions = {
x: this.startX,
y: this.startY
};
}
let move = {
x: Math.floor(positions.x - this.startX),
y: Math.floor(positions.y - this.startY)
};
// Reverse Mouse Movement
if (viewport) {
move.x = -move.x;
move.y = -move.y;
}
let image = element.getBoundingClientRect();
let container = element.parentNode.getBoundingClientRect();
let translate = {
left: Math.floor((container.left - image.left) - (move.x * this.zoomLevel)),
right: Math.floor((container.right - image.right) - (move.x * this.zoomLevel)),
top: Math.floor((container.top - image.top) - (move.y * this.zoomLevel)),
bottom: Math.floor((container.bottom - image.bottom) - (move.y * this.zoomLevel))
};
// Reverse Translate Movement
if (viewport) {
translate.left = -translate.left;
translate.right = -translate.right;
translate.top = -translate.top;
translate.bottom = -translate.bottom;
}
if (zooming) {
if (translate.left <= 0) {
this.translateX += Math.floor(translate.left);
}
if (translate.right >= 0) {
this.translateX += Math.floor(translate.right);
}
if (translate.top <= 0) {
this.translateY += Math.floor(translate.top);
}
if (translate.bottom >= 0) {
this.translateY += Math.floor(translate.bottom);
}
}
if (translate.left >= 0 && translate.right <= 0) {
this.translateX += Math.floor(move.x);
}
if (translate.top >= 0 && translate.bottom <= 0) {
this.translateY += Math.floor(move.y);
}
this.startX = positions.x;
this.startY = positions.y;
}
},
computed: {
nextZoomLevel: function() {
const closest = this.zoomLevels.reduce((a, b) => {
return Math.abs(b - this.zoomLevel) < Math.abs(a - this.zoomLevel) ? b : a;
});
if (this.zoomLevels.indexOf(closest) === this.zoomLevels.length - 1) {
return this.zoomLevels[0];
}
return this.zoomLevels[this.zoomLevels.indexOf(closest) + 1];
},
viewportTransform: function() {
if (this.viewportEnabled) {
let translateX = -((this.translateX * this.viewportScale) * this.zoomLevel);
let translateY = -((this.translateY * this.viewportScale) * this.zoomLevel);
return `scale(${1 / this.zoomLevel}) translateX(${translateX}px) translateY(${translateY}px)`;
}
},
transform: function() {
return `scale(${this.zoomLevel}) translateX(${this.translateX}px) translateY(${this.translateY}px)`;
},
canZoomIn: function() {
const closest = this.zoomLevels.reduce((a, b) => {
return Math.abs(b - this.zoomLevel) < Math.abs(a - this.zoomLevel) ? b : a;
});
return this.zoomLevels[this.zoomLevels.indexOf(closest) + 1] === undefined
},
canZoomOut: function() {
const closest = this.zoomLevels.reduce((a, b) => {
return Math.abs(b - this.zoomLevel) < Math.abs(a - this.zoomLevel) ? b : a;
});
return this.zoomLevels[this.zoomLevels.indexOf(closest) + -1] === undefined
}
}
});
window.vue = new Vue({el: '#app'});
.media-360-viewer {
position: relative;
overflow: hidden;
background: #000;
}
.media-360-viewer>img {
width: 100%;
}
.media-360-viewer>img.canTranslate {
cursor: grab;
}
.media-360-viewer>img.isTranslating {
cursor: grabbing;
}
.media-360-viewer>img.canRotate {
cursor: w-resize;
}
.media-360-viewer__loader {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
}
.media-360-viewer__loader * {
user-select: none;
}
.media-360-viewer__loader>svg {
width: 100%;
height: 100%;
transform: rotate(270deg);
}
.media-360-viewer__loader--text {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.media-360-viewer__loader--text p {
font-size: 100%;
font-weight: bold;
color: #fff;
}
.media-360-viewer__loader--text p.large {
font-size: 150%;
}
.media-360-viewer__loader--background {
stroke-dasharray: 0;
stroke-dashoffset: 0;
stroke: rgba(0, 0, 0, 0.7);
stroke-width: 25px;
}
.media-360-viewer__loader--cover {
stroke-dasharray: 200%;
stroke: #848484;
stroke-width: 15px;
stroke-linecap: round;
}
.media-360-viewer__loader--background,
.media-360-viewer__loader--cover {
fill: transparent;
}
.media-360-viewer__viewport {
position: absolute;
top: 10px;
left: 10px;
z-index: 2;
border: 1px solid black;
overflow: hidden;
}
.media-360-viewer__viewport--image {
width: 100%;
pointer-events: none;
}
.media-360-viewer__viewport--zoom {
position: absolute;
bottom: 5px;
right: 5px;
color: #fff;
z-index: 3;
font-size: 12px;
pointer-events: none;
}
.media-360-viewer__viewport--square {
border: 1px solid black;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
box-shadow: rgba(0, 0, 0, 0.5) 0 0 0 10000px;
cursor: grab;
transition: background ease-in-out 0.1s;
}
.media-360-viewer__viewport--square:hover {
background: rgba(255, 255, 255, 0.2);
}
.media-360-viewer__header {
position: absolute;
top: 10px;
left: 0;
width: 100%;
}
.media-360-viewer__tools {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 10px;
}
.media-360-viewer__tools>a {
margin: 0 5px;
color: #000;
background: #fff;
border-radius: 50%;
width: 40px;
text-align: center;
line-height: 40px;
}
.media-360-viewer__tools>a[disabled] {
opacity: .5;
cursor: not-allowed;
}
.media-360-viewer__tools>a[disabled]:hover {
color: #000;
background: #fff;
}
.media-360-viewer__tools>a:hover {
background: #000;
color: #fff;
}
.media-360-viewer__tools--autoplay:before {
font-family: 'ClickIcons';
content: '\ea81';
}
.media-360-viewer__tools--autoplay.active:before {
content: '\eb48';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<test></test>
</div>
<script type="text/x-template" id="template">
<div class="media-360-viewer" ref="container">
<transition name="fade">
<div class="media-360-viewer__viewport" v-if="zoomLevel > 1 && viewportEnabled" :style="{ width: (viewportScale * 100) + '%' }">
<img tabindex="1" draggable="false" alt="Viewport" class="media-360-viewer__viewport--image" src="https://www.bennetts.co.uk/-/media/bikesocial/2019-september-images/2020-yamaha-yzf-r1-and-r1m-review/2020-yamaha-r1-and-r1m_005.ashx?h=493&w=740&la=en&hash=F97CD240F0DDFA9540E912DCF7F07019017035C6">
<span class="media-360-viewer__viewport--zoom">
x{{ Math.round(zoomLevel * 10) / 10 }}
</span>
<span :style="{ transform: viewportTransform }" #mouseup="handleEnd" #mousedown="handleStart" #mousemove="handleMove($event, true)" #touchstart="handleStart" #touchend="handleEnd" #touchmove="handleMove($event, true)" class="media-360-viewer__viewport--square"></span>
</div>
</transition>
<img tabindex="1" ref="image" draggable="false" src="https://www.bennetts.co.uk/-/media/bikesocial/2019-september-images/2020-yamaha-yzf-r1-and-r1m-review/2020-yamaha-r1-and-r1m_005.ashx?h=493&w=740&la=en&hash=F97CD240F0DDFA9540E912DCF7F07019017035C6" :style="{ transform: transform }" :class="{
canTranslate: zoomLevel > 1 && zoomEnabled,
canRotate: zoomLevel === 1,
isTranslating: zoomLevel > 1 && zoomEnabled && isMoving
}" #mouseup="handleEnd" #mousedown="handleStart" #mousemove="handleMove" #touchstart="handleStart" #touchend="handleEnd" #touchmove="handleMove" #dblclick="zoom" #wheel="zoomWheel" alt="360 Image" />
</div>
</script>
Does anyone know how I can fix this?
Edit
Below is the updated code with the changes suggested by the accepted answer, only issue now is the viewport square going out of frame.
Vue.component('test', {
template: '#template',
data: function() {
return {
loading: true,
loop: true,
speed: 8,
speedController: 0,
zoomEnabled: true,
zoomLevels: [1, 1.5, 2, 2.5, 3],
zoomLevel: 1,
frame: 1,
images: [],
imagesPreloaded: 0,
reverse: false,
viewportScale: 0.3,
viewportEnabled: true,
viewportOpacity: 0.8,
lastX: 0,
lastY: 0,
startX: 0,
startY: 0,
translateX: 0,
translateY: 0,
isMoving: false,
isDragging: false,
};
},
mounted() {
window.addEventListener('mouseup', this.handleEnd);
window.addEventListener('touchend', this.handleEnd);
},
beforeDestroy() {
window.removeEventListener('mouseup', this.handleEnd);
window.removeEventListener('touchend', this.handleEnd);
},
methods: {
zoom(direction) {
// todo: Load high res image based on zoom level
const closest = this.zoomLevels.reduce((a, b) => {
return Math.abs(b - this.zoomLevel) < Math.abs(a - this.zoomLevel) ? b : a;
});
if (this.zoomLevels[this.zoomLevels.indexOf(closest) + direction] === undefined) {
return;
}
let current = this.zoomLevels.indexOf(closest);
let index = current += direction;
if (direction === 0) {
index = 0;
}
this.zoomLevel = this.zoomLevels[index];
this.translate(null, this.$refs.image, true);
},
zoomWheel($event) {
$event.preventDefault();
this.zoomLevel += $event.deltaY * -0.01;
if (this.zoomLevel < 1) {
this.zoomLevel = 1;
}
let maxZoom = this.zoomLevels[this.zoomLevels.length - 1];
this.zoomLevel = Math.min(Math.max(.125, this.zoomLevel), maxZoom);
this.translate(null, this.$refs.image, true);
},
handleStart($event) {
$event.preventDefault();
if ($event.button && $event.button !== 0) {
return;
}
this.isMoving = true;
this.isDragging = true;
this.startX = $event.pageX || $event.touches[0].pageX;
this.startY = $event.pageY || $event.touches[0].pageY;
},
handleMove($event, viewport) {
if ($event.button && $event.button !== 0) {
return;
}
if (this.isMoving && this.isDragging) {
const positions = {
x: $event.pageX || $event.touches[0].pageX,
y: $event.pageY || $event.touches[0].pageY
}
if (this.zoomLevel !== 1) {
this.translate(positions, $event.target, null, viewport);
}
}
},
handleEnd($event) {
if ($event.button && $event.button !== 0) {
return;
}
this.isMoving = false;
},
translate(positions, element, zooming, viewport) {
window.requestAnimationFrame(() => {
positions = positions || {
x: this.startX,
y: this.startY
};
if (viewport) {
this._translateFromViewport(positions, element);
} else {
this._translateFromImage(positions, element, zooming);
}
this.startX = positions.x;
this.startY = positions.y;
});
},
_translateFromViewport: function(positions, element) {
let move = {
x: positions.x - this.startX,
y: positions.y - this.startY
};
let box = element.getBoundingClientRect();
let container = element.parentNode.getBoundingClientRect();
let translate = {
left: (container.left - box.left) - ((move.x * this.viewportScale) * this.zoomLevel),
right: (container.right - box.right) - ((move.x * this.viewportScale) * this.zoomLevel),
top: (container.top - box.top) - ((move.y * this.viewportScale) * this.zoomLevel),
bottom: (container.bottom - box.bottom) - ((move.y * this.viewportScale) * this.zoomLevel)
};
if (translate.left <= 0 && translate.right >= 0) {
this.translateX -= move.x / this.viewportScale;
}
if (translate.top <= 0 && translate.bottom >= 0) {
this.translateY -= move.y / this.viewportScale
}
},
_translateFromImage: function(positions, element, zooming) {
let move = {
x: Math.floor(positions.x - this.startX),
y: Math.floor(positions.y - this.startY)
};
let image = element.getBoundingClientRect();
let container = element.parentNode.getBoundingClientRect();
let translate = {
left: (container.left - image.left) - (move.x * this.zoomLevel),
right: (container.right - image.right) - (move.x * this.zoomLevel),
top: (container.top - image.top) - (move.y * this.zoomLevel),
bottom: (container.bottom - image.bottom) - (move.y * this.zoomLevel)
};
if (zooming) {
if (translate.left <= 0) {
this.translateX += translate.left;
}
if (translate.right >= 0) {
this.translateX += translate.right;
}
if (translate.top <= 0) {
this.translateY += translate.top;
}
if (translate.bottom >= 0) {
this.translateY += translate.bottom;
}
}
if (translate.left >= 0 && translate.right <= 0) {
this.translateX += move.x / this.zoomLevel;
}
if (translate.top >= 0 && translate.bottom <= 0) {
this.translateY += move.y / this.zoomLevel;
}
},
},
computed: {
preloadProgress: function() {
return Math.floor(this.imagesPreloaded / this.images.length * 100);
},
currentPath: function() {
return this.images[this.frame - 1];
},
nextZoomLevel: function() {
const closest = this.zoomLevels.reduce((a, b) => {
return Math.abs(b - this.zoomLevel) < Math.abs(a - this.zoomLevel) ? b : a;
});
if (this.zoomLevels.indexOf(closest) === this.zoomLevels.length - 1) {
return this.zoomLevels[0];
}
return this.zoomLevels[this.zoomLevels.indexOf(closest) + 1];
},
viewportTransform: function() {
if (this.viewportEnabled) {
let translateX = -((this.translateX * this.viewportScale) * this.zoomLevel);
let translateY = -((this.translateY * this.viewportScale) * this.zoomLevel);
return `scale(${1 / this.zoomLevel}) translateX(${translateX}px) translateY(${translateY}px)`;
}
},
transform: function() {
return `scale(${this.zoomLevel}) translateX(${this.translateX}px) translateY(${this.translateY}px)`;
},
canZoomIn: function() {
const closest = this.zoomLevels.reduce((a, b) => {
return Math.abs(b - this.zoomLevel) < Math.abs(a - this.zoomLevel) ? b : a;
});
return this.zoomLevels[this.zoomLevels.indexOf(closest) + 1] === undefined
},
canZoomOut: function() {
const closest = this.zoomLevels.reduce((a, b) => {
return Math.abs(b - this.zoomLevel) < Math.abs(a - this.zoomLevel) ? b : a;
});
return this.zoomLevels[this.zoomLevels.indexOf(closest) + -1] === undefined
}
}
});
window.vue = new Vue({
el: '#app'
});
.media-360-viewer {
position: relative;
overflow: hidden;
background: #000;
width: 500px;
}
.media-360-viewer__image {
width: 100%;
}
.media-360-viewer__image.canTranslate {
cursor: grab;
}
.media-360-viewer__image.isTranslating {
cursor: grabbing;
}
.media-360-viewer__image.canRotate {
cursor: w-resize;
}
.media-360-viewer__loader {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
}
.media-360-viewer__loader * {
user-select: none;
}
.media-360-viewer__loader > svg {
width: 100%;
height: 100%;
transform: rotate(270deg);
}
.media-360-viewer__loader--text {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.media-360-viewer__loader--text p {
font-size: 100%;
font-weight: bold;
color: #fff;
}
.media-360-viewer__loader--text p.large {
font-size: 150%;
}
.media-360-viewer__loader--background {
stroke-dasharray: 0;
stroke-dashoffset: 0;
stroke: rgba(0, 0, 0, 0.7);
stroke-width: 25px;
}
.media-360-viewer__loader--cover {
stroke-dasharray: 200%;
stroke: #848484;
stroke-width: 15px;
stroke-linecap: round;
}
.media-360-viewer__loader--background,
.media-360-viewer__loader--cover {
fill: transparent;
}
.media-360-viewer__viewport {
position: absolute;
top: 10px;
left: 10px;
z-index: 2;
overflow: hidden;
}
.media-360-viewer__viewport--image {
width: 100%;
pointer-events: none;
}
.media-360-viewer__viewport--zoom {
position: absolute;
bottom: 5px;
right: 5px;
color: #fff;
z-index: 3;
font-size: 12px;
pointer-events: none;
}
.media-360-viewer__viewport--square {
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
box-shadow: rgba(0, 0, 0, 0.8) 0 0 0 10000px;
cursor: grab;
transition: background ease-in-out 0.1s;
}
.media-360-viewer__viewport--square:hover {
background: rgba(255, 255, 255, 0.2);
}
.media-360-viewer__tools {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 10px;
}
.media-360-viewer__tools > a {
margin: 0 5px;
color: #000;
background: #fff;
border-radius: 50%;
width: 40px;
text-align: center;
line-height: 40px;
}
.media-360-viewer__tools > a[disabled] {
opacity: .5;
cursor: not-allowed;
}
.media-360-viewer__tools > a[disabled]:hover {
color: #000;
background: #fff;
}
.media-360-viewer__tools > a:hover {
background: #000;
color: #fff;
}
.media-360-viewer__tools--autoplay:before {
font-family: 'ClickIcons';
content: '\ea81';
}
.media-360-viewer__tools--autoplay.active:before {
content: '\eb48';
}
.fade-enter-active,
.fade-leave-active {
transition: opacity .5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<test></test>
</div>
<script type="text/x-template" id="template">
<div class="media-360-viewer" ref="container">
<transition name="fade">
<div class="media-360-viewer__viewport" v-if="zoomLevel > 1 && viewportEnabled" :style="{ width: (viewportScale * 100) + '%' }">
<img tabindex="1" draggable="false" alt="Viewport" class="media-360-viewer__viewport--image" src="https://www.bennetts.co.uk/-/media/bikesocial/2019-september-images/2020-yamaha-yzf-r1-and-r1m-review/2020-yamaha-r1-and-r1m_005.ashx?h=493&w=740&la=en&hash=F97CD240F0DDFA9540E912DCF7F07019017035C6">
<span class="media-360-viewer__viewport--zoom">
x{{ Math.round(zoomLevel * 10) / 10 }}
</span>
<span :style="{ transform: viewportTransform }" #mouseup="handleEnd" #mousedown="handleStart" #mousemove="handleMove($event, true)" #touchstart="handleStart" #touchend="handleEnd" #touchmove="handleMove($event, true)" class="media-360-viewer__viewport--square"></span>
</div>
</transition>
<img tabindex="1" ref="image" draggable="false" src="https://www.bennetts.co.uk/-/media/bikesocial/2019-september-images/2020-yamaha-yzf-r1-and-r1m-review/2020-yamaha-r1-and-r1m_005.ashx?h=493&w=740&la=en&hash=F97CD240F0DDFA9540E912DCF7F07019017035C6"
:style="{ transform: transform }" :class="{
canTranslate: zoomLevel > 1 && zoomEnabled,
canRotate: zoomLevel === 1,
isTranslating: zoomLevel > 1 && zoomEnabled && isMoving
}" #mouseup="handleEnd" #mousedown="handleStart" #mousemove="handleMove" #touchstart="handleStart" #touchend="handleEnd" #touchmove="handleMove" #dblclick="zoom" #wheel="zoomWheel" alt="360 Image" />
</div>
</script>
Math.floor only when necessary
A part of this problem is a result of calling Math.floor all the time. Each time you call Math.floor your next calculations will be less accurate.
If you still want to round numbers, do it only at the end of your calculations chain or even in the place where you are using the variable. For example:
transform: function() {
const translateX = Math.floor(this.translateX)
const translateY = Math.floor(this.translateY)
return `scale(${this.zoomLevel}) translateX(${translateX}px) translateY(${translateY}px)`;
}
Scaling factor
However when moving the image around it is moving faster than the mouse
This can be fixed by dividing number you're adding to the translate value by scale factor, which is determined by zoomLevel like so:
if (translate.left >= 0 && translate.right <= 0) {
this.translateX += move.x / this.zoomLevel
}
if (translate.top >= 0 && translate.bottom <= 0) {
this.translateY += move.y / this.zoomLevel
}
Scaling factor - viewport
Viewport is still somehow broken too because of scaling, we need to adjust translation value too, but this time not using zoomLevel but scale of the viewport which is stored in this.viewportScale. So, merging two of solutions together we now have code like this:
if (translate.left >= 0 && translate.right <= 0) {
if (viewport) {
this.translateX += move.x / this.viewportScale
} else {
this.translateX += move.x / this.zoomLevel
}
}
if (translate.top >= 0 && translate.bottom <= 0) {
if (viewport) {
this.translateY += move.y / this.viewportScale
} else {
this.translateY += move.y / this.zoomLevel
}
}
Reversing values
I also feel like when i'm clicking and dragging on the viewport I shouldn't be reversing the values twice
I don't think that there is a better way to do it unless you want to make two inner translate functions that will handle translation depending on the input source (viewport or image). It will be definetely cleaner approach to coding. For example if in future you would like to write some viewport specific code you will not need to include another and another if. Your function could like like so:
translate (positions, element, zooming, viewport) {
positions = positions || {
x: this.startX,
y: this.startY
}
if (viewport) {
this._translateFromViewport(positions, element, zooming)
} else {
this._translateFromImage(positions, element, zooming)
}
this.startX = positions.x
this.startY = positions.y
}
where _translateFromViewport and _translateFromImage functions hold feature specific code.

Starter Question, overlay Div with Text over an Animation

I would like to overlay a div over another div.
But there are some problems because i am newbie.
// particle.min.js hosted on GitHub
// Scroll down for initialisation code
!function(a){var b="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global;"function"==typeof define&&define.amd?define(["exports"],function(c){b.ParticleNetwork=a(b,c)}):"object"==typeof module&&module.exports?module.exports=a(b,{}):b.ParticleNetwork=a(b,{})}(function(a,b){var c=function(a){this.canvas=a.canvas,this.g=a.g,this.particleColor=a.options.particleColor,this.x=Math.random()*this.canvas.width,this.y=Math.random()*this.canvas.height,this.velocity={x:(Math.random()-.5)*a.options.velocity,y:(Math.random()-.5)*a.options.velocity}};return c.prototype.update=function(){(this.x>this.canvas.width+20||this.x<-20)&&(this.velocity.x=-this.velocity.x),(this.y>this.canvas.height+20||this.y<-20)&&(this.velocity.y=-this.velocity.y),this.x+=this.velocity.x,this.y+=this.velocity.y},c.prototype.h=function(){this.g.beginPath(),this.g.fillStyle=this.particleColor,this.g.globalAlpha=.7,this.g.arc(this.x,this.y,1.5,0,2*Math.PI),this.g.fill()},b=function(a,b){this.i=a,this.i.size={width:this.i.offsetWidth,height:this.i.offsetHeight},b=void 0!==b?b:{},this.options={particleColor:void 0!==b.particleColor?b.particleColor:"#fff",background:void 0!==b.background?b.background:"#1a252f",interactive:void 0!==b.interactive?b.interactive:!0,velocity:this.setVelocity(b.speed),density:this.j(b.density)},this.init()},b.prototype.init=function(){if(this.k=document.createElement("div"),this.i.appendChild(this.k),this.l(this.k,{position:"absolute",top:0,left:0,bottom:0,right:0,"z-index":1}),/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.background))this.l(this.k,{background:this.options.background});else{if(!/\.(gif|jpg|jpeg|tiff|png)$/i.test(this.options.background))return console.error("Please specify a valid background image or hexadecimal color"),!1;this.l(this.k,{background:'url("'+this.options.background+'") no-repeat center',"background-size":"cover"})}if(!/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.particleColor))return console.error("Please specify a valid particleColor hexadecimal color"),!1;this.canvas=document.createElement("canvas"),this.i.appendChild(this.canvas),this.g=this.canvas.getContext("2d"),this.canvas.width=this.i.size.width,this.canvas.height=this.i.size.height,this.l(this.i,{position:"relative"}),this.l(this.canvas,{"z-index":"20",position:"relative"}),window.addEventListener("resize",function(){return this.i.offsetWidth===this.i.size.width&&this.i.offsetHeight===this.i.size.height?!1:(this.canvas.width=this.i.size.width=this.i.offsetWidth,this.canvas.height=this.i.size.height=this.i.offsetHeight,clearTimeout(this.m),void(this.m=setTimeout(function(){this.o=[];for(var a=0;a<this.canvas.width*this.canvas.height/this.options.density;a++)this.o.push(new c(this));this.options.interactive&&this.o.push(this.p),requestAnimationFrame(this.update.bind(this))}.bind(this),500)))}.bind(this)),this.o=[];for(var a=0;a<this.canvas.width*this.canvas.height/this.options.density;a++)this.o.push(new c(this));this.options.interactive&&(this.p=new c(this),this.p.velocity={x:0,y:0},this.o.push(this.p),this.canvas.addEventListener("mousemove",function(a){this.p.x=a.clientX-this.canvas.offsetLeft,this.p.y=a.clientY-this.canvas.offsetTop}.bind(this)),this.canvas.addEventListener("mouseup",function(a){this.p.velocity={x:(Math.random()-.5)*this.options.velocity,y:(Math.random()-.5)*this.options.velocity},this.p=new c(this),this.p.velocity={x:0,y:0},this.o.push(this.p)}.bind(this))),requestAnimationFrame(this.update.bind(this))},b.prototype.update=function(){this.g.clearRect(0,0,this.canvas.width,this.canvas.height),this.g.globalAlpha=1;for(var a=0;a<this.o.length;a++){this.o[a].update(),this.o[a].h();for(var b=this.o.length-1;b>a;b--){var c=Math.sqrt(Math.pow(this.o[a].x-this.o[b].x,2)+Math.pow(this.o[a].y-this.o[b].y,2));c>120||(this.g.beginPath(),this.g.strokeStyle=this.options.particleColor,this.g.globalAlpha=(120-c)/120,this.g.lineWidth=.7,this.g.moveTo(this.o[a].x,this.o[a].y),this.g.lineTo(this.o[b].x,this.o[b].y),this.g.stroke())}}0!==this.options.velocity&&requestAnimationFrame(this.update.bind(this))},b.prototype.setVelocity=function(a){return"fast"===a?1:"slow"===a?.33:"none"===a?0:.66},b.prototype.j=function(a){return"high"===a?5e3:"low"===a?2e4:isNaN(parseInt(a,10))?1e4:a},b.prototype.l=function(a,b){for(var c in b)a.style[c]=b[c]},b});
// Initialisation
var canvasDiv = document.getElementById('particle-canvas');
var options = {
particleColor: '#888',
background: 'https://raw.githubusercontent.com/JulianLaval/canvas-particle-network/master/img/demo-bg.jpg',
interactive: true,
speed: 'medium',
density: 'high'
};
var particleCanvas = new ParticleNetwork(canvasDiv, options);
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#particle-canvas {
width: 100%;
height: 100%;
}
h1 {
text-align: center;
position: inherit;
float: none;
}
#container {
width: 100px;
height: 100px;
}
#back,
.overstyle {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 50%;
}
.overstyle h1{
font-family: 'Open Sans Condensed', sans-serif;
font-size: 230%;
font-family: 'Indie Flower', cursive;
}
.overstyle {
text-align: center;
color: white;
z-index: 100;
}
<body>
<div id="container" style="width: 100%; height: 100%;">
<div id="particle-canvas" id="back"></div>
<script src='https://rawgit.com/JulianLaval/canvas-particle-network/master/particle-network.min.js'></script>
<script src="js/index.js"></script>
<!--- Content Div --->
<div style="width: 100%; color: rgba(255, 255, 255, 0.55);" class="overstyle">
<h1>TestFont</h1>
</div>
<!--- End of Content Div --->
</div>
</body>
The code is a div with id="particle-canavas". For more information about that visit this page here.
This is my Css stylesheet.
So now how could I improve the overlay div with class "overstyle"?
Thanks for all help.
This centers as you need.
When I need to center something, I always try:
width:100%;
margin-left:auto;
margin-right:auto;
// particle.min.js hosted on GitHub
// Scroll down for initialisation code
! function(a) {
var b = "object" == typeof self && self.self === self && self || "object" == typeof global && global.global === global && global;
"function" == typeof define && define.amd ? define(["exports"], function(c) {
b.ParticleNetwork = a(b, c)
}) : "object" == typeof module && module.exports ? module.exports = a(b, {}) : b.ParticleNetwork = a(b, {})
}(function(a, b) {
var c = function(a) {
this.canvas = a.canvas, this.g = a.g, this.particleColor = a.options.particleColor, this.x = Math.random() * this.canvas.width, this.y = Math.random() * this.canvas.height, this.velocity = {
x: (Math.random() - .5) * a.options.velocity,
y: (Math.random() - .5) * a.options.velocity
}
};
return c.prototype.update = function() {
(this.x > this.canvas.width + 20 || this.x < -20) && (this.velocity.x = -this.velocity.x), (this.y > this.canvas.height + 20 || this.y < -20) && (this.velocity.y = -this.velocity.y), this.x += this.velocity.x, this.y += this.velocity.y
}, c.prototype.h = function() {
this.g.beginPath(), this.g.fillStyle = this.particleColor, this.g.globalAlpha = .7, this.g.arc(this.x, this.y, 1.5, 0, 2 * Math.PI), this.g.fill()
}, b = function(a, b) {
this.i = a, this.i.size = {
width: this.i.offsetWidth,
height: this.i.offsetHeight
}, b = void 0 !== b ? b : {}, this.options = {
particleColor: void 0 !== b.particleColor ? b.particleColor : "#fff",
background: void 0 !== b.background ? b.background : "#1a252f",
interactive: void 0 !== b.interactive ? b.interactive : !0,
velocity: this.setVelocity(b.speed),
density: this.j(b.density)
}, this.init()
}, b.prototype.init = function() {
if (this.k = document.createElement("div"), this.i.appendChild(this.k), this.l(this.k, {
position: "absolute",
top: 0,
left: 0,
bottom: 0,
right: 0,
"z-index": 1
}), /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.background)) this.l(this.k, {
background: this.options.background
});
else {
if (!/\.(gif|jpg|jpeg|tiff|png)$/i.test(this.options.background)) return console.error("Please specify a valid background image or hexadecimal color"), !1;
this.l(this.k, {
background: 'url("' + this.options.background + '") no-repeat center',
"background-size": "cover"
})
}
if (!/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(this.options.particleColor)) return console.error("Please specify a valid particleColor hexadecimal color"), !1;
this.canvas = document.createElement("canvas"), this.i.appendChild(this.canvas), this.g = this.canvas.getContext("2d"), this.canvas.width = this.i.size.width, this.canvas.height = this.i.size.height, this.l(this.i, {
position: "relative"
}), this.l(this.canvas, {
"z-index": "20",
position: "relative"
}), window.addEventListener("resize", function() {
return this.i.offsetWidth === this.i.size.width && this.i.offsetHeight === this.i.size.height ? !1 : (this.canvas.width = this.i.size.width = this.i.offsetWidth, this.canvas.height = this.i.size.height = this.i.offsetHeight, clearTimeout(this.m), void(this.m = setTimeout(function() {
this.o = [];
for (var a = 0; a < this.canvas.width * this.canvas.height / this.options.density; a++) this.o.push(new c(this));
this.options.interactive && this.o.push(this.p), requestAnimationFrame(this.update.bind(this))
}.bind(this), 500)))
}.bind(this)), this.o = [];
for (var a = 0; a < this.canvas.width * this.canvas.height / this.options.density; a++) this.o.push(new c(this));
this.options.interactive && (this.p = new c(this), this.p.velocity = {
x: 0,
y: 0
}, this.o.push(this.p), this.canvas.addEventListener("mousemove", function(a) {
this.p.x = a.clientX - this.canvas.offsetLeft, this.p.y = a.clientY - this.canvas.offsetTop
}.bind(this)), this.canvas.addEventListener("mouseup", function(a) {
this.p.velocity = {
x: (Math.random() - .5) * this.options.velocity,
y: (Math.random() - .5) * this.options.velocity
}, this.p = new c(this), this.p.velocity = {
x: 0,
y: 0
}, this.o.push(this.p)
}.bind(this))), requestAnimationFrame(this.update.bind(this))
}, b.prototype.update = function() {
this.g.clearRect(0, 0, this.canvas.width, this.canvas.height), this.g.globalAlpha = 1;
for (var a = 0; a < this.o.length; a++) {
this.o[a].update(), this.o[a].h();
for (var b = this.o.length - 1; b > a; b--) {
var c = Math.sqrt(Math.pow(this.o[a].x - this.o[b].x, 2) + Math.pow(this.o[a].y - this.o[b].y, 2));
c > 120 || (this.g.beginPath(), this.g.strokeStyle = this.options.particleColor, this.g.globalAlpha = (120 - c) / 120, this.g.lineWidth = .7, this.g.moveTo(this.o[a].x, this.o[a].y), this.g.lineTo(this.o[b].x, this.o[b].y), this.g.stroke())
}
}
0 !== this.options.velocity && requestAnimationFrame(this.update.bind(this))
}, b.prototype.setVelocity = function(a) {
return "fast" === a ? 1 : "slow" === a ? .33 : "none" === a ? 0 : .66
}, b.prototype.j = function(a) {
return "high" === a ? 5e3 : "low" === a ? 2e4 : isNaN(parseInt(a, 10)) ? 1e4 : a
}, b.prototype.l = function(a, b) {
for (var c in b) a.style[c] = b[c]
}, b
});
// Initialisation
var canvasDiv = document.getElementById('particle-canvas');
var options = {
particleColor: '#888',
background: 'https://raw.githubusercontent.com/JulianLaval/canvas-particle-network/master/img/demo-bg.jpg',
interactive: true,
speed: 'medium',
density: 'high'
};
var particleCanvas = new ParticleNetwork(canvasDiv, options);
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#particle-canvas {
width: 100%;
height: 100%;
}
h1 {
text-align: center;
position: inherit;
float: none;
}
#container {
width: 100px;
height: 100px;
}
#back,
.overstyle {
width: 100%;
height: 100%;
position: absolute;
top: 0;
}
.overstyle h1{
font-family: 'Open Sans Condensed', sans-serif;
font-size: 230%;
font-family: 'Indie Flower', cursive;
width: 100%;
margin-left: auto;
margin-right: auto;
}
.overstyle {
text-align: center;
color: white;
z-index: 100;
}
<body>
<div id="container" style="width: 100%; height: 100%;">
<div id="particle-canvas" id="back"></div>
<script src='https://rawgit.com/JulianLaval/canvas-particle-network/master/particle-network.min.js'></script>
<script src="js/index.js"></script>
<!--- Content Div --->
<div style="width: 100%; color: rgba(255, 255, 255, 0.55);" class="overstyle">
<h1>TestFont</h1>
</div>
<!--- End of Content Div --->
</div>
</body>
I have tried it on the example you provided -
This worked for me:
.overstyle h1 {
z-index:2;
color: #fff;
position: absolute;
top: 20px;
left: 20px;
}

Values from the slider [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
How to take values ​​and use them to hide or display div s
I use this (jQuery Simple Slider) slider
Try this but work so bad.
Need when slider value is "3" div id 3 = visible, other hidden. when slider value is "5" div id 5 = visible, other hidden etc
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" data-slider="true" data-slider-values="3, 5, 10, 15, 20, 25, 30" data-slider-equal-steps="true" data-slider-snap="true">
<div>
<script>
$("[data-slider]")
.each(function () {
var input = $(this);
$("<span>")
.addClass("output")
.insertAfter($(this));
})
.bind("slider:ready slider:changed", function (event, data) {
$(this)
.nextAll(".output:first")
.html(data.value);
if (document.getElementById(data.value).style.display == "none")
{document.getElementById(data.value).style.display = "block"}
else
{document.getElementById(data.value).style.display = "none"}
});
</script>
</div>
<div id="3">3</div>
<div id="5">5</div>
<div id="10">10</div>
<div id="15">15</div>
<div id="20">20</div>
<div id="25">25</div>
<div id="30">30</div>
It is extremely unclear what you want to achieve but I have tried based on my understanding.
Firstly there no div with ids on page whose style you want to edit. So I have added it.
Take a look at the snippet below that I have created based on code you provided above. See if this is what you needed
<input type="text" data-slider="true" data-slider-values="3, 5, 10, 15, 20, 25, 30" data-slider-equal-steps="true" data-slider-snap="true">
<div>
<script>
$("[data-slider]")
.each(function () {
var input = $(this);
$("<span>")
.addClass("output")
.insertAfter($(this));
})
.bind("slider:ready slider:changed", function (event, data) {
$(this)
.nextAll(".output:first")
.html(data.value);
if (document.getElementById(data.value).style.display == "none")
{document.getElementById(data.value).style.display = "block"}
else
{document.getElementById(data.value).style.display = "none"}
});
</script>
</div>
$("[data-slider]")
.each(function () {
var input = $(this);
$("<span>")
.addClass("output")
.insertAfter($(this));
}).bind("slider:ready",function(event,data) {
$('.number').css('display','none');
$('#' + data.value).css('display','block');
}).bind(" slider:changed", function(event,data) {
$('.number').css('display','none');
$('#' + data.value).css('display','block');
});
.slider {
width: 300px;
}
.slider > .dragger {
background: #8DCA09;
background: -webkit-linear-gradient(top, #8DCA09, #72A307);
background: -moz-linear-gradient(top, #8DCA09, #72A307);
background: linear-gradient(top, #8DCA09, #72A307);
-webkit-box-shadow: inset 0 2px 2px rgba(255,255,255,0.5), 0 2px 8px rgba(0,0,0,0.2);
-moz-box-shadow: inset 0 2px 2px rgba(255,255,255,0.5), 0 2px 8px rgba(0,0,0,0.2);
box-shadow: inset 0 2px 2px rgba(255,255,255,0.5), 0 2px 8px rgba(0,0,0,0.2);
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
border: 1px solid #496805;
width: 16px;
height: 16px;
}
.slider > .dragger:hover {
background: -webkit-linear-gradient(top, #8DCA09, #8DCA09);
}
.slider > .track, .slider > .highlight-track {
background: #ccc;
background: -webkit-linear-gradient(top, #bbb, #ddd);
background: -moz-linear-gradient(top, #bbb, #ddd);
background: linear-gradient(top, #bbb, #ddd);
-webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
-moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
border: 1px solid #aaa;
height: 4px;
}
.slider > .highlight-track {
background-color: #8DCA09;
background: -webkit-linear-gradient(top, #8DCA09, #72A307);
background: -moz-linear-gradient(top, #8DCA09, #72A307);
background: linear-gradient(top, #8DCA09, #72A307);
border-color: #496805;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script> /*
jQuery Simple Slider
Copyright (c) 2012 James Smith (http://loopj.com)
Licensed under the MIT license (http://mit-license.org/)
*/
var __slice = [].slice,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
(function($, window) {
var SimpleSlider;
SimpleSlider = (function() {
function SimpleSlider(input, options) {
var ratio,
_this = this;
this.input = input;
this.defaultOptions = {
animate: true,
snapMid: false,
classPrefix: null,
classSuffix: null,
theme: null,
highlight: false
};
this.settings = $.extend({}, this.defaultOptions, options);
if (this.settings.theme) {
this.settings.classSuffix = "-" + this.settings.theme;
}
this.input.hide();
this.slider = $("<div>").addClass("slider" + (this.settings.classSuffix || "")).css({
position: "relative",
userSelect: "none",
boxSizing: "border-box"
}).insertBefore(this.input);
if (this.input.attr("id")) {
this.slider.attr("id", this.input.attr("id") + "-slider");
}
this.track = this.createDivElement("track").css({
width: "100%"
});
if (this.settings.highlight) {
this.highlightTrack = this.createDivElement("highlight-track").css({
width: "0"
});
}
this.dragger = this.createDivElement("dragger");
this.slider.css({
minHeight: this.dragger.outerHeight(),
marginLeft: this.dragger.outerWidth() / 2,
marginRight: this.dragger.outerWidth() / 2
});
this.track.css({
marginTop: this.track.outerHeight() / -2
});
if (this.settings.highlight) {
this.highlightTrack.css({
marginTop: this.track.outerHeight() / -2
});
}
this.dragger.css({
marginTop: this.dragger.outerHeight() / -2,
marginLeft: this.dragger.outerWidth() / -2
});
this.track.mousedown(function(e) {
return _this.trackEvent(e);
});
if (this.settings.highlight) {
this.highlightTrack.mousedown(function(e) {
return _this.trackEvent(e);
});
}
this.dragger.mousedown(function(e) {
if (e.which !== 1) {
return;
}
_this.dragging = true;
_this.dragger.addClass("dragging");
_this.domDrag(e.pageX, e.pageY);
return false;
});
$("body").mousemove(function(e) {
if (_this.dragging) {
_this.domDrag(e.pageX, e.pageY);
return $("body").css({
cursor: "pointer"
});
}
}).mouseup(function(e) {
if (_this.dragging) {
_this.dragging = false;
_this.dragger.removeClass("dragging");
return $("body").css({
cursor: "auto"
});
}
});
this.pagePos = 0;
if (this.input.val() === "") {
this.value = this.getRange().min;
this.input.val(this.value);
} else {
this.value = this.nearestValidValue(this.input.val());
}
this.setSliderPositionFromValue(this.value);
ratio = this.valueToRatio(this.value);
this.input.trigger("slider:ready", {
value: this.value,
ratio: ratio,
position: ratio * this.slider.outerWidth(),
el: this.slider
});
}
SimpleSlider.prototype.createDivElement = function(classname) {
var item;
item = $("<div>").addClass(classname).css({
position: "absolute",
top: "50%",
userSelect: "none",
cursor: "pointer"
}).appendTo(this.slider);
return item;
};
SimpleSlider.prototype.setRatio = function(ratio) {
var value;
ratio = Math.min(1, ratio);
ratio = Math.max(0, ratio);
value = this.ratioToValue(ratio);
this.setSliderPositionFromValue(value);
return this.valueChanged(value, ratio, "setRatio");
};
SimpleSlider.prototype.setValue = function(value) {
var ratio;
value = this.nearestValidValue(value);
ratio = this.valueToRatio(value);
this.setSliderPositionFromValue(value);
return this.valueChanged(value, ratio, "setValue");
};
SimpleSlider.prototype.trackEvent = function(e) {
if (e.which !== 1) {
return;
}
this.domDrag(e.pageX, e.pageY, true);
this.dragging = true;
return false;
};
SimpleSlider.prototype.domDrag = function(pageX, pageY, animate) {
var pagePos, ratio, value;
if (animate == null) {
animate = false;
}
pagePos = pageX - this.slider.offset().left;
pagePos = Math.min(this.slider.outerWidth(), pagePos);
pagePos = Math.max(0, pagePos);
if (this.pagePos !== pagePos) {
this.pagePos = pagePos;
ratio = pagePos / this.slider.outerWidth();
value = this.ratioToValue(ratio);
this.valueChanged(value, ratio, "domDrag");
if (this.settings.snap) {
return this.setSliderPositionFromValue(value, animate);
} else {
return this.setSliderPosition(pagePos, animate);
}
}
};
SimpleSlider.prototype.setSliderPosition = function(position, animate) {
if (animate == null) {
animate = false;
}
if (animate && this.settings.animate) {
this.dragger.animate({
left: position
}, 200);
if (this.settings.highlight) {
return this.highlightTrack.animate({
width: position
}, 200);
}
} else {
this.dragger.css({
left: position
});
if (this.settings.highlight) {
return this.highlightTrack.css({
width: position
});
}
}
};
SimpleSlider.prototype.setSliderPositionFromValue = function(value, animate) {
var ratio;
if (animate == null) {
animate = false;
}
ratio = this.valueToRatio(value);
return this.setSliderPosition(ratio * this.slider.outerWidth(), animate);
};
SimpleSlider.prototype.getRange = function() {
if (this.settings.allowedValues) {
return {
min: Math.min.apply(Math, this.settings.allowedValues),
max: Math.max.apply(Math, this.settings.allowedValues)
};
} else if (this.settings.range) {
return {
min: parseFloat(this.settings.range[0]),
max: parseFloat(this.settings.range[1])
};
} else {
return {
min: 0,
max: 1
};
}
};
SimpleSlider.prototype.nearestValidValue = function(rawValue) {
var closest, maxSteps, range, steps;
range = this.getRange();
rawValue = Math.min(range.max, rawValue);
rawValue = Math.max(range.min, rawValue);
if (this.settings.allowedValues) {
closest = null;
$.each(this.settings.allowedValues, function() {
if (closest === null || Math.abs(this - rawValue) < Math.abs(closest - rawValue)) {
return closest = this;
}
});
return closest;
} else if (this.settings.step) {
maxSteps = (range.max - range.min) / this.settings.step;
steps = Math.floor((rawValue - range.min) / this.settings.step);
if ((rawValue - range.min) % this.settings.step > this.settings.step / 2 && steps < maxSteps) {
steps += 1;
}
return steps * this.settings.step + range.min;
} else {
return rawValue;
}
};
SimpleSlider.prototype.valueToRatio = function(value) {
var allowedVal, closest, closestIdx, idx, range, _i, _len, _ref;
if (this.settings.equalSteps) {
_ref = this.settings.allowedValues;
for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
allowedVal = _ref[idx];
if (!(typeof closest !== "undefined" && closest !== null) || Math.abs(allowedVal - value) < Math.abs(closest - value)) {
closest = allowedVal;
closestIdx = idx;
}
}
if (this.settings.snapMid) {
return (closestIdx + 0.5) / this.settings.allowedValues.length;
} else {
return closestIdx / (this.settings.allowedValues.length - 1);
}
} else {
range = this.getRange();
return (value - range.min) / (range.max - range.min);
}
};
SimpleSlider.prototype.ratioToValue = function(ratio) {
var idx, range, rawValue, step, steps;
if (this.settings.equalSteps) {
steps = this.settings.allowedValues.length;
step = Math.round(ratio * steps - 0.5);
idx = Math.min(step, this.settings.allowedValues.length - 1);
return this.settings.allowedValues[idx];
} else {
range = this.getRange();
rawValue = ratio * (range.max - range.min) + range.min;
return this.nearestValidValue(rawValue);
}
};
SimpleSlider.prototype.valueChanged = function(value, ratio, trigger) {
var eventData;
if (value.toString() === this.value.toString()) {
return;
}
this.value = value;
eventData = {
value: value,
ratio: ratio,
position: ratio * this.slider.outerWidth(),
trigger: trigger,
el: this.slider
};
return this.input.val(value).trigger($.Event("change", eventData)).trigger("slider:changed", eventData);
};
return SimpleSlider;
})();
$.extend($.fn, {
simpleSlider: function() {
var params, publicMethods, settingsOrMethod;
settingsOrMethod = arguments[0], params = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
publicMethods = ["setRatio", "setValue"];
return $(this).each(function() {
var obj, settings;
if (settingsOrMethod && __indexOf.call(publicMethods, settingsOrMethod) >= 0) {
obj = $(this).data("slider-object");
return obj[settingsOrMethod].apply(obj, params);
} else {
settings = settingsOrMethod;
return $(this).data("slider-object", new SimpleSlider($(this), settings));
}
});
}
});
return $(function() {
return $("[data-slider]").each(function() {
var $el, allowedValues, settings, x;
$el = $(this);
settings = {};
allowedValues = $el.data("slider-values");
if (allowedValues) {
settings.allowedValues = (function() {
var _i, _len, _ref, _results;
_ref = allowedValues.split(",");
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
x = _ref[_i];
_results.push(parseFloat(x));
}
return _results;
})();
}
if ($el.data("slider-range")) {
settings.range = $el.data("slider-range").split(",");
}
if ($el.data("slider-step")) {
settings.step = $el.data("slider-step");
}
settings.snap = $el.data("slider-snap");
settings.equalSteps = $el.data("slider-equal-steps");
if ($el.data("slider-theme")) {
settings.theme = $el.data("slider-theme");
}
if ($el.attr("data-slider-highlight")) {
settings.highlight = $el.data("slider-highlight");
}
if ($el.data("slider-animate") != null) {
settings.animate = $el.data("slider-animate");
}
return $el.simpleSlider(settings);
});
});
})(this.jQuery || this.Zepto, this);</script>
<input type="text" data-slider="true" data-slider-values="3, 5, 10, 15, 20, 25, 30" data-slider-equal-steps="true" data-slider-snap="true">
<div id="3" class="number">3</div>
<div id="5" class="number">5</div>
<div id="10" class="number">10</div>
<div id="15" class="number">15</div>
<div id="20" class="number">20</div>
<div id="25" class="number">25</div>
<div id="30" class="number">30</div>
This right answer, thank all for help)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script> /*
jQuery Simple Slider
Copyright (c) 2012 James Smith (http://loopj.com)
Licensed under the MIT license (http://mit-license.org/)
*/
var __slice = [].slice,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
(function($, window) {
var SimpleSlider;
SimpleSlider = (function() {
function SimpleSlider(input, options) {
var ratio,
_this = this;
this.input = input;
this.defaultOptions = {
animate: true,
snapMid: false,
classPrefix: null,
classSuffix: null,
theme: null,
highlight: false
};
this.settings = $.extend({}, this.defaultOptions, options);
if (this.settings.theme) {
this.settings.classSuffix = "-" + this.settings.theme;
}
this.input.hide();
this.slider = $("<div>").addClass("slider" + (this.settings.classSuffix || "")).css({
position: "relative",
userSelect: "none",
boxSizing: "border-box"
}).insertBefore(this.input);
if (this.input.attr("id")) {
this.slider.attr("id", this.input.attr("id") + "-slider");
}
this.track = this.createDivElement("track").css({
width: "100%"
});
if (this.settings.highlight) {
this.highlightTrack = this.createDivElement("highlight-track").css({
width: "0"
});
}
this.dragger = this.createDivElement("dragger");
this.slider.css({
minHeight: this.dragger.outerHeight(),
marginLeft: this.dragger.outerWidth() / 2,
marginRight: this.dragger.outerWidth() / 2
});
this.track.css({
marginTop: this.track.outerHeight() / -2
});
if (this.settings.highlight) {
this.highlightTrack.css({
marginTop: this.track.outerHeight() / -2
});
}
this.dragger.css({
marginTop: this.dragger.outerHeight() / -2,
marginLeft: this.dragger.outerWidth() / -2
});
this.track.mousedown(function(e) {
return _this.trackEvent(e);
});
if (this.settings.highlight) {
this.highlightTrack.mousedown(function(e) {
return _this.trackEvent(e);
});
}
this.dragger.mousedown(function(e) {
if (e.which !== 1) {
return;
}
_this.dragging = true;
_this.dragger.addClass("dragging");
_this.domDrag(e.pageX, e.pageY);
return false;
});
$("body").mousemove(function(e) {
if (_this.dragging) {
_this.domDrag(e.pageX, e.pageY);
return $("body").css({
cursor: "pointer"
});
}
}).mouseup(function(e) {
if (_this.dragging) {
_this.dragging = false;
_this.dragger.removeClass("dragging");
return $("body").css({
cursor: "auto"
});
}
});
this.pagePos = 0;
if (this.input.val() === "") {
this.value = this.getRange().min;
this.input.val(this.value);
} else {
this.value = this.nearestValidValue(this.input.val());
}
this.setSliderPositionFromValue(this.value);
ratio = this.valueToRatio(this.value);
this.input.trigger("slider:ready", {
value: this.value,
ratio: ratio,
position: ratio * this.slider.outerWidth(),
el: this.slider
});
}
SimpleSlider.prototype.createDivElement = function(classname) {
var item;
item = $("<div>").addClass(classname).css({
position: "absolute",
top: "50%",
userSelect: "none",
cursor: "pointer"
}).appendTo(this.slider);
return item;
};
SimpleSlider.prototype.setRatio = function(ratio) {
var value;
ratio = Math.min(1, ratio);
ratio = Math.max(0, ratio);
value = this.ratioToValue(ratio);
this.setSliderPositionFromValue(value);
return this.valueChanged(value, ratio, "setRatio");
};
SimpleSlider.prototype.setValue = function(value) {
var ratio;
value = this.nearestValidValue(value);
ratio = this.valueToRatio(value);
this.setSliderPositionFromValue(value);
return this.valueChanged(value, ratio, "setValue");
};
SimpleSlider.prototype.trackEvent = function(e) {
if (e.which !== 1) {
return;
}
this.domDrag(e.pageX, e.pageY, true);
this.dragging = true;
return false;
};
SimpleSlider.prototype.domDrag = function(pageX, pageY, animate) {
var pagePos, ratio, value;
if (animate == null) {
animate = false;
}
pagePos = pageX - this.slider.offset().left;
pagePos = Math.min(this.slider.outerWidth(), pagePos);
pagePos = Math.max(0, pagePos);
if (this.pagePos !== pagePos) {
this.pagePos = pagePos;
ratio = pagePos / this.slider.outerWidth();
value = this.ratioToValue(ratio);
this.valueChanged(value, ratio, "domDrag");
if (this.settings.snap) {
return this.setSliderPositionFromValue(value, animate);
} else {
return this.setSliderPosition(pagePos, animate);
}
}
};
SimpleSlider.prototype.setSliderPosition = function(position, animate) {
if (animate == null) {
animate = false;
}
if (animate && this.settings.animate) {
this.dragger.animate({
left: position
}, 200);
if (this.settings.highlight) {
return this.highlightTrack.animate({
width: position
}, 200);
}
} else {
this.dragger.css({
left: position
});
if (this.settings.highlight) {
return this.highlightTrack.css({
width: position
});
}
}
};
SimpleSlider.prototype.setSliderPositionFromValue = function(value, animate) {
var ratio;
if (animate == null) {
animate = false;
}
ratio = this.valueToRatio(value);
return this.setSliderPosition(ratio * this.slider.outerWidth(), animate);
};
SimpleSlider.prototype.getRange = function() {
if (this.settings.allowedValues) {
return {
min: Math.min.apply(Math, this.settings.allowedValues),
max: Math.max.apply(Math, this.settings.allowedValues)
};
} else if (this.settings.range) {
return {
min: parseFloat(this.settings.range[0]),
max: parseFloat(this.settings.range[1])
};
} else {
return {
min: 0,
max: 1
};
}
};
SimpleSlider.prototype.nearestValidValue = function(rawValue) {
var closest, maxSteps, range, steps;
range = this.getRange();
rawValue = Math.min(range.max, rawValue);
rawValue = Math.max(range.min, rawValue);
if (this.settings.allowedValues) {
closest = null;
$.each(this.settings.allowedValues, function() {
if (closest === null || Math.abs(this - rawValue) < Math.abs(closest - rawValue)) {
return closest = this;
}
});
return closest;
} else if (this.settings.step) {
maxSteps = (range.max - range.min) / this.settings.step;
steps = Math.floor((rawValue - range.min) / this.settings.step);
if ((rawValue - range.min) % this.settings.step > this.settings.step / 2 && steps < maxSteps) {
steps += 1;
}
return steps * this.settings.step + range.min;
} else {
return rawValue;
}
};
SimpleSlider.prototype.valueToRatio = function(value) {
var allowedVal, closest, closestIdx, idx, range, _i, _len, _ref;
if (this.settings.equalSteps) {
_ref = this.settings.allowedValues;
for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
allowedVal = _ref[idx];
if (!(typeof closest !== "undefined" && closest !== null) || Math.abs(allowedVal - value) < Math.abs(closest - value)) {
closest = allowedVal;
closestIdx = idx;
}
}
if (this.settings.snapMid) {
return (closestIdx + 0.5) / this.settings.allowedValues.length;
} else {
return closestIdx / (this.settings.allowedValues.length - 1);
}
} else {
range = this.getRange();
return (value - range.min) / (range.max - range.min);
}
};
SimpleSlider.prototype.ratioToValue = function(ratio) {
var idx, range, rawValue, step, steps;
if (this.settings.equalSteps) {
steps = this.settings.allowedValues.length;
step = Math.round(ratio * steps - 0.5);
idx = Math.min(step, this.settings.allowedValues.length - 1);
return this.settings.allowedValues[idx];
} else {
range = this.getRange();
rawValue = ratio * (range.max - range.min) + range.min;
return this.nearestValidValue(rawValue);
}
};
SimpleSlider.prototype.valueChanged = function(value, ratio, trigger) {
var eventData;
if (value.toString() === this.value.toString()) {
return;
}
this.value = value;
eventData = {
value: value,
ratio: ratio,
position: ratio * this.slider.outerWidth(),
trigger: trigger,
el: this.slider
};
return this.input.val(value).trigger($.Event("change", eventData)).trigger("slider:changed", eventData);
};
return SimpleSlider;
})();
$.extend($.fn, {
simpleSlider: function() {
var params, publicMethods, settingsOrMethod;
settingsOrMethod = arguments[0], params = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
publicMethods = ["setRatio", "setValue"];
return $(this).each(function() {
var obj, settings;
if (settingsOrMethod && __indexOf.call(publicMethods, settingsOrMethod) >= 0) {
obj = $(this).data("slider-object");
return obj[settingsOrMethod].apply(obj, params);
} else {
settings = settingsOrMethod;
return $(this).data("slider-object", new SimpleSlider($(this), settings));
}
});
}
});
return $(function() {
return $("[data-slider]").each(function() {
var $el, allowedValues, settings, x;
$el = $(this);
settings = {};
allowedValues = $el.data("slider-values");
if (allowedValues) {
settings.allowedValues = (function() {
var _i, _len, _ref, _results;
_ref = allowedValues.split(",");
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
x = _ref[_i];
_results.push(parseFloat(x));
}
return _results;
})();
}
if ($el.data("slider-range")) {
settings.range = $el.data("slider-range").split(",");
}
if ($el.data("slider-step")) {
settings.step = $el.data("slider-step");
}
settings.snap = $el.data("slider-snap");
settings.equalSteps = $el.data("slider-equal-steps");
if ($el.data("slider-theme")) {
settings.theme = $el.data("slider-theme");
}
if ($el.attr("data-slider-highlight")) {
settings.highlight = $el.data("slider-highlight");
}
if ($el.data("slider-animate") != null) {
settings.animate = $el.data("slider-animate");
}
return $el.simpleSlider(settings);
});
});
})(this.jQuery || this.Zepto, this);</script>
.slider {
width: 300px;
}
.output {
color: red;
}
.slider > .dragger {
background: #8DCA09;
background: -webkit-linear-gradient(top, #8DCA09, #72A307);
background: -moz-linear-gradient(top, #8DCA09, #72A307);
background: linear-gradient(top, #8DCA09, #72A307);
-webkit-box-shadow: inset 0 2px 2px rgba(255,255,255,0.5), 0 2px 8px rgba(0,0,0,0.2);
-moz-box-shadow: inset 0 2px 2px rgba(255,255,255,0.5), 0 2px 8px rgba(0,0,0,0.2);
box-shadow: inset 0 2px 2px rgba(255,255,255,0.5), 0 2px 8px rgba(0,0,0,0.2);
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
border: 1px solid #496805;
width: 16px;
height: 16px;
}
.slider > .dragger:hover {
background: -webkit-linear-gradient(top, #8DCA09, #8DCA09);
}
.slider > .track, .slider > .highlight-track {
background: #ccc;
background: -webkit-linear-gradient(top, #bbb, #ddd);
background: -moz-linear-gradient(top, #bbb, #ddd);
background: linear-gradient(top, #bbb, #ddd);
-webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
-moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
border: 1px solid #aaa;
height: 4px;
}
.slider > .highlight-track {
background-color: #8DCA09;
background: -webkit-linear-gradient(top, #8DCA09, #72A307);
background: -moz-linear-gradient(top, #8DCA09, #72A307);
background: linear-gradient(top, #8DCA09, #72A307);
border-color: #496805;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" data-slider="true" data-slider-values="3, 5, 10, 15, 20, 25, 30" data-slider-equal-steps="true" data-slider-snap="true">
<div>
<script>
$("[data-slider]")
.each(function() {
var input = $(this);
$("<span>")
.addClass("output")
.insertAfter($(this));
})
.bind("slider:ready slider:changed", function(event, data) {
$(this)
.nextAll(".output:first")
.html(data.value);
$('.results > div').each(function(i, elm) {
$(elm).toggle($(elm).attr('id') == data.value);
});
});
</script>
</div>
<div class="results">
<div id="3">3</div>
<div id="5">5</div>
<div id="10">10</div>
<div id="15">15</div>
<div id="20">20</div>
<div id="25">25</div>
<div id="30">30</div>
</div>

Categories