Doughnut code directly copied from codepen not working - javascript
I just copy pasted the code from this.Not changed anything:
http://codepen.io/anon/pen/rapJzN
but it doesn't work.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style>
#import url(//fonts.googleapis.com/css?family=Oswald:400);
body {
background: #222428;
font-family: "Oswald", sans-serif;
}
h1 {
color: #eee;
text-align: center;
margin: 20px 0;
text-transform: uppercase;
}
.chart {
margin: 0 auto;
width: 450px;
height: 450px;
position: relative;
}
.doughnutTip {
position: absolute;
float: left;
min-width: 30px;
max-width: 300px;
padding: 5px 15px;
border-radius: 1px;
background: rgba(0,0,0,.8);
color: #ddd;
font-size: 17px;
text-shadow: 0 1px 0 #000;
text-transform: uppercase;
text-align: center;
line-height: 1.3;
letter-spacing: .06em;
box-shadow: 0 1px 3px rgba(0,0,0,0.5);
transform: all .3s;
pointer-events: none;
}
.doughnutTip:after {
position: absolute;
left: 50%;
bottom: -6px;
content: "";
height: 0;
margin: 0 0 0 -6px;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
border-top: 6px solid rgba(0,0,0,.7);
line-height: 0;
}
.doughnutSummary {
position: absolute;
top: 50%;
left: 50%;
color: #d5d5d5;
text-align: center;
text-shadow: 0 -1px 0 #111;
cursor: default;
}
.doughnutSummaryTitle {
position: absolute;
top: 50%;
width: 100%;
margin-top: -27%;
font-size: 22px;
letter-spacing: .06em;
}
.doughnutSummaryNumber {
position: absolute;
top: 50%;
width: 100%;
margin-top: -15%;
font-size: 55px;
}
.chart path:hover {
opacity: .65;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Is it useful to distinguish between "web apps" and "web sites"?</h1>
<div id="doughnutChart" class="chart"></div>
</div>
<script>
$("#doughnutChart").drawDoughnutChart([
{
title: "Nope, It's all just the web",
value: 4822,
color: "#f3e32b"
},
{
title: "Yep. They are different things with different concerns",
value: 12339,
color: "#35a8ff"
}
]);
</script>
</form>
</body>
</html>
What is going wrong ? Am I missing something ?
Do I need to link it to something ? or download some file ? I am new to using codepen
you have 2 issues. First you need to include jQuery like this:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
Second, you need to include drawDoughnutChart, find the source files here:
https://github.com/githiro/drawDoughnutChart
Good luck!
[EDIT] Here os some working code, but instead of having the JS inside the html file, it should be included like jQuery...
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<style>
#import url(//fonts.googleapis.com/css?family=Oswald:400);
body {
background: #222428;
font-family: "Oswald", sans-serif;
}
h1 {
color: #eee;
text-align: center;
margin: 20px 0;
text-transform: uppercase;
}
.chart {
margin: 0 auto;
width: 450px;
height: 450px;
position: relative;
}
.doughnutTip {
position: absolute;
float: left;
min-width: 30px;
max-width: 300px;
padding: 5px 15px;
border-radius: 1px;
background: rgba(0,0,0,.8);
color: #ddd;
font-size: 17px;
text-shadow: 0 1px 0 #000;
text-transform: uppercase;
text-align: center;
line-height: 1.3;
letter-spacing: .06em;
box-shadow: 0 1px 3px rgba(0,0,0,0.5);
transform: all .3s;
pointer-events: none;
}
.doughnutTip:after {
position: absolute;
left: 50%;
bottom: -6px;
content: "";
height: 0;
margin: 0 0 0 -6px;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
border-top: 6px solid rgba(0,0,0,.7);
line-height: 0;
}
.doughnutSummary {
position: absolute;
top: 50%;
left: 50%;
color: #d5d5d5;
text-align: center;
text-shadow: 0 -1px 0 #111;
cursor: default;
}
.doughnutSummaryTitle {
position: absolute;
top: 50%;
width: 100%;
margin-top: -27%;
font-size: 22px;
letter-spacing: .06em;
}
.doughnutSummaryNumber {
position: absolute;
top: 50%;
width: 100%;
margin-top: -15%;
font-size: 55px;
}
.chart path:hover {
opacity: .65;
}
</style>
<script type="application/javascript">
/*!
* jquery.drawDoughnutChart.js
* Version: 0.4(Beta)
* Inspired by Chart.js(http://www.chartjs.org/)
*
* Copyright 2014 hiro
* https://github.com/githiro/drawDoughnutChart
* Released under the MIT license.
*
*/
;(function($, undefined) {
$.fn.drawDoughnutChart = function(data, options) {
var $this = this,
W = $this.width(),
H = $this.height(),
centerX = W/2,
centerY = H/2,
cos = Math.cos,
sin = Math.sin,
PI = Math.PI,
settings = $.extend({
segmentShowStroke : true,
segmentStrokeColor : "#0C1013",
segmentStrokeWidth : 1,
baseColor: "rgba(0,0,0,0.5)",
baseOffset: 4,
edgeOffset : 10,//offset from edge of $this
percentageInnerCutout : 75,
animation : true,
animationSteps : 90,
animationEasing : "easeInOutExpo",
animateRotate : true,
tipOffsetX: -8,
tipOffsetY: -45,
showTip: true,
showLabel: false,
ratioFont: 1.5,
shortInt: false,
tipClass: "doughnutTip",
summaryClass: "doughnutSummary",
summaryTitle: "TOTAL:",
summaryTitleClass: "doughnutSummaryTitle",
summaryNumberClass: "doughnutSummaryNumber",
beforeDraw: function() { },
afterDrawed : function() { },
onPathEnter : function(e,data) { },
onPathLeave : function(e,data) { }
}, options),
animationOptions = {
linear : function (t) {
return t;
},
easeInOutExpo: function (t) {
var v = t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t;
return (v>1) ? 1 : v;
}
},
requestAnimFrame = function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
}();
settings.beforeDraw.call($this);
var $svg = $('<svg width="' + W + '" height="' + H + '" viewBox="0 0 ' + W + ' ' + H + '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>').appendTo($this),
$paths = [],
easingFunction = animationOptions[settings.animationEasing],
doughnutRadius = Min([H / 2,W / 2]) - settings.edgeOffset,
cutoutRadius = doughnutRadius * (settings.percentageInnerCutout / 100),
segmentTotal = 0;
//Draw base doughnut
var baseDoughnutRadius = doughnutRadius + settings.baseOffset,
baseCutoutRadius = cutoutRadius - settings.baseOffset;
$(document.createElementNS('http://www.w3.org/2000/svg', 'path'))
.attr({
"d": getHollowCirclePath(baseDoughnutRadius, baseCutoutRadius),
"fill": settings.baseColor
})
.appendTo($svg);
//Set up pie segments wrapper
var $pathGroup = $(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
$pathGroup.attr({opacity: 0}).appendTo($svg);
//Set up tooltip
if (settings.showTip) {
var $tip = $('<div class="' + settings.tipClass + '" />').appendTo('body').hide(),
tipW = $tip.width(),
tipH = $tip.height();
}
//Set up center text area
var summarySize = (cutoutRadius - (doughnutRadius - cutoutRadius)) * 2,
$summary = $('<div class="' + settings.summaryClass + '" />')
.appendTo($this)
.css({
width: summarySize + "px",
height: summarySize + "px",
"margin-left": -(summarySize / 2) + "px",
"margin-top": -(summarySize / 2) + "px"
});
var $summaryTitle = $('<p class="' + settings.summaryTitleClass + '">' + settings.summaryTitle + '</p>').appendTo($summary);
$summaryTitle.css('font-size', getScaleFontSize( $summaryTitle, settings.summaryTitle )); // In most of case useless
var $summaryNumber = $('<p class="' + settings.summaryNumberClass + '"></p>').appendTo($summary).css({opacity: 0});
for (var i = 0, len = data.length; i < len; i++) {
segmentTotal += data[i].value;
$paths[i] = $(document.createElementNS('http://www.w3.org/2000/svg', 'path'))
.attr({
"stroke-width": settings.segmentStrokeWidth,
"stroke": settings.segmentStrokeColor,
"fill": data[i].color,
"data-order": i
})
.appendTo($pathGroup)
.on("mouseenter", pathMouseEnter)
.on("mouseleave", pathMouseLeave)
.on("mousemove", pathMouseMove)
.on("click", pathClick);
}
//Animation start
animationLoop(drawPieSegments);
//Functions
function getHollowCirclePath(doughnutRadius, cutoutRadius) {
//Calculate values for the path.
//We needn't calculate startRadius, segmentAngle and endRadius, because base doughnut doesn't animate.
var startRadius = -1.570,// -Math.PI/2
segmentAngle = 6.2831,// 1 * ((99.9999/100) * (PI*2)),
endRadius = 4.7131,// startRadius + segmentAngle
startX = centerX + cos(startRadius) * doughnutRadius,
startY = centerY + sin(startRadius) * doughnutRadius,
endX2 = centerX + cos(startRadius) * cutoutRadius,
endY2 = centerY + sin(startRadius) * cutoutRadius,
endX = centerX + cos(endRadius) * doughnutRadius,
endY = centerY + sin(endRadius) * doughnutRadius,
startX2 = centerX + cos(endRadius) * cutoutRadius,
startY2 = centerY + sin(endRadius) * cutoutRadius;
var cmd = [
'M', startX, startY,
'A', doughnutRadius, doughnutRadius, 0, 1, 1, endX, endY,//Draw outer circle
'Z',//Close path
'M', startX2, startY2,//Move pointer
'A', cutoutRadius, cutoutRadius, 0, 1, 0, endX2, endY2,//Draw inner circle
'Z'
];
cmd = cmd.join(' ');
return cmd;
};
function pathMouseEnter(e) {
var order = $(this).data().order;
if (settings.showTip) {
$tip.text(data[order].title + ": " + data[order].value)
.fadeIn(200);
}
if(settings.showLabel) {
$summaryTitle.text(data[order].title).css('font-size', getScaleFontSize( $summaryTitle, data[order].title));
var tmpNumber = settings.shortInt ? shortKInt(data[order].value) : data[order].value;
$summaryNumber.html(tmpNumber).css('font-size', getScaleFontSize( $summaryNumber, tmpNumber));
}
settings.onPathEnter.apply($(this),[e,data]);
}
function pathMouseLeave(e) {
if (settings.showTip) $tip.hide();
if(settings.showLabel) {
$summaryTitle.text(settings.summaryTitle).css('font-size', getScaleFontSize( $summaryTitle, settings.summaryTitle));
var tmpNumber = settings.shortInt ? shortKInt(segmentTotal) : segmentTotal;
$summaryNumber.html(tmpNumber).css('font-size', getScaleFontSize( $summaryNumber, tmpNumber));
}
settings.onPathLeave.apply($(this),[e,data]);
}
function pathMouseMove(e) {
if (settings.showTip) {
$tip.css({
top: e.pageY + settings.tipOffsetY,
left: e.pageX - $tip.width() / 2 + settings.tipOffsetX
});
}
}
function pathClick(e){
var order = $(this).data().order;
if (typeof data[order].action != "undefined")
data[order].action();
}
function drawPieSegments (animationDecimal) {
var startRadius = -PI / 2,//-90 degree
rotateAnimation = 1;
if (settings.animation && settings.animateRotate) rotateAnimation = animationDecimal;//count up between0~1
drawDoughnutText(animationDecimal, segmentTotal);
$pathGroup.attr("opacity", animationDecimal);
//If data have only one value, we draw hollow circle(#1).
if (data.length === 1 && (4.7122 < (rotateAnimation * ((data[0].value / segmentTotal) * (PI * 2)) + startRadius))) {
$paths[0].attr("d", getHollowCirclePath(doughnutRadius, cutoutRadius));
return;
}
for (var i = 0, len = data.length; i < len; i++) {
var segmentAngle = rotateAnimation * ((data[i].value / segmentTotal) * (PI * 2)),
endRadius = startRadius + segmentAngle,
largeArc = ((endRadius - startRadius) % (PI * 2)) > PI ? 1 : 0,
startX = centerX + cos(startRadius) * doughnutRadius,
startY = centerY + sin(startRadius) * doughnutRadius,
endX2 = centerX + cos(startRadius) * cutoutRadius,
endY2 = centerY + sin(startRadius) * cutoutRadius,
endX = centerX + cos(endRadius) * doughnutRadius,
endY = centerY + sin(endRadius) * doughnutRadius,
startX2 = centerX + cos(endRadius) * cutoutRadius,
startY2 = centerY + sin(endRadius) * cutoutRadius;
var cmd = [
'M', startX, startY,//Move pointer
'A', doughnutRadius, doughnutRadius, 0, largeArc, 1, endX, endY,//Draw outer arc path
'L', startX2, startY2,//Draw line path(this line connects outer and innner arc paths)
'A', cutoutRadius, cutoutRadius, 0, largeArc, 0, endX2, endY2,//Draw inner arc path
'Z'//Cloth path
];
$paths[i].attr("d", cmd.join(' '));
startRadius += segmentAngle;
}
}
function drawDoughnutText(animationDecimal, segmentTotal) {
$summaryNumber
.css({opacity: animationDecimal})
.text((segmentTotal * animationDecimal).toFixed(1));
var tmpNumber = settings.shortInt ? shortKInt(segmentTotal) : segmentTotal;
$summaryNumber.html(tmpNumber).css('font-size', getScaleFontSize( $summaryNumber, tmpNumber));
}
function animateFrame(cnt, drawData) {
var easeAdjustedAnimationPercent =(settings.animation)? CapValue(easingFunction(cnt), null, 0) : 1;
drawData(easeAdjustedAnimationPercent);
}
function animationLoop(drawData) {
var animFrameAmount = (settings.animation)? 1 / CapValue(settings.animationSteps, Number.MAX_VALUE, 1) : 1,
cnt =(settings.animation)? 0 : 1;
requestAnimFrame(function() {
cnt += animFrameAmount;
animateFrame(cnt, drawData);
if (cnt <= 1) {
requestAnimFrame(arguments.callee);
} else {
settings.afterDrawed.call($this);
}
});
}
function Max(arr) {
return Math.max.apply(null, arr);
}
function Min(arr) {
return Math.min.apply(null, arr);
}
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function CapValue(valueToCap, maxValue, minValue) {
if (isNumber(maxValue) && valueToCap > maxValue) return maxValue;
if (isNumber(minValue) && valueToCap < minValue) return minValue;
return valueToCap;
}
function shortKInt (int) {
int = int.toString();
var strlen = int.length;
if(strlen<5)
return int;
if(strlen<8)
return '<span title="' + int + '">' + int.substring(0, strlen-3) + 'K</span>';
return '<span title="' + int + '">' + int.substring( 0, strlen-6) + 'M</span>';
}
function getScaleFontSize(block, newText) {
block.css('font-size', '');
newText = newText.toString().replace(/(<([^>]+)>)/ig,"");
var newFontSize = block.width() / newText.length * settings.ratioFont;
// Not very good : http://stephensite.net/WordPressSS/2008/02/19/how-to-calculate-the-character-width-accross-fonts-and-points/
// But best quick way the 1.5 number is to affinate in function of the police
var maxCharForDefaultFont = block.width() - newText.length * block.css('font-size').replace(/px/, '') / settings.ratioFont;
if(maxCharForDefaultFont<0)
return newFontSize+'px';
else
return '';
}
/**
function getScaleFontSize(block, newText) {
block.css('font-size', '');
newText = newText.toString().replace(/(<([^>]+)>)/ig,"");
var newFontSize = block.width() / newText.length;
if(newFontSize<block.css('font-size').replace(/px/, ''))
return newFontSize+'px';
else
return '';
}*/
return $this;
};
})(jQuery);
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Is it useful to distinguish between "web apps" and "web sites"?</h1>
<div id="doughnutChart" class="chart"></div>
</div>
<script>
$("#doughnutChart").drawDoughnutChart([
{
title: "Nope, It's all just the web",
value: 4822,
color: "#f3e32b"
},
{
title: "Yep. They are different things with different concerns",
value: 12339,
color: "#35a8ff"
}
]);
</script>
</form>
</body>
</html>
[EDIT2]
Also, use your browsers developer tools (usually F12) to see what error messages comes up... On your first example, the error was $ is undefined or something, and this usually means that jQuery is needed. After that it said drawDoughnutChart() is undefined, and a quick google search got me the sourcecode needed...
Just add this at the beginning of your <head>:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/githiro/drawDoughnutChart/master/jquery.drawDoughnutChart.js"></script>
Problem solved :)
Related
Detect if user trying resize a draggable element
I'm trying create draggable elements that can also be resized by dragging bottom right corner with the help of resize: both CSS rule. So far I'm able drag it around screen, but I can't figure out how to detect if cursor at "resize" state, because attempting resize the element moves it instead. Currently as a work around I'm simply checking if cursor within 20px from bottom-right corner, but that's not very accurate (and probably browser/os dependent), in some places it refuses resize and move the element at all. Any suggestions? !function(){ "use strict"; let x, y, drag; document.addEventListener("mousedown", function(e) { if (e.target.parentNode.lastChild !== e.target && e.target.parentNode.classList.contains("main")) { //bring element to the front and dispatch mousedown event again otherwise resize doesn't work e.target.parentNode.appendChild(e.target); return e.target.dispatchEvent(new MouseEvent(e.type, e)); } if (!e.target.classList.contains("draggable")) return; /* if cursor within 20px from bottom right corner don't move */ const r = e.target.getBoundingClientRect(); if (r.right < e.x + 20 && r.bottom < e.y + 20) return; drag = e.target; x = e.x - drag.offsetLeft; y = e.y - drag.offsetTop; document.body.classList.add("drag"); drag.classList.add("drag"); }); document.addEventListener("mouseup", function(e) { document.body.classList.remove("drag"); drag = drag && drag.classList.remove("drag"); }); document.addEventListener("mousemove", function(e) { if (!drag || e.x - drag.offsetLeft == x || e.y - drag.offsetTop == y) return; drag.style.left = (e.x - x) + "px"; drag.style.top = (e.y - y) + "px"; }); /*init*/ for (let i = 0, c, d = document.getElementsByClassName("main")[0].children; i < d.length; i++) { c = (0x1000000 + Math.random() * 0xffffff).toString(16).substr(1, 6); d[i].style.backgroundColor = '#' + c; d[i].classList.toggle("dark", ((parseInt(c.substr(0, 2), 16) * 299) + (parseInt(c.substr(2, 2), 16) * 587) + (parseInt(c.substr(4, 2), 16) * 114)) / 1000 < 128); d[i].style.left = document.documentElement.scrollWidth / 8 + Math.random() * (document.documentElement.scrollWidth / 1.33 - d[i].offsetWidth) + "px"; d[i].style.top = document.documentElement.scrollHeight / 8 + Math.random() * (document.documentElement.scrollHeight / 1.33 - d[i].offsetHeight) + "px"; } }() div.main>div { width: 5em; height: 5em; border: 1px solid black; position: absolute; resize: both; overflow: hidden; mix-blend-mode: hard-light; display: flex; border-radius: 0.3em; } div.main>div:hover { box-shadow: 0 0 5px black; } div.main>div:last-child { box-shadow: 0 0 10px black; } div.draggable { cursor: grab; } div.main>div:not(.draggable):before { content: "can't move me"; } div.main>div.draggable:before { content: "move me"; } div.main>div:before { color: black; text-shadow: 0 0 1em black; margin: auto; text-align: center; } div.main>div.dark:before { color: white; text-shadow: 0 0 1em white; } body.drag { user-select: none; } body.drag div.draggable { cursor: grabbing; } <div class="main"> <div></div> <div class="draggable"></div> <div class="draggable"></div> <div class="draggable"></div> </div>
You could wrap the mouse-target (.draggable) inside a resizeable container element. This way, the UI for the CSS-resize will get hit before the draggable element and you can handle only the dragging nicely: !function(){ "use strict"; let x, y, drag; document.addEventListener("mousedown", function(e) { if (e.target.parentNode.lastChild !== e.target && e.target.parentNode.classList.contains("main")) { //bring element to the front and dispatch mousedown event again otherwise resize doesn't work e.target.parentNode.appendChild(e.target); return e.target.dispatchEvent(new MouseEvent(e.type, e)); } if (!e.target.classList.contains("draggable")) return; e.preventDefault(); drag = e.target.parentNode; x = e.x - drag.offsetLeft; y = e.y - drag.offsetTop; document.body.classList.add("drag"); drag.classList.add("drag"); }); document.addEventListener("mouseup", function(e) { document.body.classList.remove("drag"); drag = drag && drag.classList.remove("drag"); }); document.addEventListener("mousemove", function(e) { if (!drag || e.x - drag.offsetLeft == x || e.y - drag.offsetTop == y) return; drag.style.left = (e.x - x) + "px"; drag.style.top = (e.y - y) + "px"; }); /*init*/ for (let i = 0, c, d = document.getElementsByClassName("main")[0].children; i < d.length; i++) { c = (0x1000000 + Math.random() * 0xffffff).toString(16).substr(1, 6); d[i].style.backgroundColor = '#' + c; d[i].classList.toggle("dark", ((parseInt(c.substr(0, 2), 16) * 299) + (parseInt(c.substr(2, 2), 16) * 587) + (parseInt(c.substr(4, 2), 16) * 114)) / 1000 < 128); d[i].style.left = document.documentElement.scrollWidth / 8 + Math.random() * (document.documentElement.scrollWidth / 1.33 - d[i].offsetWidth) + "px"; d[i].style.top = document.documentElement.scrollHeight / 8 + Math.random() * (document.documentElement.scrollHeight / 1.33 - d[i].offsetHeight) + "px"; } }() .resizeable { width: 5em; height: 5em; border: 1px solid black; position: absolute; resize: both; overflow: hidden; mix-blend-mode: hard-light; border-radius: 0.3em; } div.main>div:hover { box-shadow: 0 0 5px black; } div.main>div:last-child { box-shadow: 0 0 10px black; } div.draggable { cursor: grab; width: 100%; height: 100%; display: flex; } div.no-drag { display: flex; } div.main div.no-drag:before { content: "can't move me"; } div.draggable:before { content: "move me"; } div.main div:before { color: black; text-shadow: 0 0 1em black; margin: auto; text-align: center; } div.main>div.dark:before { color: white; text-shadow: 0 0 1em white; } body.drag { user-select: none; } body.drag div.draggable { cursor: grabbing; } <div class="main"> <div class="resizeable no-drag"></div> <div class="resizeable"><div class="draggable"></div></div> <div class="resizeable"><div class="draggable"></div></div> <div class="resizeable"><div class="draggable"></div></div> </div>
JS not working in Django Templates (Errors within Inspect Console not Django Console)
I have a javascript that works when I run it outside of Django; however, when I try to run it within my Django Project, I get an error saying "TypeError: null is not an object (evaluating 'element.parentNode')" and an error saying "SyntaxError: Can't duplicate variable: 'Dragger'". When I run it, it appears the Div; but doesn't use the JS; there is no error within the Django console that is running the script; I see the error when I look at the Inspect Console. I was wondering if JS works the same within Django Templates as it does it normal html. Please find the Github test project that isolates the issue tab https://github.com/walterrose/Django_Testing_JS Javascript: var PADDING = 8; var rect; var viewport = { bottom: 0, left: 0, right: 0, top: 0 } let getPropertyValue = function(style, prop) { let value = style.getPropertyValue(prop); value = value ? value.replace(/[^0-9.]/g, '') : '0'; return parseFloat(value); } let getElementRect = function(element) { let style = window.getComputedStyle(element, null); var x = getPropertyValue(style, 'left') var y = getPropertyValue(style, 'top') var width = getPropertyValue(style, 'width') var height = getPropertyValue(style, 'height') return { x, y, width, height } } class Resizer { constructor(wrapper, element) { this.wrapper = wrapper; this.element = element; this.offsetX = 0; this.offsetY = 0; this.handle = document.createElement('div'); this.handle.setAttribute('class', 'drag-resize-handlers'); this.handle.setAttribute('data-direction', 'br'); this.wrapper.appendChild(this.handle); this.wrapper.style.top = this.element.style.top; this.wrapper.style.left = this.element.style.left; this.wrapper.style.width = this.element.style.width; this.wrapper.style.height = this.element.style.height; this.element.style.position = 'relative'; this.element.style.top = 0; this.element.style.left = 0; this.onResize = this.resizeHandler.bind(this); this.onStop = this.stopResize.bind(this); this.handle.addEventListener('mousedown', this.initResize.bind(this)); } initResize(event) { this.stopResize(event, true); this.handle.addEventListener('mousemove', this.onResize); this.handle.addEventListener('mouseup', this.onStop); } resizeHandler(event) { this.offsetX = event.clientX - (this.wrapper.offsetLeft + this.handle.offsetLeft); this.offsetY = event.clientY - (this.wrapper.offsetTop + this.handle.offsetTop); let wrapperRect = getElementRect(this.wrapper); let elementRect = getElementRect(this.element); this.wrapper.style.width = (wrapperRect.width + this.offsetX) + 'px'; this.wrapper.style.height = (wrapperRect.height + this.offsetY) + 'px'; this.element.style.width = (elementRect.width + this.offsetX) + 'px'; this.element.style.height = (elementRect.height + this.offsetY) + 'px'; } stopResize(event, nocb) { this.handle.removeEventListener('mousemove', this.onResize); this.handle.removeEventListener('mouseup', this.onStop); } } class Dragger { constructor(wrapper, element) { this.wrapper = wrapper; this.element = element; this.element.draggable = true; this.element.setAttribute('draggable', true); this.element.addEventListener('dragstart', this.dragStart.bind(this)); } dragStart(event) { let wrapperRect = getElementRect(this.wrapper); var x = wrapperRect.x - parseFloat(event.clientX); var y = wrapperRect.y - parseFloat(event.clientY); event.dataTransfer.setData("text/plain", this.element.id + ',' + x + ',' + y); } dragStop(event, prevX, prevY) { // store the current viewport and element dimensions when a drag starts viewport.bottom = window.innerHeight - PADDING; viewport.left = PADDING; viewport.right = window.innerWidth - PADDING; viewport.top = PADDING; let wrapperRect = getElementRect(this.wrapper); var height = wrapperRect.height var width = wrapperRect.width var newLeft = parseFloat(event.clientX) + prevX; var newTop = parseFloat(event.clientY) + prevY; var newRight = newLeft + width var newBottom = newTop + height // Deal with Left and Right boundary // If either out of bounds if (newLeft < viewport.left || newRight > viewport.right ) { // If left is out of bounds if (newLeft < viewport.left){ this.wrapper.style.left = viewport.left + 'px'; } // If right is out of bounds if (newRight > viewport.right){ this.wrapper.style.left = viewport.right - width + 'px'; } } else { //If neither right or left is out of bounds this.wrapper.style.left = newLeft + 'px'; } // Deal with Top and Bottom boundary // If either out of bounds if (newTop < viewport.top || newBottom > viewport.bottom ) { // If top is out of bounds if (newTop < viewport.top){ this.wrapper.style.top = viewport.top + 'px'; } // If bottom is out of bounds if (newBottom > viewport.bottom){ this.wrapper.style.top = viewport.bottom - height + 'px'; } } else { //If neither right or left is out of bounds this.wrapper.style.top = newTop + 'px'; } } } class DragResize { constructor(element) { this.wrapper = document.createElement('div'); this.wrapper.setAttribute('class', 'tooltip drag-resize'); if (element.parentNode) { element.parentNode.insertBefore(this.wrapper, element); } this.wrapper.appendChild(element); element.resizer = new Resizer(this.wrapper, element); element.dragger = new Dragger(this.wrapper, element); } } document.body.addEventListener('dragover', function (event) { event.preventDefault(); return false; }); document.body.addEventListener('drop', function (event) { event.preventDefault(); var dropData = event.dataTransfer.getData("text/plain").split(','); var element = document.getElementById(dropData[0]); element.dragger.dragStop(event, parseFloat(dropData[1]), parseFloat(dropData[2])); return false; }); new DragResize(document.getElementById('content1')) CSS .drag-resize { position: absolute; border: 1px dashed transparent; z-index: 999; padding: 5px; margin-top: -5px; margin-left: -5px; transform: translate3d(0, 0, 0); -webkit-transform: translate3d(0, 0, 0); /*transition: all 0.1s linear;*/ } .drag-resize:hover { border-color: rgb(0, 150, 253); cursor: move; display: block; } .drag-resize:hover .drag-resize-handlers { display: block; } .drag-resize > div.drag-window { width: 100%; height: 100%; position: absolute; } .drag-resize-handlers { position: absolute; display: none; width: 5px; height: 5px; font-size: 1px; background: rgb(0, 150, 253); -webkit-transition: all 0.1s linear; transition: all 0.1s linear; opacity: 0; border: 1px solid rgb(255, 255, 255); } .drag-resize .drag-resize-handlers { opacity: 1; } .drag-resize-handlers:hover { transform: scale(3); /*chrome*/ -webkit-transform: scale(3); /*nodewebkit*/ } .drag-resize-handlers[data-direction="tl"] { top: -5px; left: -5px; cursor: nw-resize; } .drag-resize-handlers[data-direction="tm"] { top: -5px; left: 50%; margin-left: -5px; cursor: n-resize; } .drag-resize-handlers[data-direction="tr"] { top: -5px; right: -5px; cursor: ne-resize; } .drag-resize-handlers[data-direction="ml"] { top: 50%; margin-top: -5px; left: -5px; cursor: w-resize; } .drag-resize-handlers[data-direction="mr"] { top: 50%; margin-top: -5px; right: -5px; cursor: e-resize; } .drag-resize-handlers[data-direction="bl"] { bottom: -5px; left: -5px; cursor: sw-resize; } .drag-resize-handlers[data-direction="bm"] { bottom: -5px; left: 50%; margin-left: -5px; cursor: s-resize; } .drag-resize-handlers[data-direction="br"] { bottom: -5px; right: -5px; cursor: se-resize; } .wrap { background-color:#aabbbb; text-align:center; width:300px; height:200px; color:#fff; } HTML (when testing outside of Django) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta html-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="style.css" /> </head> <body> <div style= "width:70%; height:1000px; /*background-color: #0000ff";*/ > <div id="content1" class="wrap">Drag and resize me!</div> <!-- <div id="content2" class="wrap">Drag and resize me!</div> --> </div> <script src="main.js"></script> </body> </html> HTML for within Django is inside of a block (with this sheet being a new Django Tab) and the base.html connects to the javascript file {% extends "blog/base.html" %} {% block content %} <div id="content1" class="wrap">Drag and resize me!</div> {% endblock content %}
Javascript carosel animation
I'm trying to make an image carousel with center animation. I don't want to use CSS animations, instead I'd like to use jQuery. By pressing the 'Prev' button the animation will start. One of the slides which will be central begins to grow. I've used jQuery's animate() to animate width and height. Everything works as required except I can't understand why the animation makes the central slide jump. I have created this sample. If you push the 'Prev' button the animation will start. var scroll_speed = 4000; var items_cnt = $('.mg_item').length; var container_size = $(".main_cnt").innerWidth(); var item_avg_w = container_size / 5; var item_center_w = ((item_avg_w / 100) * 20) + item_avg_w; var item_center_h = (item_center_w / 16) * 9 + 30; var item_w = ((container_size - item_center_w) / 4) - 2; var item_h = ((item_w / 16) * 9); var gallery_content = $('.gallery_body').html(); $('.gallery_body').html(gallery_content + gallery_content + gallery_content); var items_offset = items_cnt * item_w + 14; $('.gallery_body').css('left', -items_offset); $('.mg_item').css("width", item_w); $('.mg_item').css("height", item_h); //$('.mg_item').css("margin-bottom", (item_center_h - item_h) / 2); //$('.mg_item').css("margin-top", (item_center_h - item_h) / 2); //$('.mg_item_с').css("width", item_center_w); //$('.mg_item_с').css("height", item_center_h); //document.documentElement.style.setProperty('--center_width', item_center_w + "px"); //document.documentElement.style.setProperty('--center_height', item_center_h + "px"); $('.main_cnt').css("height", item_center_h); check_visible(); AssignCenter(0); function gonext() { AssignCenter(-1); ZoomIn(); $('.gallery_body').animate({ left: '+=' + (item_w + 2), }, scroll_speed, "linear", function() { LoopSlides(); }); } function goprev() { AssignCenter(1); ZoomIn(); $('.gallery_body').animate({ left: '-=' + (item_w + 2), }, scroll_speed, "linear", function() { LoopSlides(); }); } function ZoomIn() { $('.center').animate({ width: item_center_w + 'px', height: item_center_h + 'px', }, scroll_speed, function() {}); } function LoopSlides() { var cur_pos = $('.gallery_body').position().left var left_margin = Math.abs(items_offset * 2 - item_w) * -1; var right_margin = 0 - item_w; if (cur_pos < left_margin) { $('.gallery_body').css('left', -items_offset); } if (cur_pos >= 0) { $('.gallery_body').css('left', -items_offset); } check_visible(); AssignCenter(0); } function check_visible() { $('.mg_item').each(function(i, obj) { var pos = $(this).offset().left; if (pos < 0 || pos > container_size) { $(this).addClass("invisible"); $(this).removeClass("active"); } else { $(this).addClass("active"); $(this).removeClass("invisible"); } }); } function AssignCenter(offset) { var center_slide = $('.active')[2 + offset]; $('.center').each(function(i, obj) { $(this).removeClass("center"); }); $(center_slide).addClass("center"); //$(center_slide).css("width", item_center_w); //$(center_slide).css("height", item_center_h); } :root { --center_width: 0px; --center_height: 0px; } .main_cnt { background-color: rgb(255, 0, 0); padding: 0px; overflow: hidden; margin: 0px; } .gallery_body { width: 500%; background-color: rgb(128, 128, 128); position: relative; } .mg_item { width: 198px; height: 150px; background-color: blue; display: inline-block; position: relative; margin: -1px; padding: 0px; font-size: 120px; } .center { background-color: brown; /*width: var(--center_width) !important; height: var(--center_height) !important;*/ } .item_c { width: 410px; height: 150px; background-color: blueviolet; display: inline-block; position: relative; margin: -1px; padding: 0px; font-size: 120px; } .video-js .vjs-dock-text { text-align: right; } <script src="https://code.jquery.com/jquery-2.2.0.min.js" type="text/javascript"></script> <div class="main_cnt"> <div class="gallery_body"> <div class="mg_item">1</div> <div class="mg_item">2</div> <div class="mg_item">3</div> <div class="mg_item">4</div> <div class="mg_item">5</div> <div class="mg_item">6</div> <div class="mg_item">7</div> </div> </div> <br><br> <button onclick="gonext()">GONEXT</button> <button onclick="goprev()">GOPREV</button> <button onclick="check_visible()">CHEVIS</button>
Issues with ScaleX() on browser Zoom
When zooming in the browser, the scaleX() property is not staying consistent. TranslateX() works exactly as it should which is why I'm reaching out. I am building out a stepped progress bar with the Web Animations API and Vanilla JS, the intention is that there will be a form inserted into this so as we step through form steps the animation/steps will show progress through it. The issue I am encountering is when I am testing for ADA compliance, specifically when zooming in on the page. And even more specifically, it's only when the zoom percentage is not a multiple of 100. So 100, 200, 300, and 400% work perfectly. But 110, 125, 250%, just to name a few, are having issues. The dot that slides across the screen is working as it should. The unexpected behavior is in the bar that expands across the screen along with the dot, sometimes it goes too far sometimes it doesn't go far enough. The thing that is really confusing me is that both the bar and the dot are both being "controlled" by the same measurements, which is taking the parent div's width and dividing by 3 and then multiplying by the current step. This is what leads me to assuming the issue is in the scaleX transform. I am still testing this overall in IE, encountering the issue in chrome and firefox. HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>My stepped progress bar</title> <link href="style.css" type="text/css" rel="stylesheet" /> <link href="fonts.css" type="text/css" rel="stylesheet" /> <!-- Web Animation API polyfill--> <script src="https://rawgit.com/web-animations/web-animations-js/master/web-animations.min.js"></script> </head> <body> <section> <div class="progress__container"> <div class="progress__bar"> <div id="progress__fill" class="step1"></div> <div class="circ__container"> <div class="circ" id="circ__1"></div> <div class="circ" id="circ__2"></div> <div class="circ" id="circ__3"></div> <div class="circ" id="circ__4"></div> </div> <div id="progress__dot" class="prog__1"></div> </div> <div class="backBar"></div> <div class="flexrow"> <span class="stepName tab-1">Account</span> <span class="stepName tab-2">Frequency</span> <span class="stepName tab-3">Amount</span> <span class="stepName tab-4">Taxes</span> </div> <div class="button__container"> <button class="buttonStep" id="back">Back</button> <button class="buttonStep is-active" id="next">Next</button> </div> </div> </section> <script src="script-api.js"></script> </body> </html> CSS: /* General Styles */ body { font-family: Arial, helvetica, sans-serif; } /* Slider Bar Animation */ #progress__fill { height:2px; position: absolute; top: 7px; left: 0; background-color: darkred; width: 1px; } #progress__dot { background-color: darkred; color: #fff; border-radius: 50%; height: 8px; width: 8px; position: absolute; text-align:center; line-height: 8px; padding: 6px; top: 0; font-size: 12px; } /* Static Bar Elements */ .progress__container { width: 600px; margin: 20px auto; position: relative; } .backBar { height:2px; width:96%; position: absolute; top: 7px; left: 2%; background-color: lightgrey; } .progress__bar { z-index: 100; position: relative; width: 96%; margin: 0 auto; } .circ { background-color: #fff; border: 2px solid lightgrey; border-radius: 50%; height: 8px; width: 8px; display: inline-block; position: absolute; } .hide { visibility: hidden } .flexrow { display: flex; flex-direction: row; justify-content: space-between; } .circ__container { padding-top: 3px; } .flexrow { margin-top: 20px; } .stepName { font-size: 12px; text-align: center; } .stepName:first-child { text-align: left; } .stepName:last-child { text-align: right; } .stepName.bold { font-weight: 600; } /* Buttons */ .button__container { padding-top: 100px; } .buttonStep { background: grey; color: #fff; padding: 10px 25px; border-radius: 10px; font-size: 16px; } #back { float: left; } #next { float: right; } .is-active { background: darkred; } JS: // give a starting value for the transformation var slideBarWidth = 0, slideBarScalePoint = 0, currentStep = 1, dot = document.getElementById('progress__dot'), boxWidth = dot.parentElement.offsetWidth; // insert the current step number into the progress dot dot.innerHTML = currentStep; // place the background dots on the bar for (var x = 1; x < 5; x++) { document.getElementById('circ__' + x).setAttribute('style', 'left: ' + ((boxWidth / 3) * (x - 1)) + 'px'); if (x == 4) { document.getElementById('circ__' + x).setAttribute('style', 'left: ' + (((boxWidth / 3) * (x - 1)) - document.getElementById('circ__' + x).offsetWidth)+ 'px'); } } // define the timing for progress dot var dotTiming = { duration: 500, fill: "both", easing: 'ease-in-out' } // define the timing for sliding bar var barTiming = { duration: 500, fill: "both", easing: 'ease-in-out' } var passedTiming = { fill: "both" } // make the first step name bold document.getElementsByClassName('tab-' + currentStep)[0].classList.add('bold'); // on click fire the animation document.getElementById('next').addEventListener('click', function() { // make sure the slider does not go further than it should if (currentStep > 3){return;} // define the keyframes for the progress dot if (currentStep == 3) { var moveDot = [ {transform: 'translateX(' + ((boxWidth / 3) * (currentStep - 1)) + 'px)'}, {transform: 'translateX(' + (((boxWidth / 3) * (currentStep)) - dot.offsetWidth) + 'px)'} ]; } else { var moveDot = [ {transform: 'translateX(' + ((boxWidth / 3) * (currentStep - 1)) + 'px)'}, {transform: 'translateX(' + ((boxWidth / 3) * (currentStep)) + 'px)'}, ]; } // define the keyframes for the sliding bar var slideBar = [ { transform: 'scaleX(' + ((boxWidth / 3) * (currentStep - 1)) + ')', transformOrigin: 'left' }, { transform: 'scaleX(' + ((boxWidth / 3) * (currentStep)) + ')', transformOrigin: 'left' } ]; var showDot = [ {backgroundColor: '#fff', border: '2px solid lightgrey' }, {backgroundColor: 'darkred', border: '2px solid darkred' } ]; // putting the keyframes and timings together (progress dot) var movingDot = document.getElementById("progress__dot").animate( moveDot, dotTiming ); // putting the keyframes and timings together (sliding bar) var slidingBar = document.getElementById("progress__fill").animate( slideBar, barTiming ); var passingDot = document.getElementById('circ__' + currentStep).animate( showDot, passedTiming ); // making the animation play forwards movingDot.playbackRate = 1; slidingBar.playbackRate = 1; passingDot.playbackRate = 1; // starting the animations movingDot.play(); slidingBar.play(); movingDot.onfinish = passingDot; // incrementing and setting the step counter currentStep++; document.getElementById("progress__dot").innerHTML = currentStep; if (currentStep > 1) { document.getElementById('back').classList.add('is-active'); } if (currentStep > 3) { document.getElementById('next').classList.remove('is-active'); } // toggling the bold class for the step names document.getElementsByClassName('tab-' + (currentStep - 1))[0].classList.remove('bold'); setTimeout(() => { document.getElementsByClassName('tab-' + currentStep)[0].classList.add('bold'); }, 600); }); document.getElementById('back').addEventListener('click', function() { // make sure the slider does not go back past the beginning if (currentStep < 2){return;} // define the keyframes if (currentStep == 4) { var moveDot = [ {transform: 'translateX(' + ((boxWidth / 3) * (currentStep - 2)) + 'px)'}, {transform: 'translateX(' + (((boxWidth / 3) * (currentStep - 1)) - dot.offsetWidth) + 'px)'} ]; } else { var moveDot = [ {transform: 'translateX(' + ((boxWidth / 3) * (currentStep - 2)) + 'px)'}, {transform: 'translateX(' + ((boxWidth / 3) * (currentStep - 1)) + 'px)'} ]; } var slideBar = [ { transform: 'scaleX(' + ((boxWidth / 3) * (currentStep - 2)) + ')', transformOrigin: 'left' }, { transform: 'scaleX(' + ((boxWidth / 3) * (currentStep -1 )) + ')', transformOrigin: 'left' } ]; var showDot = [ {backgroundColor: 'darkred', border: '2px solid darkred' }, {backgroundColor: '#fff', border: '2px solid lightgrey' } ]; // putting the keyframes and timings together var movingDot = document.getElementById("progress__dot").animate( moveDot, dotTiming ); var slidingBar = document.getElementById("progress__fill").animate( slideBar, barTiming ); var passingDot = document.getElementById('circ__' + currentStep).animate( showDot, passedTiming ); // making the animation reverse movingDot.playbackRate = -1; slidingBar.playbackRate = -1; passingDot.playbackrate = -1; // starting the animation movingDot.play(); slidingBar.play(); movingDot.onfinish = passingDot; // decrementing and setting the step counter currentStep--; // set the current step number as the number in the progress dot on the page document.getElementById("progress__dot").innerHTML = currentStep; if (currentStep < 4) { document.getElementById('next').classList.add('is-active'); } if (currentStep < 2) { document.getElementById('back').classList.remove('is-active'); } // toggling the bold class for the step names document.getElementsByClassName('tab-' + (currentStep + 1))[0].classList.remove('bold'); setTimeout(() => { document.getElementsByClassName('tab-' + currentStep)[0].classList.add('bold'); }, 400); }); I expect the dot and the slider to be aligned as they go across the page, regardless of zoom percentage
In doing some experimenting, I figured out that I could just use "width" to transform the item rather than scaleX. Here is what I ended up using: next button event: var slideBar = [ { width: ((boxWidth / 3) * (currentStep - 1)) + 'px' }, { width: ((boxWidth / 3) * (currentStep)) + 'px' } ]; back button event: var slideBar = [ { width: ((boxWidth / 3) * (currentStep - 2)) + 'px' }, { width: ((boxWidth / 3) * (currentStep -1 )) + 'px' } ];
Single page scroll with jQuery
I am struggling to create a web page where there are 2 sections. The first section is the complete website except for the menu. The second section should be the menu displayed on full screen. The user should be able to scroll with a nice effect between the two sections. Here is a code pen example: HTML: <!DOCTYPE html> <html> <head> <style> /* SCROLL BEGIN */ a.back-to-top { display: none; width: 100px; height: 100px; text-indent: -9999px; position: fixed; z-index: 999; top: 85%; left: 45%; background: url("http://www.cleanmyride.ca/wp-content/uploads/2015/01/Down-Arrow.png"); -webkit-border-radius: 30px; -moz-border-radius: 30px; border-radius: 30px; } /* SCROLL END*/ </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"> </script> <link href="https://fonts.googleapis.com/css?family=Bree+Serif" rel="stylesheet"> <link href="test.css" rel="stylesheet"> <title>Pandaniell</title> </head> <body> <a class="back-to-top" href="#">Back To Top</a> <!-- SCROLL BEGIN --> <script> var amountScrolled = 4800; $('a.back-to-top').fadeIn('slow'); $(window).scroll(function () { if ($(window).scrollTop() < amountScrolled) { $('a.back-to-top').fadeIn('slow'); } else { $('a.back-to-top').fadeOut('slow'); } }); $('a.back-to-top').click(function () { $('html, body').animate({ scrollTop: 10000 }, 1000); return false; }); </script> <!-- SCROLL END --> <div class="container"></div> <nav> <ul> <li> HOME </li> <li> ABOUT </li> <li> WHERE </li> <li> CONTACT </li> <li style="float:right"> PORTFOLIO </li> </ul> </nav> <div id="gradient"></div> <script> // target to give background to var $div = document.getElementById("gradient"); // rgb vals of the gradients var gradients = [{ start: [128, 179, 171], stop: [30, 41, 58] }, { start: [255, 207, 160], stop: [234, 92, 68] }, { start: [212, 121, 121], stop: [130, 105, 151] } ]; // how long for each transition var transition_time = 4; // internal type vars var currentIndex = 0; // where we are in the gradients array var nextIndex = 1; // what index of the gradients array is next var steps_count = 0; // steps counter var steps_total = Math.round(transition_time * 60); // total amount of steps var rgb_steps = { start: [0, 0, 0], stop: [0, 0, 0] }; // how much to alter each rgb value var rgb_values = { start: [0, 0, 0], stop: [0, 0, 0] }; // the current rgb values, gets altered by rgb steps on each interval var prefixes = ["-webkit-", "-moz-", "-o-", "-ms-", ""]; // for looping through adding styles var div_style = $div.style; // short cut to actually adding styles var color1, color2; // sets next current and next index of gradients array function set_next(num) { return (num + 1 < gradients.length) ? num + 1 : 0; } // work out how big each rgb step is function calc_step_size(a, b) { return (a - b) / steps_total; } // populate the rgb_values and rgb_steps objects function calc_steps() { for (var key in rgb_values) { if (rgb_values.hasOwnProperty(key)) { for (var i = 0; i < 3; i++) { rgb_values[key][i] = gradients[currentIndex][key][i]; rgb_steps[key][i] = calc_step_size(gradients[nextIndex][key][i], rgb_values[key][i]); } } } } // update current rgb vals, update DOM element with new CSS background function updateGradient() { // update the current rgb vals for (var key in rgb_values) { if (rgb_values.hasOwnProperty(key)) { for (var i = 0; i < 3; i++) { rgb_values[key][i] += rgb_steps[key][i]; } } } // generate CSS rgb values var t_color1 = "rgb(" + (rgb_values.start[0] | 0) + "," + (rgb_values.start[ 1] | 0) + "," + (rgb_values.start[2] | 0) + ")"; var t_color2 = "rgb(" + (rgb_values.stop[0] | 0) + "," + (rgb_values.stop[ 1] | 0) + "," + (rgb_values.stop[2] | 0) + ")"; // has anything changed on this interation if (t_color1 != color1 || t_color2 != color2) { // update cols strings color1 = t_color1; color2 = t_color2; // update DOM element style attribute div_style.backgroundImage = "-webkit-gradient(linear, left bottom, right top, from(" + color1 + "), to(" + color2 + "))"; for (var i = 0; i < 4; i++) { div_style.backgroundImage = prefixes[i] + "linear-gradient(45deg, " + color1 + ", " + color2 + ")"; } } // we did another step steps_count++; // did we do too many steps? if (steps_count > steps_total) { // reset steps count steps_count = 0; // set new indexs currentIndex = set_next(currentIndex); nextIndex = set_next(nextIndex); // calc steps calc_steps(); } if (div_style.backgroundImage.indexOf("gradient") != -1) { window.requestAnimationFrame(updateGradient) } } // initial step calc calc_steps(); // go go go! window.requestAnimationFrame(updateGradient); </script> <h1>Dit is mijn website</h1> <h2><img alt="Instagram" border="0" class="instagram" height="50" src="https://image.ibb.co/nHgkKQ/Instagram.png" width="50"></h2> <h3><img alt="Facebook" border="0" class="facebook" height="50" src="https://image.ibb.co/bLf7zQ/Facebook.png" width="50"></h3> <h4><a href="https://www.dropbox.com/sh/omjvrdt5b3a5x6m/AACYBA_EKBeNzAK1YVQmTtH7a?dl=0" target="_blank"><img alt="Dropbox" border="0" class="dropbox" height="50" src="https://image.ibb.co/i2fUDk/Dropbox.png" width="50"></a></h4> <script> document.addEventListener('DOMContentLoaded', function (event) { // array with texts to type in typewriter var dataText = ["Welkom op mijn website! dit is een voorbeeld tekst"]; // type one text in the typwriter // keeps calling itself until the text is finished function typeWriter(text, i, fnCallback) { // chekc if text isn't finished yet if (i < (text.length)) { // add next character to h1 document.querySelector("h1").innerHTML = text.substring(0, i + 1) + '<span aria-hidden="true"><\/span>'; // wait for a while and call this function again for next character setTimeout(function () { typeWriter(text, i + 1, fnCallback) }, 100); } // text finished, call callback if there is a callback function else if (typeof fnCallback == 'function') { // call callback after timeout setTimeout(fnCallback, 700); } } // start a typewriter animation for a text in the dataText array function StartTextAnimation(i) { if (typeof dataText[i] == 'undefined') { setTimeout(function () { StartTextAnimation(0); }, 20000); } // check if dataText[i] exists if (i < dataText[i].length) { // text exists! start typewriter animation typeWriter(dataText[i], 0, function () { // after callback (and whole text has been animated), start next text StartTextAnimation(i + 1); }); } } // start the text animation StartTextAnimation(0); }); </script> </body> </html> CSS: .instagram { margin: auto; position: absolute; top: -20 % % ; left: 5 % ; bottom: 5 % ; right: 8 % ; } .facebook { margin: auto; position: absolute; top: -20 % % ; left: 5 % ; bottom: 5 % ; right: 16 % ; } .dropbox { margin: auto; position: absolute; top: -20 % % ; left: 5 % ; bottom: 5 % ; right: 0 % ; } .container { width: 95 % ; margin - left: auto; margin - right: auto; height: 1000 px; } /* Navigation */ nav { width: 100 % ; height: 6.5 % ; background - color: rgba(255, 255, 255, 0.13); } ul li { list - style - type: none; float: left; color: #FFFFFF; font - size: 16 px; text - align: left; margin - right: 25 px; margin - top: 25 px; letter - spacing: 2 px; font - weight: bold; } ul li a { color: #FFFFFF; text - decoration: none; visibility: visible; opacity: 1; transition: 0.2 s ease; } ul li: hover a { color: #1115B4; visibility: visible; opacity: 1; } # gradient { position: absolute; left: 0; top: 0; right: 0; bottom: 0; background: #836997; } h1 { width: 50%; font-family: 'Bree Serif', serif; font-size: 80px; color: white; margin: auto; position: absolute; top: 30%; left: 5%; bottom: 5%; right: 5%; } body { font-family: arial; background-color: rgb(0, 0, 0); margin-top: 0px; margin-right: 0px; margin-bottom: 100px; margin-left: 0px; font-style: normal; font-weight: 200; height: 100%; {