How to fade background images - javascript

UPDATE:THIS WORKS ON CHROME, HOW CAN I GET THIS TO WORK ON FIREFOX
I am trying to fade consecutive background images when I hover over a specific element. For example, if I have three text elements, and if I hover over one, I would like the background image to change with a transitional effect.
Here is my codepen: https://codepen.io/tmocodes/pen/MWwXxZO?editors=0110
Here is my inspiration source: https://www.awwwards.com/inspiration/fullscreen-menu-66nord
let seattleEl = document.querySelector("#Seattle");
let ecuadorEl = document.querySelector("#Ecuador");
let arizonaEl = document.querySelector("#Arizona");
let imgArea = document.querySelector(".container");
ecuadorEl.addEventListener("mouseover", e => {
imgArea.style.background = "url('https://www.telegraph.co.uk/content/dam/Travel/2019/November/ecuador.jpg')";
imgArea.classList.add = 'bg'
});
seattleEl.addEventListener("mouseover", e => {
imgArea.style.background =
"url('https://cdn.vox-cdn.com/thumbor/avHeJenMsyJoJ3WBGHl24QWnybk=/0x0:7360x4912/1200x675/filters:focal(3092x1868:4268x3044)/cdn.vox-cdn.com/uploads/chorus_image/image/66498601/shutterstock_482690140.0.jpg')";
imgArea.classList.add = 'bg'
});
*{
padding:0;
margin:0;
box-sizing:border-box
}
.container{
background: url("https://www.telegraph.co.uk/content/dam/Travel/2019/November/ecuador.jpg");
background-size: cover !important;
background-repeat: no-repeat !important;
background-position: center !important;
height:100vh;
transition: all .3s;
h1{
color:white;
opacity: .6;
font-family: Helvetica;
font-size: 48px;
padding: 10px;
cursor:pointer;
display:block;
width:min-content;
height:min-content;
margin-bottom:10px;
&:hover{
opacity:1;
}
}
}
#keyframes transition {
from {
opacity:0
}
to {
opacity:1
}
}
.bg{
background-color: black;
z-index:10;
animation: transition .3s !important;
transition: all .2s;
}
<div class="container">
<h1 id="Ecuador">Ecuador</h1>
<h1 id="Seattle">Seattle</h1>
<h1 id="Arizona">Arizona</h1>
</div>

