In google maps Api for javaScript V3 , it's possible show dialog same as location dialog
Example:
When click some marker:
marker.addListener('click', function () {
// console.log(marcador['geo']);
mostrarInfoMarcas(marcador['user'], marcador['geo']);
});
Here is my solution,
I create the marker by OverlayView Object
So You can treat it as DIV and input the HTML content
function CustomMarker(latlng, map, args) {
this.latlng = latlng;
this.args = args;
this.setMap(map);
}
CustomMarker.prototype = new google.maps.OverlayView();
CustomMarker.prototype.draw = function() {
var self = this;
var div = this.div;
if (!div) {
div = this.div = document.createElement('div');
var style = '';
var content = '';
if (typeof(self.args.marker_style) !== 'undefined') {
style = self.args.marker_style;
div.className = 'iot-node-'+style;
}
if (typeof(self.args.marker_content) !== 'undefined') {
content = self.args.marker_content;
var a = document.createElement('a');
var cur = this.getPosition();
a.style.backgroundColor='blue';
a.style.color = 'white';
a.style.fontSize = "3em";
a.style.textAlign= "center";
a.innerHTML = (content=="-1"?"-":content);
var sub_div = document.createElement('div');
sub_div.style.paddingLeft = '2px';
var sub_info = self.args.marker_info;
sinfo = '<BR>'+sub_info.name+'<BR>'+
'<font size=2>'+sub_info.office+'</font>';
sub_div.innerHTML = sinfo;
sub_div.className = 'showme';
sub_div.style.lineHeight= "16px";
sub_div.style.backgroundColor = 'blue';
sub_div.style.color = 'white';
a.appendChild(sub_div);
div.appendChild(a);
if(style=='info') {
var span = document.createElement('span');
span.innerHTML = 'x';
google.maps.event.addDomListener(span, "click", function(event) {
});
//a.appendChild(span);
}
}
if (typeof(self.args.marker_style) !== 'undefined' && style!='') {
var cur = this.getPosition();
var me = this;
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
var point = this.getProjection().fromLatLngToDivPixel(this.getPosition());
if (point) {
if(style!='info') {
div.style.left = (point.x-20 ) + 'px';
div.style.top = (point.y-10) + 'px';
var my_info= null;
var sub = {latLng: cur, style: 'info', content: root_content.replace('[type]', style.toUpperCase()).replace('[address]', addr)};
my_info= create_node(map, sub);
nd.push(my_info);
} else {
div.style.left = (point.x - 35 ) + 'px';
div.style.top = (point.y - 60 ) + 'px';
}
}
}
}
};
CustomMarker.prototype.remove = function() {
if (this.div) {
this.div.parentNode.removeChild(this.div);
this.div = null;
}
this.setMap(null);
};
CustomMarker.prototype.getPosition = function() {
return this.latlng;
};
function create_node(map, node) {
return new CustomMarker(
node.latLng,
map,
{
marker_style: node.style,
marker_content: node.content,
marker_info: node.info
}
);
}
var map;
function initialize() {
var centerLat = 21.04731; //default lat
var centerLng = 105.792137; //default long
var cen = new google.maps.LatLng(centerLat, centerLng) ;
map = new google.maps.Map(document.getElementById('map'), {
zoom: 17,
center: cen,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
Draw();
}
var nd = [];
function Draw() {
var lastest_json='{"markers":[{"markerId":"1","name":"Marker1","info":"INFO1","lat":"21.04731","lon":"105.792137"}]}'
var json_dev = JSON.parse(lastest_json);
var markers = json_dev.markers;
for(var i=0; i<markers.length; i++)
{
var dev = markers[i];
var cen = new google.maps.LatLng(parseFloat(dev.lat), parseFloat(dev.lon));
var sub = {latLng: cen, style: 'info', info: dev, content: dev.markerId};
nd.push(create_node(map, sub));
}
}
google.maps.event.addDomListener(window, 'load',initialize);
.iot-node-ae, .iot-node-asn, .iot-node-adn, .iot-node-mn, .iot-node-in, .iot-node-info {
position: absolute;
list-style-type: none;
left: 20px;
top: 20px;
}
.iot-node-ae>a, .iot-node-asn>a, .iot-node-adn>a, .iot-node-mn>a, .iot-node-in>a, .iot-node-info>a {
position: relative;
z-index: 2;
display: block;
width: 20px;
height: 20px;
border-style: solid;
border-width: 2px;
border-color: #0079ff;
border-radius: 50%;
background: white;
text-align:left;
font-weight: bold;
padding-top:0px;
padding-left:0px;
padding-right:0px;
-webkit-transition: background-color 0.2s;
-moz-transition: background-color 0.2s;
-o-transition: background-color 0.2s;
transition: background-color 0.2s;
}
.iot-node-info>a {
width: 60px;
height: 35px;
position: relative;
border-radius: 0;
}
.iot-node-info>a>span {
position: absolute; top: 2px; right:2px;
cursor: pointer;
display:inline-block;
padding:2px 5px;
background:#ccc;
}
.iot-node-info>a>span::hover {
position: absolute; top: 2px; right:2px;
cursor: pointer;
display:inline-block;
padding:2px 5px;
background:#ccc;
}
.iot-node-info>a::before {
content:"";
position: absolute;
top: 100%;
left: 0;
width: 0;
height: 0;
border-left: 13px solid transparent;
border-right: 26px solid #0079ff;
border-bottom: 13px solid transparent;
}
.iot-node-info>a>div {
display:none;
}
.iot-node-info>a:hover > .showme{
width: 150px;
height: 70px;
background-color:white;
position:absolute;
top:-70px;
left:-45px;
border-width:2px;
border-color:#0079ff;
display:block;
}
.iot-node-ae::after, .iot-node-asn::after , .iot-node-adn::after , .iot-node-mn::after , .iot-node-in::after , .iot-node-info::after{
content: '';
position: absolute;
border-radius: 50%;
width: 100%;
height: 100%;
top: 0;
left: 0;
//animation: cd-pulse 2s infinite;
}
#keyframes cd-pulse
{
0% {box-shadow:0 0 0 0 #0079ff}
100%{box-shadow:0 0 0 20px rgba(255,150,44,0)}
}
/* AE */
.iot-node-ae{
}
.iot-node-ae>a{
background: #ff3300;
font-size:14px;
}
.iot-node-ae::after{
//animation: cd-pulse 2s infinite;
}
/* asn */
.iot-node-asn{
}
.iot-node-asn>a{
background: #cc9900;
}
.iot-node-asn::after{
//animation: cd-pulse 2s infinite;
}
/* adn */
.iot-node-adn{
}
.iot-node-adn>a{
background: #330099;
}
.iot-node-adn::after{
//animation: cd-pulse 2s infinite;
}
/* mn */
.iot-node-mn{
}
.iot-node-mn>a{
background: #669900;
}
.iot-node-mn::after{
//animation: cd-pulse 2s infinite;
}
/* IN */
.iot-node-in{
}
.iot-node-in>a{
background: #ff9900;
font-size:14px;
}
.iot-node-in::after{
//animation: cd-pulse 2s infinite;
}
<script src="http://maps.google.com/maps/api/js" type="text/javascript"></script>
<div id="map" style="width: 100%; height: 238px; "></div>
Related
I modified a code to upload an image with specific size and I'm here right now:
imageUploadPrepare();
function imageUploadPrepare() {
var $profileImgDiv = document.getElementById("profile-img-div"),
$profileImg = document.getElementById("profile-img"),
$changePhoto = document.getElementById("change-photo"),
$xPosition = document.getElementById("x-position"),
$yPosition = document.getElementById("y-position"),
$saveImg = document.getElementById("save-img"),
$loader = document.getElementById("loader"),
$cancelImg = document.getElementById("cancel-img"),
$profileImgInput = document
.getElementById("profile-img-input"),
$profileImgConfirm = document
.getElementById("profile-img-confirm"),
$error = document.getElementById("error");
var currentProfileImg = "",
profileImgDivW = getSizes($profileImgDiv).elW,
NewImgNatWidth = 0,
NewImgNatHeight = 0,
NewImgNatRatio = 0,
NewImgWidth = 0,
NewImgHeight = 0,
NewImgRatio = 0,
xCut = 0,
yCut = 0;
makeSquared($profileImgDiv);
$changePhoto.addEventListener("change", function() {
currentProfileImg = $profileImg.src;
showPreview(this, $profileImg);
$loader.style.width = "100%";
$profileImgInput.style.display = "none";
$profileImgConfirm.style.display = "flex";
$error.style.display = "none";
});
$xPosition.addEventListener("input", function() {
$profileImg.style.left = -this.value + "px";
xCut = this.value;
yCut = 0;
});
$yPosition.addEventListener("input", function() {
$profileImg.style.top = -this.value + "px";
yCut = this.value;
xCut = 0;
});
$saveImg.addEventListener("click", function() {
cropImg($profileImg);
resetAll(true);
});
$cancelImg.addEventListener("click", function() {
resetAll(false);
});
window.addEventListener("resize", function() {
makeSquared($profileImgDiv);
profileImgDivW = getSizes($profileImgDiv).elW;
});
function makeSquared(el) {
var elW = el.clientWidth;
el.style.height = (elW * 0.82) + "px";
}
function showPreview(input, el) {
var reader = new FileReader();
reader.readAsDataURL(input.files[0]);
if (input.files && input.files[0]) {
reader.onload = function(e) {
setTimeout(function() {
el.src = e.target.result;
}, 300);
var poll = setInterval(function() {
if (el.naturalWidth && el.src != currentProfileImg) {
clearInterval(poll);
setNewImgSizes(el);
setTimeout(function() {
$loader.style.width = "0%";
$profileImg.style.opacity = "1";
}, 250);
}
}, 100);
};
} else {
return;
}
}
function setNewImgSizes(el) {
if (getNatSizes(el).elR > 1) {
el.style.width = "auto";
el.style.height = "100%";
newImgWidth = getSizes(el).elW;
$xPosition.style.display = "block";
$yPosition.style.display = "none";
$xPosition.max = newImgWidth - profileImgDivW;
} else if (getNatSizes(el).elR < 1) {
el.style.width = "100%";
el.style.height = "auto";
newImgHeight = getSizes(el).elH;
$xPosition.style.display = "none";
$yPosition.style.display = "block";
$yPosition.max = newImgHeight - profileImgDivW;
} else if (getNatSizes(el).elR == 1) {
el.style.width = "100%";
el.style.height = "auto";
$xPosition.style.display = "none";
$yPosition.style.display = "none";
}
}
function getNatSizes(el) {
var elW = el.naturalWidth,
elH = el.naturalHeight,
elR = elW / elH;
return {
elW: elW,
elH: elH,
elR: elR
};
}
function getSizes(el) {
var elW = el.clientWidth,
elH = el.clientHeight,
elR = elW / elH;
return {
elW: elW,
elH: elH,
elR: elR
};
}
function cropImg(el) {
var natClientImgRatio = getNatSizes(el).elW / getSizes(el).elW;
(myCanvas = document.getElementById("croppedPhoto")),
(ctx = myCanvas.getContext("2d"));
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, 400, 487);
ctx.drawImage(
el,
xCut * natClientImgRatio,
yCut * natClientImgRatio,
profileImgDivW * natClientImgRatio,
profileImgDivW * natClientImgRatio,
0,
0,
400,
487
);
var newProfileImgUrl = myCanvas.toDataURL("image/jpeg");
$profileImg.src = newProfileImgUrl;
uploadImage(newProfileImgUrl);
function uploadImage(image) {
const dashboardProfileImage = document.getElementById('profile-img');
dashboardProfileImage.src = image;
downloadImage(image);
dashboardProfileImage.download = "output.png";
async function downloadImage(imageSrc) {
const image = await fetch(imageSrc)
const imageBlog = await image.blob()
const imageURL = URL.createObjectURL(imageBlog)
const link = document.createElement('a')
link.href = imageURL
link.download = 'image file name here'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
}
}
function resetAll(confirm) {
if (!confirm) {
$profileImg.src = currentProfileImg;
}
$changePhoto.value = "";
$profileImgInput.style.display = "block";
$profileImgConfirm.style.display = "none";
$profileImg.style.left = "0";
$profileImg.style.top = "0";
$profileImg.style.width = "100%";
$profileImg.style.height = "100%";
$xPosition.style.display = "none";
$yPosition.style.display = "none";
$xPosition.value = "0";
$yPosition.value = "0";
xCut = "0";
yCut = "0";
}
function checkMinSizes(el) {
if (getNatSizes(el).elW > 400 && getNatSizes(el).elH > 400) {
return true;
} else {
return false;
}
}
}
/*Profile image*/
.profile-photo-div{
position: relative;
margin: 0 auto 40px auto;
width: 320px;
height: auto;
overflow: hidden;
border-radius: 10px;
-webkit-transition: ease .3s;
-o-transition: ease .3s;
transition: ease .3s;
}
.profile-photo-div .profile-img-div{
display: block;
position: relative;
overflow: hidden;
}
.profile-photo-div #loader{
position: absolute;
top:0;
left: 0;
width: 0%;
height: 100%;
background-color: #00cccf;
z-index:10;
-webkit-transition: .3s;
-o-transition: .3s;
transition: .3s;
}
.profile-photo-div #profile-img{
position: absolute;
display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.profile-photo-div #change-photo{
display: none;
}
.profile-photo-div .profile-buttons-div{
position: relative;
display: block;
}
.profile-photo-div .button{
position: relative;
display: block;
font-family: helvetica, sans-serif;
font-size: 15px;
padding:15px;
text-align: center;
color: white;
background-color: #8f7cff;
cursor: pointer;
-webkit-transition: .5s;
-o-transition: .5s;
transition: .5s;
overflow: hidden;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.profile-photo-div .button:hover{
letter-spacing: 1px;
}
.profile-photo-div .button:after{
content: '';
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
width: 10px;
height: 10px;
background-color: rgba(255,255,255,0.4);
border-radius: 50%;
opacity: 0;
-webkit-transition: .9s;
-o-transition: .9s;
transition: .9s;
}
.profile-photo-div .button:hover:after{
-webkit-transform: scale(50);
-ms-transform: scale(50);
transform: scale(50);
opacity: 1;
}
.profile-photo-div .button.half{
width: 50%;
}
.profile-photo-div .green{
background-color: #15ae6b;
}
.profile-photo-div .red{
background-color: #ae0000;
}
.profile-photo-div #x-position{
position: absolute;
bottom: 5px;
left: 50%;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
display: none;
}
.profile-photo-div #y-position{
position: absolute;
right: -50px;
top: 50%;
-webkit-transform: translateY(-50%) rotate(90deg);
-ms-transform: translateY(-50%) rotate(90deg);
transform: translateY(-50%) rotate(90deg);
display: none;
}
.profile-photo-div canvas{
position: absolute;
top: -2000px;
left: -2000px;
z-index: -1;
}
.profile-photo-div .profile-img-confirm{
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
width: 100%;
}
.profile-photo-div .error{
font-family: Helvetica, sans-serif;
font-size: 13px;
color: red;
text-align:center;
display: none;
}
/*end of profile image*/
<div class="profile-photo-div" id="profile-photo-div">
<div class="profile-img-div" id="profile-img-div" style="height: 150px;">
<div id="loader"></div>
<img id="profile-img" src="/dashboard/img/default-user.png">
<input id="x-position" type="range" name="x-position" value="0" min="0">
<input id="y-position" type="range" name="y-position" value="0" min="0">
</div>
<div class="profile-buttons-div">
<div class="profile-img-input" id="profile-img-input">
<label class="button" id="change-photo-label" for="change-photo">UPLOAD PHOTO</label>
<input id="change-photo" name="change-photo" type="file" style="display: none;" accept="image/*">
</div>
<div class="profile-img-confirm" id="profile-img-confirm" style="display: none;">
<div class="button half green" id="save-img">
<i class="fa fa-check" aria-hidden="true"></i>
</div>
<div class="button half red" id="cancel-img">
<i class="fa fa-remove" aria-hidden="true"></i>
</div>
</div>
</div>
<div class="error" id="error">حداقل سایز مجاز 400×400</div>
<canvas id="croppedPhoto" width="400" height="400"></canvas>
</div>
The issue is so far the image is always cropped with fixed dimensions of 400 * 400 pixels !!
But I want to crop them at 454.138px * 306px and no matter how I modify the numbers I always get that 400* 400 fix size?!
How can fix this?
NOTE: Since Stack overflow snippet code is completely useless in order to test the code please use this Codepen:
https://codepen.io/pixy-dixy/pen/RwZGKBQ
Trying to use this beautiful Hexagon Text Roller I have faced a confusing issue.
Here is the code in CodePen.
And Here is the code:
const carouselData = [
{ phrase: 'we have a phrase 1', translation: 'this is the translation'},
{ phrase: 'we have a phrase 2', translation: 'this is the translation'},
{ phrase: 'we have a phrase 3', translation: 'this is the translation'},
{ phrase: 'we have a phrase 4', translation: 'this is the translation'},
{ phrase: 'we have a phrase 5', translation: 'this is the translation'},
{ phrase: 'we have a phrase 6', translation: 'this is the translation'},
//{ phrase: 'we have a phrase 7', translation: 'this is the translation'}, // this is 7th
//{ phrase: 'we have a phrase 8', translation: 'this is the translation'}, // this is 8th
];
renderCarousel();
var increment = 0;
var bdLen = 6;
var carousel = $('#carousel');
var _ua = navigator.userAgent.toLowerCase();
var TOUCHEVENT = {
touchstart: "touchstart",
touchmove: "touchmove",
touchend: "touchend",
isdesktop:_ua.indexOf('android')>-1 ||_ua.indexOf('linux')>-1 ||_ua.indexOf('mobile')>-1 ||_ua.indexOf('iphone')>-1 ||_ua.indexOf('ipad')>-1 ? false : true,
initTouchEvents: function () {
if (TOUCHEVENT.isdesktop) {
this.touchstart = "mousedown";
this.touchmove = "mousemove";
this.touchend = "mouseup";
}
},
};
$(document).ready(function(){
$('.btn').on('click', function(e) {
if($(this).hasClass('btn-next')) {
nextCarousel();
} else {
previousCarousel();
}
return false;
});
function nextCarousel() {
increment++;
var _state = (increment % bdLen) + 1;
_state = (_state < 1) ? (_state % bdLen + bdLen) : _state;
updateCarouselState(increment, _state);
}
function previousCarousel() {
increment--;
var _state = (increment % bdLen) + 1;
_state = (_state < 1) ? (_state % bdLen + bdLen) : _state;
updateCarouselState(increment, _state);
}
initTouchEventHandle();
})
/*document ready end----------*/
function updateCarouselState(_incrementId, _stateId) {
var preAngle = -(360/bdLen).toFixed(1);
carousel.css({
'-webkit-transform': 'rotateX(' + _incrementId * preAngle + 'deg)',
'-moz-transform': 'rotateX(' + _incrementId * preAngle + 'deg)',
'transform': 'rotateX(' + _incrementId * preAngle + 'deg)',
});
carousel.attr('data-state', _stateId );
}
function initTouchEventHandle(){
TOUCHEVENT.initTouchEvents();
var carouselCover = document.getElementById('cover');
carouselCover.addEventListener(TOUCHEVENT.touchstart, onTouchStartHandle, false);
carouselCover.addEventListener(TOUCHEVENT.touchmove, onTouchMoveHandle, false);
carouselCover.addEventListener(TOUCHEVENT.touchend, onTouchEndHandle,false);
carouselCover.addEventListener("touchcancel", onTouchEndHandle, false);
}
function onTouchStartHandle(e){
e.preventDefault();
// e.stopPropagation();
if(!TOUCHEVENT.startPos){TOUCHEVENT.startPos = {x: 0, y:0}};
if(!TOUCHEVENT.movePos){TOUCHEVENT.movePos = {x: 0, y:0}};
TOUCHEVENT.offsetY = 0;
TOUCHEVENT.coverTouch = true;
var touchobj = (e.changedTouches) ? e.changedTouches[0] : {};
TOUCHEVENT.startPos.x = touchobj.clientX || e.pageX;
TOUCHEVENT.startPos.y = touchobj.clientY || e.pageY; // clicked point
}
function onTouchMoveHandle(e){
e.preventDefault();
// e.stopPropagation();
if(!TOUCHEVENT.coverTouch) return;
var touchobj = (e.changedTouches) ? e.changedTouches[0] : {};
TOUCHEVENT.movePos.x = touchobj.clientX || e.pageX;
TOUCHEVENT.movePos.y = touchobj.clientY || e.pageY; // clicked point
var _offsetY = Math.floor((TOUCHEVENT.movePos.y - TOUCHEVENT.startPos.y)/25);
if(_offsetY != TOUCHEVENT.offsetY){
var _tgBtnEles = (_offsetY < TOUCHEVENT.offsetY ) ? $('.btn-prev') : $('.btn-next');
TOUCHEVENT.offsetY = _offsetY;
_tgBtnEles.trigger('click');
}
}
function onTouchEndHandle(e){
e.preventDefault();
// e.stopPropagation();
TOUCHEVENT.coverTouch =false;
}
var _carouselCover = document.getElementById('cover');
document.ontouchmove= function(e){
e.stopPropagation();
e.preventDefault();
// $('#fixed').html('touch move');
}
function renderCarousel() {
let render = '';
const carousel = document.getElementById('carousel');
for(let i = 0; i < 6; i++) {
render +=
`<figure>
<h1>${carouselData[i].phrase}</h1>
<h2>${carouselData[i].translation}</h2>
</figure>
`;
}
carousel.innerHTML = render;
}
body { background: #333; }
#carousel-wrapper,
#carousel figure {
height: 100px;
line-height: 100px;
}
#carousel-wrapper .btn{
position: absolute;
top: -45px;
line-height: 30px;
left: 50%;
background:gray;
color:white;
padding:5px;
transform:translate(-50%,0);
-webkit-transform:translate(-50%,0);
-moz-transform:translate(-50%,0);
}
#carousel-wrapper .btn-next{
bottom:-45px;
top:auto;
}
#carousel figure:nth-of-type(1) {-webkit-transform: rotateX(0deg) translateZ(86px); transform: rotateX(0deg) translateZ(86px);}
#carousel figure:nth-of-type(2) {-webkit-transform: rotateX(60deg) translateZ(86px); transform: rotateX(60deg) translateZ(86px);}
#carousel figure:nth-of-type(3) {-webkit-transform: rotateX(120deg) translateZ(86px); transform: rotateX(120deg) translateZ(86px);}
#carousel figure:nth-of-type(4) {-webkit-transform: rotateX(180deg) translateZ(86px); transform: rotateX(180deg) translateZ(86px);}
#carousel figure:nth-of-type(5) {-webkit-transform: rotateX(240deg) translateZ(86px); transform: rotateX(240deg) translateZ(86px);}
#carousel figure:nth-of-type(6) {-webkit-transform: rotateX(300deg) translateZ(86px); transform: rotateX(300deg) translateZ(86px);}
#carousel[data-state="1"] figure:nth-of-type(1),
#carousel[data-state="2"] figure:nth-of-type(2),
#carousel[data-state="3"] figure:nth-of-type(3),
#carousel[data-state="4"] figure:nth-of-type(4),
#carousel[data-state="5"] figure:nth-of-type(5),
#carousel[data-state="6"] figure:nth-of-type(6) { opacity: 1; background:rgba(180,180,180,1);}
#carousel-wrapper {
position: absolute;
top: 30%;
left: 25%;
width: 50%;
text-align: center;
perspective: 1100px;
padding: 20% 0;
}
#carousel {
width: 100%;
height: 100%;
position: absolute;
/*z-index: 100;*/
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
transition: all .6s;
height: 100px;
line-height: 100px;
}
#carousel figure {
display: block;
position: absolute;
width: 100%;
margin: 0;
font-size: 40px;
font-weight: bold;
background:rgba(180,180,180,.4);
color: black;
text-align: center;
opacity: .4;
transition: all .6s;
-webkit-transition: all .6s;
-moz-transition: all .6s;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
}
#carousel-wrapper .cover{
position: absolute;
width:100%;
height: 100%;
left:0;
top:0;
background:rgba(0,0,0,0);
/*z-index: 100;*/
}
#fixed{
position: absolute;
left:auto;
right: 0;
top: 0;
color: white;
}
#carousel figure h1 {
color: #ff0d4d;
font-size: 15px;
font-weight: bold;
height: 10px;
line-height: 10px;
margin: 0;
margin-top: 3%;
}
#carousel figure h2 {
color: white;
font-size: 10px;
height: 10px;
line-height: 10px;
margin: 0;
margin-top: 3%;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<div id="carousel-wrapper">
<div id="carousel" data-state="1" style="-webkit-transform: rotateX(0deg)">
<!-- <figure>Side 1</figure>
<figure>Side 2</figure>
<figure>Side 3</figure>
<figure>Side 4</figure>
<figure>Side 5</figure>
<figure>Side 6</figure> -->
</div>
<span class="cover" id = "cover"></span>
prev
next
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
As you see at the very beginning of the code I have this variable carouselData holding data to render the hexagon's content.
The hexagon has 6 faces. and the Css of the code tries to control those 6 faces But what if we want to render more than 6 contents inside these 6 faces?
I mean we still have 6 face in the hexagon but as user touches (the code supports touch) or clicks the next or prev buttons he/she can see the 7th and 8th content after the 6th face.. after the 8th one he/she will see the first face again...
Here are the things what need to be amended:
JS:
Change var bdLen = 6; to var bdLen = carouselData.length;
Change for(let i = 0; i < 6; i++) { to for(let i = 0; i < carouselData.length; i++) { inside function renderCarousel()
CSS:
Removed all rules for #carousel figure:nth-of-type(x), they are now set in js
Left #carousel[data-state="x"] figure:nth-of-type(x) only for the first element, others will be updated from js
const carouselData = [{
phrase: 'we have a phrase 1',
translation: 'this is the translation'
},
{
phrase: 'we have a phrase 2',
translation: 'this is the translation'
},
{
phrase: 'we have a phrase 3',
translation: 'this is the translation'
},
{
phrase: 'we have a phrase 4',
translation: 'this is the translation'
},
{
phrase: 'we have a phrase 5',
translation: 'this is the translation'
},
{
phrase: 'we have a phrase 6',
translation: 'this is the translation'
},
{
phrase: 'we have a phrase 7',
translation: 'this is the translation'
},
{
phrase: 'we have a phrase 8',
translation: 'this is the translation'
}
];
renderCarousel();
var increment = 0;
var bdLen = carouselData.length;
var carousel = $('#carousel');
var _ua = navigator.userAgent.toLowerCase();
var TOUCHEVENT = {
touchstart: "touchstart",
touchmove: "touchmove",
touchend: "touchend",
isdesktop: _ua.indexOf('android') > -1 || _ua.indexOf('linux') > -1 || _ua.indexOf('mobile') > -1 || _ua.indexOf('iphone') > -1 || _ua.indexOf('ipad') > -1 ? false : true,
initTouchEvents: function() {
if (TOUCHEVENT.isdesktop) {
this.touchstart = "mousedown";
this.touchmove = "mousemove";
this.touchend = "mouseup";
}
},
};
$(document).ready(function() {
$('.btn').on('click', function(e) {
if ($(this).hasClass('btn-next')) {
nextCarousel();
} else {
previousCarousel();
}
return false;
});
function nextCarousel() {
increment++;
var _state = (increment % bdLen) + 1;
_state = (_state < 1) ? (_state % bdLen + bdLen) : _state;
updateCarouselState(increment, _state);
}
function previousCarousel() {
increment--;
var _state = (increment % bdLen) + 1;
_state = (_state < 1) ? (_state % bdLen + bdLen) : _state;
updateCarouselState(increment, _state);
}
initTouchEventHandle();
})
/*document ready end----------*/
function updateCarouselState(_incrementId, _stateId) {
var preAngle = -(360 / bdLen).toFixed(1);
carousel.css({
'-webkit-transform': 'rotateX(' + _incrementId * preAngle + 'deg)',
'-moz-transform': 'rotateX(' + _incrementId * preAngle + 'deg)',
'transform': 'rotateX(' + _incrementId * preAngle + 'deg)',
});
carousel.attr('data-state', _stateId);
carousel.find('figure').css({
opacity: .4,
backgroundColor: 'rgba(180, 180, 180, .4)'
}).eq(_stateId - 1).css({
opacity: 1,
backgroundColor: 'rgb(180, 180, 180)'
})
}
function initTouchEventHandle() {
TOUCHEVENT.initTouchEvents();
var carouselCover = document.getElementById('cover');
carouselCover.addEventListener(TOUCHEVENT.touchstart, onTouchStartHandle, false);
carouselCover.addEventListener(TOUCHEVENT.touchmove, onTouchMoveHandle, false);
carouselCover.addEventListener(TOUCHEVENT.touchend, onTouchEndHandle, false);
carouselCover.addEventListener("touchcancel", onTouchEndHandle, false);
}
function onTouchStartHandle(e) {
e.preventDefault();
// e.stopPropagation();
if (!TOUCHEVENT.startPos) {
TOUCHEVENT.startPos = {
x: 0,
y: 0
}
};
if (!TOUCHEVENT.movePos) {
TOUCHEVENT.movePos = {
x: 0,
y: 0
}
};
TOUCHEVENT.offsetY = 0;
TOUCHEVENT.coverTouch = true;
var touchobj = (e.changedTouches) ? e.changedTouches[0] : {};
TOUCHEVENT.startPos.x = touchobj.clientX || e.pageX;
TOUCHEVENT.startPos.y = touchobj.clientY || e.pageY; // clicked point
}
function onTouchMoveHandle(e) {
e.preventDefault();
// e.stopPropagation();
if (!TOUCHEVENT.coverTouch) return;
var touchobj = (e.changedTouches) ? e.changedTouches[0] : {};
TOUCHEVENT.movePos.x = touchobj.clientX || e.pageX;
TOUCHEVENT.movePos.y = touchobj.clientY || e.pageY; // clicked point
var _offsetY = Math.floor((TOUCHEVENT.movePos.y - TOUCHEVENT.startPos.y) / 25);
if (_offsetY != TOUCHEVENT.offsetY) {
var _tgBtnEles = (_offsetY < TOUCHEVENT.offsetY) ? $('.btn-prev') : $('.btn-next');
TOUCHEVENT.offsetY = _offsetY;
_tgBtnEles.trigger('click');
}
}
function onTouchEndHandle(e) {
e.preventDefault();
// e.stopPropagation();
TOUCHEVENT.coverTouch = false;
}
var _carouselCover = document.getElementById('cover');
document.ontouchmove = function(e) {
e.stopPropagation();
e.preventDefault();
// $('#fixed').html('touch move');
}
function renderCarousel() {
let render = '';
const carousel = document.getElementById('carousel');
const rotateXincrement = 360 / carouselData.length;
for (let i = 0; i < carouselData.length; i++) {
const rotateX = rotateXincrement * i;
render +=
`<figure style='transform: rotateX(${rotateX}deg) translateZ(100px);'>
<h1>${carouselData[i].phrase}</h1>
<h2>${carouselData[i].translation}</h2>
</figure>
`;
}
carousel.innerHTML = render;
}
body {
background: #333;
}
#carousel-wrapper,
#carousel figure {
height: 100px;
line-height: 100px;
}
#carousel-wrapper .btn {
position: absolute;
top: -45px;
line-height: 30px;
left: 50%;
background: gray;
color: white;
padding: 5px;
transform: translate(-50%, 0);
-webkit-transform: translate(-50%, 0);
-moz-transform: translate(-50%, 0);
}
#carousel-wrapper .btn-next {
bottom: -45px;
top: auto;
}
#carousel[data-state="1"] figure:nth-of-type(1) {
opacity: 1;
background: rgba(180, 180, 180, 1);
}
#carousel-wrapper {
position: absolute;
top: 30%;
left: 25%;
width: 50%;
text-align: center;
perspective: 1100px;
padding: 20% 0;
}
#carousel {
width: 100%;
height: 100%;
position: absolute;
/*z-index: 100;*/
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
transition: all .6s;
height: 100px;
line-height: 100px;
}
#carousel figure {
display: block;
position: absolute;
width: 100%;
margin: 0;
font-size: 40px;
font-weight: bold;
background: rgba(180, 180, 180, .4);
color: black;
text-align: center;
opacity: .4;
transition: all .6s;
-webkit-transition: all .6s;
-moz-transition: all .6s;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
}
#carousel-wrapper .cover {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0);
/*z-index: 100;*/
}
#fixed {
position: absolute;
left: auto;
right: 0;
top: 0;
color: white;
}
#carousel figure h1 {
color: #ff0d4d;
font-size: 15px;
font-weight: bold;
height: 10px;
line-height: 10px;
margin: 0;
margin-top: 3%;
}
#carousel figure h2 {
color: white;
font-size: 10px;
height: 10px;
line-height: 10px;
margin: 0;
margin-top: 3%;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<div id="carousel-wrapper">
<div id="carousel" data-state="1" style="-webkit-transform: rotateX(0deg)">
</div>
<span class="cover" id="cover"></span>
prev
next
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
I have an application that I have written that adds a set of traffic lights on the screen upon the press of a button. The traffic light automatically cycles from red to yellow after 10 seconds, then on to green after two seconds, then back to yellow after 10 seconds and finally back to red. I would like to add several of these traffic lights to the screen and have them operating at the same time, but when I add a second traffic light, the first traffic light's sequence is frozen at whatever state it has reached. Any ideas as to how to get it to continue to operate - and thus have more than one light cycling through the sequence at the same time?
The transition is controlled by javascript via a state machine.
Anyone have any ideas as to how to get this working smoothly?
Thanks!
Rob
London, UK
var i = 1;
var TrafficLight = function(i) {
var count = 0;
var light_container = document.getElementById('light-container-' + i);
var currentState = new Red(this, light_container);
this.change = function(state) {
currentState = state;
currentState.go();
}
this.start = function() {
currentState.go();
}
}
var Red = function(light, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('#inner-circle-red').style.backgroundColor = '#d8412c';
console.log(light_container);
setTimeout(function() {
light.change(new Yellow(light, 'red', light_container))
}, 10000);
}
}
var Yellow = function(light, origin, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('#inner-circle-yellow').style.backgroundColor = '#fad201';
setTimeout(function() {
if (origin == 'red') {
light.change(new Green(light, light_container));
light_container.querySelector('#inner-circle-red').style.backgroundColor = '#111111';
light_container.querySelector('#inner-circle-yellow').style.backgroundColor = '#111111';
} else if (origin == 'green') {
light.change(new Red(light, light_container));
light_container.querySelector('#inner-circle-yellow').style.backgroundColor = '#111111';
}
}, 2000);
}
}
var Green = function(light, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('#inner-circle-green').style.backgroundColor = '#33A532';
setTimeout(function() {
light.change(new Yellow(light, 'green', light_container))
light_container.querySelector('#inner-circle-green').style.backgroundColor = '#111111';
}, 10000);
}
};
function run() {
document.getElementById("container").innerHTML += '<div id="light-container-' + i + '"><div class="outer-circle-red"><div id="inner-circle-red"></div></div><div class="outer-circle-yellow"><div id="inner-circle-yellow"></div></div><div class="outer-circle-green"><div id="inner-circle-green"></div></div></div>';
var light = new TrafficLight(i);
light.start();
i++;
}
.outer-circle-red,
.outer-circle-yellow,
.outer-circle-green {
background-color: #696969;
border: 2px solid black;
width: 50px;
height: 40px;
border-radius: 15px;
display: table;
}
#light-container-1,
#light-container-2,
#light-container-3 {
margin-top: 20px;
float: left;
margin-left: 70px;
}
#inner-circle-red,
#inner-circle-yellow,
#inner-circle-green {
width: 20px;
height: 20px;
border-radius: 25px;
border: 2px solid #111111;
margin: 0 auto;
margin-top: 7.5px;
background-color: #111111;
}
#button {
width: 200px;
height: 20px;
padding: 10px;
background-color: blue;
color: #ffffff;
cursor: pointer;
}
<div id="button" onclick="run()">+ Add a new traffic light</div>
<div id="container">
</div>
One issue is, as Lewis already stated that you have multiple elements with the same id. JavaScript can only handle one of those.
The other issue is that you delete the content of #container by using innerHTML. The references you have stored in your TrafficLight, Red, Yellow, and Green classes is then destroyed. The store works correctly, but it can't be seen so. Use the DOM manipulation instead.
var light_container = document.createElement('div');
light_container.id = "light-container-" + i;
light_container.innerHTML = '<div class="outer-circle-red"><div class="inner-circle-red"></div></div><div class="outer-circle-yellow"><div class="inner-circle-yellow"></div></div><div class="outer-circle-green"><div class="inner-circle-green"></div></div>';
document.getElementById("container").appendChild(light_container);
var i = 1;
var TrafficLight = function(i) {
var count = 0;
var light_container = document.getElementById('light-container-' + i);
var currentState = new Red(this, light_container);
this.change = function(state) {
currentState = state;
currentState.go();
}
this.start = function() {
currentState.go();
}
}
var Red = function(light, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#d8412c';
setTimeout(function() {
light.change(new Yellow(light, 'red', light_container))
}, 10000);
}
}
var Yellow = function(light, origin, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#fad201';
setTimeout(function() {
if (origin == 'red') {
light.change(new Green(light, light_container));
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
} else if (origin == 'green') {
light.change(new Red(light, light_container));
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
}
}, 2000);
}
}
var Green = function(light, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#33A532';
setTimeout(function() {
light.change(new Yellow(light, 'green', light_container))
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#111111';
}, 10000);
}
};
function run() {
var light_container = document.createElement('div');
light_container.id = "light-container-" + i;
light_container.innerHTML = '<div class="outer-circle-red"><div class="inner-circle-red"></div></div><div class="outer-circle-yellow"><div class="inner-circle-yellow"></div></div><div class="outer-circle-green"><div class="inner-circle-green"></div></div>';
document.getElementById("container").appendChild(light_container);
var light = new TrafficLight(i);
light.start();
i++;
}
.outer-circle-red,
.outer-circle-yellow,
.outer-circle-green {
background-color: #696969;
border: 2px solid black;
width: 50px;
height: 40px;
border-radius: 15px;
display: table;
}
[id^=light-container] {
margin-top: 20px;
float: left;
margin-left: 70px;
}
.inner-circle-red,
.inner-circle-yellow,
.inner-circle-green {
width: 20px;
height: 20px;
border-radius: 25px;
border: 2px solid #111111;
margin: 0 auto;
margin-top: 7.5px;
background-color: #111111;
}
#button {
width: 200px;
height: 20px;
padding: 10px;
background-color: blue;
color: #ffffff;
cursor: pointer;
}
<div id="button" onclick="run()">+ Add a new traffic light</div>
<div id="container">
</div>
I'd imagine it's because you aren't using unique #IDs. Here's an example from your code;
light_container.querySelector('#inner-circle-red').style.backgroundColor
If there's more than one #inner-circle-red on the page, you'll see errors like this. Perhaps try and be more specific with your selectors - like this;
#light-container-1 .inner-circle-red
#light-container-2 .inner-circle-red
I also added a couple of variables and a loop to help manage multiple lights;
for(let i = 1; i <= lights; i++){
var light = new TrafficLight(i);
light.start();
}
See the snippet below for all changes;
var lights = 0;
var TrafficLight = function(i) {
var count = 0;
var light_container = document.getElementById('light-container-' + i);
var currentState = new Red(this, light_container);
this.change = function(state) {
currentState = state;
currentState.go();
}
this.start = function() {
currentState.go();
}
}
var Red = function(light, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#d8412c';
console.log(light_container);
setTimeout(function() {
light.change(new Yellow(light, 'red', light_container))
}, 10000);
}
}
var Yellow = function(light, origin, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#fad201';
setTimeout(function() {
if (origin == 'red') {
light.change(new Green(light, light_container));
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
} else if (origin == 'green') {
light.change(new Red(light, light_container));
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
}
}, 2000);
}
}
var Green = function(light, light_container) {
this.light = light;
this.go = function() {
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#33A532';
setTimeout(function() {
light.change(new Yellow(light, 'green', light_container))
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#111111';
}, 10000);
}
};
function run() {
lights++;
document.getElementById("container").innerHTML += '<div id="light-container-' + lights + '"><div class="outer-circle-red"><div class="inner-circle-red"></div></div><div class="outer-circle-yellow"><div class="inner-circle-yellow"></div></div><div class="outer-circle-green"><div class="inner-circle-green"></div></div></div>';
for(let i = 1; i <= lights; i++){
var light = new TrafficLight(i);
light.start();
}
}
.outer-circle-red,
.outer-circle-yellow,
.outer-circle-green {
background-color: #696969;
border: 2px solid black;
width: 50px;
height: 40px;
border-radius: 15px;
display: table;
}
#light-container-1,
#light-container-2,
#light-container-3 {
margin-top: 20px;
float: left;
margin-left: 70px;
}
.inner-circle-red,
.inner-circle-yellow,
.inner-circle-green {
width: 20px;
height: 20px;
border-radius: 25px;
border: 2px solid #111111;
margin: 0 auto;
margin-top: 7.5px;
background-color: #111111;
}
#button {
width: 200px;
height: 20px;
padding: 10px;
background-color: blue;
color: #ffffff;
cursor: pointer;
}
<div id="button" onclick="run()">+ Add a new traffic light</div>
<div id="container">
</div>
Thanks for your answer. Just as an extra feature I have added a control which allows the user to start each traffic light individually. I am trying to figure out how to enable the user to permanently stop each traffic light, without it stopping all the others.
Here is my updated code so far - note the addition of the 'this.stop()' function inside of var Red. I would like the code to stop the rotation there, rather than continue to yellow and green.
Thanks,
Rob
<!DOCTYPE html>
<html>
<head>
<title>Traffic Lights</title>
<style type="text/css">
#button {
width: 200px;
height: 20px;
padding: 10px;
background-color: blue;
color: #ffffff;
cursor: pointer;
}
.button {
width: 15px;
height: 20px;
padding: 10px;
background-color: red;
color: #ffffff;
cursor: pointer;
margin: 20px auto;
text-align: center;
text-transform: uppercase;
font-weight: bold;
}
.outer-circle-red, .outer-circle-yellow, .outer-circle-green {
background-color: #696969;
margin: 0 auto;
border: 2px solid black;
width: 50px;
height: 40px;
border-radius: 15px;
display: table;
}
.light-container {
margin: 20px 30px 0 30px;
margin-top: 20px;
float: left;
}
.inner-circle-red, .inner-circle-yellow, .inner-circle-green {
width: 20px;
height: 20px;
border-radius: 25px;
border: 2px solid #111111;
margin: 0 auto;
margin-top: 7.5px;
background-color: #111111;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
margin-top: 20px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
</style>
</head>
<body>
<div id="button" onclick="initiate()">+ Add a new traffic light</div>
<div id="container">
</div>
<script type="text/javascript">
var i = 1;
var TrafficLight = function (i) {
var count = 0;
var light_container = document.getElementById('light-container-' + i);
var currentState = new Red(this, light_container);
this.change = function (state) {
currentState = state;
currentState.go();
}
this.start = function () {
currentState.go();
}
this.stop = function () {
currentState.stop();
}
}
var Red = function (light, light_container) {
this.light = light;
this.go = function () {
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#d8412c';
console.log(light_container);
setTimeout(function(){
light.change(new Yellow(light, 'red', light_container))
}, 12000);
}
this.stop = function () {
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#111111';
// Switch all the lights off.
return;
}
}
var Yellow = function (light, origin, light_container) {
this.light = light;
this.go = function () {
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#fad201';
setTimeout(function(){
if(origin == 'red'){
light.change(new Green(light, light_container));
light_container.querySelector('.inner-circle-red').style.backgroundColor = '#111111';
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
} else if(origin == 'green'){
light.change(new Red(light, light_container));
light_container.querySelector('.inner-circle-yellow').style.backgroundColor = '#111111';
}
}, 2000);
}
}
var Green = function (light, light_container) {
this.light = light;
console.log('here');
this.go = function () {
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#33A532';
setTimeout(function(){
light.change(new Yellow(light, 'green', light_container))
light_container.querySelector('.inner-circle-green').style.backgroundColor = '#111111';
}, 14000);
}
};
function initiate(){
var light_container = document.createElement('div');
light_container.id = "light-container-" + i;
light_container.className = "light-container";
light_container.innerHTML = '<div class="outer-circle-red"><div class="inner-circle-red"></div></div><div class="outer-circle-yellow"><div class="inner-circle-yellow"></div></div><div class="outer-circle-green"><div class="inner-circle-green"></div></div><label class="switch"><input type="checkbox" class="off" onclick="toggleRun(this, ' + i + ');"><span class="slider round"></span></label>';
document.getElementById("container").appendChild(light_container);
i++;
}
function toggleRun(item, i){
if(item.className == "off"){
item.className="on";
run(i);
} else {
item.className="off";
stop(i);
}
}
function run(i){
var light = new TrafficLight(i);
light.start();
}
function stop(i){
var light = new TrafficLight(i);
light.stop();
}
function exit( status ){
var i;
if (typeof status === 'string') {
alert(status);
}
window.addEventListener('error', function (e) {e.preventDefault();e.stopPropagation();}, false);
var handlers = [
'copy', 'cut', 'paste',
'beforeunload', 'blur', 'change', 'click', 'contextmenu', 'dblclick', 'focus', 'keydown', 'keypress', 'keyup', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'resize', 'scroll',
'DOMNodeInserted', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument', 'DOMNodeInsertedIntoDocument', 'DOMAttrModified', 'DOMCharacterDataModified', 'DOMElementNameChanged', 'DOMAttributeNameChanged', 'DOMActivate', 'DOMFocusIn', 'DOMFocusOut', 'online', 'offline', 'textInput',
'abort', 'close', 'dragdrop', 'load', 'paint', 'reset', 'select', 'submit', 'unload'
];
function stopPropagation (e) {
e.stopPropagation();
// e.preventDefault(); // Stop for the form controls, etc., too?
}
for (i=0; i < handlers.length; i++) {
window.addEventListener(handlers[i], function (e) {stopPropagation(e);}, true);
}
if (window.stop) {
window.stop();
}
throw '';
}
</script>
</body>
</html>```
I have created a todo-list following watchandcode.com course and I tried to add more functionality to it. So I want to make the COMPLETED button which toggles the non-completed list items ad completed,DISAPPEAR after I click on it and after it turns the list item into completed. I hope I expressed my self properly of what I'd like to achieve. Here's the code down below, thanks in advance!
I copied the whole code down below, but if you only need to see the parts that I might be referring (I am not sure, as I am really new into JS), here they are:
var view = {
displayTodos: function(){
var todosUl = document.querySelector("ul");
todosUl.innerHTML = '';
for (var i = 0; i < todoList.todos.length; i++){
var todoLi = document.createElement("li");
var todo = todoList.todos[i];
var todoTextForCompleted = "";
if (todo.completed === true){
todoTextForCompleted = todo.todoText;
todoLi.classList.toggle("checked");
} else {
todoTextForCompleted = todo.todoText;
todoLi.classList.toggle("notCompleted");
}
todoLi.id = i;
todoLi.textContent = todoTextForCompleted;
todoLi.appendChild(this.createDeleteButton());
todoLi.appendChild(this.createToggleButton());
todosUl.appendChild(todoLi);
}
},
createToggleButton: function(){
var toggleButton = document.createElement("button");
toggleButton.textContent = "Completed";
toggleButton.id= "toggleBtn";
return toggleButton;
},
Here's the whole code if its necessary:
//The object that holds the todo list:
var todoList = {
todos: [],
//Method for ADDING a TODO items
addTodo: function(todoText){
this.todos.push({
todoText: todoText,
completed: false,
});
},
//Method for changing the made TODO items
changeTodo: function(position, newValue){
this.todos[position].todoText = newValue;
},
//Method for deleting TODO items:
deleteTodo: function(position){
this.todos.splice(position, 1);
},
//Method for toggling a todo item as COMPLETED:
toggleCompleted: function(position){
var todo = this.todos[position];
todo.completed = !todo.completed;
},
//Method for toggling ALL todo items:
toggleAll: function(){
var totalTodos = this.todos.length;
//Counting the ones that are completed
var completedTodos = 0;
//Getting the number of the completed todos:
for(var i = 0; i < totalTodos; i++){
if(this.todos[i].completed === true) {
//For every todo item that is completed, increase completedTodos by 1;
completedTodos++;
}
}
//Case 1: If everything is true, the turn it into FALSE;
if(completedTodos === totalTodos){
for(var i = 0; i < totalTodos; i++){
this.todos[i].completed = false
}
//Case 2: Otherwise, make everything TRUE;
} else {
for (var i = 0; i < totalTodos; i++){
this.todos[i].completed = true;
};
};
}
}
//Object for the BUTTON HANDLERS:
var handlers = {
addTodo: function(){
var addTodoText = document.getElementById("addTodoTextInput");
todoList.addTodo(addTodoTextInput.value);
//Clear the input
addTodoText.value = "";
view.displayTodos();
},
//Change todo
changeTodo: function(){
var changeTodoText = document.getElementById("changeTodoText");
var changeTodoPosition = document.getElementById("changeTodoPosition");
//Get the CHANGE TODO method in the object TODOLIST and set these parameters
todoList.changeTodo(changeTodoPosition.valueAsNumber, changeTodoText.value);
//Clear the inputs
changeTodoText.value = "";
changeTodoPosition.value = "";
//Call upon VIEW object and trigger displayTodos() method/function;
view.displayTodos();
},
deleteTodo: function(position){
todoList.deleteTodo(position);
view.displayTodos();
},
deleteAll:function(position){
todoList.todos.splice(position);
view.displayTodos();
},
toggleCompleted: function(){
var toggleCompletedInput = document.getElementById("toggleBtn");
todoList.toggleCompleted(toggleCompletedInput.valueAsNumber);
toggleCompletedInput.value = "";
view.displayTodos();
},
toggleAll: function(){
todoList.toggleAll();
view.displayTodos();
}
};
//Object that is used only to DISPLAY the items:
var view = {
displayTodos: function(){
var todosUl = document.querySelector("ul");
todosUl.innerHTML = '';
for (var i = 0; i < todoList.todos.length; i++){
var todoLi = document.createElement("li");
var todo = todoList.todos[i];
var todoTextForCompleted = "";
if (todo.completed === true){
todoTextForCompleted = todo.todoText;
todoLi.classList.toggle("checked");
} else {
todoTextForCompleted = todo.todoText;
todoLi.classList.toggle("notCompleted");
}
todoLi.id = i;
todoLi.textContent = todoTextForCompleted;
todoLi.appendChild(this.createDeleteButton());
todoLi.appendChild(this.createToggleButton());
todosUl.appendChild(todoLi);
}
},
createDeleteButton: function(){
var deleteButton = document.createElement("button");
deleteButton.textContent = "DELETE";
deleteButton.className = "deleteBtn";
return deleteButton;
},
createToggleButton: function(){
var toggleButton = document.createElement("button");
toggleButton.textContent = "Completed";
toggleButton.id= "toggleBtn";
return toggleButton;
},
//
setUpEventListeners: function(){
var todosUl = document.querySelector("ul");
todosUl.addEventListener("click", function(event){
var elementClicked = event.target;
if(elementClicked.className === "deleteBtn"){
handlers.deleteTodo(parseInt(elementClicked.parentNode.id));
}
if (elementClicked.id === "toggleBtn"){
todoList.toggleCompleted(parseInt(elementClicked.parentNode.id));
var toggleCompletedInput = document.getElementById("toggleBtn");
toggleCompletedInput.value = "";
view.displayTodos();
view.removeTodoButton();
}
});
}
}
view.setUpEventListeners();
The code was a bit messy... the main problem I saw is that you were using multiple elements with same id (toggleBtn). I changed it to use a className. Here you have a working version following the design pattern (view-model-handlers).
The changes are:
toggleCompleted: function(position) {
var toggleCompletedInput = document.querySelector("#" + position + " toggleBtn");
var todoLi = document.createElement("li");
var todo = todoList.todos[i];
todoLi.id = i;
todoLi.textContent = todo.todoText;
if (todo.completed === true) {
todoLi.classList.toggle("checked");
} else {
todoLi.classList.toggle("notCompleted");
todoLi.appendChild(this.createToggleButton());
}
todoLi.appendChild(this.createDeleteButton());
todosUl.appendChild(todoLi);
toggleButton.className = "toggleBtn";
if (elementClicked.className === "toggleBtn") {
todoList.toggleCompleted(parseInt(elementClicked.parentNode.id));
view.displayTodos();
}
And in CSS:
.toggleBtn {
background-color: #eee;
color: #e84118;
cursor: pointer;
position: absolute;
right: 70px;
bottom: 3px;
animation: delete 0.5s ease-out 1 forwards;
}
.toggleBtn:hover {
background-color: #4cd137;
color: #eee;
}
.toggleBtn.removed {
display: none;
}
//The object that holds the todo list:
var todoList = {
todos: [],
//Method for ADDING a TODO items
addTodo: function(todoText) {
this.todos.push({
todoText: todoText,
completed: false,
});
},
//Method for changing the made TODO items
changeTodo: function(position, newValue) {
this.todos[position].todoText = newValue;
},
//Method for deleting TODO items:
deleteTodo: function(position) {
this.todos.splice(position, 1);
},
//Method for toggling a todo item as COMPLETED:
toggleCompleted: function(position) {
var todo = this.todos[position];
todo.completed = !todo.completed;
},
//Method for toggling ALL todo items:
toggleAll: function() {
var totalTodos = this.todos.length;
//Counting the ones that are completed
var completedTodos = 0;
//Getting the number of the completed todos:
for (var i = 0; i < totalTodos; i++) {
if (this.todos[i].completed === true) {
//For every todo item that is completed, increase completedTodos by 1;
completedTodos++;
}
}
//Case 1: If everything is true, the turn it into FALSE;
if (completedTodos === totalTodos) {
for (var i = 0; i < totalTodos; i++) {
this.todos[i].completed = false
}
//Case 2: Otherwise, make everything TRUE;
} else {
for (var i = 0; i < totalTodos; i++) {
this.todos[i].completed = true;
};
};
}
}
//Object for the BUTTON HANDLERS:
var handlers = {
addTodo: function() {
var addTodoText = document.getElementById("addTodoTextInput");
todoList.addTodo(addTodoTextInput.value);
//Clear the input
addTodoText.value = "";
view.displayTodos();
},
//Change todo
changeTodo: function() {
var changeTodoText = document.getElementById("changeTodoText");
var changeTodoPosition = document.getElementById("changeTodoPosition");
//Get the CHANGE TODO method in the object TODOLIST and set these parameters
todoList.changeTodo(changeTodoPosition.valueAsNumber, changeTodoText.value);
//Clear the inputs
changeTodoText.value = "";
changeTodoPosition.value = "";
//Call upon VIEW object and trigger displayTodos() method/function;
view.displayTodos();
},
deleteTodo: function(position) {
todoList.deleteTodo(position);
view.displayTodos();
},
deleteAll: function(position) {
todoList.todos.splice(position);
view.displayTodos();
},
toggleCompleted: function(position) {
var toggleCompletedInput = document.querySelector("#" + position + " toggleBtn");
todoList.toggleCompleted(toggleCompletedInput.valueAsNumber);
toggleCompletedInput.value = "";
view.displayTodos();
},
toggleAll: function() {
todoList.toggleAll();
view.displayTodos();
}
};
//Object that is used only to DISPLAY the items:
var view = {
displayTodos: function() {
var todosUl = document.querySelector("ul");
todosUl.innerHTML = '';
for (var i = 0; i < todoList.todos.length; i++) {
var todoLi = document.createElement("li");
var todo = todoList.todos[i];
todoLi.id = i;
todoLi.textContent = todo.todoText;
if (todo.completed === true) {
todoLi.classList.toggle("checked");
} else {
todoLi.classList.toggle("notCompleted");
todoLi.appendChild(this.createToggleButton());
}
todoLi.appendChild(this.createDeleteButton());
todosUl.appendChild(todoLi);
}
},
createDeleteButton: function() {
var deleteButton = document.createElement("button");
deleteButton.textContent = "DELETE";
deleteButton.className = "deleteBtn";
return deleteButton;
},
createToggleButton: function() {
var toggleButton = document.createElement("button");
toggleButton.textContent = "Completed";
toggleButton.className = "toggleBtn";
return toggleButton;
},
//
setUpEventListeners: function() {
var todosUl = document.querySelector("ul");
todosUl.addEventListener("click", function(event) {
var elementClicked = event.target;
if (elementClicked.className === "deleteBtn") {
handlers.deleteTodo(parseInt(elementClicked.parentNode.id));
}
if (elementClicked.className === "toggleBtn") {
todoList.toggleCompleted(parseInt(elementClicked.parentNode.id));
view.displayTodos();
}
});
}
}
view.setUpEventListeners();
* {
margin: 0;
padding: 0;
}
body {
background-color: #dcdde1;
font-family: 'Poppins', sans-serif;
}
li {
color: #eee;
margin: 5px 0;
list-style-type: none;
padding: 10px;
background-color: grey;
display: flex;
justify-content: flex-start;
align-items: center;
user-select: none;
width: 100%;
animation: listitem 1s 1 forwards;
position: relative;
border-radius: 5px;
}
li.deleted {
animation: listItem 1s 1;
}
#keyframes listItem {
from {
opacity: 0
}
to {
opacity: 1
}
;
}
li.checked {
background-color: #4cd137;
color: #eee;
}
li.checked:before {
color: #eee;
margin: 0 10px;
content: "\2714";
animation: checkmark 1s 1 forwards;
}
#keyframes checkmark {
0% {
transform: scale(0);
}
60% {
transform: scale(1.3);
}
100% {
transform: scale(1);
}
}
li.notCompleted {
background-color: #e84118;
color: #eee;
}
li.notCompleted:before {
content: "\2716";
animation: check 1s 1 forwards;
margin: 0 10px;
}
#keyframes check {
0% {
transform: scale(0);
}
60% {
transform: scale(1.3);
}
100% {
transform: scale(1);
}
}
ul li .deleteBtn {
background-color: #eee;
color: #e84118;
cursor: pointer;
position: absolute;
right: 10px;
bottom: 3px;
animation: delete 0.5s ease-out 1 forwards;
}
.deleteBtn:hover {
background-color: #353b48;
color: #eee;
}
.toggleBtn {
background-color: #eee;
color: #e84118;
cursor: pointer;
position: absolute;
right: 70px;
bottom: 3px;
animation: delete 0.5s ease-out 1 forwards;
}
.toggleBtn:hover {
background-color: #4cd137;
color: #eee;
}
.toggleBtn.removed {
display: none;
}
#keyframes delete {
0% {
transform: scale(0);
}
50% {
transform: scale(1.05);
}
80% {
transform: scale(0.95);
}
100% {
transform: scale(1);
}
}
.wrapper {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: 10px;
}
h1 {
color: #e84118;
font-size: 35px;
font-weight: 700;
text-transform: uppercase;
}
h1 span {
color: #0097e6;
font-size: 65px;
font-weight: 800;
opacity: 0;
letter-spacing: -50px;
animation: headerSpan 2s 0.5s 1 forwards;
}
#keyframes headerSpan {
0% {
opacity: 0;
letter-spacing: -50px;
transform: scale(0);
}
50% {
letter-spacing: 10px;
}
100% {
opacity: 1;
transform: scale(1);
letter-spacing: 0px;
}
}
input {
padding: 5px;
border: none;
background-color: #f5f6fa;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
border-radius: 3px;
color: #e84118;
font-family: 'Poppins';
width: 100%;
margin: 2px 0;
}
input:focus {
outline: none !important;
}
input::placeholder {
color: #e84118;
font-family: "Poppins";
font-style: italic;
font-size: 12px;
padding-left: 5px;
}
button {
margin: 5px 0;
padding: 3px;
border: none;
border-radius: 3px;
font-family: 'Poppins';
text-transform: uppercase;
color: #eee;
background-color: #00a8ff;
font-weight: bold;
font-size: 14px;
transition: 0.2s ease-out;
}
button:focus {
outline: none!important;
}
button:hover {
background-color: #e84118;
color: #eee;
}
.container_todo {
border-radius: 5px;
padding: 35px;
display: flex;
flex-direction: column;
background-color: #f4f4f4;
box-shadow: 0 2px 25px rgba(0, 0, 0, 0.25);
animation: container 1s 1 forwards;
}
.toggleAllButtons {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.all.active {
background-color: red;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The Todo List</title>
<link rel="stylesheet" type="text/css" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Gaegu|Indie+Flower|Pacifico|Raleway" rel="stylesheet">
</head>
<body>
<div class="wrapper">
<!-- Title -->
<h1>The <span>Todo</span> List !</h1>
<!-- TODO LIST container -->
<div class="container_todo">
<!-- BUTTONS -->
<!-- Add Todo item -->
<div class="add">
<button onclick="handlers.addTodo()">Add todo</button>
<input type="text" id="addTodoTextInput" placeholder="Add a Todo item">
</div>
<!-- Change Todo Item-->
<div class="change">
<button onclick="handlers.changeTodo()">Change Todo</button>
<input type="text" id="changeTodoText" placeholder="Change a Todo item">
<input type="number" id="changeTodoPosition" placeholder="Choose which Item to change">
</div>
<!-- Toggle completed Todo item -->
<div class="toggleAllButtons">
<!-- Toggle All items button -->
<div class="all">
<button onclick="handlers.toggleAll()">Toggle All</button>
<button onclick="handlers.deleteAll()">Delete All</button>
</div>
</div>
<ul></ul>
</div>
</div>
<!-- /////////////////////////////////////// -->
<!-- JS link -->
<script src="script.js"></script>
</body>
</html>
I'm having problem with getting CSS animation work properly in firefox browser. I've tried to use the "moz" - prefix, without success.The animation works as expected in chrome, see code below.
var ss = document.styleSheets;
var rec;
var bg = document.getElementById('bg');
function getRule (name) {
var indexArr = [];
for(var i = 0; i<ss[0].cssRules.length; i++){
if(ss[0].cssRules[i].name !== "undefined" && ss[0].cssRules[i].name === name){
indexArr.push(i);
}
}
return indexArr;
}
function swapNode(node){
tmp = node.cloneNode(false);
node.parentNode.removeChild(node);
rec = tmp;
bg.appendChild(rec);
}
function modifyRule(element, name, val){
var browser = checkBrowser();
// if(element.style.webkitAnimationPlayState === "paused")
// element.style.webkitAnimationPlayState = "running";
var indexes = getRule(name);
var rule = [];
if(indexes.length){
element.style.WebkitAnimationName = "none";
element.style.WebkitAnimationName = name;
element.style.mozAnimationName = "none";
element.style.mozAnimationName = name;
element.style.AnimationName = "none";
element.style.AnimationName = name;
swapNode(element);
if(name === "translate"){
rule[0] = "#-"+browser+"-keyframes "+name+" {"+
"0% {-"+browser+"-transform: "+name+"(0px);}"+
"50% {-"+browser+"-transform: "+name+"("+val+");}"+
"100% {-"+browser+"-transform: "+name+"(0px);}}";
rule[1] = "#keyframes "+name+" {"+
"0% {transform: "+name+"(0px);}"+
"50% {transform: "+name+"("+val+");}"+
"100% {transform: "+name+"(0px);}}";
}
else{
rule[0] = "#-"+browser+"-keyframes "+name+" {"+
"100% {-"+browser+"-transform: "+name+"("+val+");}}";
rule[1] = "#keyframes "+name+" {"+
"100% {transform: "+name+"("+val+");}}";
}
for(var i = 0; i<indexes.length; i++){
console.log(rule[i]);
ss[0].deleteRule(indexes[i]);
ss[0].insertRule(rule[i], indexes[i]);
}
}
else{
console.log('err');
}
}
function stopAnim (element) {
element.style.WebkitAnimationPlayState = "paused";
}
function checkBrowser () {
if(navigator.userAgent.indexOf("Chrome") != -1 )
{
return "webkit";
}
else if(navigator.userAgent.indexOf("Firefox") != -1 )
{
return "moz";
}
}
.container {
position: relative;
left: 40px;
top: 50px;
width: 240px;
height: 150px;
}
#bg {
width: 100%;
height: 90px;
background-color: #f3f3ff;
border: solid;
border-width: 1px;
}
#recBlue{
height: 50px;
width: 50px;
background-color: #aaaaff;
border: solid;
border-width: 3px;
position: absolute;
left: 35px;
top: 20px;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: "bounce";
-webkit-animation-fill-mode: forwards;
-moz-animation-duration: 2s;
-moz-animation-timing-function: "bounce";
-moz-animation-fill-mode: forwards;
}
#recRed{
height: 50px;
width: 50px;
background-color: #ffaaaa;
border: solid;
border-width: 3px;
position: absolute;
left: 150px;
top: 20px;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: "ease-in-out";
-webkit-animation-fill-mode: forwards;
-webkit-animation-iteration-count: infinite;
}
#btn-grp{
text-align: center;
}
#-webkit-keyframes rotate {
}
#-webkit-keyframes translate {
}
#-moz-keyframes rotate {
}
#-moz-keyframes translate {
}
<div class="container">
<div id="bg">
<div id="recBlue">
</div>
<div id="recRed">
</div>
</div>
<div id="btn-grp">
<button id="clock" onclick='modifyRule(recBlue, "rotate", "100deg");'>></button>
<button id="anticlock" onclick='modifyRule(recBlue, "rotate", "-100deg");'><</button>
<button id="move" onclick='modifyRule(recRed, "translate", "-100px")'>></button>
<button id="stop" onclick='stopAnim(recRed)'>#</button>
</div>
</div>
Any help would be appreciated!
var ss = document.styleSheets;
var rec;
var bg = document.getElementById('bg');
function getRule (name) {
for(var i = 0; i<ss[0].cssRules.length; i++){
if(ss[0].cssRules[i].name !== "undefined" && ss[0].cssRules[i].name === name)
return i;
}
}
function swapNode(node){
tmp = node.cloneNode(false);
node.parentNode.removeChild(node);
rec = tmp;
bg.appendChild(rec);
}
function modifyRule(element, name, val){
var browser = checkBrowser();
console.log(browser);
if(element.style.webkitAnimationPlayState === "paused")
element.style.webkitAnimationPlayState = "running";
var index = getRule(name);
var rule = "";
if(typeof index !== "undefined"){
element.style.WebkitAnimationName = "none";
element.style.WebkitAnimationName = name;
element.style.mozAnimationName = "none";
element.style.mozAnimationName = name;
ss[0].deleteRule(index);
swapNode(element);
if(name === "translate"){
rule = "#-"+browser+"-keyframes "+name+" {"+
"0% {-"+browser+"-transform: "+name+"(0px);}"+
"50% {-"+browser+"-transform: "+name+"("+val+");}"+
"100% {-"+browser+"-transform: "+name+"(0px);}}";
}
else{
rule = "#-"+browser+"-keyframes "+name+" {"+
"100% {-"+browser+"-transform: "+name+"("+val+");}}";
console.log(rule);
}
ss[0].insertRule(rule, index);
}
else{
console.log('err');
}
}
function stopAnim (element) {
element.style.WebkitAnimationPlayState = "paused";
}
function checkBrowser () {
if(navigator.userAgent.indexOf("Chrome") != -1 )
{
return "webkit";
}
else if(navigator.userAgent.indexOf("Firefox") != -1 )
{
return "moz";
}
}
.container {
position: relative;
left: 40px;
top: 50px;
width: 240px;
height: 150px;
}
#bg {
width: 100%;
height: 90px;
background-color: #f3f3ff;
border: solid;
border-width: 1px;
}
#recBlue{
height: 50px;
width: 50px;
background-color: #aaaaff;
border: solid;
border-width: 3px;
position: absolute;
left: 35px;
top: 20px;
animation-duration: 2s;
animation-timing-function: "bounce";
animation-fill-mode: forwards;
animation-name:translate;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: "bounce";
-webkit-animation-fill-mode: forwards;
-webkit-animation-name:translate;
}
#recRed{
height: 50px;
width: 50px;
background-color: #ffaaaa;
border: solid;
border-width: 3px;
position: absolute;
left: 150px;
top: 20px;
animation-duration: 2s;
animation-timing-function: "ease-in-out";
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name:rotate;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: "ease-in-out";
-webkit-animation-fill-mode: forwards;
-webkit-animation-iteration-count: infinite;
-webkit-animation-name:rotate;
}
#btn-grp{
text-align: center;
}
#-webkit-keyframes rotate {
}
#-webkit-keyframes translate {
}
#keyframes rotate {
}
#keyframes translate {
}
<div class="container">
<div id="bg">
<div id="recBlue">
</div>
<div id="recRed">
</div>
</div>
<div id="btn-grp">
<button id="clock" onclick='modifyRule(recBlue, "rotate", "100deg");'>></button>
<button id="anticlock" onclick='modifyRule(recBlue, "rotate", "-100deg");'><</button>
<button id="move" onclick='modifyRule(recRed, "translate", "-100px")'>></button>
<button id="stop" onclick='stopAnim(recRed)'>#</button>
</div>
</div>
You are not define animation name -webkit-animation-name:rotate; and animation-name:rotate;.
Hope it will helps you.
Problem solved, it was the wrong syntax of animationname.
element.style.MozAnimationName = "none";
element.style.MozAnimationName = name;
element.style.animationName = "none";
element.style.animationName = name;
Is correct.