Autodesk Viewer API, not rendering markup to screenshot canvas for new version - markup
Codes runs upto version 2.15.* of the Viewer but doesn't run on higher version. The markup doesn't shows up with the image.
/**
* Get's the markup data as a base 64 image.
*
* #param viewer
* #returns {Promise}
*/
service.getDataFromMarkup = function (viewer) {
if (!viewer) {
throw new Error('Viewer instance not provided');
}
let base64Img = viewer.getScreenShotBuffer();
return loadImageWithData(base64Img).then(img => {
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
let markupCore = viewer.loadedExtensions['Autodesk.Viewing.MarkupsCore'];
let viewerBounds = viewer.container.getBoundingClientRect();
markupCore.generateData();
canvas.width = viewerBounds.width;
canvas.height = viewerBounds.height;
context.drawImage(img, 0, 0, viewerBounds.width, viewerBounds.height);
markupCore.renderToCanvas(context);
return canvas.toDataURL();
});
};
/**
* Returns an <img> DOM element with the provided image as a source.
*
* #param src
* #returns {*}
*/
function loadImageWithData(src) {
return $q((resolve) => {
let img = new Image();
// Resolve with img element when the
// source image has been completely loaded.
img.onload = function () {
resolve(img);
};
img.src = src;
});
}
Prepared a testing sample code that works fine on Viewer 3.3.
Note I'm using a string var markupSVG that contains the definition of the markup in SVG, the code restores this markup, capture the screenshot and restores the Viewer (by hiding the markups). Left with Viewer, right with canvas.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Snapshot with Markup</title>
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/style.min.css?v=v3.3" type="text/css">
</head>
<body>
<body onload="initializeViewer();" style="margin:0px; overflow:hidden">
<div style="width:49vw; height:100vh; position:relative; display:inline-block;">
<div id="viewer3d" style="margin:0;">
</div>
</div>
<div style="width:49vw; height:100vh;display:inline-block;">
<canvas id="snapshot" style="position:absolute;"></canvas>
<button onclick="snaphot();" style="position:absolute;">Snapshot!</button>
</div>
</body>
<!-- The Viewer JS -->
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/three.min.js"></script>
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/viewer3D.js?v=v3.3"></script>
<!-- Developer JS -->
<script>
var viewer;
function initializeViewer() {
// initialize the viewer in "offline" mode (no security from Forge)
var myViewerDiv = document.getElementById('viewer3d');
viewer = new Autodesk.Viewing.Private.GuiViewer3D(myViewerDiv);
var options = {
'env': 'Local',
'document': 'http://autodesk-forge.github.io/viewer-javascript-offline.sample/shaver/0.svf'
};
Autodesk.Viewing.Initializer(options, function () {
viewer.start(options.document, options);
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, function () {
viewer.utilities.fitToView();
});
});
}
function snaphot() {
var screenshot = new Image();
screenshot.onload = function () {
viewer.loadExtension('Autodesk.Viewing.MarkupsCore').then(function (markupCore) {
// load the markups
markupCore.show();
markupCore.loadMarkups(markupSVG, "layerName");
// ideally should also restore state of Viewer for this markup
// prepare to render the markups
var canvas = document.getElementById('snapshot');
canvas.width = viewer.container.clientWidth;
canvas.height = viewer.container.clientHeight;
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(screenshot, 0, 0, canvas.width, canvas.height);
markupCore.renderToCanvas(ctx);
// hide the markups
markupCore.hide();
});
};
// Get the full image
viewer.getScreenShot(viewer.container.clientWidth, viewer.container.clientHeight, function (blobURL) {
screenshot.src = blobURL;
});
}
var markupSVG = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full" style="position:absolute; left:0; top:0; transform:scale(1,-1); -ms-transform:scale(1,-1); -webkit-transform:scale(1,-1); -moz-transform:scale(1,-1); -o-transform:scale(1,-1); transformOrigin:0, 0; -ms-transformOrigin:0, 0; -webkit-transformOrigin:0, 0; -moz-transformOrigin:0, 0; -o-transformOrigin:0, 0; " width="510" height="960" viewBox="-531.25 -1000 1062.5 2000" cursor="crosshair" pointer-events="painted"><metadata><markup_document xmlns="http://www.w3.org/1999/xhtml" data-model-version="4"></markup_document></metadata><g cursor="inherit" pointer-events="stroke"><metadata><markup_element xmlns="http://www.w3.org/1999/xhtml" stroke-width="10.416666666666629" stroke-linejoin="miter" stroke-color="#ff0000" stroke-opacity="1" fill-color="#ff0000" fill-opacity="0" type="cloud" position="-48.958333333333336 307.2916666666667" size="418.75 377.08333333333337" rotation="0"></markup_element></metadata><path id="markup" d="M -183.75000000000003 -142.59259259259264 a 20.416666666666668 20.37037037037037 0 1 1 20.416666666666668 -20.37037037037037 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 a 20.416666666666668 20.37037037037037 0 1 1 20.416666666666668 20.37037037037037 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 a 20.416666666666668 20.37037037037037 0 1 1 -20.416666666666668 20.37037037037037 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 a 20.416666666666668 20.37037037037037 0 1 1 -20.416666666666668 -20.37037037037037 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 z" stroke-width="10.416666666666629" stroke="rgba(255,0,0,1)" fill="none" transform="translate( -48.958333333333336 , 307.2916666666667 ) rotate( 0 )"/></g></svg>';
</script>
</body>
</html>
Related
handling objects offscreen for a view frustum
I have a view frustum that works great when looking at stuff from a distance. But for example, when i stand in the middle of a square, my current system struggles to place vertices which are behind me. For example the image below demonstrates looking at a tile from a distance vs standing on top of it ... My proccess for putting things onto screen can be described in 5 steps cross product the co-ordinates of the object with my camera matrix cross product the result of 1 with my projection_matrix normalize the result of 2 by dividing through the 4th dimension of my co-ordinates (my w co-ordinate) cull results of 3 (its not causing the problem, i tried without culling) cross product 4 with to_screen_matrix Basically the problem i have, is this procces is great at putting things on the screen but sometimes an object isnt on the screen... what co-ordinates should be used then? Below is a drawing of what i think the problem is below is my screen_projection function return_screen_projection(dont_cull = false){ var position = cross_product(this.position , player.camera_matrix()) position = cross_product(position , projection.projection_matrix) // does this just convert the position to cameras reference frame. for (let i = 0; i < position.length; i++) { position[i] = position[i]/position[3] } if (dont_cull == false){ for (let i = 0; i < position.length; i++) { if (i != 1){ if (this.is_this_object_behind_player()){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling1")} if (position[i] > 2){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling2")} if (position[i] < -2){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling3")} } } // also all examples say set position = 0 if culling } position = cross_product(position , projection.to_screen_matrix) return [position[0],position[1]] } how could i better handle the position of a vertex offscreen, when some vertexes of the object im dealing with are on screen? ################## extra info below below is a blob of 300 lines of code (sorry , i cant make it more minimal and reproducable with just a copy n paste) running the below in a web browser will give you an example of the problem (w,a,s,d) to move (you start mired in the middle of an object, you may wish to step back to see better the first time) <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/11.3.3/math.js"></script> <script async src="https://unpkg.com/es-module-shims#1.3.6/dist/es-module-shims.js"></script> </head> <body> <div id="canvas div" style = "position: relative; left: 0px; float:left; top: 0px;" > <h1> first person below </h1> <canvas id="mi_canvas" width="300" height="300" style="border-style: solid;"></canvas> <br> </div> <script> var floor_y_pos = 9 canvas = document.getElementById("mi_canvas"); ctx = canvas.getContext("2d"); render_distance = 1000; fov = math.pi / 2 class Projection{ constructor(){ var NEAR = player.near_plane var FAR = player.far_plane var RIGHT = Math.tan(player.h_fov/2) var LEFT = - RIGHT var TOP = Math.tan(player.v_fov /2) var BOTTOM = -TOP var m00 = 2*NEAR / (RIGHT - LEFT) var m02 = (RIGHT + LEFT)/(RIGHT - LEFT) var m11 = 2*NEAR / (TOP - BOTTOM) var m12 = (TOP + BOTTOM) /(TOP - BOTTOM) var m22 = (FAR * NEAR) / (FAR - NEAR) var m23 = -2 * NEAR * FAR / (FAR-NEAR) this.projection_matrix = [ [-m00,0,m02,0], [0,m11,0,0], [m02,m12,-m22,-1], [0,0,m23,0] ] var HW=player.H_WIDTH var HH = player.H_HEIGHT this.to_screen_matrix = [ [HW,0,0,0], [0,HH,0,0], [0,0,1,0], [HW,HH,0,1] ] } } function multiply(a, b) { var aNumRows = a.length, aNumCols = a[0].length, bNumRows = b.length, bNumCols = b[0].length, m = new Array(aNumRows); // initialize array of rows for (var r = 0; r < aNumRows; ++r) { m[r] = new Array(bNumCols); // initialize the current row for (var c = 0; c < bNumCols; ++c) { m[r][c] = 0; // initialize the current cell for (var i = 0; i < aNumCols; ++i) { m[r][c] += a[r][i] * b[i][c]; } } } return m; } function mi_position_matrix_multiplier(A, B) { var new_matrix = [] for (var new_num_ind = 0; new_num_ind < A.length; ++new_num_ind) { this_num = 0; for (var a_ind = 0; a_ind < A.length; ++a_ind) { this_num += (A[a_ind] * B[a_ind][new_num_ind]) } new_matrix.push(this_num) } return new_matrix; } function pythagoras(thing1, thing2) { dist = (((thing1[0]-thing2[0])**2)+((thing1[1]-thing2[1])**2))**0.5 return dist } class vertex{ constructor(x, y,z , id){ this.id = id this.position = [x,y,z,1] this.min_dist = 1.5 // minimum possible distance between player and object } is_this_object_behind_player(){ var arrow_length = 0.0001; var pointing_position = [player.position[0]+(player.forward[0]*arrow_length) , player.position[2]-(player.forward[2]*arrow_length)] var dist1 = pythagoras([this.position[0],this.position[2]], pointing_position) var dist2 = pythagoras([this.position[0],this.position[2]], [player.position[0],player.position[2]]) if (dist1 < dist2){ return true;} else if (dist1 > dist2){ return false;} else{} } return_screen_projection(dont_cull = false){ var position = mi_position_matrix_multiplier(this.position , player.camera_matrix()) position = mi_position_matrix_multiplier(position , projection.projection_matrix) // does this just convert the position to cameras reference frame. for (let i = 0; i < position.length; i++) { position[i] = position[i]/position[3] } if (dont_cull == false){ for (let i = 0; i < position.length; i++) { if (i != 1){ if (this.is_this_object_behind_player()){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling1")} if (position[i] > 2){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling2")} if (position[i] < -2){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling3")} } } // also all examples say set position = 0 if culling } position = mi_position_matrix_multiplier(position , projection.to_screen_matrix) return [position[0],position[1]] } } class player{ constructor(){ this.position =[0,0,0,1.0] this.forward = [0,0,1,1] this.up = [0,1,0,1] this.right =[1,0,0,1] this.h_fov = 3.1415926535/3 this.v_fov = this.h_fov * (canvas.height / canvas.width) this.near_plane = 1 this.far_plane = 100 this.moving_speed = 0.2 this.rotation_speed = 0.1 this.H_WIDTH = canvas.width/2 this.H_HEIGHT = canvas.height/2 this.anglePitch = 0 this.angleYaw = 0 } set_camera_angle(){ var rotate = multiply(rotate_x(this.anglePitch) , rotate_y(this.angleYaw)) this.forward = [0, 0, 1, 1] this.up = [0, 1, 0, 1] this.right = [1, 0, 0, 1] this.forward = mi_position_matrix_multiplier(this.forward , rotate) this.right = mi_position_matrix_multiplier(this.right , rotate) this.up = mi_position_matrix_multiplier(this.up , rotate) } camera_yaw(angle){ this.angleYaw += angle} translate_matrix(self){ var x = this.position[0]; var y = this.position[1]; var z = this.position[2]; var w = this.position[3]; return [ [1,0,0,0], [0,1,0,1], [0,0,1,0], [-x,-y,z, 1] ]} rotate_matrix(){ var rx = this.right[0] var ry = this.right[1] var rz = this.right[2] var w = this.right[3] var fx = this.forward[0] var fy = this.forward[1] var fz = this.forward[2] var w = this.forward[3] var ux = this.up[0] var uy = this.up[1] var uz = this.up[2] var w = this.up[3] return [ [rx,ux,fx,0], [ry,uy,fy,0], [rz,uz,fz,0], [0,0,0,1] ] } camera_matrix(){ return multiply(this.translate_matrix(), this.rotate_matrix()); } move(event) { var key_code = parseInt(event.keyCode) if (key_code == 37 || key_code == 39 || key_code == 83 || key_code == 87 || key_code == 119|| key_code == 115) { var dx = Math.cos(this.angleYaw)*this.moving_speed var dy = Math.sin(this.angleYaw)*this.moving_speed // console.log("that were moving = dx , dy = "+dx.toString()+" , "+dy.toString()) if ( key_code == 37 || key_code == 87 || key_code == 119) { this.position[0] += -dy this.position[2] += dx } if (key_code == 39 || key_code == 83 || key_code == 115) { for (let i = 0; i < this.position.length; i++) { this.position[0] += dy this.position[2] += -dx } } } else { if ( key_code == 38 || key_code == 65 || key_code == 97) { this.camera_yaw(-this.rotation_speed) } if (key_code == 40 || key_code == 68 || key_code == 100) { this.camera_yaw(this.rotation_speed) } this.set_camera_angle() } } } function translate(pos){ tx,ty,tz=pos return np.array([ [1,0,0,0], [0,1,0,0], [0,0,1,0], [tx,ty,tz,1] ])} function rotate_x(angle){ return [ [1,0,0,0], [0,Math.cos(angle),Math.sin(angle),0], [0,-Math.sin(angle),Math.cos(angle),0], [0,0,0,1] ] } function rotate_y(a){ return [ [math.cos(a),0, -math.sin(a),0], [0,1,0,0], [math.sin(a), 0 , math.cos(a),0], [0,0,0,1] ] } function update_matrix_info_debug(matrix_name, matrix){ if (matrix[0].length > 1) { for (let x = 1; x < matrix.length+1; x++) { for (let y = 1; y < matrix.length+1; y++) { document.getElementById(matrix_name.toString()+"_"+x.toString()+y.toString()).innerHTML = matrix[x-1][y-1] } } } else { for (let x = 1; x < matrix.length+1; x++) {document.getElementById(matrix_name.toString()+"_"+"1"+x.toString()).innerHTML = matrix[x-1]} } } class two_d_surdace { constructor(verex1,verex2,verex3,verex4 , colour){ this.vertices = [verex1,verex2,verex3,verex4] this.colour = colour } draw_all_faces(){ var each_point = [] for (let i = 0; i < this.vertices.length; i++) { each_point.push(this.vertices[i].return_screen_projection(true)) } ctx.fillStyle = this.colour; var moved_to_first_yet = false for (let vertex = 0; vertex < this.vertices.length; vertex++) { if (moved_to_first_yet == false) { moved_to_first_yet = true ctx.moveTo( each_point[vertex][0],each_point[vertex][1]); } else{ctx.lineTo( each_point[vertex][0],each_point[vertex][1]);} } ctx.closePath(); ctx.fill(); } } function if_off_screen(x, y) { if (x> canvas.width || x < 0){ return true;} if (y > canvas.height || y < 0){ return true;} return false; } function if_most_of_these_numbers_are_off_screen(numbers){ var threshold = 1; //Math.floor(numbers.length*0.49) var counter = 0 for (let i = 0; i < numbers.length; i++) { if (if_off_screen(numbers[i][0], numbers[i][1])){ counter +=1} else{} } if (counter >= threshold){return true} return false; } player = new player(); projection = new Projection() floor = new two_d_surdace(new vertex(50,floor_y_pos,50) , new vertex(-50,floor_y_pos,50) , new vertex(-50,floor_y_pos,-50) , new vertex(50,floor_y_pos,-50) , '#F90' ) $(document).on("keypress", function (event) { player.move(event) ctx.beginPath(); ctx.clearRect(0, 0, canvas.width, canvas.height); floor.draw_all_faces() }); </script> </body>
How to output an image caption in custom typoscript template?
I use an image from page resources as a header image of the page. I could not find a solution to output the image caption (description). Here is the code. lib.headerImage = COA lib.headerImage { 30 = FILES 30 { references { table = pages uid.data = page:uid fieldName = media } begin = 0 renderObj = IMAGE renderObj { file { import.data = file:current:uid treatIdAsReference = 1 maxW = 640 maxH = 360 } altText.data = file:current:alternative titleText.data = file:current:title layoutKey = picture layout { picture { element = <picture class="header-image__picture">###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS### />###CAPTION###</picture> source = <source srcset="###SRC###" media="###MEDIAQUERY###" /> } } sourceCollection { big { maxW = 2000 maxH = 1080 mediaQuery = (min-width: 1025px) } small { maxW = 640 maxH = 360 mediaQuery = (max-width: 767px) } } } maxItems = 1 } wrap = <div class="header-image">|</div> } Is it possible somehow to output the caption in the mark ###CAPTION### ? or somewhere below the image? or it is better to use FLUID instead of typoscript ?
I found a solution. I put the image object inside COA renderObj = COA renderObj { 10 = IMAGE 10 { file { import.data = file:current:uid treatIdAsReference = 1 maxW = 640 maxH = 360 } altText.data = file:current:alternative titleText.data = file:current:title layoutKey = picture layout { picture { element = <picture class="header-image__picture">###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS### /></picture> source = <source srcset="###SRC###" media="###MEDIAQUERY###" /> } } sourceCollection { big { maxW = 2000 maxH = 1080 mediaQuery = (min-width: 1025px) } small { maxW = 640 maxH = 360 mediaQuery = (max-width: 767px) } } } 20 = TEXT 20.data = file:current:description }
Porting ESP32 CameraWebServer example to https
I am trying to run the Arduino-ESP32 CameraWebServer example on https instead of http. I started by including esp_https_server.h instead of esp_http_server.h and changing the startCameraServer() function as follows: void startCameraServer(){ #ifndef _ESP_HTTPS_SERVER_H_ httpd_config_t config = HTTPD_DEFAULT_CONFIG(); #else httpd_ssl_config config = HTTPD_SSL_CONFIG_DEFAULT(); config.cacert_len = cert->getCertLength(); config.cacert_pem = cert->getCertData(); config.prvtkey_len = cert->getPKLength(); config.prvtkey_pem = cert->getPKData(); #endif httpd_uri_t index_uri = { .uri = "/", .method = HTTP_GET, .handler = index_handler, .user_ctx = NULL }; httpd_uri_t status_uri = { .uri = "/status", .method = HTTP_GET, .handler = status_handler, .user_ctx = NULL }; httpd_uri_t cmd_uri = { .uri = "/control", .method = HTTP_GET, .handler = cmd_handler, .user_ctx = NULL }; httpd_uri_t capture_uri = { .uri = "/capture", .method = HTTP_GET, .handler = capture_handler, .user_ctx = NULL }; httpd_uri_t stream_uri = { .uri = "/stream", .method = HTTP_GET, .handler = stream_handler, .user_ctx = NULL }; ra_filter_init(&ra_filter, 20); mtmn_config.type = FAST; mtmn_config.min_face = 80; mtmn_config.pyramid = 0.707; mtmn_config.pyramid_times = 4; mtmn_config.p_threshold.score = 0.6; mtmn_config.p_threshold.nms = 0.7; mtmn_config.p_threshold.candidate_number = 20; mtmn_config.r_threshold.score = 0.7; mtmn_config.r_threshold.nms = 0.7; mtmn_config.r_threshold.candidate_number = 10; mtmn_config.o_threshold.score = 0.7; mtmn_config.o_threshold.nms = 0.7; mtmn_config.o_threshold.candidate_number = 1; face_id_init(&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES); #ifndef _ESP_HTTPS_SERVER_H_ Serial.printf("Starting web server on port: '%d'\n", config.server_port); if (httpd_start(&camera_httpd, &config) == ESP_OK) { #else Serial.printf("Starting web server on port: '%d'\n", config.port_secure); if (httpd_ssl_start(&camera_httpd, &config) == ESP_OK) { #endif httpd_register_uri_handler(camera_httpd, &index_uri); httpd_register_uri_handler(camera_httpd, &cmd_uri); httpd_register_uri_handler(camera_httpd, &status_uri); httpd_register_uri_handler(camera_httpd, &capture_uri); } #ifndef _ESP_HTTPS_SERVER_H_ config.server_port += 1; config.ctrl_port += 1; Serial.printf("Starting stream server on port: '%d'\n", config.server_port); if (httpd_start(&stream_httpd, &config) == ESP_OK) { #else config.port_secure += 1; config.httpd.ctrl_port += 1; Serial.printf("Starting stream server on port: '%d'\n", config.port_secure); if (httpd_ssl_start(&stream_httpd, &config) == ESP_OK) { #endif httpd_register_uri_handler(stream_httpd, &stream_uri); } } If I include esp_http_server.h the original code will compile and everything runs fine. If I include esp_https_server.h the changes will compile and the webserver nicely comes up at port 443. The menu shows and I can get a still from the camera. The only thing that doesn't work is what it's all about: the live stream. The video window shows but only with a broken image icon. I see no messages in the terminal window in PlatformIO or anything in the browser's console. The stream_handler function, defined in stream_uri, is called when using http but not when using https. My knowledge about webserver software is very minimalistic, I have no idea where to look further. Does anybody know if I could get this working, any ideas?
Amchart with two lines
i have an amchart with two lines: <script type="text/javascript"> var chart; var graph; var chartData2 = [ {"year":"2014-10-04 23:30:03", "v1":9.1, "v2":0}, {"year":"2014-10-04 23:45:02", "v1":8.8, "v2":86.2}, ... {"year":"2014-10-05 23:30:02", "v1":8.7, "v2":98.7}, {"year":"2014-10-05 23:45:02", "v1":8.5, "v2":98.7}, {"year":"2014-10-06 00:00:01", "v1":8.4, "v2":98.5}, {"year":"2014-10-06 00:15:02", "v1":8.5, "v2":98.3}, {"year":"2014-10-06 00:30:01", "v1":8.4, "v2":97.9} ]; AmCharts.ready(function () { // SERIAL CHART chart = new AmCharts.AmSerialChart(); chart.pathToImages = "../amcharts/images/"; chart.dataProvider = chartData2; chart.marginLeft = 10; chart.categoryField = "year"; chart.dataDateFormat = "JJ:NN:SS"; //chart.addListener("dataUpdated", zoomChart); // AXES // category var categoryAxis = chart.categoryAxis; categoryAxis.parseDates = true; categoryAxis.minPeriod = "100"; categoryAxis.dashLength = 3; categoryAxis.minorGridEnabled = true; categoryAxis.minorGridAlpha = 0.1; // value var valueAxis = new AmCharts.ValueAxis(); valueAxis.id = "ax1"; valueAxis.axisAlpha = 0; valueAxis.inside = true; valueAxis.dashLength = 3; valueAxis.position = "right"; chart.addValueAxis(valueAxis); var valueAxis2 = new AmCharts.ValueAxis(); valueAxis2.id = "ax2"; valueAxis2.axisAlpha = 0; valueAxis2.inside = true; valueAxis2.dashLength = 3; valueAxis2.baseValue = -20; valueAxis2.position = "left"; chart.addValueAxis(valueAxis2); // GRAPH graph = new AmCharts.AmGraph(); graph.valueaxis = "ax1"; graph.type = "smoothedLine"; graph.lineColor = "#d1655d"; graph.negativeLineColor = "#637bb6"; graph.bullet = "square"; graph.bulletSize = 8; graph.bulletBorderColor = "#FFFFFF"; graph.bulletBorderAlpha = 1; graph.bulletBorderThickness = 2; graph.lineThickness = 2; graph.valueField = "v1"; graph.title = "title v1"; graph.balloonText = "[[category]]<br><b><span style='font-size:14px;'>[[value]]</span></b>"; chart.addGraph(graph); graph2 = new AmCharts.AmGraph(); graph2.valueAxis = "ax2"; graph2.type = "smoothedLine"; graph2.lineColor = "#d1655d"; graph2.negativeLineColor = "#637bb6"; graph2.bullet = "round"; graph2.bulletSize = 8; graph2.bulletBorderColor = "#FFFFFF"; graph2.bulletBorderAlpha = 1; graph2.bulletBorderThickness = 2; graph2.lineThickness = 2; graph2.valueField = "v2"; graph2.title = "title v2"; graph2.balloonText = "[[category]]<br><b><span style='font-size:14px;'>[[value]]</span></b>"; chart.addGraph(graph2); // CURSOR var chartCursor = new AmCharts.ChartCursor(); chartCursor.cursorAlpha = 0; chartCursor.cursorPosition = "mouse"; chartCursor.categoryBalloonDateFormat = "JJ:NN:SS"; chart.addChartCursor(chartCursor); // SCROLLBAR var chartScrollbar = new AmCharts.ChartScrollbar(); chart.addChartScrollbar(chartScrollbar); chart.creditsPosition = "bottom-right"; // WRITE chart.write("chartdiv2"); }); I can see the x-and y-axis, but no lines with values. Can anyone please help me?
Two problems: dataDateFormat is incorrect, should be: chart.dataDateFormat = "YYYY-MM-DD JJ:NN:SS"; minPeriod is incorrect, should be: categoryAxis.minPeriod = "ss";
loading multiple collada objects at the same time Three.js
i have to load the same collada object multiple times. Here is the code var ai = []; function setupAI() { var c = getMapSector(cam.position); var loader = new THREE.ColladaLoader(); loader.options.convertUpAxis = true; loader.load('models/monster.DAE',function colladaReady( collada ){ var op = collada.scene; skin = collada.skins [ 0 ]; for (var i = 0; i < NUMAI; i++) { var o = THREE.SceneUtils.cloneObject(op); o.scale.x = o.scale.y = o.scale.z = 0.006; o.updateMatrix(); do { var x = getRandBetween(0, mapW-1); var z = getRandBetween(0, mapH-1); } while (map[x][z] > 0 || (x == c.x && z == c.z)); x = Math.floor(x - mapW/2) * UNITSIZE; z = Math.floor(z - mapW/2) * UNITSIZE; o.position.set(x, UNITSIZE * 0.15, z); o.health = 100; //o.path = getAIpath(o); o.pathPos = 1; o.lastRandomX = Math.random(); o.lastRandomZ = Math.random(); o.lastShot = Date.now(); // Higher-fidelity timers aren't a big deal here. ai.push(o); scene.add(o); } }); } but this gives error in this line var o = THREE.SceneUtils.cloneObject(op); but if i put loader inside the loop it becomes heavy and not load in browser.