Maybe this will help?
//<![CDATA[
/* js/external.js */
let get, post, doc, html, bod, nav, M, I, mobile, S, Q, hC, aC, rC, tC, inArray, isNum, isInt; // for use on other loads
addEventListener('load', ()=>{
get = (url, success)=>{
const x = new XMLHttpRequest;
x.open('GET', url);
x.onload = ()=>{
if(success)success(JSON.parse(x.responseText));
}
x.send();
return x;
}
post = (url, send, success)=>{
const x = new XMLHttpRequest;
x.open('POST', url);
x.onload = ()=>{
if(success)success(JSON.parse(x.responseText));
}
if(typeof send === 'object' && send && !(send instanceof Array)){
if(typeof FormData !== 'undefined' && send instanceof FormData){
x.send(send);
}
else{
let s, r = [];
for(let p in send){
s = send[p];
if(typeof s === 'object')s = JSON.stringify(s);
r.push(encodeURIComponent(p)+'='+encodeURIComponent(s));
}
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); x.send(r.join('&'));
}
}
else{
throw new Error('send argument must be an Object');
}
return x;
}
doc = document; html = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
S = (selector, within)=>{
const w = within || doc;
return w.querySelector(selector);
}
Q = (selector, within)=>{
const w = within || doc;
return w.querySelectorAll(selector);
}
hC = (element, className)=>{
return element.classList.contains(className);
}
aC = (element, className, func)=>{
element.classList.add(className.trim());
if(func)func(element);
return (className, func)=>{
return aC(element, className, func);
}
}
rC = (element, className, func)=>{
element.classList.remove(className.trim());
if(func)func(element);
return (className, func)=>{
return rC(element, className, func);
}
}
tC = (element, className, yFunc, nFunc)=>{
const c = element.classList, n = className.trim();
if(c.contains(n)){
c.remove(n);
if(nFunc)nFunc(element);
}
else{
c.add(n);
if(yFunc)yFunc(element);
}
return (className, yFunc, nFunc)=>{
return tC(element, className, yFunc, nFunc);
}
}
inArray = (mixed, array)=>{
if(array.indexOf(mixed) === -1){
return false;
}
return true;
}
isNum = mixed=>typeof mixed === 'number' && !isNaN(mixed); isInt = mixed=>Number.isInteger(mixed);
// put below on another page using a load Event - except the end load line and below
function FadeMaker(faderElement, placesElement){
const places = [];
let place;
this.addPlace = (name, background)=>{
const h = M('h1'), d = M('div');
aC(d, 'fadeOut'); d.style.backgroundImage = 'url("'+background+'")';
h.textContent = name;
h.onmouseenter = ()=>{
rC(place, 'fadeIn'); aC(place, 'fadeOut'); rC(d, 'fadeOut'); aC(d, 'fadeIn');
place = d;
}
placesElement.appendChild(h); faderElement.appendChild(d); places.push([h, d]);
return this;
}
this.make = ()=>{
place = places[0][1]; rC(place, 'fadeOut');
places.forEach(a=>{
aC(a[1], 'fade');
});
return this;
}
}
const fm = new FadeMaker(I('fader'), I('places'));
fm.addPlace('Equador', 'https://www.telegraph.co.uk/content/dam/Travel/2019/November/ecuador.jpg').addPlace('Seattle', 'https://cdn.vox-cdn.com/thumbor/avHeJenMsyJoJ3WBGHl24QWnybk=/0x0:7360x4912/1200x675/filters:focal(3092x1868:4268x3044)/cdn.vox-cdn.com/uploads/chorus_image/image/66498601/shutterstock_482690140.0.jpg').addPlace('Arizona', 'https://azgovernor.gov/sites/default/files/styles/panopoly_image_original/public/6871930-arizona.jpg?itok=sbFgZG8r').make();
}); // end load
//]]>
/* css/external.css */
*{
box-sizing:border-box; padding:0; margin:0;
}
html,body,.container,#fader,.fade{
width:100%; height:100%;
}
.container{
position:relative;
}
.container>div,.fade{
position:absolute;
}
.fade{
background-position:center; background-size:cover; transition:opacity 0.5s ease-in-out;
}
.hide{
display:none;
}
#places>h1{
cursor:pointer; color:#fff; font:bold 48px Helvetica; padding:10px 20px 10px;
}
.fadeOut{
opacity:0;
}
.fadeIn{
opacity:1;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
<title>Title Here</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script src='js/external.js'></script>
</head>
<body>
<div class='container'>
<div id='fader'></div>
<div id='places'></div>
</div>
</body>
</html>
You can ignore most of the JavaScript above FadeMaker... but use that stuff all the time in the future. Notice that FadeMaker takes two arguments. One where all the fader Elements go and one where the name Elements go. Once you create a new instance, you just fadeMakerInstance.addPlace(yourNameHere, yourURLHere), then .make() when your done. Note that you don't have to chain the methods like I show in the example. Once you have the instance variable you can just execute right off that like fm.addPlace(nameOne, urlOne); fm.addPlace(nameTwo, urlTwo); fm.make().

Related

How can I fix this photo gallery?

I created or tried to make a Photo Gallery on one of my web pages. It worked perfectly at first, but when the "Show more images" button is clicked, it changes the logo and doesn't show the other added images. (See pictures below). How can I avoid the logo changing and show the rest of the photos?
I really will appreciate if somebody can help me to find the error. Thanks!
Here's the html code:
<h1 class="headings1">ABOUT US</h1>
<article>
<div id="leftarrow">
<p><</p>
</div>
<figure id="fig2">
<img class="about" width="360" height="202" />
</figure>
<figure id="fig3">
<img class="about" width="480" height="270" />
</figure>
<figure id="fig4">
<img class="about" width="360" height="202" />
</figure>
<div id="rightarrow">
<p>></p>
</div>
<div id="fiveButton">
<p>Show more images</p>
</div>
</article>
Here's javascript code:
"use strict"; // interpret document contents in JavaScript strict mode
/* global variables */
var photoOrder = [1,2,3,4,5];
var figureCount = 3;
/* add src values to img elements based on order specified on photoOrder array */
function populateFigures() {
var filename;
var currentFig;
if (figureCount === 3){
for (var i = 1; i < 4; i++) {
filename = "images/about_0" + photoOrder[i] + "sm.jpg";
currentFig = document.getElementsByClassName("about") [i - 1];
currentFig.src = filename;
}
} else {
for (var i = 0; i < 5; i++) {
filename = "image/about_0" + photoOrder[i] + "sm.jpg";
currentFig = document.getElementsByClassName("about")[1];
currentFig.src = filename;
}
}
}
/* shift all images one figure to the left, and change values in photoOrder array to match */
function rightArrow() {
for (var i = 0; i < 5; i++) {
if ((photoOrder[i] + 1) === 6) {
photoOrder[i] = 1;
} else {
photoOrder[i] += 1;
}
populateFigures();
}
}
/* shift all images one figure to the right, and change values in photoOrder array to match */
function leftArrow() {
for (var i = 0; i < 5; i++) {
if ((photoOrder[i] - 1) === 0) {
photoOrder[i] = 5;
} else {
photoOrder[i] -= 1;
}
populateFigures();
}
}
/* switch to 5-images */
function previewFive() {
//create figure and img elements for fifth image
var articleEl = document.getElementsByTagName("article")[0];
var lastFigure = document.createElement("figure");
lastFigure.id = "fig5";
lastFigure.style.zIndex = "5";
lastFigure.style.position = "absolute";
lastFigure.style.right = "45px"
lastFigure.style.top = "67px";
var lastImage = document.createElement("img");
lastImage.classList = "about";
lastImage.width = "240";
lastImage.height = "135"
lastFigure.appendChild(lastImage);
// articleEl.appendChild(lastFigure);
articleEl.insertBefore(lastFigure, document.getElementById("rightarrow"));
//clone figure element for fifth image and edit to be first image
var firstFigure = lastFigure.cloneNode(true);
firstFigure.id = "fig1";
firstFigure.style.right = "";
firstFigure.style.left = "45px";
// articleEl.appendChild(firstFigure);
articleEl.insertBefore(firstFigure, document.getElementById("fig2"));
//add appropiate src values to two img elements
document.getElementsByTagName("img")[0].src = "images/about_0" + photoOrder[0] + "sm.jpg";
document.getElementsByTagName("img")[4].src = "images/about_0" + photoOrder[4] + "sm.jpg";
figureCount = 5;
//change button to hide extra images
var numberButton = document.querySelector("#fiveButton p");
numberButton.innerHTML = "Show fewer images";
if (numberButton.addEventListener) {
numberButton.removeEventListener("click", previewFive, false);
numberButton.addEventListener("click", previewThree, false);
} else if (numberButton.attachEvent) {
numberButton.detachEvent("onclick", previewFive);
numberButton.attachEvent("onclick", previewThree);
}
}
/* switch to 3-image layout */
function previewThree() {
var articleEl = document.getElementsByTagName("article") [0];
var numberButton = document.querySelector("#fiveButton p");
articleEl.removeChild(document.getElementById("fig1"));
articleEl.removeChild(document.getElementById("fig5"));
figureCount = 3;
numberButton.innerHTML = "Show more images";
if (numberButton.addEventListener) {
numberButton.removeEventListener("click", previewThree, false);
numberButton.addEventListener("click", previewFive, false);
} else if (numberButton.attachEvent) {
numberButton.detachEvent("onclick", previewThree);
numberButton.attachEvent("onclick", previewFive);
}
}
/* Create event listener for left arrow, right arrow and center figure element */
function createEventListeners() {
var leftarrow = document.getElementById("leftarrow");
if (leftarrow.addEventListener) {
leftarrow.addEventListener("click", leftArrow, false);
} else if (leftarrow.attachEvent) {
leftarrow.attachEvent("onclick", leftArrow);
}
var rightarrow = document.getElementById("rightarrow");
if (rightarrow.addEventListener) {
rightarrow.addEventListener("click", rightArrow, false);
}else if (rightarrow.attachEvent) {
rightarrow.attachEvent("onclick", rightArrow);
}
var mainFig = document.getElementsByTagName("img")[1];
if (mainFig.addEventListener) {
mainFig.addEventListener("click", zoomFig, false);
} else if (mainFig.attachEvent) {
mainFig.attachEvent("onclick", zoomFig);
}
var showAllButton = document.querySelector("#fiveButton p");
if (showAllButton.addEventListener) {
showAllButton.addEventListener("click", previewFive, false);
}else if (showAllButton.attachEvent) {
showAllButton.attachEvent("onclick", previewFive);
}
}
/* open center figure in separate window */
function zoomFig() {
var propertyWidth = 960;
var propertyHeight = 600;
var winLeft = ((screen.width - propertyWidth) / 2);
var winTop = ((screen.height - propertyHeight) / 2);
var winOptions = "width = 960, height = 600";
winOptions += ",left=" + winLeft;
winOptions += ",top=" + winTop;
var zoomWindow = window.open("zoom.html", "zoomwin", winOptions);
zoomWindow.focus();
}
/* create event listeners and populate image elements */
function setUpPage() {
createEventListeners();
populateFigures();
}
/* run setUpPage() function when page finishes loading */
if (window.addEventListener) {
window.addEventListener("load", setUpPage, false);
} else if (window.attachEvent) {
window.attachEvent("onload", setUpPage);
}
I have included a tiny library with a constructor called ImgViewer. Admittedly, if you resize the screen vertically, it can be a slight issue, but it's all the time I'm willing to take right now. Hopefully you can learn something from this.
//<![CDATA[
/* js/external.js */
let doc, htm, bod, nav, M, I, mobile, S, Q, hC, aC, rC, tC, ImgViewer; // for use on other loads
addEventListener('load', ()=>{
doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id); mobile = /Mobi/i.test(nav.userAgent);
S = (selector, within)=>{
let w = within || doc;
return w.querySelector(selector);
}
Q = (selector, within)=>{
let w = within || doc;
return w.querySelectorAll(selector);
}
hC = (node, className)=>{
return node.classList.contains(className);
}
aC = (node, ...classNames)=>{
node.classList.add(...classNames);
return aC;
}
rC = (node, ...classNames)=>{
node.classList.remove(...classNames);
return rC;
}
tC = (node, className)=>{
node.classList.toggle(className);
return tC;
}
ImgViewer = function(imgArray, imgsWide = 3){
if(imgsWide % 2 === 0){
throw new Error('imgsWide must be odd number');
}
this.container = M('div'); this.leftArrow = M('div'); this.view = M('div');
this.rightArrow = M('div'); this.container.className = 'imgViewer';
this.view.className = 'view';
this.leftArrow.className = this.rightArrow.className = 'arrow';
this.leftArrow.textContent = '<'; this.rightArrow.textContent = '>';
this.container.appendChild(this.leftArrow); this.container.appendChild(this.view); this.container.appendChild(this.rightArrow);
const center = Math.floor(imgsWide/2), iA = [], imA = imgArray.slice();
this.size = ()=>{
const b = this.view.getBoundingClientRect(), w = b.width/imgsWide-40;
for(let i=0,l=iA.length; i<l; i++){
iA[i].width = i === center ? w+50 : w;
}
return this;
}
this.create = (where = bod)=>{ // default document.body
where.appendChild(this.container);
const v = this.view, b = v.getBoundingClientRect(), w = b.width/imgsWide-40;
for(let i=0,m,l=imgArray.length; i<l; i++){
m = M('img');
m.width = i === center ? w+50 : w;
m.src = imgArray[i]; iA.push(m); // cache all the images
if(i < imgsWide){
if(i === center){
// add a click event to center if you want - I did not
}
else if(i < center){
m.onclick = ()=>{
for(let n=i; n<center; n++){
this.rightArrow.onclick();
}
}
}
else{
m.onclick = ()=>{
for(let n=i; n<imgsWide; n++){
this.leftArrow.onclick();
}
}
}
v.appendChild(m);
}
}
const c = v.children;
const dispImgs = ()=>{
for(let n=0; n<imgsWide; n++){
c[n].src = imA[n];
}
}
this.leftArrow.onclick = ()=>{
imA.push(imA.shift()); dispImgs();
}
this.rightArrow.onclick = ()=>{
imA.unshift(imA.pop()); dispImgs();
}
onresize = this.size;
return this;
}
}
// tiny library above - magic below can be put on another page using a load Event except `}); // end load` line
const imgURLs = [
'https://images.freeimages.com/images/large-previews/afa/black-jaguar-1402097.jpg',
'https://images.freeimages.com/images/large-previews/7e9/ladybird-1367182.jpg',
'https://images.freeimages.com/images/large-previews/535/natural-wonders-1400924.jpg',
'https://images.freeimages.com/images/large-previews/035/young-golden-retriever-1404848.jpg',
'https://images.freeimages.com/images/large-previews/981/cow-1380252.jpg',
'https://images.freeimages.com/images/large-previews/9fc/yet-another-flower-1399208.jpg',
'https://images.freeimages.com/images/large-previews/72c/fox-1522156.jpg',
'https://images.freeimages.com/images/large-previews/e2a/boise-downtown-1387405.jpg',
'https://images.freeimages.com/images/large-previews/f37/cloudy-scotland-1392088.jpg'
];
const imgV = new ImgViewer(imgURLs);
imgV.create();
}); // end load
//]]>
/* css/external.css */
*{ /* size font individually to avoid font whitespace */
box-sizing:border-box; font-size:0; margin:0; padding:0; overflow:hidden;
}
html,body{
width:100%; height:100%;
} /* below is what you need to see - above is set for this example */
.imgViewer{
width:100%; height:100%;
}
.imgViewer,.imgViewer *{
display:flex; justify-content:center; align-items:center;
}
.imgViewer>.arrow{
cursor:pointer; width:32px; height:70px; background:#777; color:#fff; font:bold 14px san-serif;
}
.imgViewer>.view{
width:calc(100% - 32px); height:100%;
}
.imgViewer>.view>img{
cursor:pointer; margin:0 7px; box-shadow:1px 1px 2px;
}
.imgViewer>.view>img:first-child{
margin-left:0;
}
.imgViewer>.view>img:last-child{
margin-right:0;
}
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
<title>ImgViewer</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script src='js/external.js'></script>
</head>
<body>
</body>
</html>
Of course, I didn't make the dummy window for zooming, but you can ask another question for that!

