HTML preprocessors can make writing HTML more powerful or convenient. For instance, Markdown is designed to be easier to write and read for text documents and you could write a loop in Pug.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. So you don't have access to higher-up elements like the <html>
tag. If you want to add classes there that can affect the whole document, this is the place to do it.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. If you need things in the <head>
of the document, put that code here.
The resource you are linking to is using the 'http' protocol, which may not work when the browser is using https.
CSS preprocessors help make authoring CSS easier. All of them offer things like variables and mixins to provide convenient abstractions.
It's a common practice to apply CSS to a page that styles elements such that they are consistent across all browsers. We offer two of the most popular choices: normalize.css and a reset. Or, choose Neither and nothing will be applied.
To get the best cross-browser support, it is a common practice to apply vendor prefixes to CSS properties and values that require them to work. For instance -webkit-
or -moz-
.
We offer two popular choices: Autoprefixer (which processes your CSS server-side) and -prefix-free (which applies prefixes via a script, client-side).
Any URLs added here will be added as <link>
s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.
You can apply CSS to your Pen from any stylesheet on the web. Just put a URL to it here and we'll apply it, in the order you have them, before the CSS in the Pen itself.
You can also link to another Pen here (use the .css
URL Extension) and we'll pull the CSS from that Pen and include it. If it's using a matching preprocessor, use the appropriate URL Extension and we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
JavaScript preprocessors can help make authoring JavaScript easier and more convenient.
Babel includes JSX processing.
Any URL's added here will be added as <script>
s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.
You can apply a script from anywhere on the web to your Pen. Just put a URL to it here and we'll add it, in the order you have them, before the JavaScript in the Pen itself.
If the script you link to has the file extension of a preprocessor, we'll attempt to process it before applying.
You can also link to another Pen here, and we'll pull the JavaScript from that Pen and include it. If it's using a matching preprocessor, we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
Search for and use JavaScript packages from npm here. By selecting a package, an import
statement will be added to the top of the JavaScript editor for this package.
Using packages here is powered by esm.sh, which makes packages from npm not only available on a CDN, but prepares them for native JavaScript ESM usage.
All packages are different, so refer to their docs for how they work.
If you're using React / ReactDOM, make sure to turn on Babel for the JSX processing.
If active, Pens will autosave every 30 seconds after being saved once.
If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.
If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.
Visit your global Editor Settings.
x<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP32 on the rail</title>
<style>
footer{font-size: 10px;background-color: #ffffff;font-family: "Comic Sans MS"; margin: 5em 0 0 13em;}
</style>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body onload='draw(0);'>
<div class="container" >
<h1> ESP32 on the Rail</h1>
<div class="row">
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<h4 class="card-title">DC motor controller</h4>
<canvas id="speedometer" width="400" height="200">Canvas not available.</canvas>
<p class="card-text">
プラレールを制御するコントロール画面。このメータはモータデューティを表示していて、
下のボタンで増減を調整します。トグルSWで前進・後退が切り替えられます。
</p>
<br>
<fieldset style="margin:0 0 0 2em">
<p> 進行方向切り替えSW </p>
<input id="item-1" class="radio-inline__input" type="radio" name="accessible-radio" value="se1" checked="checked"/>
<label class="radio-inline__label" for="item-1">
Forward
</label>
<input id="item-2" class="radio-inline__input" type="radio" name="accessible-radio" value="se2"/>
<label class="radio-inline__label" for="item-2">
Backward
</label>
<br>
<button type="button" id="upbtn" class="btn btn-success" style="margin : 0 0 0 5em"><i class="glyphicon glyphicon-upload"></i> UP</button>
<button type="button" id="stopbtn" class="btn btn-danger"><i class="glyphicon glyphicon-pause"></i>brake</button>
<button type="button" id="dwnbtn" class="btn btn-warning"><i class="glyphicon glyphicon-download"></i>DOWN</button>
</fieldset>
<br>
</div>
</div>
</div>
<div class="col-sm-6"></div>
</div>
<footer>
<p> ぼくのマイコン開発のメモ Copyright 2020</p>
</footer>
</div>
<script>
var DutyArr = [0, 100, 150, 200, 215, 255];
var mascon=0;
var bBackward = 0;
var TarDuty=DutyArr[mascon];
$( 'input[name="accessible-radio"]:radio' ).change( function() {
// document.getElementById("stopbtn").click();
var val = $(this).val();
switch (val){
case 'se1':
bBackward =0;
break;
case 'se2':
bBackward =1;
break;
}
TarDuty=0;
DCTar(TarDuty,bBackward);
delay(500);
});
$('#upbtn').on('click', function() {
var temp=mascon+1;
if(temp>5){mascon =5;}
else{mascon = temp;}
TarDuty = DutyArr[Math.abs(mascon)];
console.log(TarDuty);
drawWithInputValue(TarDuty);
DCTar(TarDuty,bBackward);
enableRadio(TarDuty);
});
$('#dwnbtn').on('click', function() {
var temp = mascon -1;
if(temp<0){mascon=0;}
else{mascon = temp;}
TarDuty = DutyArr[Math.abs(mascon)];
console.log(TarDuty);
drawWithInputValue(TarDuty);
DCTar(TarDuty,bBackward);
enableRadio(TarDuty);
});
$('#stopbtn').on('click', function() {
mascon=0;
TarDuty=0;
DCTar(TarDuty,bBackward);
drawWithInputValue(0);
enableRadio(TarDuty);
});
function enableRadio(TarDuty){
var dir_radio = $('input[name="accessible-radio"]');
if(TarDuty==0){
dir_radio.prop('disabled', false);
}
else{
dir_radio.prop('disabled', true);
}
}
function DCTar(pos,bBackward) {
$.get("/?valduty=" + pos + "_" + "/?valdir="+ bBackward + "&");
{Connection: close};
}
/*jslint plusplus: true, sloppy: true, indent: 4 */
(function () {
"use strict";
// this function is strict...
}());
var iCurrentSpeed= 0,
iTargetSpeed = 0,
bDecrement = null,
job = null;
function degToRad(angle) {
// Degrees to radians
return ((angle * Math.PI) / 180);
}
function radToDeg(angle) {
// Radians to degree
return ((angle * 180) / Math.PI);
}
function drawLine(options, line) {
// Draw a line using the line object passed in
options.ctx.beginPath();
// Set attributes of open
options.ctx.globalAlpha = line.alpha;
options.ctx.lineWidth = line.lineWidth;
options.ctx.fillStyle = line.fillStyle;
options.ctx.strokeStyle = line.fillStyle;
options.ctx.moveTo(line.from.X,
line.from.Y);
// Plot the line
options.ctx.lineTo(
line.to.X,
line.to.Y
);
options.ctx.stroke();
}
function createLine(fromX, fromY, toX, toY, fillStyle, lineWidth, alpha) {
// Create a line object using Javascript object notation
return {
from: {
X: fromX,
Y: fromY
},
to: {
X: toX,
Y: toY
},
fillStyle: fillStyle,
lineWidth: lineWidth,
alpha: alpha
};
}
function drawBackground(options) {
/* Black background with alphs transparency to
* blend the edges of the metallic edge and
* black background
*/
var i = 0;
options.ctx.globalAlpha = 0.4;
options.ctx.fillStyle = "rgb(0,0,0)";
// Draw semi-transparent circles
for (i = 170; i < 190; i++) {
options.ctx.beginPath();
options.ctx.arc(options.center.X,
options.center.Y,
i, //半径
0, //スタート角度
Math.PI, //エンド角度
true); //時計周り or 反時計周り
options.ctx.fill();
}
}
function applyDefaultContextSettings(options) {
/* Helper function to revert to gauges
* default settings
*/
options.ctx.lineWidth = 2;
options.ctx.globalAlpha = 0.5;
options.ctx.strokeStyle = "rgb(255, 255, 255)";
options.ctx.fillStyle = 'rgb(255,255,255)';
}
function drawSmallTickMarks(options) {
/* The small tick marks against the coloured
* arc drawn every 5 mph from 10 degrees to
* 170 degrees.
*/
var tickvalue = options.levelRadius - 8,
iTick = 0,
gaugeOptions = options.gaugeOptions,
iTickRad = 0,
onArchX,
onArchY,
innerTickX,
innerTickY,
fromX,
fromY,
line,
toX,
toY;
applyDefaultContextSettings(options);
// Tick every 20 degrees (small ticks)
for (iTick = 10; iTick < 180; iTick += 20) {
iTickRad = degToRad(iTick);
/* Calculate the X and Y of both ends of the
* line I need to draw at angle represented at Tick.
* The aim is to draw the a line starting on the
* coloured arc and continueing towards the outer edge
* in the direction from the center of the gauge.
*/
onArchX = gaugeOptions.radius - (Math.cos(iTickRad) * tickvalue);
onArchY = gaugeOptions.radius - (Math.sin(iTickRad) * tickvalue);
innerTickX = gaugeOptions.radius - (Math.cos(iTickRad) * gaugeOptions.radius);
innerTickY = gaugeOptions.radius - (Math.sin(iTickRad) * gaugeOptions.radius);
fromX = (options.center.X - gaugeOptions.radius) + onArchX;
fromY = (gaugeOptions.center.Y - gaugeOptions.radius) + onArchY;
toX = (options.center.X - gaugeOptions.radius) + innerTickX;
toY = (gaugeOptions.center.Y - gaugeOptions.radius) + innerTickY;
// Create a line expressed in JSON
line = createLine(fromX, fromY, toX, toY, "rgb(255,255,255)", 3, 0.6);
// Draw the line
drawLine(options, line);
}
}
function drawLargeTickMarks(options) {
/* The large tick marks against the coloured
* arc drawn every 10 mph from 10 degrees to
* 170 degrees.
*/
var tickvalue = options.levelRadius - 8,
iTick = 0,
gaugeOptions = options.gaugeOptions,
iTickRad = 0,
innerTickY,
innerTickX,
onArchX,
onArchY,
fromX,
fromY,
toX,
toY,
line;
applyDefaultContextSettings(options);
tickvalue = options.levelRadius - 2;
// 10 units (major ticks)
for (iTick = 20; iTick < 180; iTick += 20) {
iTickRad = degToRad(iTick);
/* Calculate the X and Y of both ends of the
* line I need to draw at angle represented at Tick.
* The aim is to draw the a line starting on the
* coloured arc and continueing towards the outer edge
* in the direction from the center of the gauge.
*/
onArchX = gaugeOptions.radius - (Math.cos(iTickRad) * tickvalue);
onArchY = gaugeOptions.radius - (Math.sin(iTickRad) * tickvalue);
innerTickX = gaugeOptions.radius - (Math.cos(iTickRad) * gaugeOptions.radius);
innerTickY = gaugeOptions.radius - (Math.sin(iTickRad) * gaugeOptions.radius);
fromX = (options.center.X - gaugeOptions.radius) + onArchX;
fromY = (gaugeOptions.center.Y - gaugeOptions.radius) + onArchY;
toX = (options.center.X - gaugeOptions.radius) + innerTickX;
toY = (gaugeOptions.center.Y - gaugeOptions.radius) + innerTickY;
// Create a line expressed in JSON
line = createLine(fromX, fromY, toX, toY, "rgb(255,255,255)", 3, 0.6);
// Draw the line
drawLine(options, line);
}
}
function drawTicks(options) {
/* Two tick in the coloured arc!
* Small ticks every 5
* Large ticks every 10
*/
drawSmallTickMarks(options);
drawLargeTickMarks(options);
}
function drawTextMarkers(options) {
/* The text labels marks above the coloured
* arc drawn every 10 mph from 10 degrees to
* 170 degrees.
*/
var innerTickX = 0,
innerTickY = 0,
iTick = 0,
gaugeOptions = options.gaugeOptions,
iTickToPrint = 00;
applyDefaultContextSettings(options);
// Font styling
options.ctx.font = 'italic 15px sans-serif';
options.ctx.textBaseline = 'top';
options.ctx.beginPath();
// Tick every 20 (small ticks)
for (iTick = 10; iTick < 180; iTick += 20) {
innerTickX = gaugeOptions.radius - (Math.cos(degToRad(iTick)) * gaugeOptions.radius);
innerTickY = gaugeOptions.radius - (Math.sin(degToRad(iTick)) * gaugeOptions.radius);
// Some cludging to center the values (TODO: Improve)
if (iTick <= 10) {
options.ctx.fillText(iTickToPrint, (options.center.X - gaugeOptions.radius - 12) + innerTickX,
(gaugeOptions.center.Y - gaugeOptions.radius - 12) + innerTickY + 5);
} else if (iTick < 50) {
options.ctx.fillText(iTickToPrint, (options.center.X - gaugeOptions.radius - 12) + innerTickX - 5,
(gaugeOptions.center.Y - gaugeOptions.radius - 12) + innerTickY + 5);
} else if (iTick < 90) {
options.ctx.fillText(iTickToPrint, (options.center.X - gaugeOptions.radius - 12) + innerTickX,
(gaugeOptions.center.Y - gaugeOptions.radius - 12) + innerTickY);
} else if (iTick === 90) {
options.ctx.fillText(iTickToPrint, (options.center.X - gaugeOptions.radius - 12) + innerTickX + 4,
(gaugeOptions.center.Y - gaugeOptions.radius - 12) + innerTickY);
} else if (iTick < 145) {
options.ctx.fillText(iTickToPrint, (options.center.X - gaugeOptions.radius - 12) + innerTickX + 10,
(gaugeOptions.center.Y - gaugeOptions.radius - 12) + innerTickY);
} else {
options.ctx.fillText(iTickToPrint, (options.center.X - gaugeOptions.radius - 12) + innerTickX + 15,
(gaugeOptions.center.Y - gaugeOptions.radius - 12) + innerTickY + 5);
}
// MPH increase by 10 every 20 degrees
//iTickToPrint += Math.round(2160 / 9);
iTickToPrint += 30;
}
options.ctx.stroke();
}
function drawSpeedometerPart(options, alphaValue, strokeStyle, startPos) {
/* Draw part of the arc that represents
* the colour speedometer arc
*/
options.ctx.beginPath();
options.ctx.globalAlpha = alphaValue;
options.ctx.lineWidth = 5;
options.ctx.strokeStyle = strokeStyle;
options.ctx.arc(options.center.X,
options.center.Y,
options.levelRadius,
Math.PI + (Math.PI / 360 * startPos),
0 - (Math.PI / 360 * 10),
false);
options.ctx.stroke();
}
function drawSpeedometerColourArc(options) {
/* Draws the colour arc. Three different colours
* used here; thus, same arc drawn 3 times with
* different colours.
* TODO: Gradient possible?
*/
var startOfGreen = 10,
endOfGreen = 200,
endOfOrange = 280;
drawSpeedometerPart(options, 1.0, "rgb(50,205,50)", startOfGreen);
drawSpeedometerPart(options, 0.9, "rgb(255,165,0)", endOfGreen);
drawSpeedometerPart(options, 0.9, "rgb(255,69,0) ", endOfOrange);
}
function drawNeedleDial(options, alphaValue, strokeStyle, fillStyle,bBackward) {
/* Draws the metallic dial that covers the base of the
* needle.
*/
var i = 0;
options.ctx.globalAlpha = alphaValue;
options.ctx.lineWidth = 3;
options.ctx.strokeStyle = strokeStyle;
if (bBackward==1){
options.ctx.fillStyle = "rgb(255,0,0)";
}
else{
options.ctx.fillStyle = fillStyle;
}
// Draw several transparent circles with alpha
for (i = 0; i < 30; i++) {
options.ctx.beginPath();
options.ctx.arc(options.center.X,
options.center.Y,
i,
0,
Math.PI,
true);
options.ctx.fill();
options.ctx.stroke();
}
}
function convertSpeedToAngle(options) {
/* Helper function to convert a speed to the
* equivelant angle.
*/
var iSpeed = options.speed,
iSpeedAsAngle = (iSpeed)/255 * 180+10;
// Ensure the angle is within range
if (iSpeedAsAngle > 180) {
iSpeedAsAngle = 180;
} else if (iSpeedAsAngle < 10) {
iSpeedAsAngle = 10;
}
return iSpeedAsAngle;
}
function drawNeedle(options,bBackward) {
/* Draw the needle in a nice read colour at the
* angle that represents the options.speed value.
*/
var iSpeedAsAngle = convertSpeedToAngle(options),
iSpeedAsAngleRad = degToRad(iSpeedAsAngle),
gaugeOptions = options.gaugeOptions,
innerTickX = gaugeOptions.radius - (Math.cos(iSpeedAsAngleRad) * 20),
innerTickY = gaugeOptions.radius - (Math.sin(iSpeedAsAngleRad) * 20),
fromX = (options.center.X - gaugeOptions.radius) + innerTickX,
fromY = (gaugeOptions.center.Y - gaugeOptions.radius) + innerTickY,
endNeedleX = gaugeOptions.radius - (Math.cos(iSpeedAsAngleRad) * gaugeOptions.radius),
endNeedleY = gaugeOptions.radius - (Math.sin(iSpeedAsAngleRad) * gaugeOptions.radius),
toX = (options.center.X - gaugeOptions.radius) + endNeedleX,
toY = (gaugeOptions.center.Y - gaugeOptions.radius) + endNeedleY,
line = createLine(fromX, fromY, toX, toY, "rgb(255, 0, 0)", 3, 1);
drawLine(options, line);
// Two circle to draw the dial at the base (give its a nice effect?)
drawNeedleDial(options, 0.6, "rgb(255, 255, 255)", "rgb(255,255,255)",bBackward);
drawNeedleDial(options, 0.2, "rgb(255, 255, 255)", "rgb(127,127,127)",bBackward);
}
function buildOptionsAsJSON(canvas, iSpeed) {
/* Setting for the speedometer
* Alter these to modify its look and feel
*/
var centerX = 210,
centerY = 210,
radius = 150,
outerRadius = 200;
// Create a speedometer object using Javascript object notation
return {
ctx: canvas.getContext('2d'),
speed: iSpeed,
center: {
X: centerX,
Y: centerY
},
levelRadius: radius - 10,
gaugeOptions: {
center: {
X: centerX,
Y: centerY
},
radius: radius
},
radius: outerRadius
};
}
function clearCanvas(options) {
options.ctx.clearRect(0, 0, 800, 600);
applyDefaultContextSettings(options);
}
function drawLabel(options,bBackward)
{
var offsetX=0;
var offsetY=60;
options.ctx.font = '20pt sans-serif';
if(bBackward==0){
options.ctx.strokeStyle='#ffffff';
}else{
options.ctx.strokeStyle='#ff0000';
}
var X=options.center.X;
var Y=options.center.Y;
options.ctx.textAlign = 'center';
//options.ctx.globalCompositeOperation = 'destination-over';
options.ctx.strokeText(options.speed,X-offsetX, Y-offsetY);
options.ctx.textAlign = 'start';
}
function draw() {
/* Main entry point for drawing the speedometer
* If canvas is not support alert the user.
*/
// console.log('Target: ' + iTargetSpeed);
// console.log('Current: ' + iCurrentSpeed);
var canvas = document.getElementById('speedometer'),
options = null;
// Canvas good?
if (canvas !== null && canvas.getContext) {
options = buildOptionsAsJSON(canvas, iCurrentSpeed);
// Clear canvas
clearCanvas(options);
// Draw thw background
drawBackground(options);
// Draw tick marks
drawTicks(options);
// Draw labels on markers
drawTextMarkers(options);
// Draw speeometer colour arc
drawSpeedometerColourArc(options);
// Draw text of dashboard
drawLabel(options,bBackward);
// Draw the needle and base
drawNeedle(options,bBackward);
} else {
alert("Canvas not supported by your browser!");
}
if(iTargetSpeed == iCurrentSpeed) {
clearTimeout(job);
return;
} else if(iTargetSpeed < iCurrentSpeed) {
bDecrement = true;
} else if(iTargetSpeed > iCurrentSpeed) {
bDecrement = false;
}
if(bDecrement) {
if(iCurrentSpeed - 10 < iTargetSpeed)
iCurrentSpeed = iCurrentSpeed - 1;
else
iCurrentSpeed = iCurrentSpeed - 1;
} else {
if(iCurrentSpeed + 10 > iTargetSpeed)
iCurrentSpeed = iCurrentSpeed + 1;
else
iCurrentSpeed = iCurrentSpeed + 1;
}
job = setTimeout("draw()", 5);
}
function drawWithInputValue(mascon) {
iTargetSpeed = mascon;
// Sanity checks
if (isNaN(iTargetSpeed)) {
iTargetSpeed = 0;
} else if (iTargetSpeed < 0) {
iTargetSpeed = 0;
} else if (iTargetSpeed > 255) {
iTargetSpeed = 255;
}
job = setTimeout("draw()", 5);
}
</script>
</body>
</html>
Also see: Tab Triggers