I'm currently working on a simple drawing program and I'm having trouble making some spaces between my drawing canvas and buttons & colors (pickers). I just want to ask if there is any way to space them properly? I tried just to <br> the lines but it's restricting my drawing area for some reason. I also tried bordering it and making the border transparent but it didn't work. Any tips?
const canvas = document.getElementById("canvas");
canvas.width = window.innerWidth = 650;
canvas.height = 350;
let context = canvas.getContext("2d");
context.fillStyle = "white";
context.fillRect(0, 0, canvas.width, canvas.height);
let draw_color = "black";
let draw_width = "2";
let is_drawing = false;
canvas.addEventListener("touchstart", start, false);
canvas.addEventListener("touchmove", draw, false);
canvas.addEventListener("mousedown", start, false);
canvas.addEventListener("mousemove", draw, false);
canvas.addEventListener("mtouchstart", stop, false);
canvas.addEventListener("mouseup", stop, false);
canvas.addEventListener("mouseout", stop, false);
function start(event) {
is_drawing = true;
context.beginPath();
context.moveTo(event.clientX - canvas.offsetLeft,
event.clientY - canvas.offsetTop);
event.preventDefault();
}
function draw(event) {
if (is_drawing) {
context.lineTo(event.clientX - canvas.offsetLeft,
event.clientY - canvas.offsetTop);
context.strokeStyle = draw_color;
context.lineWidth = draw_width;
context.lineCap = "round";
context.lineJoin = "round";
context.stroke();
}
event.preventDefault();
}
function stop(event) {
if (is_drawing) {
context.stroke();
context.closePath();
is_drawing = false;
}
event.preventDefault();
}
body,
a,
a:hover {
cursor: url('https://66.media.tumblr.com/7659e714cab33f9d59124f924405e793/tumblr_inline_p7g82dZq1h1r466gz_75sq.png'), auto
}
body {
background-image: url('img_girl.jpg');
background-repeat: no-repeat;
background-attachment: fixed;
}
canvas {
cursor: pointer;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 200px;
padding: 5px
}
.tools .color-field {
height: 40px;
width: 40px;
cursor: pointer;
display: inline-block;
box-sizing: border-box;
border-radius: 50%;
border: 2px solid white;
align-self: center;
margin: 5px 5px;
}
.color-field {
display: block;
margin-left: auto;
margin-right: auto;
}
.tools {
display: flex;
justify-content: center;
flex-direction: row;
margin-top: 15px;
}
.tools .button {
align-self: center;
width: 100px;
height: 40px;
border: 2px solid white;
cursor: pointer;
color: white;
background: #DB7093;
font-weight: bold;
margin: 0 10px;
display: block;
}
.button {
display: block;
margin-left: auto;
margin-right: auto;
}
.color-picker {
align-self: center;
margin: 0 15px;
background-color: pink;
}
.pen-range {
align-self: center;
margin: o 15px;
background-color: #DB7093;
}
.container {
width: 600px;
display: block;
margin-left: auto;
margin-right: auto;
position: absolute;
z-index: -1;
margin-left: 425px;
<head>
<img src="logo.png" style="width:50%; margin-right: auto; margin-left: 400px; ">
</head>
<body style="background-image: url('https://images8.alphacoders.com/105/1055726.png');">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> cute drawing program </title>
<div class="container">
<div id="status" style="color: white;"></div>
<img src="container.png" style="width:120%;">
</div>
<div class="field">
<canvas id="canvas"> </canvas>
<div class="tools">
<button type="button" class="button"> Undo </button>
<button type="button" class="button"> Clear </button>
<div class="color-field" style="background: red;"></div>
<div class="color-field" style="background: blue;"></div>
<div class="color-field" style="background: yellow;"></div>
<div class="color-field" style="background: green;"></div>
<div class="color-field" style="background: orange;"></div>
<div class="color-field" style="background: pink;"></div>
<div class="color-field" style="background: brown;"></div>
<div class="color-field" style="background: gray;"></div>
<div class="color-field" style="background: black;"></div>
<div class="color-field" style="background: white;"></div>
<input type="color" class="color-picker">
<input type="range" min="1" max="100" class="pen-range">
</div>
</div>
on your .tools, change margin top
.tools {
display: flex;
justify-content: center;
flex-direction: row;
margin-top: 15px; /* <- change this number */
}
you may also want to remove the margin-top: 200px; on your .canvas because it's breaking it
Think your design as boxes inside boxes, one thing I do is to set up a background color to better visualize where is a box and where is the other so I can fix their positions, when I'm done, I just put the color back to normal.
I also suggest getting started with flex, here is a fun game to learn flex, I started with this too :) https://flexboxfroggy.com/
Hopefully it works!
Here is link which provided
codepen
const canvas = document.getElementById("canvas");
canvas.width = window.innerWidth = 650;
canvas.height = 350;
let context = canvas.getContext("2d");
context.fillStyle = "white";
context.fillRect(0, 0, canvas.width, canvas.height);
let draw_color = "black";
let draw_width = "2";
let is_drawing = false;
canvas.addEventListener("touchstart", start, false);
canvas.addEventListener("touchmove", draw, false);
canvas.addEventListener("mousedown", start, false);
canvas.addEventListener("mousemove", draw, false);
canvas.addEventListener("mtouchstart", stop, false);
canvas.addEventListener("mouseup", stop, false);
canvas.addEventListener("mouseout", stop, false);
function start(event) {
is_drawing = true;
context.beginPath();
context.moveTo(event.clientX - canvas.offsetLeft,
event.clientY - canvas.offsetTop);
event.preventDefault();
}
function draw(event) {
if ( is_drawing ) {
context.lineTo(event.clientX - canvas.offsetLeft,
event.clientY - canvas.offsetTop);
context.strokeStyle = draw_color;
context.lineWidth = draw_width;
context.lineCap = "round";
context.lineJoin = "round";
context.stroke();
}
event.preventDefault();
}
function stop(event) {
if (is_drawing) {
context.stroke();
context.closePath();
is_drawing = false;
}
event.preventDefault();
}
body, a, a:hover { cursor:url('https://66.media.tumblr.com/7659e714cab33f9d59124f924405e793/tumblr_inline_p7g82dZq1h1r466gz_75sq.png'), auto
}
body {
background-image: url('img_girl.jpg');
background-repeat: no-repeat;
background-attachment: fixed;
}
canvas {
cursor: pointer;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 200px;
padding: 5px;
}
.tools .color-field {
height: 40px;
width: 40px;
cursor: pointer;
display: inline-block;
box-sizing: border-box;
border-radius: 50%;
border: 2px solid white;
align-self: center;
margin: 5px 5px ;
}
.color-field {
display: block;
margin-left: auto;
margin-right: auto;
}
.tools {
display: flex;
justify-content: center;
flex-direction: row;
margin-top: 15px;
}
.tools .button{
align-self: center;
width: 100px;
height: 40px;
border: 2px solid white;
cursor: pointer;
color: white;
background: #DB7093;
font-weight: bold;
margin: 0 10px;
display: block;
}
.button {
display: block;
margin-left: auto;
margin-right: auto;
}
.color-picker {
align-self: center;
margin: 0 15px;
background-color: pink;
}
.pen-range {
align-self: center;
margin: o 15px;
background-color: #DB7093;
}
.container {
width: 600px;
display: block;
margin-left: auto;
margin-right: auto;
position: absolute;
z-index:-1;
margin-left: 425px;
}
/* Added */
.canvas {
padding: 10px;
}
There's a few issues with your html which are creating unexpected results.
On top of that, there is a lot of CSS that doesn't quite add up.
I recommend checking out the free tutorials and documentation on W3Schools.com to get a stronger grasp on HTML, specifically structure-wise.
Here is an example of what I assume you are going for, with some major additions to the HTML structure.
To answer your initial question, using position: fixed; along with setting the now fixed position to left:0; and bottom:0 to make the "tools" div a sticky at the bottom of the page.
To keep the canvas in the center without affecting the tools section and visa-versa,
I went ahead and applied position:relative; along with a vertical position of +48px against the top of the parent element, this way your header, "container", now centered as well with margin: 0 auto;, will be centered and clearly displayed at the top.
The main thing you should take from this is that checking out some tutorials on HTML structure will help you greatly.
<!DOCTYPE html>
<html>
<head>
<!--META-->
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cute Drawing Program</title>
<meta name="description" content="A cute drawing app!">
<meta src="logo.png" alt="a logo!">
<style>
body, a, a:hover { cursor:url('https://66.media.tumblr.com/7659e714cab33f9d59124f924405e793/tumblr_inline_p7g82dZq1h1r466gz_75sq.png'), auto}
body {
background-image: url('img_girl.jpg');
background-repeat: no-repeat;
background-attachment: fixed;
}
canvas {
position: relative;
top: 48px;
cursor: pointer;
display: block;
margin: 0 auto;
}
.tools .color-field {
height: 40px;
width: 40px;
cursor: pointer;
display: inline-block;
box-sizing: border-box;
border-radius: 50%;
border: 2px solid white;
align-self: center;
margin: 5px 5px ;
}
.color-field {
display: block;
margin-left: auto;
margin-right: auto;
}
.tools {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
text-align: center;
display: flex;
justify-content: center;
flex-direction: row;
}
.tools .button{
align-self: center;
width: 100px;
height: 40px;
border: 2px solid white;
cursor: pointer;
color: white;
background: #DB7093;
font-weight: bold;
margin: 0 10px;
display: block;
}
.button {
display: block;
margin-left: auto;
margin-right: auto;
}
.color-picker {
align-self: center;
margin: 0 15px;
background-color: pink;
}
.pen-range {
align-self: center;
margin: o 15px;
background-color: #DB7093;
}
.container {
overflow: auto;
width: 100%;
display: block;
margin-left: auto;
margin-right: auto;
position: absolute;
z-index:-1;
margin: 0 auto;
text-align: center;
}
</style>
</head>
<!--END HEAD TAG-->
<!--BEGIN BODY TAG-->
<body style="background-image: url('https://images8.alphacoders.com/105/1055726.png');">
<div class="container">
<div id="status" style="color: white;"></div>
<div style="width: 100%;text-align: center;">
<img src="container.png">
</div>
</div>
<div class="field">
<canvas id="canvas"> </canvas>
<div class="tools">
<button type="button" class="button"> Undo </button>
<button type="button" class="button"> Clear </button>
<div class="color-field" style="background: red;"></div>
<div class="color-field" style="background: blue;"></div>
<div class="color-field" style="background: yellow;"></div>
<div class="color-field" style="background: green;"></div>
<div class="color-field" style="background: orange;"></div>
<div class="color-field" style="background: pink;"></div>
<div class="color-field" style="background: brown;"></div>
<div class="color-field" style="background: gray;"></div>
<div class="color-field" style="background: black;"></div>
<div class="color-field" style="background: white;"></div>
<input type="color" class="color-picker">
<input type="range" min="1" max="100" class="pen-range">
</div>
</div>
<script>
const canvas = document.getElementById("canvas");
canvas.width = window.innerWidth = 650;
canvas.height = 350;
let context = canvas.getContext("2d");
context.fillStyle = "white";
context.fillRect(0, 0, canvas.width, canvas.height);
let draw_color = "black";
let draw_width = "2";
let is_drawing = false;
canvas.addEventListener("touchstart", start, false);
canvas.addEventListener("touchmove", draw, false);
canvas.addEventListener("mousedown", start, false);
canvas.addEventListener("mousemove", draw, false);
canvas.addEventListener("mtouchstart", stop, false);
canvas.addEventListener("mouseup", stop, false);
canvas.addEventListener("mouseout", stop, false);
function start(event) {
is_drawing = true;
context.beginPath();
context.moveTo(event.clientX - canvas.offsetLeft,
event.clientY - canvas.offsetTop);
event.preventDefault();
}
function draw(event) {
if ( is_drawing ) {
context.lineTo(event.clientX - canvas.offsetLeft,
event.clientY - canvas.offsetTop);
context.strokeStyle = draw_color;
context.lineWidth = draw_width;
context.lineCap = "round";
context.lineJoin = "round";
context.stroke();
}
event.preventDefault();
}
function stop(event) {
if (is_drawing) {
context.stroke();
context.closePath();
is_drawing = false;
}
event.preventDefault();
}
</script>
</body>
</html>
Here's the Codepen
Related
i create a form where i upload image into database where i create icon input to select the image i want to convert that icon into that picture which i select after slecting the picture.
<label class="custom-file-upload">
<input asp-for="imge1" name="imge1" type="file" />
<i class="fa fa-camera"></i>
CSS
input[type="file"] {
display: none;
}
.custom-file-upload {
border: 1px solid #ccc;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
height: 80px;
width: 100px;
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
color: var(--primary-color);
}
Using readAsDataURL you can get file path and set to img tag.
jQuery(document).ready(function() {
var readURL = function(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$('.input-img').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("input[type='file']").on('change', function() {
readURL(this);
});
});
.custom-input-file {
position: relative;
cursor:pointer;
}
.custom-input-file .input-file-wrapper {
height: 150px;
width: 150px;
border-radius: 10px;
position: relative;
}
.custom-input-file .input-file-wrapper .input-img {
height: 100%;
-o-object-fit: cover;
object-fit: cover;
border: 1px solid #ced4da;
border-radius: 10px;
width: 100%;;
}
.custom-input-file .input-file-wrapper input[type=file] {
position: absolute;
left: 0;
width: 100%;
height: 100%;
padding: 0;
opacity: 0;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="input-wrapper">
<div class="custom-input-file ">
<div class="input-file-wrapper ">
<img src="https://storage.googleapis.com/proudcity/mebanenc/uploads/2021/03/placeholder-image.png " class="input-img">
<input type="file" class="form-control ">
</div>
</div>
</div>
little bit change and add some javascrpt and jquery in it.
firslty add this
<div class="form">
<div class="grid">
<div class="form-element">
<input type="file" id="file-1" asp-for="imge1" name="imge1">
<label for="file-1" id="file-1-preview">
<div>
<span>+</span>
</div>
</label>
</div>
</div>
</div>
then add this javascript and jquery
<script>
function previewBeforeUpload(id){
document.querySelector("#"+id).addEventListener("change",function(e){
if(e.target.files.length == 0){
return;
}
let file = e.target.files[0];
let url = URL.createObjectURL(file);
document.querySelector("#"+id+"-preview div").innerText = file.name;
document.querySelector("#"+id+"-preview img").src = url;
});
}
previewBeforeUpload("file-1");
previewBeforeUpload("file-2");
previewBeforeUpload("file-3");
previewBeforeUpload("file-4");
previewBeforeUpload("file-5");
previewBeforeUpload("file-6");
previewBeforeUpload("file-7");
previewBeforeUpload("file-8");
previewBeforeUpload("file-9");
previewBeforeUpload("file-10");
</script>
Also add this CSS
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
body {
font-family: "Raleway",sans-serif;
background: #f8f8f8;
}
.form {
margin: 20px 0px 20px;
padding: 0px 10px;
}
.form h2 {
text-align: center;
color: #acacac;
font-size: 12px;
font-weight: 100;
}
.form .grid {
margin-top: 5px;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
gap: 20px;
}
.form .grid .form-element {
width: 80px;
height: 80px;
box-shadow: 0px 0px 20px 5px rgba(100,100,100,0.1);
}
.form .grid .form-element input {
display: none;
}
.form .grid .form-element img {
width: 80px;
height: 80px;
object-fit: cover;
}
.form .grid .form-element div {
position: relative;
height: 30px;
margin-top: -40px;
background: rgba(0,0,0,0.5);
text-align: center;
line-height: 40px;
font-size: 13px;
color: #f5f5f5;
font-weight: 600;
}
.form .grid .form-element div span {
font-size: 15px;
}
I am trying to use a single letter as a logo, the problem is that the containing box of the letter, also called 'em-box' is too large and/or too small, like here:
I would like it to have the exact same size as the letter so that I can centre it perfectly into the circle, like the 'w' logo. The 'b' one, using the same css, is totally off.
#import url('https://fonts.googleapis.com/css2?family=Fredoka:wght#200&family=Press+Start+2P&display=swap');
.container {
display: flex;
gap: 30px;
}
.circle {
display: flex;
height: 175px;
width: 175px;
justify-content: center;
align-items: center;
border-radius: 100px;
background: #1231b3;
}
.text {
display: flex;
font-family: 'Press Start 2P';
font-size: 120px;
color: white;
background-color: light-blue;
}
.light {
background: #7c8dd7;
}
<div class="container">
<div class="circle">
<div class="text">b</div>
</div>
<div class="circle">
<div class="text light">b</div>
</div>
</div>
CSS doesn't know where a character begins and ends (in terms of its visible parts as opposed to its overall width/height).
To find out the top/bottom/left/right visible extremities of a character this snippet draws it on a canvas and then scans the canvas rows and columns to find the first points that have non-zero alpha settings.
A logo is taken to be the full rounded square and its contents. The inner circle is drawn as a before pseudo element.
The character is drawn not in the DOM but as content to the after pseudo element.That way its position can be adjusted depending on its visible dimensions.
Characters that have no ascenders (e.g. w and c in the example given in the question) are moved up slightly (depending on their overall visible height) so they are centered.
The typeface in question differs a bit from the standard typefaces in that the descenders hardly have any height so the position of the baseline in relation to an overall character is different.
This snippet cheats slightly by building in the height of a character with an ascender (a lowercase b in this case) as a guide for which characters need adjusting. It's therefore not a completely general solution for any typeface which might be thrown at it. A bit more work would need to be done to first ascertain the range of heights in any given font.
<!doctype html>
<html>
<head>
<title>Chars as logos</title>
<!-- https://stackoverflow.com/questions/72772445/remove-unused-space-from-letter -->
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<style>
body {
font-family: 'Press Start 2P';
letter-spacing: -4px;
font-size: 30px;
}
/* container added just for demo */
.container {
display: flex;
gap: 3vw;
background: #eeeeee;
rtext-align: center;
}
.logo {
width: 70px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
background-color: var(--col1);
border-radius: 10px;
position: relative;
padding: 0;
margin: 0;
line-height: 1em;
}
.logo::before {
content: '';
width: 50px;
height: 50px;
background-color: var(--col2);
border-radius: 50%;
position: absolute;
top: 10px;
left: 10px;
padding: 0;
margin: 0;
}
.logo::after {
content: var(--char1);
font-family: 'Press Start 2P';
font-size: 30px;
height: calc(var(--h) * 1px);
width: calc(var(--w) * 1px);
padding: 0;
margin: 0;
display: inline-block;
position: absolute;
color: white;
z-index: 1;
text-align: center;
margin-top: calc(var(--top) * 1px);
}
canvas {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<div class="container">
<div class="logo" style="--char: g; --char1: 'g'; --col1: #c920df; --col2: #e48fef;"></div>
<div class="logo" style="--char: w; --char1: 'w'; --col1: #df208d; --col2: #ef8fc6;"></div>
<div class="logo" style="--char: b; --char1: 'b'; --col1: #1231b3; --col2: lightblue;"></div>
</div>
<script>
const logos = document.querySelectorAll('.logo');
function fontLoaded() {
logos.forEach(logo => {
let canvas = document.createElement("canvas");
canvas.width = 200;
canvas.height = 200;
let ctx = canvas.getContext("2d");
ctx.font = "30px 'Press Start 2P'";
ctx.fillText(logo.style.getPropertyValue('--char'), 10, 60); //baseline of the character will be at 60
let d = ctx.getImageData(0, 0, 200, 200);
let foundTop = false;
foundBottom = false;
foundLeft = false;
foundRight = false;
let top = [];
let bottom = [];
let left = [];
let right = [];
let r, c;
//// Find the visible height ////
for (r = 0; r < 200; r++) {
for (c = 3; c < (800 - 1); c += 4) {
if (d.data[(r * 800) + c] != 0) {
foundTop = true;
top = [r, c];
break;
}
}
if (foundTop) break;
}
for (r = 200 - 1; r >= 0; r--) {
for (c = (800 - 1); c >= 0; c -= 4) {
if (d.data[(r * 800) + c] != 0) {
foundBottom = true;
bottom = [r, c];
break;
}
}
if (foundBottom) break;
}
//// now find the width ////
for (c = 3; c < (800 - 1); c += 4) {
for (r = 0; r < (200 - 1); r++) {
if (d.data[(r * 800) + c] != 0) {
foundLeft = true;
left = [r, c];
break;
}
}
if (foundLeft) break;
}
for (c = (800 - 1); c >= 0; c -= 4) {
for (r = 200 - 1; r >= 0; r--) {
if (d.data[(r * 800) + c] != 0) {
foundRight = true;
right = [r, c];
break;
}
}
if (foundRight) break;
}
logo.style.setProperty('--h', bottom[0] - top[0]);
logo.style.setProperty('--w', (right[1] - left[1] - 1) / 4);
if ((bottom[0] - top[0]) < 26) logo.style.setProperty('--top', (top[0] - bottom[0]) / 2);
});
}
WebFont.load({
google: {
families: ['Press Start 2P:300,400,700']
},
loading: function() {},
active: function() {
fontLoaded();
}
});
</script>
</body>
</html>
Note: before a typeface is drawn on a canvas we have to be sure that it has been loaded, hence the use of the google library
# A Haworth's answer is awesome. I could never have come up with that.
But if you want a quick and dirty css-only solution, get rid of the flex properties, set text-align to center, and massage the padding for the .text boxes. Use em measurements so the layout will scale without breaking.
Big Font: 120px
#import url('https://fonts.googleapis.com/css2?family=Fredoka:wght#200&family=Press+Start+2P&display=swap');
/* only used for this example */
.wrapper {
display: flex;
gap: 30px;
}
.container {
font-size: 120px;
/* font-size: 24px;*/
display: inline-block;
padding: .25em;
border-radius: .5em;
}
.container.blue {
background-color: #8fa1ef;
}
.container.purple {
background-color: #e48fef;
}
.container.red {
background-color: #ef8fc6;
}
.circle {
height: 1.5em;
width: 1.5em;
border-radius: 1em;
}
.blue .circle {
background-color: #1231b3;
}
.red .circle {
background-color: #df208d;
}
.purple .circle {
background-color: #c920df;
}
.text {
font-family: 'Press Start 2P';
color: white;
text-align: center;
}
.blue .text {
padding: .18em 0 0 .125em;
}
.red .text {
padding: .08em 0 .04em .04em;
}
.purple .text {
padding: .08em 0 0 .1em;
}
<div class="wrapper">
<div class="container blue">
<div class="circle">
<div class="text">b</div>
</div>
</div>
<div class="container red">
<div class="circle">
<div class="text">c</div>
</div>
</div>
<div class="container purple">
<div class="circle">
<div class="text">w</div>
</div>
</div>
</div>
Small Font: Exactly the same, but the font size is set to 24px.
#import url('https://fonts.googleapis.com/css2?family=Fredoka:wght#200&family=Press+Start+2P&display=swap');
/* Only used for this example */
.wrapper {
display: flex;
gap: 30px;
}
.container {
/* font-size: 120px;*/
font-size: 24px;
display: inline-block;
padding: .25em;
border-radius: .5em;
}
.container.blue {
background-color: #8fa1ef;
}
.container.purple {
background-color: #e48fef;
}
.container.red {
background-color: #ef8fc6;
}
.circle {
height: 1.5em;
width: 1.5em;
border-radius: 1em;
}
.blue .circle {
background-color: #1231b3;
}
.red .circle {
background-color: #df208d;
}
.purple .circle {
background-color: #c920df;
}
.text {
font-family: 'Press Start 2P';
color: white;
text-align: center;
}
.blue .text {
padding: .18em 0 0 .125em;
}
.red .text {
padding: .08em 0 .04em .04em;
}
.purple .text {
padding: .08em 0 0 .1em;
}
<div class="wrapper">
<div class="container blue">
<div class="circle">
<div class="text">b</div>
</div>
</div>
<div class="container red">
<div class="circle">
<div class="text">c</div>
</div>
</div>
<div class="container purple">
<div class="circle">
<div class="text">w</div>
</div>
</div>
</div>
It looks like there are several questions on StackOverflow similar to
this question. However, I tried several methods and nothing worked for
me. :(
Hello!
I'm currently using a MVC model in PHP.
I'm using GSAP & ScrollMagic for this webpage.
When I scroll down the page, images show up in an order.
By the way, when the trigger reaches the second image, I see the footer behind the second image.
My folder structure is the following:
-- controller
-- backend
-- frontend
-- 0_header_and_footer.php
-- model
-- public
-- css
-- images
-- js
-- backend
-- frontend
-- 0_header_and_footer
-- 1_work
-- 2_writings
-- 3_about
-- personality.js
-- view
personality.php
-- backend
-- frontend
-- 0_header_and_footer
-- 1_work
-- 2_writings
-- 3_about
-- personality.php
index.php
view / template.php
<!DOCTYPE html>
<html lang="en">
<head>
<!-- code for <head> -->
</head>
<body>
<?php require("view/frontend/0_header_and_footer/header.php");?>
<?=$content?>
<?php require("view/frontend/0_header_and_footer/footer.php");?>
</body>
</html>
view / frontend / 3_about / personality.php
<?php $title='Account'; ?>
<?php ob_start(); ?>
<h2 class="title">Personality / Interests</h2>
<section>
<!-- code for <section> -->
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/ScrollMagic.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/plugins/debug.addIndicators.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/plugins/animation.gsap.min.js"></script>
<script src="public/js/frontend/3_about/personality.js"></script>
<?php $content = ob_get_clean(); ?>
<?php require('view/template.php') ?>
The following code shows the problem:
I changed the footer background to orange to show the footer more clearly.
This doesn't include the MVC model, though.
Please check out this CodePen to see what happens:
https://codepen.io/hlim18/pen/MRWjbp.
I tried several methods to solve the problem:
[FIRST TRY]
After reading this StackOverflow question, I added the following code that I got from this CodePen.
.page-wrap {
min-height: 100%;
/* equal to footer height */
margin-bottom: -80px;
}
.page-wrap:after {
content: "";
display: block;
}
.site-footer, .page-wrap:after {
/* .push must be the same height as footer */
height: 80px;
}
However, that didn't solve my problem.
[SECOND TRY]
Accepted answer of this StackOverflow question suggested fixing the footer at the bottom.
-- This is NOT what I want. I want to show the footer at the bottom only when a user finishes scrolling to the bottom.
[THIRD TRY]
This CSS-Tricks article showed five ways for making a sticky footer:
3 ways of requiring fixed height footers including my first try
1 way of using flexbox
1 way of using grid.
I tried the grid method.
HTML
<div>
<h2 class="title">...</h2>
<section class="page-wrap">...</section>
</div>
<footer class="site-footer">...</footer>
CSS
body {
min-height: 100%;
display: grid;
grid-template-rows: 1fr auto;
}
footer {
grid-row-start: 2;
grid-row-end: 3;
height: 80px;
}
This didn't work either: https://codepen.io/hlim18/pen/LvYNaZ :(
[FOURTH TRY]
I tried the accepted answer of this StackOverflow question.
footer {
position:absolute;
right:0;
left:0;
}
It didn't work either: https://codepen.io/hlim18/pen/eoYdpW :(
How could I solve this problem? I'd greatly appreciate any help. Thank you!
As in doc use the code below to set the footer in the end of the page
var scene2 = new ScrollMagic.Scene({
triggerElement: "#footer",
duration: 1000,
triggerHook: 3
})
.setPin("#footer")
.addTo(controller);
See full code:
var controller = new ScrollMagic.Controller();
var project_left = document.querySelectorAll('.project_left');
project_left.forEach((element) => {
var pic_overlay = element.children[0].children[1],
project_info = element.children[1],
small_title = element.children[1].children[0],
h4_test = element.children[1].children[1],
project_link = element.children[1].children[2];
var animate_in = new TimelineMax();
animate_in
.fromTo(pic_overlay, 2, {
skewX: 10,
scale: 1.5
}, {
skewX: 0,
xPercent: 100,
transformOrigin: "0% 100%",
ease: Power2.easeOut
})
.from(project_info, 1, {
scaleY: 0,
transformOrigin: 'bottom left'
}, '-=1.5')
.from(small_title, 0.3, {
autoAlpha: 0,
y: 30,
ease: Power4.easeOut
}, '-=0.8')
.from(project_link, 0.2, {
autoAlpha: 0,
y: 30,
ease: Power4.easeOut
}, '-=0.8')
.from(h4_test, 0.2, {
autoAlpha: 0,
y: 30,
ease: Power4.easeOut
}, '-=0.8');
// Make a ScrollMagic scene
var scene = new ScrollMagic.Scene({
triggerElement: element
})
.addIndicators()
.setTween(animate_in).addTo(controller);
});
var project_right = document.querySelectorAll('.project_right');
project_right.forEach((element) => {
var pic_overlay = element.children[0].children[1],
project_info = element.children[1],
small_title = element.children[1].children[0],
h4_test = element.children[1].children[1],
project_link = element.children[1].children[2];
var animate_in = new TimelineMax();
animate_in
.fromTo(pic_overlay, 2, {
skewX: 10,
scale: 1.5
}, {
skewX: 0,
xPercent: 100,
transformOrigin: "0% 100%",
ease: Power2.easeOut
})
.from(project_info, 1, {
scaleY: 0,
transformOrigin: 'bottom left'
}, '-=1.5')
.from(small_title, 0.3, {
autoAlpha: 0,
y: 30,
ease: Power4.easeOut
}, '-=0.8')
.from(project_link, 0.2, {
autoAlpha: 0,
y: 30,
ease: Power4.easeOut
}, '-=0.8')
.from(h4_test, 0.2, {
autoAlpha: 0,
y: 30,
ease: Power4.easeOut
}, '-=0.8');
// Make a ScrollMagic scene
var scene = new ScrollMagic.Scene({
triggerElement: element
})
.addIndicators()
.setTween(animate_in).addTo(controller);
var scene2 = new ScrollMagic.Scene({
triggerElement: "#footer",
duration: 1000,
triggerHook: 3
})
.setPin("#footer")
.addTo(controller);
});
.h1_test {
font-weight: 600;
font-size: 48px;
color: red;
margin: 0;
line-height: 1.3;
letter-spacing: 0.0001em;
}
.h4_test {
font-weight: 600;
font-size: 28px;
color: #666;
margin: 0;
line-height: 1.3;
letter-spacing: 0.0001em;
}
p.top_titles {
font-size: 10px;
font-weight: 500;
letter-spacing: 0.2em;
text-transform: uppercase;
}
.small_title {
font-size: 10px;
font-weight: 500;
letter-spacing: 0.2em;
text-transform: uppercase;
}
.project_link {
text-decoration: none;
border-bottom: 2px solid #b00f24;
padding: 5px 0;
font-size: 1.5rem;
}
.section_test {
height: 90vh;
width: 100vw;
}
.grid_test {
display: grid;
height: 100%;
align-content: center;
justify-content: center;
text-align: center;
}
.project_div {
display: grid;
position: relative;
grid-template-columns: repeat(12, 1fr);
}
.project_left .box_test {
position: relative;
overflow: hidden;
height: 90vh;
grid-row: 1/span 3;
width: 100%;
}
.project_left .project_info {
position: absolute;
height: 200px;
width: 400px;
top: 20%;
background: lightgoldenrodyellow;
padding: 20px;
}
.project_left .box_test {
grid-column: 2/span 7;
}
.project_left .project_info {
left: 5%;
}
.project_right .box_test {
position: relative;
overflow: hidden;
height: 90vh;
grid-row: 1/span 3;
width: 100%;
}
.project_right .project_info {
position: absolute;
height: 200px;
width: 400px;
top: 20%;
background: lightgoldenrodyellow;
padding: 20px;
}
.project_right .box_test {
grid-column: 5/span 7;
}
.project_right .project_info {
right: 5%;
}
.img_test {
width: 100%;
}
.overlay_test {
display: block;
position: absolute;
left: 0;
top: 0;
background: white;
width: 100%;
height: 100%;
}
footer {
display: flex;
margin-top: 10px;
padding-top: 7px;
justify-content: space-between;
height: 80px;
background-color: orange;
}
#footer_left {
display: flex;
flex-direction: row;
padding-left: 2vw;
width: 100%;
}
#footer_left #input_icon_footer {
position: absolute;
left: 10px;
width: 24px;
height: 24px;
top: 10px;
}
#footer_left #search_input {
text-indent: 40px;
margin: 10px 0;
width: 100%;
background-color: #e0e2e5;
text-indent: 40px;
margin-top: 0px;
width: 150px;
background-color: #e0e2e5;
box-sizing: border-box;
}
#footer_left #search_input:focus {
outline: none !important;
border: 2px solid #0b82dc;
padding: 5px 0;
}
#footer_left #search_input:focus {
box-sizing: border-box;
width: 300px;
transition: width 0.7s cubic-bezier(0.47, 0, 0.75, 0.72);
}
#footer_left #search_input:focus::-webkit-input-placeholder {
color: #e0e2e5;
}
#footer_middle {
padding-left: 0;
margin-top: 22px;
color: #6c6e70;
width: 450px;
text-align: center;
}
#footer_middle>li {
list-style-type: none;
}
#footer_right {
padding-left: 0px;
padding-right: 2vw;
width: 100%;
justify-content: flex-end;
display: flex;
flex-direction: row;
}
#footer_right>li {
list-style-type: none;
padding-right: 15px;
padding-top: 10px;
}
#footer_right>li>a>i {
color: #6c6e70;
}
#footer_right>li>a>i:hover {
color: #0b82dc;
}
#footer_right>li:last-child {
padding-right: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenMax.min.js"></script>
<?php $title='Account'; ?>
<?php ob_start(); ?>
<h2 class="title">Personality / Interests</h2>
<section>
<section class="section_test">
<div class="grid_test">
<h1 class="h1_test">StrengthsQuest!</h1>
<p>scroll down</p>
</div>
</section>
<section class="section_test">
<div class="project_div project_left">
<div class="box_test">
<img class="img_test" src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1353&q=80" alt="korea">
<div class="overlay_test"></div>
</div>
<div class="project_info">
<p class="small_title">Identity // Website // Print</p>
<h4 class="h4_test">This is the first project</h4>
See case study
</div>
</div>
<div class="project_div project_right">
<div class="box_test">
<img class="img_test" src="https://images.unsplash.com/photo-1553696801-25638feb93fe?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1000&q=80" alt="korea">
<div class="overlay_test"></div>
</div>
<div class="project_info">
<p class="small_title">Identity // Website // Print</p>
<h4 class="h4_test">This is the first project</h4>
See case study
</div>
</div>
<div class="project_div project_left">
<div class="box_test">
<img class="img_test" src="https://images.unsplash.com/photo-1553714191-c89281730c67?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="korea">
<div class="overlay_test"></div>
</div>
<div class="project_info">
<p class="small_title">Identity // Website // Print</p>
<h4 class="h4_test">This is the first project</h4>
See case study
</div>
</div>
</section>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/ScrollMagic.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/plugins/debug.addIndicators.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/plugins/animation.gsap.min.js"></script>
<script src="public/js/frontend/3_about/personality.js"></script>
<footer id="footer">
<ul id="footer_left">
<form action="" action="view/frontend/4_acct/footer_searchbar.php" method="POST">
<div id="search_div" class="input_container">
<i class="material-icons" id="input_icon_footer">search</i>
<input id="search_input" class="acct_input" name="search" type="text" placeholder="search">
</div>
</form>
</ul>
<ul id="footer_middle">
<li>Copyright © 2019 Jen Lim
<li>
</ul>
<ul id="footer_right">
</ul>
</footer>
I am making a site where you can click on a button and it will scroll you down to the information below. My issue is that the size of the opening screen is relative to the device screen. That means that a fixed scroll can be too far or not far enough on different devices. In summary my question is: how do i jump the exact device sreen height?
Here is my code:`
<div id='textPage1'>
<div id='leesMeer'>
<a href="#page2" class='leesMeer'type="button" value='Lees Meer'>LEES MEER</a>
</div>
</div>
<div id='page2'>
<div id='textPage2'>
<p>hi</p>
</div>
</div>
And my css:
#textPage1 {
float: right;
margin-right: 100px;
z-index: -1;
}
#beschrijving {
font-family: agency;
font-size: 20px;
color: #f2f2f2;
letter-spacing: 2px;
transform: scale(1, 1.1);
line-height: 30px;
z-index: 1;
margin-left: 50px;
}
.leesMeer {
font-family: agency;
font-size: 30px;
color: #f2f2f2;
border: 5px solid #f2f2f2;
border-radius: 15px;
padding: 12px 40px 12px 40px;
text-decoration: none;
-webkit-transition-duration: 0.5s;
position: absolute;
}
You can use Javascript to specify the scroll down like this example:
HTML:
<div class="first"><button type="button" onclick="smoothScroll(document.getElementById('second'))">Click Me!</button></div>
<div class="second" id="second">Hi</div>
CSS:
.first {
width: 100%;
height: 1000px;
background: #ccc;
}
.second {
width: 100%;
height: 1000px;
background: #999;
}
Javascript:
window.smoothScroll = function(target) {
var scrollContainer = target;
do { //find scroll container
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
} while (scrollContainer.scrollTop == 0);
var targetY = 0;
do { //find the top of target relatively to the container
if (target == scrollContainer) break;
targetY += target.offsetTop;
} while (target = target.offsetParent);
scroll = function(c, a, b, i) {
i++; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function(){ scroll(c, a, b, i); }, 20);
}
// start scrolling
scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0);
}
here is the code in jsfiddle http://jsfiddle.net/rjSfP/
I'm making a messaging app in Electron. I'm using backdrop-filter to blur the messages as they scroll past the title bar, so I need the messages to pass behind the title bar, rather than being contained inside their own div in the middle of the screen.
When the page is not scrolled, the messages behave as expected. However, at the bottom of the page, the messages are cut off by the bottom bar for entering messages.
HTML
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="css/chat.css" />
<script src="js/chatWindow.js"></script>
</head>
<body>
<div class="header">
<span class="name">Room Name</span>
</div>
<div class="messageBar">
<input id="messageBox" type="text" placeholder="Enter a message..." />
<div class="sendBtn">Send</div>
</div>
<div class="messageList"></div>
</body>
</html>
CSS
#font-face {
font-family: "Roboto Light";
font-style: "normal";
font-weight: 400;
src: url("fonts/Roboto-Light.ttf") format("truetype");
}
body {
background-color: white;
font-family: "Roboto Light";
padding: 45px 0px;
}
.header {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 45px;
z-index: 100;
background-color: rgba(56, 92, 254, 0.75);
display: flex;
text-align: center;
justify-content: center;
align-items: center;
backdrop-filter: blur(3px);
-webkit-backdrop-filter: blur(3px);
-webkit-app-region: drag;
}
.header span {
font-weight: bold;
}
.messageBar {
position: fixed;
top: calc(100% - 45px);
left: 0px;
width: 100%;
height: 45px;
z-index: 100;
background-color: rgba(57, 93, 255, 0.75);
padding: 0px;
display: flex;
text-align: center;
justify-content: center;
align-items: center;
vertical-align: middle;
backdrop-filter: blur(3px);
-webkit-backdrop-filter: blur(3px);
}
#messageBox {
width: 90%;
height: 100%;
background-color: rgba(255,255,255,0.5);
font-size: 1em;
margin: none;
border: none;
padding: 0px 5px 0px 5px;
}
#messageBox::-webkit-input-placeholder {
color: dimgray;
}
.sendBtn {
float: right;
width: 10%;
height: 100%;
padding: 0px 3px;
line-height: 45px;
transition: 0.2s;
}
.sendBtn:hover {
background-color: rgba(0,0,0,0.25);
}
.messageList {
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
}
.message {
display: block;
width: auto;
max-width: 50%;
border-radius: 10px;
padding: 4px;
margin: 5px 0px;
box-sizing: border-box;
background-color: lightblue;
overflow-wrap: break-word;
float: left;
clear: both;
}
.message.mine {
float: right;
background-color: lightgreen;
}
Does anybody know how to fix this issue? Here's a CodePen for an example of what's happening. Any help would be greatly appreciated!
Try this javascript code may this help you.
window.addEventListener("load", function(){
var messageList = document.querySelector(".messageList");
var messageBox = document.getElementById("messageBox")
var sendBtn = document.querySelector(".sendBtn");
for(var i = 0; i < 100; i++) {
var content = "Message body: " + i + "\nThe quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog.";
createMessageBubble(content, Math.random() > 0.5);
}
sendBtn.onclick = function() {
var message = messageBox.value;
messageBox.value = "";
if(!message || message.length <= 0) {
return;
}
createMessageBubble(message, true);
// TODO: actually send the message
};
function createMessageBubble(content, isUser) {
var el = document.createElement("div");
el.classList.add("message");
if(isUser) {
el.classList.add("mine");
}
el.innerText = content;
messageList.appendChild(el);
}
var div = document.createElement("div");
div.style.width = "100%";
div.style.height = "45px";
div.style.float = "left";
messageList.parentNode.appendChild(div);
});