How to make each square (div) fall down (like gravity) after it is created

inside the squareGenerator() function I create a yellow square every 1000 milliseconds. But I want each square to fall from the top of the screen to the very bottom, I want to do this in the fallingFunction(), something like what you would see in the "Guitar Hero" video game, where the notes fall down. Thank you.
//Square Generation
var allSquares = [];
var idGenerated = 0;
function squareGenerator() {
var newSquare = $(document.createElement("div"));
newSquare.css({
"background-color": "yellow",
"height": "200px",
"width": "200px",
"position": "absolute"
});
newSquare.attr('id', idGenerated);
idGenerated++;
allSquares.push(newSquare);
$('.father').append(newSquare);
}
var squareGenerationInterval = setInterval(squareGenerator, 1000);
//Square Falling
function fallingFunction() {
$("#" + idGenerated).css({"margin-top": "100px",});
}
var squareGenerationInterval = setInterval(fallingFunction, 1000);
body {
padding: 0;
margin: 0;
}
.father {
width: 100%;
height: 1000px;
background-color: lightblue;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>NovaNote</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="father">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="function.js" charset="utf-8"></script>
</body>
</html>
This is easy, you can use JQuery Animate. Although the code does need to be customized in other places in order to work.
First, let's add a parameter to fallingFunction which is square.
function fallingFunction(square) {
square.animate(
// Styles
{"margin-top": "100px"},
// Speed in miliseconds
5000);
}
This basically just animates the margin-top to 100px.
Second, remove the interval that calls fallingFunction.
So delete var squareGenerationInterval = setInterval(fallingFunction, 1000);.
Now you'll have to edit your square ids because #0 is not accepted, try something like #square0.
newSquare.attr('id', 'square' + idGenerated);
And Finnaly, you can call fallingFunction after $('.father').append(newSquare); passing in the newSquare object. Call it like this: fallingFunction(newSquare);.
So this is how your code should look like:
//Square Generation
var allSquares = [];
var idGenerated = 0;
function squareGenerator() {
var newSquare = $(document.createElement("div"));
newSquare.css({
"background-color": "yellow",
"height": "200px",
"width": "200px",
"position": "absolute"
});
newSquare.attr('id', 'square' + idGenerated);
idGenerated++;
allSquares.push(newSquare);
$('.father').append(newSquare);
fallingFunction(newSquare);
}
var squareGenerationInterval = setInterval(squareGenerator, 1000);
//Square Falling
function fallingFunction(sqaure) {
sqaure.animate(
// Styles
{"margin-top": "100px"},
// Speed in miliseconds
5000);
}
body {
padding: 0;
margin: 0;
}
.father {
width: 100%;
height: 1000px;
background-color: lightblue;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>NovaNote</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="father">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="function.js" charset="utf-8"></script>
</body>
</html>
I used CSS keyframes and some additional CSS to achieve this.
//Square Generation
var allSquares = [];
var idGenerated = 0;
function squareGenerator() {
// if (idGenerated < 5) return false;
var newSquare = $(document.createElement("div"));
newSquare.css({
"background-color": idGenerated % 2 === 0 ? 'green' : 'blue',
"height": "200px",
"width": "200px",
"position": "absolute"
});
newSquare.attr('class', 'sq'); // add class
newSquare.attr('id', idGenerated);
idGenerated++;
allSquares.push(newSquare);
$('.father').append(newSquare);
}
var squareGenerationInterval = setInterval(squareGenerator, 1000);
// comment out not needed
//Square Falling
// function fallingFunction() {
// $("#" + idGenerated).css({"margin-top": "100px",});
// }
// var squareGenerationInterval = setInterval(fallingFunction, 1000);
body {
padding: 0;
margin: 0;
}
.father {
width: 100%;
height: 1000px;
background-color: lightblue;
}
#keyframes slidein {
from {
top: 0;
}
to {
top: calc(100% - 200px);
}
}
div.sq {
animation-name: slidein;
animation-duration: 2s;
animation-iteration-count: 1;
top: calc(100% - 200px);
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>NovaNote</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="father">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="function.js" charset="utf-8"></script>
</body>
</html>
http://jsfiddle.net/apHLu/4/
Use this as your reference, Every time the text is clicked, the div falls down..
Keeping this as reference, use a setTimeout function for a few seconds ( may be 1-2 seconds ) on your sqaureGenerator() function and put fallingFunction() as a callback function running the Reference Code to make the objects fall
I would use transition. I wouldn't use jQuery these days, since it's now easy to do nearly anything just as easily with raw JavaScript. Including a small library for reuse, here's a full example of what your code might look like:
//<![CDATA[
/* js/external.js */
let get, post, doc, htm, bod, nav, M, I, mobile, beacon, S, Q, hC, aC, rC, tC, shuffle, rand, DropBox;
addEventListener('load', ()=>{
get = (url, func, responseType = 'json', context = null)=>{
const x = new XMLHttpRequest;
const c = context || x;
x.open('GET', url); x.responseType = responseType;
x.onload = ()=>{
if(func)func.call(c, x.response);
}
x.onerror = e=>{
if(func)func.call(c, {xhrErrorEvent:e});
}
x.send();
return x;
}
post = function(url, send, func, responseType ='json', context = null){
const x = new XMLHttpRequest;
if(typeof send === 'object' && send && !(send instanceof Array)){
const c = context || x;
x.open('POST', url); x.responseType = responseType;
x.onload = ()=>{
if(func)func.call(c, x.response);
}
x.onerror = e=>{
if(func)func.call(c, {xhrErrorEvent:e});
}
let d;
if(send instanceof FormData){
d = send;
}
else{
let s;
d = new FormData;
for(let k in send){
s = send[k];
if(typeof s === 'object' && s)s = JSON.stringify(s);
d.append(k, s);
}
}
x.send(d);
}
else{
throw new Error('send argument must be an Object');
}
return x;
}
doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
beacon = function(url, send){
let r = false;
if(typeof send === 'object' && send && !(send instanceof Array)){
let d;
if(send instanceof FormData){
d = send;
}
else{
let s;
d = new FormData;
for(let k in send){
s = send[k];
if(typeof s === 'object' && s)s = JSON.stringify(s);
d.append(k, s);
}
}
r = nav.sendBeacon(url, d);
}
else{
throw new Error('send argument must be an Object');
}
return r;
}
S = (selector, within)=>{
let w = within || doc;
return w.querySelector(selector);
}
Q = (selector, within)=>{
let w = within || doc;
return w.querySelectorAll(selector);
}
hC = function(node, className){
return node.classList.contains(className);
}
aC = function(){
const a = [].slice.call(arguments), n = a.shift();
n.classList.add(...a);
return aC;
}
rC = function(){
const a = [].slice.call(arguments), n = a.shift();
n.classList.remove(...a);
return rC;
}
tC = function(){
const a = [].slice.call(arguments), n = a.shift();
n.classList.toggle(...a);
return tC;
}
shuffle = array=>{
let a = array.slice(), i = a.length, n, h;
while(i){
n = Math.floor(Math.random()*i--); h = a[i]; a[i] = a[n]; a[n] = h;
}
return a;
}
rand = (min, max)=>{
let mn = min, mx = max;
if(mx === undefined){
mx = mn; mn = 0;
}
return mn+Math.floor(Math.random()*(mx-mn+1));
}
DropBox = function(width, height, backgroundColor){
this.box = M('div');
let bs = this.box.style, w, h;
w = isNaN(width) ? width : width+'px';
h = isNaN(height) ? height : height+'px';
bs.width = w; bs.height = h; bs.position = 'absolute';
bs.backgroundColor = backgroundColor;
this.setPosition = (left = 0, top = 0)=>{
bs.left = isNaN(left) ? left : left+'px';
bs.top = isNaN(top) ? top : top+'px';
return this;
}
this.setPosition();
this.moveTo = (left = null, top = null, transition = 'left 1s ease-in-out, top 1s ease-in-out')=>{
let l = isNaN(left) || left === null ? left : left+'px';
let t = isNaN(top) || top === null ? top : top+'px';
bs.transition = transition;;
if(l === null && t === null){
bs.top = 'calc(100% - '+h+')';
}
else{
bs.left = l; bs.top = t;
}
return this;
}
}
// magic happens under here
const stage = I('stage'), yellow = new DropBox(50, 50, '#cc0');
const red = new DropBox('20px', '30', '#c00'), blue = new DropBox(25, 25, '#00c');
yellow.setPosition(50, 100); red.setPosition('calc(50% - 10px)');
stage.appendChild(yellow.box); stage.appendChild(red.box);
stage.appendChild(blue.box);
setTimeout(()=>{
red.moveTo(50, 100);
setTimeout(()=>{
yellow.moveTo();
setTimeout(()=>{
blue.moveTo();
}, 250);
}, 1000);
}, 500);
}); // end load
/* css/external.css */
*{
box-sizing:border-box; font:22px Tahoma, Geneva, sans-serif; color:#000; padding:0; margin:0; overflow:hidden;
}
html,body,#stage{
width:100%; height:100%;
}
#stage{
position:relative; background:#add8e6; overflow-y:auto;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
<title>Title Here</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script src='js/external.js'></script>
</head>
<body>
<div id='stage'></div>
</body>
</html>
You can start reading the JavaScript at // magic happens under here. Of course, the code uses the DropBox constructor that I've made for your reuse. By the way, if you require more versatility I would do animations with canvas.

Draw a black point at a specific position in an image

I have a function that gets me the coordinates of the position of an image when you click on it. What I want to achieve is that when I click on the image draw a point in that same position as shown in the image:
this is my code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://t1.up.ltmcdn.com/es/images/2/6/6/img_organos_internos_del_cuerpo_humano_lista_completa_1662_600.jpg" height="500" width="500" alt="dragon">
<script>
$(document).ready(function() {
$("img").on("click", function(event) {
var x = event.pageX - this.offsetLeft;
var y = event.pageY - this.offsetTop;
alert("X Coordinate: " + x + " Y Coordinate: " + y);
});
});
</script>
Just append an absolutely positioned element to the coordinates:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://t1.up.ltmcdn.com/es/images/2/6/6/img_organos_internos_del_cuerpo_humano_lista_completa_1662_600.jpg" height="500" width="500" alt="dragon">
<script>
$(document).ready(function() {
const size = 4;
$("img").on("click", function(event) {
var x = event.pageX - this.offsetLeft;
var y = event.pageY - this.offsetTop;
$(this).parent().append(`<div style="width: ${size}px; height: ${size}px; background: black; position: absolute; top: ${y + size}px; left: ${x + size}px; border-radius: ${size}px"/>`);
});
});
</script>
I would use raw JavaScript. I don't have time to fully explain right now, but may later. Good Luck!
//<![CDATA[
/* js/external.js */
let get, post, doc, htm, bod, nav, M, I, mobile, S, Q, aC, rC, tC; // for use on other loads
addEventListener('load', ()=>{
get = (url, success, context)=>{
const x = new XMLHttpRequest;
const c = context || x;
x.open('GET', url);
x.onload = ()=>{
if(success)success.call(c, JSON.parse(x.responseText));
}
x.send();
}
post = function(url, send, success, context){
const x = new XMLHttpRequest;
const c = context || x;
x.open('POST', url);
x.onload = ()=>{
if(success)success.call(c, JSON.parse(x.responseText));
}
if(typeof send === 'object' && send && !(send instanceof Array)){
if(send instanceof FormData){
x.send(send);
}
else{
const fd = new FormData;
for(let k in send){
fd.append(k, JSON.stringify(send[k]));
}
x.send(fd);
}
}
else{
throw new Error('send argument must be an Object');
}
return x;
}
doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
S = (selector, within)=>{
var w = within || doc;
return w.querySelector(selector);
}
Q = (selector, within)=>{
var w = within || doc;
return w.querySelectorAll(selector);
}
aC = function(){
const a = [].slice.call(arguments), n = a.shift();
n.classList.add(...a);
return aC;
}
rC = function(){
const a = [].slice.call(arguments), n = a.shift();
n.classList.remove(...a);
return rC;
}
tC = function(){
const a = [].slice.call(arguments), n = a.shift();
n.classList.toggle(...a);
return tC;
}
// magic under here
const stage = I('stage'), human = I('human'), dot = M('div'), dotStyle = dot.style;
dot.id = 'dot';
let move = false;
function moveDot(e){
if(move === true){
let left = e.clientX, top = e.clientY;
if(!stage.contains(dot))stage.appendChild(dot);
dotStyle.left = left+'px'; dotStyle.top = top+'px';
}
}
if(mobile){
human.ontouchstart = (e)=>{
move = true; moveDot(e);
}
human.ontouchmove = moveDot;
human.ontouchend = ()=>{
move = false;
}
}
else{
human.onmousedown = e=>{
move = true; e.preventDefault(); moveDot(e);
}
human.onmousemove = moveDot;
human.onmouseup = ()=>{
move = false;
}
}
}); // end load
/* css/external.css */
*{
box-sizing:border-box;
}
html,body{
width:100%; height:100%; padding:0; margin:0; background:#ccc;
}
.main,#stage{
width:100%; height:100%;
}
#stage{
position:relative; height:100%;
}
#stage>*{
position:absolute;
}
#human{
height:100%; margin:auto; top:0; right:0; bottom;0; left:0;
}
#dot{
border:1px solid #009; border-radius:50%;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
<title>Title Here</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script src='js/external.js'></script>
</head>
<body>
<div class='main'>
<div id='stage'>
<img id='human' src='https://t1.up.ltmcdn.com/es/images/2/6/6/img_organos_internos_del_cuerpo_humano_lista_completa_1662_600.jpg' alt='dragon' />
</div>
</div>
</body>
</html>

textarea undo & redo button using only plain JavaScript

I understand that Chrome has built in CTRL Z and Y for Undo and Redo function. But is it possible for the Undo/Redo button to work on textarea using plain JavaScript?
I found the code here (answered by Neil) helpful but it needs jQuery:
How do I make undo/redo in <textarea> to react on 1 word at a time, word by word or character by character?
Here is a StateMaker I made. It is used for undo, redo, and save. It's quite simple. It works fine.
The issue is that e.ctrlKey && e.key === 'z' and the like have strange behavior, when e.preventDefault() in Firefox, so I removed that part. The code below is admittedly imperfect, in that it writes over the last state if the words and states are the same length. But, if I didn't do that, it would have saved a state with every character, which is also doable. Another solution would be to save states based on time. I did not go that route for this example.
//<![CDATA[
/* external.js */
/* StateMaker created by Jason Raymond Buckley */
var doc, bod, I, StateMaker; // for use on other loads
addEventListener('load', function(){
doc = document; bod = doc.body;
I = function(id){
return doc.getElementById(id);
}
StateMaker = function(initialState){
var o = initialState;
if(o){
this.initialState = o; this.states = [o];
}
else{
this.states = [];
}
this.savedStates = []; this.canUndo = this.canRedo = false; this.undoneStates = [];
this.addState = function(state){
this.states.push(state); this.undoneStates = []; this.canUndo = true; this.canRedo = false;
return this;
}
this.undo = function(){
var sl = this.states.length;
if(this.initialState){
if(sl > 1){
this.undoneStates.push(this.states.pop()); this.canRedo = true;
if(this.states.length < 2){
this.canUndo = false;
}
}
else{
this.canUndo = false;
}
}
else if(sl > 0){
this.undoneStates.push(this.states.pop()); this.canRedo = true;
}
else{
this.canUndo = false;
}
return this;
}
this.redo = function(){
if(this.undoneStates.length > 0){
this.states.push(this.undoneStates.pop()); this.canUndo = true;
if(this.undoneStates.length < 1){
this.canRedo = false;
}
}
else{
this.canRedo = false;
}
return this;
}
this.save = function(){
this.savedStates = this.states.slice();
return this;
}
this.isSavedState = function(){ // test to see if current state in use is a saved state
if(JSON.stringify(this.states) !== JSON.stringify(this.savedStates)){
return false;
}
return true;
}
}
var text = I('text'), val, wordCount = 0, words = 0, stateMaker = new StateMaker, save = I('save');
text.onkeyup = function(e){
save.className = undefined; val = this.value.trim(); wordCount = val.split(/\s+/).length;
if(wordCount === words && stateMaker.states.length){
stateMaker.states[stateMaker.states.length-1] = val;
}
else{
stateMaker.addState(val); words = wordCount;
}
}
I('undo').onclick = function(){
stateMaker.undo(); val = text.value = (stateMaker.states[stateMaker.states.length-1] || '').trim();
text.focus();
save.className = stateMaker.isSavedState() ? 'saved' : undefined;
}
I('redo').onclick = function(){
stateMaker.redo(); val = text.value = (stateMaker.states[stateMaker.states.length-1] || '').trim();
text.focus();
save.className = stateMaker.isSavedState() ? 'saved' : undefined;
}
save.onclick = function(){
stateMaker.save(); text.focus(); this.className = 'saved';
}
}); // end load
//]]>
/* external.css */
*{
padding:0; margin:0; border:0; box-sizing:border-box;
}
html,body{
width:100%; height:100%; background:#aaa; color:#000;
}
input{
font:22px Tahoma, Geneva, sans-serif; padding:3px;
}
#text{
width:calc(100% - 20px); height:calc(100% - 70px); font:22px Tahoma, Geneva, sans-serif; padding:3px 5px; margin:10px;
}
#undoRedoSave{
text-align:right;
}
input[type=button]{
padding:0 7px; border-radius:5px; margin-right:10px; border:2px solid #ccc;
}
input[type=button].saved{
border:2px solid #700;
}
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1' />
<title>Test Template</title>
<link type='text/css' rel='stylesheet' href='external.css' />
<script type='text/javascript' src='external.js'></script>
</head>
<body>
<textarea id='text'></textarea>
<div id='undoRedoSave'>
<input id='undo' type='button' value='undo' />
<input id='redo' type='button' value='redo' />
<input id='save' type='button' value='save' />
</div>
</body>
</html>

How to link two if statements

I am learning JS and have created a carousel with a caption underneath.
How do I get the Prev/Next buttons to affect the caption as well as the image? I've tried combining the if statements in several ways but have failed miserably.
Relevant HTML:
<span id="prev" class="arrow">❮</span>
<div class="karussell" id="karussell">
<img class="karu" name="esislaid">
</div>
<span id="next" class="arrow">❯</span>
<div class="caption">
<h3 id="esikiri"></h3>
</div>
JS:
var p = 0;
var s = 0;
var esileht = [];
var aeg = 5000;
var kiri = [];
//Image List
esileht[0] = 'img/tooted/raamat/graafvanalinn2016.jpg';
esileht[1] = 'img/tooted/kaart/kaart_taskus_esipool.jpg';
esileht[2] = 'img/tooted/kaart/graafkaart_esikylg.jpg';
//Captions
kiri[0] = 'Raamat "Tallinn. Graafiline vanalinn"';
kiri[1] = 'Tallinna vanalinna graafiline kaart (suur formaat)';
kiri[2] = 'Tallinna vanalinna graafiline kaart (väike formaat)';
// Left and Right arrows
//Eelmine
function eelmine(){
if (p === 0){
p = esileht.length;
}
p = p - 1;
return esileht[p];
}
//Jargmine
function jargmine(){
p = p + 1;
p = p % esileht.length;
return esileht[p];
}
document.getElementById('prev').addEventListener('click', function (e){
document.querySelector('#karussell img').src = eelmine();
}
);
document.getElementById('next').addEventListener('click', function (e) {
document.querySelector('#karussell img').src = jargmine();
}
);
//Change Image
function changePilt (){
document.esislaid.src = esileht[p];
if(p < esileht.length -1){
p++;
} else {
p = 0;
}
setTimeout("changePilt()", aeg);
}
//Change Caption
function changeKiri(){
document.getElementById('esikiri').innerHTML = kiri[s];
if(s < kiri.length - 1){
s++;
}
else {
s = 0;
}
setTimeout('changeKiri()', aeg);
}
document.body.onload = function(){
changePilt();
changeKiri();
};
CSS, just in case:
.karussell {
position: relative;
width: 100%;
max-height: 600px;
overflow: hidden;
}
.arrow {
cursor: pointer;
position: absolute;
top: 40%;
width: auto;
color: #00A7E0;
padding: 16px;
font-weight: bold;
font-size: 18px;
border-radius: 3px;
transition: 0.6s ease;
}
#next {
right: 0;
}
#prev {
left: 0;
}
.arrow:hover {
background-color: rgba(0,0,0,0.8);
}
.caption {
text-align: center;
color: #00A7E0;
padding: 2px 16px;
}
.karu {
max-width: 75%;
animation-name: fade;
animation-duration: 2s;
}
#keyframes fade {
from {opacity: 0.4}
to {opacity: 1}
}
#media (max-width:767px){.karu{max-width: 95%;}}
I made a fiddle to try to illustrate (had to paste the js into the html tab to gt it to work for some reason): Fiddle
Really you just need to use the .innerHTML() feature and do exactly what you already have. Either create a eelmine2() function (or something like that) and call it again, grabbing the content from kiri[] or instead just return the p and use it in two places:
document.getElementById('prev').addEventListener('click', function (e){
document.querySelector('#karussell img').src = eelmine();
document.querySelector('#esikiri').innerHTML = eelmine2();
});
function eelmine2(){
if (p === 0){
p = kiri.length;
}
p = p - 1;
return kiri[p];
}
or
document.getElementById('prev').addEventListener('click', function (e){
var change = eelmine();
document.querySelector('#karussell img').src = esileht[change];
document.querySelector('#esikiri').innerHTML = kiri[change];
});
function eelmine(){
if (p === 0){
p = kiri.length;
}
p = p - 1;
return p;
}
This assumes your code is using the same global vars inside public functions that you have set up in your Fiddle. You should fix that to have variables passed into the functions before going live with all of this, but I'm not addressing that any further here.

Categories

Resources